Reputation: 92
I'm trying to copy data from one excel workbook to another. To do that i'm using a ADODB connection. Through a SQL query i'm copying all data, from the sheets that I want, to the other workbook. However, for some reason it skips the first row in each sheet. Thus the copied data always start on row 2. Maybe one of you can spot my mistake or explain to me why this happens?
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
Upvotes: 1
Views: 1058
Reputation: 29296
Poblem is that Excel (or, the driver, to be more precise) expects that the first row of the source data contains a header row (holding the name of the columns).
In theory, there is a parameter in the connection string where you define if there is a header row, HDR=YES;
, but it seems that this parameter is ignored for this driver, and instead, a value from the registry is read. See https://stackoverflow.com/a/49555650/7599798
As an alternative, you can use the OLE driver: Try
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filepath _
& ";Extended Properties=""Excel 12.0 Xml;HDR=NO;"""
This respects the setting for HDR
, so if you write HDR=NO
, it will copy the first row, while HDR=YES
skips it. If you have a header row, you can access the columns by their name in the SQL
-statement, else you have to access them by the column characters.
Upvotes: 1