ExcelADO. Table name. Run-time error '-2147217865 (80040e37)'. Acc2013x64 - sql

I've successfully used ExcelADO for reading and importing Excel data into MSAccess during long time reading the entire SpreadSheet.
This time I need to import some table objects that can coexist with other table objects in the same spreadsheet.
According to the documentation http://support.microsoft.com/kb/278973, the only thing that needs to be changed is the From clause in the SQL string:
oRS.Open "Select * from Table1", oConn, adOpenStatic
However this fails and shows the error number mentioned in the title of this thread that essentially says that the object Table1 does not exists in that spreadsheet.
The complete code I'm using is this:
Private Sub Command0_Click()
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H1
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim dbs As DAO.Database
Set dbs = CurrentDb
Set cnn = New ADODB.Connection
Set rst = New ADODB.Recordset
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\MyPath\MyFile.xlsx;" & _
"Extended Properties= 'Excel 12.0;HDR=Yes';"
rst.Open "Select * From Table1", _
cnn, adOpenStatic, adLockOptimistic, adCmdText
With rst
If Not .EOF And Not .BOF Then
Do Until .EOF
Debug.Print .Fields(0), .Fields(1), .Fields(2)
.MoveNext
Loop
End If
End With
Set rst = Nothing
Set cnn = Nothing
Set dbs = Nothing
End Sub
As I said I can retrieve the whole content of the spreadsheet using:
.Open "Select * From [Sheet1$]", oConn, adOpenStatic
Also I can get the contents of a specified range:
.Open "Select * From [Sheet1$A1:B10]", oConn, adOpenStatic
I double-checked for the existence of that object using VBA, and it's there:
Private Sub Command2_Click()
Dim xlAp As Excel.Application
Dim xlWb As Excel.Workbook
Dim i As Long
Set xlAp = New Excel.Application
Set xlWb = xlAp.Workbooks.Open("C:\MyPath\MyFile.xlsx")
For i = 1 To xlWb.ActiveSheet.ListObjects.Count
Debug.Print xlWb.ActiveSheet.ListObjects(i).Name, _
xlWb.ActiveSheet.ListObjects(i).DisplayName
Next i
Set xlWb = Nothing
Set xlAp = Nothing
End Sub
Does anybody know how to solve this issue?
Thanks in advance,
Diego
Edit:
Well, the error is right in the sense that my object Table1 is not present in the schema as evaluated by using:
Set rs = cnn.OpenSchema(adSchemaTables)
With rs
If Not .EOF And Not .BOF Then
Do Until .EOF
Debug.Print rs.Fields(0), _
rs.Fields(1), _
rs.Fields(2), _
rs.Fields(3)
.MoveNext
Loop
End If
End With
Set rs = Nothing
nor in the tables catalog:
Dim cat As ADOX.Catalog
Dim tbl As ADOX.Table
Set cat = New ADOX.Catalog
cat.ActiveConnection = cnn
For Each tbl In cat.Tables
Debug.Print tbl.Name, tbl.Type
Next tbl
Set cat = Nothing
That's strange considering that the documentation explicitly says:
Named ranges are treated as "Tables" and worksheets are treated as "System Tables,"
So my guess is that Excel 2013 x64 stores named ranges in a different way than before and for accessing them via ExcelADO the syntax needs to be modified in the best scenario or they cannot accessed this way anymore.
As I previously said, the named ranges exist in my spreadsheet and I can loop through them using the range object via automation.
Hopefully someone has an answer to this.
All the best,
Diego
Environ: Windows 7 x64, Access 2013 x64, Excel 2013 x64.

Norie from utteraccess put me in the right path:
In Excel ListObjects aren't named ranges, and what you have is a
ListObject so it's not going to appear in the schema.
So this has nothing to do with the change in the object model; listobjects and named ranges are just different objects even if they appear almost the same for the user.
Didn't find an answer yet for dealing with ListObjects via ExcelAdo, but since that's another question I leave it here: ExcelADO: Fill recordset with ListObject

I have facing the same issue too. I have named range on another sheet that I can query using the named range.
When I open my Name Manager, there is sheets name that have single quote on the name, then query using named range on this sheet will not working.
Then I rename my sheet, then try query again and it's working.
I think my sheets name before conflict with excels default names, which is my sheets name on name manager have single quote

Related

Import Named Lotus123 spreadsheet to MS Access

I'm in the process of moving all the Lotus sheets a company has to a SQL Server and I am using MS Access tables as an intermediary.
This code has been working fine for sheets that are not named but I've come across about 2300 or so sheets where it's named numb. There are too many files for me to manually change them all.
The error I am getting is:
Run-Time error '-2147217865(80040e37)':
The Microsoft Jet Database engine could not find the object "numb:A1..numb:A8000". Make sure the object exists and that you spell its name and the path name correctly.
Found this site but that hasn't provided the answer
I've seen different options for getting the destination right on an ADOB call ("SELECT * FROM [numb:A1..numb:A8000];" or ("SELECT * FROM [numb$:A1..numb$:A8000];") and those haven't worked.
Here is the functioning code when the sheet isn't named:
Dim rst As DAO.Recordset
Dim rs As DAO.Recordset
Dim LotusCn As Object
Dim rsLotus As Object
'Read WK3 Lotus files
repcode = rs![Code]
Directory = rs![Directory]
Directory = Directory & "NUMDATM.WK3"
Set LotusCn = CreateObject("ADODB.Connection")
Set rsLotus = CreateObject("ADODB.Recordset")
'This creates the objects for the lotus connctions
'below the connection string
LotusCn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Directory & ";" & _
"Extended Properties=Lotus WK3;Persist Security Info=False"
strSQL = "SELECT * FROM [A1..A8000];" 'The SQL to pick the right sections of the lotus file. Picks the Latest Available Date
rsLotus.Open strSQL, LotusCn, adOpenStatic '<<< ***Error occurs here***
If Not (rsLotus.EOF And rsLotus.BOF) Then
FindRecordCount = rsLotus.RecordCount
rsLotus.MoveFirst
Do Until rsLotus.EOF = True
Debug.Print rsLotus.Fields(0).Value
If Len(rsLotus.Fields(0).Value) > 0 Then
rst.AddNew
rst!RegNo = rsLotus.Fields(0).Value
rst.Update
End If
rsLotus.MoveNext
Loop
End If
LotusCn.Close
strSQL = ""
Set rsLotus = Nothing
Set LotusCn = Nothing
Does anyone know how to get named spreadsheets?
I dont know exactly how in Lotus but this was in Excel
Set oRs = oConn.OpenSchema(adSchemaTables) 'get the name of the sheet in Excel
oRs.MoveFirst
With oRs
While Not .EOF
If .fields("TABLE_TYPE") = "TABLE" Then
Debug.Print .fields("TABLE_NAME")
If VBA.Len(.fields("TABLE_NAME")) = 9 Then
WSnameTBL = .fields("TABLE_NAME")
Else
End If
' WSnameTBL = VBA.Replace(WSnameTBL, "$", "", 1, , vbTextCompare)
End If
.MoveNext
Wend
End With

VB6 ADODB.Recordset Record.Count doesn't work / EOF & BOF not available

I've got a question regarding ADODB recordset in VB6, which has confused me for a few weeks. I've written the recordset into worksheets to achieve some results that I can't get from recordset directly.
But as the data set builds up, writing the recordset into worksheet would slow the program down, I wonder if someone could resolve the recordset puzzle for me.
Below is the problem I have -
1) xRst.Recordcount always returns -1
2) Error message, "Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another", pops up on set (A) .cursorlocation to either adUseClient or adUseServer, and (B) .LockType
3) Unable to .getrows on recordset => I believe it's the same cause as xRst.Recordcount returning -1 ?
Below is part of my code. Could above issues caused by limitation of the provider?
xConnstring = "Provider=Microsoft.ACE.OLEDB.12.0; Extended Properties='Excel 12.0'; Data Source =" & Thisworkbook.fullname
xCnn.Open xConnstring
xSqlstring = " SELECT * FROM [APRI$] "
Set xRst = xCnn.Execute(xSqlstring)
Msgbox(xRst.RecordCount)
Do Until xRst.EOF
......
xRst.MoveNext
Loop
For the recordset, I've also tried two open methods, but doesn't work either.
Set xRst.ActiveConnection = xCnn
xRst.Source = xSqlstring
xRst.CursorType = adOpenDynamic
------Error Message Occurs On Below Two Lines------
xRst.CursorLocation = adUseServer
xRst.LockType = adLockOptimistic
xRst.Open
Below code will encounter an error, but it will pass through when the two last parameters are removed
xRst.Open xSqlstring, xCnn, adOpenKeyset, adUseServer, adLockoptimistic
Could someone please kindly advise how I can get the 1) recordset.recordcount, 2) recordset.movenext work?
Thanks heaps in advance.
Default cursortype is adOpenForwardOnly. With adOpenForwardOnly or adOpenUnspecified the record count is always returned as -1. Use either adOpenKeySet or adOpenStatic. ie: (I assume sheet name APRI is correct and not APRIL - and there is a worksheet named Dummy to list the results for test):
Dim xCnn As ADODB.Connection
Dim xRst As ADODB.Recordset
Dim xConnString As String
xConnString = "Provider=Microsoft.ACE.OLEDB.12.0; Extended Properties='Excel 12.0'; Data Source =" & ThisWorkbook.FullName
Set xCnn = New ADODB.Connection
xCnn.Open xConnString
xSqlstring = " SELECT * FROM [APRI$] "
Set xRst = New ADODB.Recordset
xRst.Open xSqlstring, xCnn, adOpenStatic
MsgBox (xRst.RecordCount)
Dim row As Integer
row = 1
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Dummy")
Do Until xRst.EOF
'...
ws.Cells(row, 1).Value = xRst.Fields(0).Value
row = row + 1
xRst.MoveNext
Loop

Excel VBA ADO SQL connection error - Could not find the object

I got a brilliant answer to my previous question from #Ryan Wildry but I thought I'd ask a different question regarding the same code: here goes.
Background Info
I have a shared (network/server) Excel template file which is both the input file and the data source (although on different sheets). Let's call that Input.xltm.
The code basically picks up a input in a range on Input Sheet, takes the first two letters and finds the closest code from Code Sheet, then populates a UserForm ListBox with the top five results.
The problem
The problem comes when users set off the UserForm and the error usually returns:
Run-time error '-2147467259'
The Microsoft Access database engine could not find the object 'C:\Users\user.name\Documents\Input1'. Make sure the object exists and that you spell its name and the path name correctly.......etc
I think it may have something to do with the fact Excel puts a number after the filename because it's a template file although I don't actually know!
The code
And here's the code:
Public MyConnection As New ADODB.Connection
Public MyRecordset As New ADODB.Recordset
Private Sub UserForm_Initialize()
Dim ColumnName As String: ColumnName = "[Variant code]"
Dim SearchStr As String: SearchStr = Left(Sheets("Input Sheet").Range("B4").Value2, 2)
Dim dbstring As String
dbstring = ThisWorkbook.FullName
Application.ScreenUpdating = False
If MyConnection.State <> adStateOpen Then
With MyConnection
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbstring & _
";Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1';"
.Open
End With
End If
If MyRecordset.State = adStateOpen Then MyRecordset.Close
MyRecordset.Open "Select top 5 " & ColumnName & " from [Code Sheet$] where " & ColumnName & _
" like '%" & SearchStr & "%'", MyConnection, adOpenForwardOnly, adLockReadOnly
Me.ListBox1.Clear
If Not MyRecordset.EOF Then MyRecordset.MoveFirst
Application.ScreenUpdating = True
Do Until MyRecordset.EOF
Me.ListBox1.AddItem MyRecordset.Fields(0).Value
MyRecordset.MoveNext
Loop
End Sub
I just need everyone who accesses the file through the server to be able to pick up the correct data source (which is only in the next sheet) and populate the ListBox.
I'd be thankful for any suggestions! Thanks
#UPDATE
I have checked, now if you open (and then save) the actual template file so there's no '1' after the file name, then the code works as expected. It's only when the template is opened normally and the number automatically appended that it stops working.
It seems that you do not make early-binding for MyConnection and MyRecordset first.
You can make a late-binding by
step 1.
Change
Public MyConnection As New ADODB.Connection
Public MyRecordset As New ADODB.Recordset
to
Public MyConnection As object
Public MyRecordset As object
.
step 2.
Add
Set MyConnection = createobject("adodb.connection")
Set MyRecordset = createobject("adodb.recordset")
before If MyConnection.State <> adStateOpen Then

Select query to Access from VBA not returning duplicate values

Any help with this issue is greatly appreciated.
I am trying to retrieve from Access, by means of Select, multiple values with the same ID and have it pasted into an Excel sheet. I am running the code from Excel VBA.
The query I am using to retrieve said values is:
SELECT Role
FROM Roles
WHERE App_ID=(SELECT ID FROM Apps WHERE NAME='app name');
which is assigned to a variable and afterwards executed by using Set variable = cn.Execute(variable). The problem is that this query, executed from Excel VBA, returns only the first value found. Now, if I run this query from Access it returns every value with the ID for the specified app.
I have tried tried using INNER JOIN, IN, HAVING, etc. but it just wont retrieve all of the values into Excel. Like I said, the query works fine when used in Access so I know this must be limitation in Excel.
Thank you for any help you guys can provide.
Assuming you are using ADODB in Excel, keep in mind that the Execute function returns a Recordset. You can loop through the Recordset to see the additional rows.
Set rng = ActiveSheet.Range("A2")
Set rst = cn.Execute(strSQL)
With rst
Do While Not .EOF
rng = CStr(!Role)
Set rng = rng.Offset(1)
.MoveNext
Loop
End With
'Applies to Access 2010
'Reference Microsoft ActiveX Data Objects 6.1 Library
Dim strSQL As String
Dim strDBPathName As String
Dim strConProvider As String
Dim strPersist As String
Dim conADODB As ADODB.Connection
Dim rsADODB As ADODB.Recordset
Set conADODB = New ADODB.Connection
strConProvider = "Provider=Microsoft.ACE.OLEDB.12.0;"
'Database path name
strDBPathName = "Data Source=C:\Temp\Database.accdb;"
strPersist = "Persist Security Info=False;"
With conADODB
.ConnectionString = strConProvider & strDBPathName & strPersist
.Open
End With
strSQL = "SELECT Role FROM Roles WHERE App_ID=(SELECT ID FROM Apps WHERE NAME='app name')"
Set rsADODB = New ADODB.Recordset
With rsADODB
.Open strSQL, conADODB, adOpenStatic, adLockPessimistic
If Not (.EOF And .BOF) Then
'Range of spreadsheet to paste records
Cells(1, 1).CopyFromRecordset rsADODB
End If
.Close
End With
Set rsADODB = Nothing
conADODB.Close
Set conADODB = Nothing

VBA LOOP in ORACLE SQL

I was trying to write a VBA to run a query assigned to MySQL only when the HCR_DM.HCR_DM_FACT table is fully loaded. I'm using the count of distinct source in that table to decide if it is fully loaded.
When I was running the Macro below, I got an error message for the Do While line, saying that Object doesn't support this property or method.
I'm quite new to VBA, and I couldn't figure out what need to be adjusted. Can some one help me with this?
Thanks!
Const CNSTR = "Provider = OraOLEDB.Oracle; Data Source =CSDPRO; ODBC;DRIVER={Oracle ODBC Driver};SERVER=CSDPRO;User ID=HCR_SANDBOX;password=******"
Sub FillWithSQLData(strSQL As String, wkSht As String)
' Given a SQL query and worksheet, fills the worksheet with a data dump of the SQL query results
' Define variables
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sql_count As String
' Set variables
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
' Connect to SQL Server
With cn
.ConnectionString = CNSTR
.Open
End With
' Query SQL Server and return results as a data dump in cell A2 of the specified worksheet
With rs
.ActiveConnection = cn
sql_count = "select count( distinct a.src_table) from hcr_dm.hcr_dm_fact a"
Set rf = cn.Execute(sql_count)
Do While rf.Fields.Value = 8
.Open strSQL
Loop
Worksheets(wkSht).Range("A2").CopyFromRecordset rs
.Close
End With
' Close connection
cn.Close
Set rs = Nothing
Set Conn = Nothing
End Sub
Sub Refresh()
' Define SQL query
Dim mySQL As String
mySQL = "select a.oracle_fin_company_id || ' - ' || a.oracle_fin_company_desc as COMPANY " & _
"From hcr_dm.legal_entity_summary a " & _
"where a.Company_Header = 'Filed'"
' Choose worksheet where results should be displayed
Dim myWkSht As String
myWkSht = "Sheet1"
' Call connection sub
Call FillWithSQLData(mySQL, myWkSht)
End Sub
You're not selecting a field. The lines
Set rf = cn.Execute(sql_count)
Do While rf.Fields.Value = 8
Should probably be
Set rs = cn.Execute(sql_count)
Do While rs.Fields(0).Value = 8
Also, note the typo in that you declared rs but you're filling rf with the Recordset.
I recommend you use the Option Explicit statement to help find these. You can read more about it here.