Load aggregate data from Excel into ADODB.RecordSet

两盒软妹~` 提交于 2020-12-15 06:25:12

问题


I am trying to load data from an Excel file in a specific sheet into an ADODB.RecordSet via a VBA macro by using SQL SELECT command. There are several columns on the Excel sheet, and I don't need all of them.

For example: col.A = Surname, col.B = Name, col.C = IDPerson, [....columns that are not needed], Col.N = Boss

The purpose would be to get a recordset of aggregated data for: col.C = IDPerson, col.N = Boss. The fields highlighted in the image below.

I would like to have a RecordSet with the aggregated (non-repeating) data of the columns highlighted in yellow.

Obviously, this problem could also be solved by loading a matrix, but, in this case I would have to build a loading algorithm to "clean" any repetitions in the data and then later I would have to provide a search function with some loops. So I thought that if I could load all the data I need by reading the WorkSheet as if it were a data table and then make a query on it to extract the data that I need and load everything in an ADODB.RecordSet would be much more efficient also for searching for data (filter data for example).

Below I report my code that loads all the data of my sheet:

Public Sub LoadRecordSet(ByVal LastRow As Long, ByVal LastCol As Integer)
    Dim cnt As ADODB.Connection
    Dim rsData As ADODB.Recordset
    Dim strSQL As String
    Dim strTMP As String

    strTMP = Cells(LastRow, LastCol).Address
    strTMP = Replace(strTMP, "$", "")

    Set cnt = New ADODB.Connection
    cnt.Mode = adModeRead
    cnt.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                            "Data Source=" & ActiveWorkbook.FullName & ";" & _
                            "Extended Properties=""Excel 12.0 Macro;HDR=Yes;"";"
    cnt.Open
    
    strSQL = "SELECT * FROM [Sheet1$C2:" & strTMP & "]"
    Set rsData = New ADODB.Recordset
    With rsData
        Set .ActiveConnection = cnt
        .Source = strSQL
        .CursorLocation = adUseClient
        .CursorType = adOpenKeyset
        .LockType = adLockOptimistic
        .Open
    End With
    
    'TODO - Something with rsData for filtering or to research
    
    'GC
    If Not rsData Is Nothing Then
        If rsData.State <> adStateClosed Then rsData.Close
        Set rsData = Nothing
    End If
    If Not cnt Is Nothing Then
        If cnt.State <> adStateClosed Then cnt.Close
        Set cnt = Nothing
    End If
End Sub

My question is: "What if I just want to load some columns as described above and aggregate them so they don't have repetitions in the data?"

For example if I want to load similar SELECT [cod.fiscale], responsabile FROM [MySheet$A3:N480] GROUP BY [cod.fiscale], responsabile

It's possible? Thank you so much.


回答1:


I improved my code which is now working:

Public Sub CaricaDati()
    Dim cnt As ADODB.Connection
    Dim rsDati As ADODB.Recordset
    Dim strSQL As String
    Dim strTMP As String
    Dim i As Integer

on Error GoTo Error_Handler
    Range("A3").Select
    g_BOLTS_UltimaRiga = LasRow
    Call LastCol
    strTMP = Cells(g_LastRow, g_LastCol).Address
    strTMP = Replace(strTMP, "$", "")

    Set cnt = New ADODB.Connection
    cnt.Mode = adModeRead
    cnt.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
                            "Data Source=" & ActiveWorkbook.FullName & ";" & _
                            "Extended Properties=""Excel 12.0 Macro;HDR=Yes;"";"
    cnt.Open
    
    'strSQL = "SELECT * FROM [2$C2:" & strTMP & "]"
    strSQL = "SELECT cf, responsabile FROM [2$C2:" & strTMP & "] GROUP BY cf, responsabile"
    Set rsDati = New ADODB.Recordset
    With rsDati
        Set .ActiveConnection = cnt
        .Source = strSQL
        .CursorLocation = adUseClient
        .CursorType = adOpenKeyset
        .LockType = adLockOptimistic
        .Open
    End With
    
    If Not (rsDati.BOF And rsDati.EOF) Then
        strTMP = ""
        For i = 0 To rsDati.Fields.Count - 1
            strTMP = strTMP & rsDati.Fields(i).Name & ";"
        Next i
        Debug.Print strTMP
        
        strTMP = ""
        rsDati.MoveFirst
        Do While Not rsDati.EOF
            strTMP = ""
            For i = 0 To rsDati.Fields.Count - 1
                strTMP = strTMP & rsDati.Fields(i).Value & ";"
            Next i
            Debug.Print strTMP
            rsDati.MoveNext
        Loop
    End If
    
Uscita:
On Error Resume Next
    'GC
    If Not rsDati Is Nothing Then
        If rsDati.State <> adStateClosed Then rsDati.Close
        Set rsDati = Nothing
    End If
    If Not cnt Is Nothing Then
        If cnt.State <> adStateClosed Then cnt.Close
        Set cnt = Nothing
    End If
Exit Sub
Error_Handler:
        On Error GoTo 0
        MsgBox Err.Number & " - " & Err.Description, vbOKOnly + vbCritical, "ERRORE IMPREVISTO"
        GoTo Uscita
    End Sub


来源:https://stackoverflow.com/questions/64029012/load-aggregate-data-from-excel-into-adodb-recordset

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!