Lập trình VBA tạo hàm chạy SQL trả về mảng động trong Excel với Add-in A-Tools

Liên hệ QC

Nguyễn Duy Tuân

Nghị Hách
Thành viên danh dự
Tham gia
13/6/06
Bài viết
4,649
Được thích
10,138
Giới tính
Nam
Nghề nghiệp
Giáo viên, CEO tại Bluesofts
Kỹ thuật lập trình VBA đặc biệt này giúp bạn tạo ra hàm trả về mảng động giống với hàm BS_SQL của Add-in A-Tools. Hàm chạy chuỗi lệnh SQL rồi lấy mảng thì bạn cần phải dùng class #BSFormulaArray, tại class này bạn điều khiển hàm bằng cấu trúc kiểm tra BEGIN, dùng hàm #ExecuteQuery() để chạy SQL nhận về recordset sau đó chuyển về array bằng hàm #GetArrayFromRecordset(). Phương pháp gọi hàm callback sử dụng toán tử AddressOf trong VBA,.
'Create UDF run SQL as BS_SQL
C#:
Function MySQL(ByVal SQL As String, Optional ByVal Options As String = "") As Variant
    Dim fa As New BSFormulaArray
    Dim fi As New BSFormulaInfo
    'Function structure:
    If fa.Begin Then
        'Create array
        fi.FunctionName = "MySQL"
        fi.OptionStr = Options
        fi.HeaderRow = True
        'AResult can be:
        '   SQL statement
        '   Array
        '   Recordset
        MySQL = fa.Add(fi, SQL)
    Else
        'Return array that created
        MySQL = fa.Result
    End If
   
    'Free memory
    Set fi = Nothing
    Set fa = Nothing
End Function

'Run SQL by callback function
C#:
'Hàm này lấy ra mảng để tùy ý tính toán
Function MySQL2(ByVal SQL As String, Optional ByVal Options As String = "") As Variant
    Dim fa As New BSFormulaArray
    Dim fi As New BSFormulaInfo
    Dim arr
    'Function structure:
    If fa.Begin Then
        'Create array
        fi.FunctionName = "MySQL2"
        fi.OptionStr = Options
        fi.HeaderRow = True
        'AResult can be:
        '   SQL statement
        '   Array
        '   Recordset
        fi.PARAMS = Array(SQL, Options) ' 0- SQL; 1- Options
        fi.lpfnOnGetResult = GetCallbackFunction(AddressOf CallbackResult)
        'CallbackResult will create array from SQL
        MySQL2 = fa.Add(fi, arr)
    Else
        'Return array that created
        MySQL2 = fa.Result
    End If
   
    'Free memory
    Set fi = Nothing
    Set fa = Nothing
End Function

Function CallbackResult(ByVal fi As AddinATools.IBSFormulaInfo, _
                        ByVal FmlRange As Range, _
                        ByVal FmlState As AddinATools.BSFmlState, _
                        AResult As Variant) As Boolean
    If FmlState = fsOnCalc Then
        'Create recordset by SQL
        Dim fa As New BSFormulaArray
        Dim rst As Object ' ADODB.Recordset
        Set rst = fa.ExecuteQuery(fi.PARAMS(0), fi.PARAMS(1))
        'Create Array
        Dim arr
        arr = fa.GetArrayFromRecordset(rst, True)
        Dim ur&, uc&, I&, J&
        ur = UBound(arr, 1): uc = UBound(arr, 2)
        ReDim arr2(ur, uc + 1) 'Create new column
        'Copy array from arr - > arr2
        arr2(0, 0) = "No."
        For I = 0 To ur
            If I > 0 Then
                arr2(I, 0) = I 'for column "No."
            End If
            For J = 0 To uc
                arr2(I, J + 1) = arr(I, J)
            Next J
        Next I
        'Modify arr if you want...
        AResult = arr2 'return array to function call it "MySQL2"
        CallbackResult = True
        Set fa = Nothing
        rst.Close ' free memory
        Set rst = Nothing
        Erase arr ' clear array
    ElseIf FmlState = fsBeforeUpdate Then
        'Do something
    End If
End Function

(*) Download sourcecode in video: https://drive.google.com/.../17QpbZQjNY33O.../view...
(*) Download Add-in A-Tools: http://bluesofts.net/.../a-tools-truy-van-loc-soan-thao...
 
SQL có nhiều phiên bản, chức năng và giới hạn khác nhau.
Cần nói rõ phiên bản nào.
(dùng trong Excel thì rất có thể là Access SQL. Tuy nhiên dùng cái tên MySQL rất dễ làm người ta nhầm lẫn)
 
Kỹ thuật lập trình VBA đặc biệt này giúp bạn tạo ra hàm trả về mảng động giống với hàm BS_SQL của Add-in A-Tools. Hàm chạy chuỗi lệnh SQL rồi lấy mảng thì bạn cần phải dùng class #BSFormulaArray, tại class này bạn điều khiển hàm bằng cấu trúc kiểm tra BEGIN, dùng hàm #ExecuteQuery() để chạy SQL nhận về recordset sau đó chuyển về array bằng hàm #GetArrayFromRecordset(). Phương pháp gọi hàm callback sử dụng toán tử AddressOf trong VBA,.
'Create UDF run SQL as BS_SQL
C#:
Function MySQL(ByVal SQL As String, Optional ByVal Options As String = "") As Variant
    Dim fa As New BSFormulaArray
    Dim fi As New BSFormulaInfo
    'Function structure:
    If fa.Begin Then
        'Create array
        fi.FunctionName = "MySQL"
        fi.OptionStr = Options
        fi.HeaderRow = True
        'AResult can be:
        '   SQL statement
        '   Array
        '   Recordset
        MySQL = fa.Add(fi, SQL)
    Else
        'Return array that created
        MySQL = fa.Result
    End If
  
    'Free memory
    Set fi = Nothing
    Set fa = Nothing
End Function

'Run SQL by callback function
C#:
'Hàm này lấy ra mảng để tùy ý tính toán
Function MySQL2(ByVal SQL As String, Optional ByVal Options As String = "") As Variant
    Dim fa As New BSFormulaArray
    Dim fi As New BSFormulaInfo
    Dim arr
    'Function structure:
    If fa.Begin Then
        'Create array
        fi.FunctionName = "MySQL2"
        fi.OptionStr = Options
        fi.HeaderRow = True
        'AResult can be:
        '   SQL statement
        '   Array
        '   Recordset
        fi.PARAMS = Array(SQL, Options) ' 0- SQL; 1- Options
        fi.lpfnOnGetResult = GetCallbackFunction(AddressOf CallbackResult)
        'CallbackResult will create array from SQL
        MySQL2 = fa.Add(fi, arr)
    Else
        'Return array that created
        MySQL2 = fa.Result
    End If
  
    'Free memory
    Set fi = Nothing
    Set fa = Nothing
End Function

Function CallbackResult(ByVal fi As AddinATools.IBSFormulaInfo, _
                        ByVal FmlRange As Range, _
                        ByVal FmlState As AddinATools.BSFmlState, _
                        AResult As Variant) As Boolean
    If FmlState = fsOnCalc Then
        'Create recordset by SQL
        Dim fa As New BSFormulaArray
        Dim rst As Object ' ADODB.Recordset
        Set rst = fa.ExecuteQuery(fi.PARAMS(0), fi.PARAMS(1))
        'Create Array
        Dim arr
        arr = fa.GetArrayFromRecordset(rst, True)
        Dim ur&, uc&, I&, J&
        ur = UBound(arr, 1): uc = UBound(arr, 2)
        ReDim arr2(ur, uc + 1) 'Create new column
        'Copy array from arr - > arr2
        arr2(0, 0) = "No."
        For I = 0 To ur
            If I > 0 Then
                arr2(I, 0) = I 'for column "No."
            End If
            For J = 0 To uc
                arr2(I, J + 1) = arr(I, J)
            Next J
        Next I
        'Modify arr if you want...
        AResult = arr2 'return array to function call it "MySQL2"
        CallbackResult = True
        Set fa = Nothing
        rst.Close ' free memory
        Set rst = Nothing
        Erase arr ' clear array
    ElseIf FmlState = fsBeforeUpdate Then
        'Do something
    End If
End Function

(*) Download sourcecode in video: https://drive.google.com/.../17QpbZQjNY33O.../view...
(*) Download Add-in A-Tools: http://bluesofts.net/.../a-tools-truy-van-loc-soan-thao...
Cái này rất hay,
Song @Nguyễn Duy Tuân cho hỏi có phải phụ thuộc vào bộ BS tool , và cài đặt theo riêng hay là chỉ kèm cùng ATool thôi?
 
SQL có nhiều phiên bản, chức năng và giới hạn khác nhau.
Cần nói rõ phiên bản nào.
(dùng trong Excel thì rất có thể là Access SQL. Tuy nhiên dùng cái tên MySQL rất dễ làm người ta nhầm lẫn)

Hàm chạy SQL ExecuteQuery(SQL, [Options]) nó chạy câu lệnh SQL theo đặc tính của database kết nối anh a. Nếu không có tham số Options với DBKEY= khóa kết nối thì nó kết nối tới file Excel đang mở - Access SQL. Nếu người lập trình không muốn qua chức năng quản lý DBKEY (nơi quản lý các khóa kết nối tới nhiều CSDL của A-Tools) thì có thể dùng BSFormulaArray.OpenDatabase(..) trước khi chạy hàm ExecuteQuery().
Từ "MySQL" em dùng trong tên hàm cũng là sơ ý có thể làm một số người nhầm sang loại CSDL MySQL.
Bài đã được tự động gộp:

Cái này rất hay,
Song @Nguyễn Duy Tuân cho hỏi có phải phụ thuộc vào bộ BS tool , và cài đặt theo riêng hay là chỉ kèm cùng ATool thôi?

Chỉ cần cài Add-in A-Tools là có thư viện addinatools.dll trong thư mục hệ thống, code các hàm mảng trong video trên phụ thuộc vào dll này anh.
 
Web KT
Back
Top Bottom