Microsoft Access database engine could not find the object Sheet - ACE OLEDB - excel

I'm trying to copy values from one workbook into another. The code below used to work. However, after making required updates (I'm on my work laptop, so don't really have a choice) to my Office, the connection to ADO in my macro no longer works.
This is the error I get:
Run-time error '-2147217865 (800040e37)':
The Microsoft Access database engine could not find the object 'CustomSheetName1$'. Make sure the object exists and that you spell its name and the path name correctly. If 'CustomSheetName1$' is not a local object, check your network connection or contact the server administrator.
I'm using Excel for Microsoft 365 MSO (16.0.13530.20368) 64-bit
The code breaks in the last line:
Public Sub GetData(sourceFile As Variant, SourceSheet As String, _
SourceRange As String, TargetRange As Range, _
Header As Boolean, UseHeaderRow As Boolean, _
pickUpZip As String, _
dropOffZip As String, logSheet As Worksheet, _
monthString As String)
Dim rsCon As Object
Dim rsData As Object
Dim szConnect As String
Dim szSQL As String
Dim lCount As Long
Dim lastLgRow As Integer
If Header = False Then
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & sourceFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=No"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & sourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=No"";"
End If
Else
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & sourceFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & sourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=Yes"";"
End If
End If
If SourceSheet = "" Then
szSQL = "SELECT * FROM " & SourceRange$ & ";"
Else
szSQL = "SELECT * FROM [" & SourceSheet$ & "$]"
szSQL = szSQL & " WHERE [Pickup Zip] LIKE '" & pickUpZip & "%'" & _
" AND [Drop Off Zip] LIKE '" & dropOffZip & "%" & "';"
End If
Set rsCon = CreateObject("ADODB.Connection")
Set rsData = CreateObject("ADODB.Recordset")
rsCon.Open szConnect
rsData.Open szSQL, rsCon, 0, 1, 1
I saw some people having similar issues when in their queries they specified a range of cells. However, this is not the case here, as I want to query the entire 'CustomSheetName1' spreadsheet.
Any ideas?

I'm not well VBA coder but here:
If SourceSheet = "" Then
szSQL = "SELECT * FROM " & SourceRange$ & ";"
Else
szSQL = "SELECT * FROM [" & SourceSheet$ & "$]"
should'nt this look like:
If SourceSheet = "" Then
szSQL = "SELECT * FROM [" & SourceRange & "$];"
Else
szSQL = "SELECT * FROM [" & SourceSheet & "$];"
?
Btw. I'm not sure what you want to do with SourceRange in place of SourceSheet

Related

Copy data from closed workbook to another open workbook in VBA?

I know this has probably been asked before but I was wondering if it was possible to copy data from another 'closed' workbook to my current open workbook. If tried to look up some things and everywhere says it is not possible... I know it's a bit of an open ended question.
Ah, this takes me back a few years. I believe this was done by Ron years ago (explained on a different platform). But there are two ways to do it. One method I forgot and gets the cells one by one and the other is the ADO method posted below. First there are two example subs (one method to bring headers and the other to not) and then followed by the main ADO sub.
Option Explicit
Sub GetData_ExampleV1()
' It will copy the Header row also (the last two arguments are True)
' Change the last argument to False if you not want to copy the header row
GetData ThisWorkbook.Path & "\test.xlsx", "Sheet1", _
"A1:C5", Sheets("Sheet1").Range("A1"), True, True
End Sub
Sub GetData_ExampleC2()
' It will not copy the Header row (the last two arguments are True, False)
' Change the last argument to True if you also want to copy the header row
GetData ThisWorkbook.Path & "\test.xlsx", "Sheet1", _
"A1:C5", Sheets("Sheet1").Range("A1"), True, False
End Sub
This is the ADO (function) you call to do it.
Public Sub GetData(SourceFile As Variant, SourceSheet As String, _
SourceRange As String, TargetRange As Range, Header As Boolean, UseHeaderRow As Boolean)
Dim rsCon As Object
Dim rsData As Object
Dim szConnect As String
Dim szSQL As String
Dim lCount As Long
' Create the connection string.
If Header = False Then
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=No"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=No"";"
End If
Else
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=Yes"";"
End If
End If
If SourceSheet = "" Then
' workbook level name
szSQL = "SELECT * FROM " & SourceRange$ & ";"
Else
' worksheet level name or range
szSQL = "SELECT * FROM [" & SourceSheet$ & "$" & SourceRange$ & "];"
End If
On Error GoTo SomethingWrong
Set rsCon = CreateObject("ADODB.Connection")
Set rsData = CreateObject("ADODB.Recordset")
rsCon.Open szConnect
rsData.Open szSQL, rsCon, 0, 1, 1
' Check to make sure we received data and copy the data
If Not rsData.EOF Then
If Header = False Then
TargetRange.Cells(1, 1).CopyFromRecordset rsData
Else
'Add the header cell in each column if the last argument is True
If UseHeaderRow Then
For lCount = 0 To rsData.Fields.Count - 1
TargetRange.Cells(1, 1 + lCount).Value = _
rsData.Fields(lCount).Name
Next lCount
TargetRange.Cells(2, 1).CopyFromRecordset rsData
Else
TargetRange.Cells(1, 1).CopyFromRecordset rsData
End If
End If
Else
MsgBox "No records returned from : " & SourceFile, vbCritical
End If
' Clean up our Recordset object.
rsData.Close
Set rsData = Nothing
rsCon.Close
Set rsCon = Nothing
Exit Sub
SomethingWrong:
MsgBox "The file name, Sheet name or Range is invalid of : " & SourceFile, _
vbExclamation, "Error"
On Error GoTo 0
End Sub

ADODB Recordset error when Range Column is beyond "Z"

I am using ADODB to get data from a closed excel file. I get an error when I use columns beyond column Z in my query.
Sub TestExcelWB()
Dim cn As Object
Dim szConnect As String
Dim SourceFile As String
Dim SourceSheet As String
Dim SourceRange As String
Dim rsData As Object
'-----For ADODB connection-----
SourceFile = ThisWorkbook.Path & "\ADO Test2.xlsm"
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=No"";"
Set cn = CreateObject("ADODB.Connection")
cn.Open szConnect
'---^^
'-----For Recordset-----
Set rsData = CreateObject("ADODB.Recordset")
SourceSheet = "Sheet1"
SourceRange = "Z1:AA10"
szSQL2 = "SELECT * FROM [" & SourceSheet$ & "$" & SourceRange$ & "];"
rsData.Open szSQL2, cn, 0, 1, 1
'---^^
cn.Close
End Sub
When I change the variable SourceRange = "A1:Z10" then there is no error. Is this a limit of the provider. Is there a way around this?

Recordset: blank for string records?

I have 2 excel workbooks and I am pulling data (A1:A20)from one (WB1) to another using below macro. I have problem that only records with numbers are pulled while string records are not. It seems that the field type is considered as a number and only numbers are being pulled. what should I change in the code to solve it?
below link includes the source file:
https://drive.google.com/open?id=0B64seB8-qtdLYk80N3hvX2F6VGc
Private Source As Variant
Sub Copy_Paste()
'copy the data from the source
Source = ThisWorkbook.Path & "\WB1.xlsx"
GetData Source, "Sheet1", "A1:A20", Sheets("Database").Range("A1")
End Sub
Public Sub GetData(Source As Variant, SourceSheet As String, SourceRange As String, TargetRange As Range)
Dim rsCon As Object
Dim rsData As Object
Dim szSQL As String
Dim szConnect As String
'Create the connection string based on excel version
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Source & ";" & _
"Extended Properties=""Excel 8.0;HDR=No"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & Source & ";" & _
"Extended Properties=""Excel 12.0;HDR=No"";"
End If
szSQL = "SELECT * FROM [" & SourceSheet$ & "$" & SourceRange$ & "];"
On Error GoTo SomethingWrong
Set rsCon = CreateObject("ADODB.Connection")
Set rsData = CreateObject("ADODB.Recordset")
rsCon.Open szConnect
rsData.Open szSQL, rsCon, 0, 1, 1
' Check to make sure we received data and copy the data
If Not rsData.EOF Then
TargetRange.Cells(1, 1).CopyFromRecordset rsData
Else
MsgBox "No records returned from : " & Source, vbCritical
End If
' Clean up our Recordset object.
rsData.Close
Set rsData = Nothing
rsCon.Close
Set rsCon = Nothing
Exit Sub
SomethingWrong:
MsgBox "The file name, Sheet name is invalid of : " & Source, vbExclamation, "Error"
On Error GoTo 0
End Sub
See here: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/ce095b10-84a4-4ae3-8944-70a2b53daa44/mixed-data-types-in-excel-column-to-oedb-destination?forum=sqlintegrationservices
You need to add IMEX=1 to your connection strings. Eg:
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Source & ";" & _
"Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";"
Otherwise, the driver guesses your data column is numeric (based on the first few rows) and ignores any non-numeric values.

Microsoft Access database engine could not find the object Worksheet - ACE OLEDB

I am trying to do a Join on 3 tables in Excel through VBA using Microsoft.ACE.OLEDB.12.0. Having lots of issues trying to get the query to run. At this point I get the following error:
Run-time error '-2147217865 (800040e37)':
The Microsoft Access database engine could not find the object 'CustomSheetName1$A$1:$AV$6027'. Make sure the object exists and that you spell its name and the path name correctly. If 'CustomSheetName1$A$1:$AV$6027' is not a local object, check your network connection or contact the server administrator.
The source file is created in the same sub and saved to the macro root folder located locally in C:\Users\localuser\Documents\MacroFolder\. I have full access to the file.
When run the connection string shows as:
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\localuser\Documents\MacroFolder\Book4.xlsx;Extended Properties='Excel 12.0 Xml;HDR=Yes;IMEX=1';"
Extract of sub below. I have obfuscated the field names and only included code I thought was relevant. Can add more and clarify further if required. Code breaks at the last line when executing the query.
Dim wbTarget As Workbook, wsTarget As Worksheet
Dim wb As Workbook, ws As Worksheet
Set wbTarget = Workbooks.Add
Set wsTarget = wbTarget.Sheets.Add(After:=wbTarget.Sheets(wbTarget.Sheets.Count))
wsTarget.Name = "CustomSheetName1"
varFilePathElements = Split(ThisWorkbook.Path, "\")
strFileName = varFilePathElements(UBound(varFilePathElements))
Dim strWBTargetFullFileName As String
strWBTargetFullFileName = Replace(ThisWorkbook.Path, "strfilename", "") & "\" & wbTarget.Name & ".xlsx"
Dim cn As Object
Dim rs As Object
Dim strCon As String
Dim strSQL As String
Dim s As String
Dim i As Integer, j As Integer
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strWBTargetFullFileName _
& ";Extended Properties='Excel 12.0 Xml;HDR=Yes;IMEX=1';"
strSQL = "SELECT " _
& "sh1.company_name, " _
& "sh1.company_type, " _
& "sh1.customer_no, " _
& "sh1.fk1, " _
& "SUM(sh3.total_stat) as total_stat, " _
& "FROM ( [CustomSheetName1" & wbTarget.Sheets("CustomSheetName1").UsedRange.Address & "] sh1 " _
& "LEFT JOIN [CustomSheetName2" & wbTarget.Sheets("CustomSheetName2").UsedRange.Address & "] sh2 " _
& "ON sh2.fk1 = sh1.fk1 ) " _
& "LEFT JOIN [CustomSheetName3" & wbTarget.Sheets("CustomSheetName3").UsedRange.Address & "] sh3 " _
& "ON sh3.fk2 = sh2.fk2 AND sh3.fk3 = sh2.fk3 " _
& "GROUP BY sh1.customer_no, sh1.company_name, sh1.company_type, sh1.fk1 " _
& "ORDER BY total_stat"
wbTarget.Sheets(1).Range("A1").Value2 = strSQL
wbTarget.SaveAs (strWBTargetFullFileName)
wbTarget.Close
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
rs.Open strSQL, cn, 3, 3
Any help would be greatly appreciated. Regards,
When reading Excel worksheets via ADO, the $ sign is appended to the end of the worksheet name, like this:
SELECT * FROM [Sheet1$]
Using the absolute range address adds extra $ signs that cause the worksheet name to be interpreted incorrectly. You need to use non-absolute range addresses to stop this happening. Adding some parameters to UsedRange.Address can fix this:
[CustomSheetName1$" & wbTarget.Sheets("CustomSheetName1").UsedRange.Address(False, False) & "]

Copying Entire Worksheet from one Excel to another

I would like to copy the entire worksheet from one Closed Excel file to the currently open excel file however I do not want to use a range as the amount of rows in the file will vary.
The code I am using to rereive data from within a range is
Public Sub GetData(SourceFile As Variant, SourceSheet As String, _
SourceRange As String, TargetRange As Range, Header As Boolean,
UseHeaderRow As Boolean)
' 30-Dec-2007, working in Excel 2000-2007
Dim rsCon As Object
Dim rsData As Object
Dim szConnect As String
Dim szSQL As String
Dim lCount As Long
' Create the connection string.
If Header = False Then
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=No"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=No"";"
End If
Else
If Val(Application.Version) < 12 Then
szConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes"";"
Else
szConnect = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 12.0;HDR=Yes"";"
End If
End If
If SourceSheet = "" Then
' workbook level name
szSQL = "SELECT * FROM " & SourceRange$ & ";"
Else
' worksheet level name or range
szSQL = "SELECT * FROM [" & SourceSheet$ & "$" & SourceRange$ & "];"
End If
On Error GoTo SomethingWrong
Set rsCon = CreateObject("ADODB.Connection")
Set rsData = CreateObject("ADODB.Recordset")
rsCon.Open szConnect
rsData.Open szSQL, rsCon, 0, 1, 1
' Check to make sure we received data and copy the data
If Not rsData.EOF Then
If Header = False Then
TargetRange.Cells(1, 1).CopyFromRecordset rsData
Else
'Add the header cell in each column if the last argument is True
If UseHeaderRow Then
For lCount = 0 To rsData.Fields.Count - 1
TargetRange.Cells(1, 1 + lCount).Value = _
rsData.Fields(lCount).Name
Next lCount
TargetRange.Cells(2, 1).CopyFromRecordset rsData
Else
TargetRange.Cells(1, 1).CopyFromRecordset rsData
End If
End If
Else
MsgBox "No records returned from : " & SourceFile, vbCritical
End If
' Clean up our Recordset object.
rsData.Close
Set rsData = Nothing
rsCon.Close
Set rsCon = Nothing
Exit Sub
SomethingWrong:
MsgBox "The file name, Sheet name or Range is invalid of : " & SourceFile, _
vbExclamation, "Error"
On Error GoTo 0
End Sub
Any help with importing the entire worksheet and all of its rows/column would be great.
Thanks.
Why not just do this?
Dim wbkSource As Workbook
Set wbkSource = Workbooks.Open("C:\BookFromWhichToCopy.xlsx")
wbkSource.Sheets("MySheet").Copy Before:=ThisWorkbook.Sheets(2)
wbkSource.Close
Note that you can call sheets by their name .Sheets("MySheet") or by their number in the workbook .Sheets(2), whichever suits you best.

Resources