在 VBA 中使用 SQL-query 导入 excel 数据会跳过第一行

Importing excel data with SQL-query in VBA jumps over first row

我正在尝试将数据从一个 excel 工作簿复制到另一个工作簿。为此,我正在使用 ADODB 连接。通过 SQL 查询,我将所有数据从我想要的 sheet 复制到另一个工作簿。但是,出于某种原因,它会跳过每个 sheet 中的第一行。因此复制的数据总是从第 2 行开始。 也许你们中的一位可以发现我的错误或向我解释为什么会这样?

Sub ImportExcelSQL()

Dim sheetName, sheetNewName, filepath, strConnection, Sql As String
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset

'-------- Close workbook updates ----------
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.AskToUpdateLinks = False
Application.StatusBar = "Importing...."
'------------------------------------------

filepath = Range("filepath")

strConnection = "DRIVER={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
                  & "DBQ=" + filepath + ";"

' Create the Connection and Recordset objects.
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset

' Open connection
conn.Open strConnection

' Loop through the sheets
Dim i As Integer
i = 1
Do Until IsEmpty(Range("importSheetNames").Offset(i, 0))

    If Range("importSaveSheetFlags").Offset(i, 0).Value = "Y" Then

    ' Get sheet names and input variables"
    sheetName = Range("importSheetNames").Offset(i, 0).Value
    sheetNewName = Range("exportSheetNames").Offset(i, 0).Value
    filepath = Range("filepath")

    ' Clear data sheet
    Sheets(sheetNewName).UsedRange.ClearContents

    ' ----------------------- SQL CODE ----------------------------
    Sql = "SELECT * FROM [" + sheetName + "$A:CA]"
    'Sql = "SELECT * FROM [" + sheetName + "$A1:CA1000]" 'Does not do any difference

    ' Open the connection and execute.
    'conn.Open strConnection
    Set rs = conn.Execute(Sql)

    ' Check we have data.
    If Not rs.EOF Then
       ' Transfer result.
       Sheets(sheetNewName).Range("A1").CopyFromRecordset rs
       ' Close the recordset
       rs.Close
    Else
       MsgBox "Error: No records returned.", vbCritical
    End If

    ' -------------- End of SQL --------------------------------------------

    End If


    i = i + 1
Loop

' Clean up
If CBool(conn.State And adStateOpen) Then conn.Close
Set conn = Nothing
Set rs = Nothing

'-----------------------------------------------
' Turn on automatic updating
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.AskToUpdateLinks = True
Application.StatusBar = "Finished"
'-----------------------------------------------

End Sub

问题是 Excel(或者更准确地说,driver)期望源数据的第一行包含一个 header 行(保存名称列)。

理论上,如果有header行,连接字符串中有一个参数定义,HDR=YES;,但是这个driver似乎忽略了这个参数],而是读取注册表中的值。参见 https://whosebug.com/a/49555650/7599798

作为替代方案,您可以使用 OLE driver:尝试

strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filepath _ 
              & ";Extended Properties=""Excel 12.0 Xml;HDR=NO;"""

这符合 HDR 的设置,所以如果您写 HDR=NO,它会复制第一行,而 HDR=YES 会跳过它。如果您有 header 行,则可以在 SQL 语句中通过名称访问列,否则您必须通过列字符访问它们。