Excel VBA Recordset SQL - No value given for required parameters - sql

Whilst the title of this question is similar to other questions asked in the past, I could not via limited searching on Google or SE find an answer that helped me with my problem below.
I am trying to pick up data from an excel sheet for processing. After finding that a more complex SQL statement with a join gave an error, I looked deeper and found the following;
The below SQL statement runs fine:
SELECT [DNSHEET$].[DNS] FROM [DNSHEET$]
However the below SQL statement does not & this gives the error stated in title later.
SELECT [DNSHEET$].[DNK] FROM [DNSHEET$]
I use the code below for running either SQL statement - they are saved in sql1 which is defined as a string.
rs.execute(sql1), cn
Where rs is the Recordset and cn the connection.
cn is defined as:
Set cn = CreateObject("ADODB.Connection")
With cn
.provider="Microsoft.ACE.OLEDB.16.0"
.ConnectionString="Data Source=" & ThisWorkbook.Path & "\" & ThisWorkbook.Name & ";" & _ "Extended Properties=""Excel 12.0 Xml;HDR=YES"";"
.open
End with
DNS and DNK headers are correctly named and match headers on DNSHEET sheet.
DNS is populated with string data, DNK contains integers from 1 to circa 25000.
Update: This issue has been worked around by closing and reopening the excel workbook. Then both of the SQL queries could run.
Hence another question is why this arises and how to find out what the cause of the problem is?

Related

How to resolve a connection problem when connecting SQL from VBA XLS " ; VBA error message= 'Not able to find ISAM file'

when setting and running ADODB connection to SQL from VBA xls, I got a error message "Not able to find the ISAM file", I writting the following connection in a VBA Module :
"Provider= Microsoft.ACE.OLEDB.12.0
"Data Source=" & PWRQRYFilePath
Im usiging xls 2019 , 32 bits. Referencing to Microsoft ActiveX Data Objects 6.1 Library.,
check any thing but not able to create and open the connection would you please help me.
Im trying to create and open the connection so I can run SQL queries from VBA xls
Following is a simple query i want to run to obtain a join inner from two spread sheets
But Actually the Query is sending me the error message.
What is the content of the variable PWRQRYFilePath?
For the sake of completeness:
If you want to go the long way, or better spoken, if you need the query more times, as you know, you can put the code lines also in a function an pass the path to the file to it.... here its represented by the Workbook-Property ThisWorkbook.Fullname
Dim rs As Object 'or AS ADODB.Recordset for EarlyBinding/IntelliSense
With rs
.Open "SELECT * FROM [worksheetname$] WHERE [column]='value'", _
";Provider=Microsoft.Ace.OLEDB.12.0" & _
";Extended Properties""Excel 12.0 xml""" & _
";Data Source=" & ThisWorkbook.FullName
'*** do your stuff with recordsetresult
.Close
End With
If you need the query just once, you can use a anonym function call as well:
With CreateObject("ADODB.Recordset")
.OPEN ...
'*** do your stuff ...
.CLOSE
End With

How to address a sheet with (2) in it's name with ADO

So I am using ADO to import data from several workbooks in a folder with several tabs in them. I have been able to set up all of the tabs to work with this except a tab named "MAT. (2)". When I use the code below, it gives me an error saying "Invalid Bracketing". I can't change the name of the tab due to it being a controlled document. Is there a way I can put the tab name in a format that will be accepted or possibly some way that I could address "Sheet3" instead (I already tried that and it threw an error saying it couldn't find the object).
Set rs = dbConnection.Execute("SELECT * FROM [" & SourceSheet$ & "$" & SourceRange & "]")
Set TargetCell = Range(TargetRange).Cells(1, 1)
TargetCell.CopyFromRecordset rs
Edit -
The connection string that I am using is as follows:
dbConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & SourceFile & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=No"";"
You could try using single or double quotes to escape the name, rather than brackets. What provider are you using to connect? I had an issue with connecting to a SQL Server database with a hyphenated name. I tried everything I could think of to escape the name, but it wouldn't work. I ended up solving the problem by switching from an ODBC connection to OLE DB connection. Maybe try the ACE OLEDB 12.0 provider and see if you can get it to work that way. OLE DB excel connstrings
EDIT:
Have you tried escaping the database name in backticks?
I'm thinking the . is the issue as this character is usually illegal as a database or table name in most SQL based RDBMS's. So try something like:
Set rs = dbConnection.Execute("SELECT * FROM `"& SourceSheet$ & "$" & SourceRange &`"
or possibly
Set rs = dbConnection.Execute("SELECT * FROM [`" & SourceSheet$ & "$" & SourceRange & "`]"
I'm not sure if either of these will work, but is worth a shot. If you can, you might want to remove the . from any worksheet names as it might cause some funny problems.

EXCEL ADODB Query on local worksheet not Including newly inserted records

I am using ADODB to query data form a worksheet in the Active workbook. The data resides on it's own sheet, and has column headers. I've defined the table as an excel ListObject - excel's automatic table formatting construct.
I open the connection like this:
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.Path & "\" & _
ThisWorkbook.Name & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
cn.Open strCon
Then I can fetch a recordset using a simple SQL statement:
strSQL = "SELECT * from [sheet1$]
rs.Open strSQL, cn, 0, 1 'cursortype = adOpenForwardOnly, locktype = adOpenReadonly
This all works fine... until I insert a new row in the table on sheet1. The new row is not included in subsequent queries, even if I close, set to nothing, and re-open both the connection and recordset variables in my code.
If I save and close the workbook, and then re-open it, the new records ARE included in the query, which leads me to believe this might be a caching issue. I've searched for ADODB Cache Flush etc, but most results appear to be related to PHP or Access. I've also tried a variety of other options for Cursor Type and Lock Type, with no difference.
Can anyone suggest how I can ensure that each time I run my query I get all the rows, even after I insert new rows in the table?
Figured out a solution:
Since I'm using Excel 2010, I discovered that I can use a newer version of ADODB.
So, instead of defining my connection string like this:
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="...
I changed it to this:
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source="...
and the problem is solved. New inserts and edits are now showing up immediately after I make them. This also removes the issue of the known memory leak in OLEDB.4.0, so that's a bonus.

Unable to query dynamically named range on Excel sheet using ADO

Suppose I have an Excel Sheet named Adjustments stored in a variable called wksName and, on that sheet, I have a named range defined as follows if you look in the Name Manager:
tblData =OFFSET(Adjustments!$A$1,0,0,COUNTA(Adjustments!$A:$A),4)
So that it expands to as many rows as we have data in columns A thru D.
Now I have the following code in my VBA module:
Set ExcelCon = CreateObject("ADODB.Connection")
Set ExcelRecSet = CreateObject("ADODB.Recordset")
ExcelCon.ConnectionString = "Provider='Microsoft.Jet.OLEDB.4.0';" & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'"
'Get the data for the update:
ExcelCon.Open
' Get the data from the spreadhseet for the update statement
Set ExcelRecSet = ExcelCon.Execute("SELECT * FROM [" & wksName & "$tblData]")
When I try and run this code, I get the error:
Run-time error '-2147217865 (80040e37)':
The Microsoft Jet database engine could not find the object 'Sheet1$tblData'.
Make sure the object exists and that you spell its name and the path name correctly.
Is this a limitation to using ADO - Named ranges can not be dynamically defined - Or is there a way I can get this to work?
Thanks!!
As stated in the comments, the code that ended up working for me (for those of you that may find you have the same issue) was something along the lines of:
Set ExcelRecSet = ExcelCon.Execute("SELECT * FROM [" & wksName & "$" & _
wks.Range("tblData").Address(0, 0) & "]")
This definitely works, but if there was a way to select a variable range without having to reference it as above, I'd love to see the way to do that.
Thanks!!

Access 2007 VBA Query Shows Data in Query Analyzer But Not in VBA Coded Recordset

I have a function I've written that was initially supposed to take a string field and populate an excel spreadsheet with the values. Those values continually came up null. I started tracking it back to the recordset and found that despite the query being valid and running properly through the Access query analyzer the recordset was empty or had missing fields.
To test the problem, I created a sub in which I created a query, opened a recordset, and then paged through the values (outputting them to a messagebox). The most perplexing part of the problem seems to revolve around the "WHERE" clause of the query. If I don't put a "WHERE" clause on the query, the recordset always has data and the values for "DESCRIPTION" are normal.
If I put anything in for the WHERE clause the recordset comes back either totally empty (rs.EOF = true) or the Description field is totally blank where the other fields have values. I want to stress again that if I debug.print the query, I can copy/paste it into the query analyzer and get a valid and returned values that I expect.
I'd sure appreciate some help with this. Thank you!
Private Sub NewTest()
' Dimension Variables
'----------------------------------------------------------
Dim rsNewTest As ADODB.Recordset
Dim sqlNewTest As String
Dim Counter As Integer
' Set variables
'----------------------------------------------------------
Set rsNewTest = New ADODB.Recordset
sqlNewTest = "SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, " & _
"dbo_part.partdescription as Description, dbo_partmtl.qtyper as [Qty Per] " & _
"FROM dbo_partmtl " & _
"LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum " & _
"WHERE dbo_partmtl.mtlpartnum=" & Chr(34) & "3C16470" & Chr(34)
' Open recordset
rsNewTest.Open sqlNewTest, CurrentProject.Connection, adOpenDynamic, adLockOptimistic
Do Until rsNewTest.EOF
For Counter = 0 To rsNewTest.Fields.Count - 1
MsgBox rsNewTest.Fields(Counter).Name
Next
MsgBox rsNewTest.Fields("Description")
rsNewTest.MoveNext
Loop
' close the recordset
rsNewTest.Close
Set rsNewTest = Nothing
End Sub
EDIT: Someone requested that I post the DEBUG.PRINT of the query. Here it is:
SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, dbo_part.partdescription as [Description], dbo_partmtl.qtyper as [Qty Per] FROM dbo_partmtl LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum WHERE dbo_partmtl.mtlpartnum='3C16470'
I have tried double and single quotes using ASCII characters and implicitly.
For example:
"WHERE dbo_partmtl.mtlpartnum='3C16470'"
I even tried your suggestion with chr(39):
"WHERE dbo_partmtl.mtlpartnum=" & Chr(39) & "3C16470" & Chr(39)
Both return a null value for description. However, if I debug.print the query and paste it into the Access query analyzer, it displays just fine. Again (as a side note), if I do a LIKE statement in the WHERE clause, it will give me a completely empty recordset. Something is really wonky here.
Here is an interesting tidbit. The tables are linked to a SQL Server. If I copy the tables (data and structure) locally, the ADO code above worked flawlessly. If I use DAO it works fine. I've tried this code on Windows XP, Access 2003, and various versions of ADO (2.5, 2.6, 2.8). ADO will not work if the tables are linked.
There is some flaw in ADO that causes the issue.
Absolutely I do. Remember, the DEBUG.PRINT query you see runs perfectly in the query analyzer. It returns the following:
Job/Sub Rev Description Qty Per
36511C01 A MAIN ELECTRICAL ENCLOSURE 1
36515C0V A VISION SYSTEM 1
36529C01 A MAIN ELECTRICAL ENCLOSURE 1
However, the same query returns empty values for Description (everything else is the same) when run through the recordset (messagebox errors because of "Null" value).
I tried renaming the "description" field to "testdep", but it's still empty. The only way to make it display data is to remove the WHERE section of the query. I'm starting to believe this is a problem with ADO. Maybe I'll rewriting it with DAO and seeing what results i get.
EDIT: I also tried compacting and repairing a couple of times. No dice.
When using ADO LIKE searches must use % instead of *. I know * works in Access but for some stupid reason ADO won't work unless you use % instead.
I had the same problem and ran accoss this forum while trying to fix it. Replacing *'s with %'s worked for me.
Description is a reserved word - put some [] brackets around it in the SELECT statement
EDIT
Try naming the column something besides Description
Also are you sure you are using the same values in the where clause - because it is a left join so the Description field will be blank if there is no corresponding record in dbo_part
EDIT AGAIN
If you are getting funny results - try a Compact/Repair Database - It might be corrupted
Well, what I feared is the case. It works FINE with DAO but not ADO.
Here is the working code:
Private Sub AltTest()
' Dimension Variables
'----------------------------------------------------------
Dim rsNewTest As DAO.Recordset
Dim dbl As DAO.Database
Dim sqlNewTest As String
Dim Counter As Integer
' Set variables
'----------------------------------------------------------
sqlNewTest = "SELECT dbo_partmtl.partnum as [Job/Sub], dbo_partmtl.revisionnum as Rev, " & _
"dbo_part.partdescription as [TestDep], dbo_partmtl.qtyper as [Qty Per] " & _
"FROM dbo_partmtl " & _
"LEFT JOIN dbo_part ON dbo_partmtl.partnum = dbo_part.partnum " & _
"WHERE dbo_partmtl.mtlpartnum=" & Chr(39) & "3C16470" & Chr(39)
Debug.Print "sqlNewTest: " & sqlNewTest
Set dbl = CurrentDb()
Set rsNewTest = dbl.OpenRecordset(sqlNewTest, dbOpenDynaset)
' rsnewtest.OpenRecordset
Do Until rsNewTest.EOF
For Counter = 0 To rsNewTest.Fields.Count - 1
MsgBox rsNewTest.Fields(Counter).Name
Next
MsgBox rsNewTest.Fields("TestDep")
rsNewTest.MoveNext
Loop
' close the recordset
dbl.Close
Set rsNewTest = Nothing
End Sub
I don't use DAO anywhere in this database and would prefer not to start. Where do we go from here?
I know some time has passed since this thread started, but just in case you're wondering, I have found out some curious about Access 2003 and the bug may have carried over to 2007 (as I can see it has).
I've had a similar problem with a WHERE clause because I needed records from a date field that also contained time, so the entire field contents would look like #6/14/2011 11:50:25 AM# (#'s added for formatting purposes).
Same issue as above, query works fine with the "WHERE ((tblTransactions.TransactionDate) Like '" & QueryDate & "*');" in the query design view, but it won't work in the VBA code using ADO.
So I resorted to using "WHERE ((tblTransactions.TransactionDate) Like '" & QueryDate & " %%:%%:%% %M');" in the VBA code, with ADO and it works just fine. Displays the record I was looking for, the trick is not to use "*" in the Like clause; or at least that was the issue in my case.
I put brackets around the word "Description" in the SELECT statement, but it's behavior remains. It works fine as long as I don't put anything in the WHERE clause. I've found if I put anything in the where clause, the description is blank (despite showing up in the Query analyzer). If I use a LIKE statement in the WHERE clause, the entire recordset is empty but it still works properly in the Query Analyzer.
Ultimately I think it's a problem with running ADO 2.8 on Vista 64
Personally I have always used DAO in Access projects.