Excel에서 ADODB.RecordSet으로 집계 데이터로드

Sep 23 2020

SQL SELECT 명령을 사용하여 VBA 매크로를 통해 특정 시트의 Excel 파일에서 ADODB.RecordSet으로 데이터를로드하려고합니다. Excel 시트에는 여러 열이 있으며 모두 필요하지는 않습니다.

예 : col.A = 성, col.B = 이름, col.C = IDPerson, [.... 필요하지 않은 열], Col.N = 보스

목적은 col.C = IDPerson, col.N = Boss에 대해 집계 된 데이터의 레코드 세트를 가져 오는 것입니다. 아래 이미지에서 강조 표시된 필드입니다.

노란색으로 강조 표시된 열의 집계 된 (반복되지 않는) 데이터가있는 RecordSet을 갖고 싶습니다.

분명히이 문제는 행렬을로드하여 해결할 수도 있지만,이 경우 데이터의 모든 반복을 "정리"하는로드 알고리즘을 구축해야하고 나중에 몇 가지 루프가있는 검색 기능을 제공해야합니다. 그래서 WorkSheet를 마치 데이터 테이블 인 것처럼 읽고 필요한 모든 데이터를로드 한 다음 필요한 데이터를 추출하고 ADODB에 모든 것을로드하는 쿼리를 수행 할 수 있다면 훨씬 더 많을 것이라고 생각했습니다. 데이터 검색에도 효율적입니다 (예 : 데이터 필터링).

아래에서 내 시트의 모든 데이터를로드하는 코드를보고합니다.

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

내 질문은 "위에서 설명한대로 일부 열을로드하고 집계하여 데이터에 반복되지 않도록하려면 어떻게해야합니까?"입니다.

예를 들어 비슷한 SELECT [cod.fiscale], responsabile FROM [MySheet $ A3 : N480] GROUP BY [cod.fiscale], responsabile을로드하려면

있을 수있다? 정말 고맙습니다.

답변

Tonky75 Sep 24 2020 at 06:19

현재 작동중인 코드를 개선했습니다.

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