• Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    nguyensang270983 > 05-04-17, 03:08 PM

    Cho mình hỏi, mình có chạy file của bạn nhưng bị báo lỗi: Module Source: modQuanlydulieu. Mình muốn hỏi bạn như sau: mình có tập tin access 2003  trên máy chủ đường dẫn như sau: "\\10.162.22.222\DULIEU\DATA_NHANSU.MDB". Mình có 1 file là chứa các giao diện dữ liệu trên, mình muốn kết nối file này vào đường dẫn chứa dữ liệu như trên thì làm sau?
    mình thử kết nối module của bạn nhưng bị báo lỗi. Cảm ơn
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    maidinhdan > 06-04-17, 01:15 AM

    (05-04-17, 03:08 PM)nguyensang270983 Đã viết: Cho mình hỏi, mình có chạy file của bạn nhưng bị báo lỗi: Module Source: modQuanlydulieu. Mình muốn hỏi bạn như sau: mình có tập tin access 2003  trên máy chủ đường dẫn như sau: "\\10.162.22.222\DULIEU\DATA_NHANSU.MDB". Mình có 1 file là chứa các giao diện dữ liệu trên, mình muốn kết nối file này vào đường dẫn chứa dữ liệu như trên thì làm sau?
    mình thử kết nối module của bạn nhưng bị báo lỗi. Cảm ơn

    Trả lời:
    Khi bạn đặt câu hỏi: "trên máy chủ đường dẫn như sau: "\\10.162.22.222\DULIEU\DATA_NHANSU.MDB" thì câu hỏi này chẳng liên quan đến chủ đề này. Nên nó báo lỗi là đúng rồi.

    Lý do: Bài viết này máy chủ phải là Database SQL Server


    Vài góp ý khi nhìn vào.
    + Xác định đúng IP Public hay IP Private.
    + Dataabse (DBMS) là: DATA_NHANSU.MDB thì bạn phải tìm hiểu về các kiểu kết nối liên quan đến Link table, hay dùng ADO hoặc DAO để kết nối đến cái file này và chú ý quan trọng nhất đó là chuỗi kết nối ( Connection String)
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    lehongduc > 09-06-17, 03:19 PM

    Chào các Bạn,

    Theo yêu cầu của nhiều Bạn, tôi xin gửi lên đây link tải file dữ liệu MS SQL SERVER để các Bạn có thể tùy nghi sử dụng làm file dữ liệu kiểm tra cho loạt bài trong chủ đề này.

    Link tải xuống: http://www.mediafire.com/file/x3c2h3gswa...4_1735.zip
    Đây là file backup (.bak), các Bạn dùng lệnh Restore Database trong SQL SERVER để phục hồi lại.

    Khối lượng dữ liệu phát sinh trong database này như sau:
    1. Bảng tblDanhsach (danh sách khách hàng): 7.592 mẫu tin
    2. Bảng tbldonvitinh (bảng đăng ký đơn vị tính của từng mặt hàng): 13.941 mẫu tin
    3. Bảng tblctunx (chứng từ nhập xuất kho): 36.570 mẫu tin, mỗi mẫu tin là 1 chứng từ
    4. Bảng tblctunxct (chi tiết chứng từ nhập xuất kho): 96.165 mẫu tin
    5. Bảng tbldmhanghoa (danh mục hàng hóa): 10.410 mẫu tin, mỗi mẫu tin là 1 mặt hàng



    Chúc sức khỏe tất cả các Bạn.
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    ongke0711 > 09-06-17, 06:14 PM

    Mới chuyển qua ngâm cứu SQL Server + Access và ngâm cứu mấy cái demo của anh lehongduc và đang ngồi tạo CSDL mẫu thì anh post cái file .bak lên. Đúng lúc thật  007 .
    Cảm ơn anh nhé.
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    ongke0711 > 13-06-17, 04:34 PM

    Cho hỏi về lấy dữ liệu cho combobox trong demo của anh lehongduc.
    Tôi thấy anh lehongduc dung ADO recordset để load dữ liệu về cho combobox, tại sao không dùng Pass through query làm Row source cho combobox vậy? Sau khi thiết lập kết nối với SQL server, sẽ cập lại chuỗi ODBC Connection cho toàn bộ pass through query rồi dùng thôi.

    Ví dụ:

    Mã PHP:
    qdf.Connect "ODBC;" GetConnectString() 

    Mã PHP:
    Option Explicit

    Global gstrConnectString As String

    Public Function GetConnectString() As String
       On Error 
    GoTo Error_Handler

       gstrConnectString 
    "DRIVER={SQL Server}" & (";SERVER=" vServer) & ";UID=" vUser & (";PWD=" vPsw) & (";DATABASE=" vData) & ";Network=DBMSSOCN"

       GetConnectString gstrConnectString

    Exit_Procedure
    :
       On Error Resume Next
       Exit 
    Function
    Error_Handler:
       GetConnectString ""
       MsgBox Err.Number ", " Err.Description
       Resume Exit_Procedure
       Resume
    End 
    Function 

    Cũng mới ngâm cứu ADO + SQL Server nên cũng chưa nắm hết thủ thuật đằng sau nó. Các bác giải thích giùm nhé.
    Cảm ơn.  007
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    lehongduc > 14-06-17, 08:34 AM

    (13-06-17, 04:34 PM)ongke0711 Đã viết: Cho hỏi về lấy dữ liệu cho combobox trong demo của anh lehongduc.
    Tôi thấy anh lehongduc dung ADO recordset để load dữ liệu về cho combobox, tại sao không dùng Pass through query làm Row source cho combobox vậy? Sau khi thiết lập kết nối với SQL server, sẽ cập lại chuỗi ODBC Connection cho toàn bộ pass through query rồi dùng thôi.

    Ví dụ:

    Mã PHP:
    qdf.Connect "ODBC;" GetConnectString() 

    Mã PHP:
    Option Explicit

    Global gstrConnectString As String

    Public Function GetConnectString() As String
       On Error 
    GoTo Error_Handler

       gstrConnectString 
    "DRIVER={SQL Server}" & (";SERVER=" vServer) & ";UID=" vUser & (";PWD=" vPsw) & (";DATABASE=" vData) & ";Network=DBMSSOCN"

       GetConnectString gstrConnectString

    Exit_Procedure
    :
       On Error Resume Next
       Exit 
    Function
    Error_Handler:
       GetConnectString ""
       MsgBox Err.Number ", " Err.Description
       Resume Exit_Procedure
       Resume
    End 
    Function 

    Cũng mới ngâm cứu ADO + SQL Server nên cũng chưa nắm hết thủ thuật đằng sau nó. Các bác giải thích giùm nhé.
    Cảm ơn.  007
    Chào các Bạn,
    Lý do tôi dùng ADO Recordset thay vì dùng SQL pass-through query là như vậy sẽ linh hoạt và nhẹ nhàng hơn.
    Các Bạn có thể tham khảo thêm hướng dẫn của Microsoft về SQL pass-through query ở link sau để biết rõ hơn lý do tôi đã nêu ở trên:
    https://support.microsoft.com/vi-vn/help...-in-access

    Và còn một lý do nữa, rất quan trọng, và là chủ đích của tôi: tôi có dụng ý muốn hướng các Bạn đến mục tiêu chuyển toàn bộ việc xử lý dữ liệu (truy xuất, tạo, tìm, xóa, ...) cho server thực hiện, không thực hiện việc này ở máy khách. Cái này gọi là ứng dụng Front-End đó các Bạn.
    Với mục tiêu đó, ứng dụng Access của chúng ta sẽ chủ yếu sử dụng các công cụ trình bày như Form, Report và code bằng ADO. 

    Trong khi query của Access thực chất là công cụ để truy xuất dữ liệu của bản thân Access. 

    Mục tiêu này tôi có nói rõ trong loạt bài tôi đã đăng ở chuyên mục này, nhưng chưa thể hiện rõ rệt trong bản demo của tôi.
    Bản demo của tôi xử lý dữ liệu bằng việc truyền các câu lệnh SQL đến server thông qua code ADO. Đó chưa phải là tối ưu, mà nên là truy xuất các công cụ xử lý dữ liệu của server bằng code ADO. Các công cụ xử lý dữ liệu của server (cụ thể ở đây là MS SQL SERVER) bao gồm:
    + View
    + Store Procedure
    + Function
    + ...
    Trong database làm demo của tôi chỉ thuần túy là các bảng (tables), chẳng có 1 object cụ thể nào của các công cụ xử lý dữ liệu kể trên cả các Bạn ạ. Đó là điều hạn chế rất lớn của database này.
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    lehongduc > 14-06-17, 09:02 AM

    (13-06-17, 04:34 PM)ongke0711 Đã viết: Cho hỏi về lấy dữ liệu cho combobox trong demo của anh lehongduc.
    Tôi thấy anh lehongduc dung ADO recordset để load dữ liệu về cho combobox, tại sao không dùng Pass through query làm Row source cho combobox vậy? Sau khi thiết lập kết nối với SQL server, sẽ cập lại chuỗi ODBC Connection cho toàn bộ pass through query rồi dùng thôi.

    Ví dụ:

    Mã PHP:
    qdf.Connect "ODBC;" GetConnectString() 

    Mã PHP:
    Option Explicit

    Global gstrConnectString As String

    Public Function GetConnectString() As String
       On Error 
    GoTo Error_Handler

       gstrConnectString 
    "DRIVER={SQL Server}" & (";SERVER=" vServer) & ";UID=" vUser & (";PWD=" vPsw) & (";DATABASE=" vData) & ";Network=DBMSSOCN"

       GetConnectString gstrConnectString

    Exit_Procedure
    :
       On Error Resume Next
       Exit 
    Function
    Error_Handler:
       GetConnectString ""
       MsgBox Err.Number ", " Err.Description
       Resume Exit_Procedure
       Resume
    End 
    Function 

    Cũng mới ngâm cứu ADO + SQL Server nên cũng chưa nắm hết thủ thuật đằng sau nó. Các bác giải thích giùm nhé.
    Cảm ơn.  007

    Chào các Bạn,
    Thêm một lý do nữa: nếu các Bạn tạo các query trên ứng dụng Access để truy xuất dữ liệu từ server, điều bắt buộc là phải duy trì kết nối liên tục với server từ đầu cho đến khi đóng ứng dụng. Trong khi thực tế đâu phải lúc nào ta cũng cần kết nối với server. Quy tắc tối ưu ứng dụng là chỉ kết nối khi cần, khi không cần thì ngắt kết nối. Tại sao nên làm như vậy? Tôi đã trình bày lý do rất rõ ràng trong loạt bài của tôi đăng trong chuyên mục này rồi. Các Bạn có thể tham khảo lại nếu cần.
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    lehongduc > 14-06-17, 10:04 AM

    Chào các Bạn,
    Bạn nào muốn tìm hiểu về Microsoft Access Pass-Through Queries để hiểu rõ hơn vấn đề tiện dùng hay không tiện dùng, có thể đọc những bài sau, hướng dẫn thao tác rõ ràng, rất dễ hiểu, tất nhiên là bằng tiếng Anh:

    https://support.office.com/en-us/article...ac62532a42

    https://www.mssqltips.com/sqlservertip/1...ql-server/

    https://www.mssqltips.com/sqlservertip/1...-database/

    https://www.mssqltips.com/sqlservertip/1...tegration/
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    hoanbhxhls > 14-06-17, 10:15 AM

    (14-06-17, 09:02 AM)lehongduc Đã viết:
    (13-06-17, 04:34 PM)ongke0711 Đã viết: Cho hỏi về lấy dữ liệu cho combobox trong demo của anh lehongduc.
    Tôi thấy anh lehongduc dung ADO recordset để load dữ liệu về cho combobox, tại sao không dùng Pass through query làm Row source cho combobox vậy? Sau khi thiết lập kết nối với SQL server, sẽ cập lại chuỗi ODBC Connection cho toàn bộ pass through query rồi dùng thôi.

    Ví dụ:

    Mã PHP:
    qdf.Connect "ODBC;" GetConnectString() 

    Mã PHP:
    Option Explicit

    Global gstrConnectString As String

    Public Function GetConnectString() As String
       On Error 
    GoTo Error_Handler

       gstrConnectString 
    "DRIVER={SQL Server}" & (";SERVER=" vServer) & ";UID=" vUser & (";PWD=" vPsw) & (";DATABASE=" vData) & ";Network=DBMSSOCN"

       GetConnectString gstrConnectString

    Exit_Procedure
    :
       On Error Resume Next
       Exit 
    Function
    Error_Handler:
       GetConnectString ""
       MsgBox Err.Number ", " Err.Description
       Resume Exit_Procedure
       Resume
    End 
    Function 

    Cũng mới ngâm cứu ADO + SQL Server nên cũng chưa nắm hết thủ thuật đằng sau nó. Các bác giải thích giùm nhé.
    Cảm ơn.  007

    Chào các Bạn,
    Thêm một lý do nữa: nếu các Bạn tạo các query trên ứng dụng Access để truy xuất dữ liệu từ server, điều bắt buộc là phải duy trì kết nối liên tục với server từ đầu cho đến khi đóng ứng dụng. Trong khi thực tế đâu phải lúc nào ta cũng cần kết nối với server. Quy tắc tối ưu ứng dụng là chỉ kết nối khi cần, khi không cần thì ngắt kết nối. Tại sao nên làm như vậy? Tôi đã trình bày lý do rất rõ ràng trong loạt bài của tôi đăng trong chuyên mục này rồi. Các Bạn có thể tham khảo lại nếu cần.

    -Mục tiêu bài viết này là hướng các bạn cách lập trình ADO+SQL server ,đặc biệt cách lập trình unbound control
    -Một số module trong ứng dụng này,rất hiệu quả,đặc biệt khi số lượng người dùng nhiều và dữ liệu lớn
    -Mình rất tâm đắc với bài viết này,hiện tại mình đã bỏ hẳn database là mdb chuyển sang sql server
  • RE: Sử dụng Class Module và Kết nối dữ liệu SQL SERVER trong Access VBA

    lehongduc > 15-06-17, 06:09 PM

    Chào các Bạn,
    Có Bạn vừa gửi email hỏi tôi nội dung tóm tắt như sau:
    Trích dẫn:Cần lấy tổng số mẫu tin trong 1 bảng dữ liệu sql server (kết nối từ ứng dụng MS Access), nhưng nếu dùng MoveLast của Recordset rồi lấy RecordCount thì e rằng quá nặng nếu bảng dữ liệu có đến vài trăm nghìn, thậm chí cả triệu dòng.
    Bạn ấy hỏi có cách nào khác hay không?
    Theo những gì tôi hiểu và đã kiểm tra thực tế thì thấy rằng:
    1. Lo ngại của Bạn ấy là có cơ sở, và chắc chắn rằng với bảng dữ liệu rất lớn thì việc "phi thân nghìn dặm" với MoveLast để "nhảy" từ đầu đến cuối Recordset, mà lại từ máy khách chứ không phải ở ngay server, đó quả là một việc cực kỳ nhọc nhằn, và tất nhiên sẽ mất nhiều thời gian để hoàn thành.

    2. Vậy nếu để server "phục vụ", tự lấy tổng số mẫu tin của bảng xác định rồi gửi con số tổng đó cho chúng ta ở máy khách, thì chắc là sẽ nhanh hơn.

    3. Nghĩ vậy, nên tôi thử viết cái Function trong Access để bảo anh server làm đi rồi gửi kết quả cho tôi biết. Nội dung của Function ấy như sau:
    Mã:
    Function RecCountOfTb(DbName As String, tbName As String, Optional OwnerSt) As Long
    '
    Dim qdf As DAO.QueryDef, rst As DAO.Recordset
    Dim sqlSt As String
    Dim intCount As Long

    Set qdf = CurrentDb.CreateQueryDef("")
    qdf.Connect = "ODBC;Driver=SQL Server;Server=.\SQLEXPRESS;Trusted_Connection=Yes;"
    sqlSt = "select Count('*') as RecCount from " & DbName
    If IsMissing(OwnerSt) Then
        sqlSt = sqlSt & ".dbo." & tbName
    Else
        sqlSt = sqlSt & "." & OwnerSt & "."
    End If
    sqlSt = sqlSt & tbName

    qdf.SQL = sqlSt
    qdf.ReturnsRecords = True
    Set rst = qdf.OpenRecordset

    intCount = rst!RecCount

    rst.Close
    Set rst = Nothing
    Set qdf = Nothing
    '
    RecCountOfTb = intCount
    End Function

    Các Bạn chú ý cái câu lệnh:
    Mã:
    select Count('*') as RecCount from ...

    Đây là câu lệnh SQL trong SQL Server dùng để lấy tổng số mẫu tin của bảng (tbName) trong database xác định (DbName).
    Với cách trên tuy ta cũng dùng 1 recordset, nhưng recordset đó chỉ có mỗi 1 dòng ghi kết quả của câu lệnh "SELECT Count('*') FROM ..." và được server thực hiện, ta khỏi phải nhảy tới nhảy lui chi cho cực.

    Còn nhiều cách khác nữa, ở đây tôi chỉ muốn nhấn mạnh là khi kết nối với data ngoài, chúng ta nên hạn chế đến mức thấp nhất chuyện ở máy khách chạy ứng dụng mà phải thực hiện những "cú nhảy" nghìn dặm hết sức nhọc sức và mất nhiều thời gian. Hãy để những công việc "nặng nhọc" ấy cho server, bởi chức năng của server là "phục vụ" theo yêu cầu mà. Hổng tin các Bạn cứ tra từ điển Anh - Việt xem nghĩa của từ server là gì thì rõ ngay.

    Chúc các Bạn nhiều sức khỏe.

    Ghi chú thêm: theo yêu cầu của Bạn đã gửi email hỏi tôi, nên tôi viết Function trên với thư viện DAO, chứ không dùng ADO. Các Bạn có thể dùng ADO viết, như vậy sẽ hợp lẽ hơn.