VBA OpenRecordset Produces Error 3061 - ms-access

databasename = "qryDataExport"
Dim grpfield As String
grpfield = "Group"
Dim keys As DAO.Recordset
groupcmd = "SELECT [" & databasename & "].[" & grpfield & "] FROM [" & databasename & "] GROUP BY [" & databasename & "].[" & grpfield & "]"
Set keys = CurrentDb.OpenRecordset(groupcmd, dbOpenSnapshot)
The above produces "Error 3061: Too few parameters. Expected 13." when run. My reading thus far has heavily implied that this is likely a spelling issue with improper field titles or an issue caused by improper quotations in the line defining groupcmd.
I have attempted the following formats for databasename:
CurrentDb.Queries.qryDataExport
CurrentDb!Queries!qryDataExport
And the above "qryDataExport". The latter two provide no error messages, while the first does not compile. I have confirmed that there is a column titled Group in both the main table and in qryDataExport.
The module being used is from this Google Code page.
(EDIT: Full edited module as of this time: http://pastebin.com/TJip86ED)
From what I've seen, I expect this is an incredibly obvious formatting error in the databasename definition, but I haven't got enough experience with VBA to spot it and I'm running out of ideas. Any suggestions would be greatly appreciated.
EDIT2: The content of generateKML() is now in ExportToKMLButton_Click(), where ExportToKMLButton is a Button on the Form DW_Form. While DW_Form is open, the query qryDataExport is usable, but when the form is closed, the query prompts for the 13 parameters mentioned in the error message.

It sounds like your qryDataExport query references controls on an Access form, perhaps similar to this one ...
SELECT *
FROM YourTable
WHERE some_field = Forms!Form1!YourTextBox
If Form1 is open (in Form View), I can run that query from Access' query designer, and it will resolve the reference to the form control.
However, if I try to use the exact same query with OpenRecordset, the reference is not resolved and, in that context, Access interprets it to be a parameter for which I have not supplied a value.
For your query with multiple control references, you can create a temporary QueryDef based on your SELECT statement, and loop through its Parameters collection, supplying each parameter value with Eval() of the parameter's .Name And finally call the QueryDef.OpenRecordset method to load your recordset:
Dim prm As DAO.Parameter
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef(vbNullString, groupcmd)
For Each prm In qdf.Parameters
prm.Value = Eval(prm.Name)
Next
Set keys = qdf.OpenRecordset

The way you use databasename is correct (databasename = "qryDataExport"), qryDataExport is likely filtering data using values from the form... that's why when you execute the query independently, the query finds it is missing 13 paramenters that it takes from said form.
You can run this procedure in a Click() event for a button within the form, it should work.

Related

MSAccess: Get ItemIDs from Recordsetclone into New Table?

I have an AccessDB app where I need to grab the ItemIDs for the current user-applied filter into a new table to use downstream. Using the subform datasheet .recordsetclone property I can see the desired recordset, .recordcount reports the correct number of records. Otherwise, the following does not produce the desired temp table and AccessVBA does not complain.
Dim db As DAO.Database
Dim rstItemIDs As DAO.Recordset
Dim strSQL as String
Set db = CurrentDb
set rstItemIDs = Forms!Mainform![Data subform].Form.RecordsetClone
msgbox rstItemIDs.recordcount 'reports the correct result
strSQL = "SELECT rstItemIDs.ItemID INTO tempTable FROM rstItemIDs;"
db.Execute strSQL
Is it possible to construct a SQL Select query against a dao.recordset?
Thanks for any pointers you can provide.
Access SQL will not accept either a DAO or ADODB Recordset as the data source for a query.
However, I'm puzzled that Access does not complain when you try. With every attempt I made to reproduce your sample code, I got error #3078, "The Microsoft Access database engine cannot find the input table or query 'rstItemIDs'. Make sure it exists and that its name is spelled correctly."
Even DoCmd.SetWarnings False did not suppress that error message.
If you're interested in alternatives, you could persist tempTable (instead of creating a new version each time), then delete its contents and move through rstItemIDs adding each value to the second recordset. Although that is a RBAR (row by agonizing row) method, it may not be too painful with a small recordset.
A set-based approach could be to create a query based on your form's .RecordSource and .Filter properties. For example, with my form's .RecordSource as SELECT * FROM foo and the current form .Filter as id>10, this would give me a SELECT which returns the form's filtered records:
Replace(Me.RecordSource, ";", "") & vbcrlf & "AND " & Me.Filter

VBA Error trying to set QueryDefs parameters for a query in access

I have this qry in access, if I go into its design it has a criteria (which as I understand it is a parameter).
The Report this qry is based off of works great, click on it a little thing pops up asks the required info and off it goes. In code I am trying to do this and get a
Run-time error '424'
Object Required
the offending line:
qdf.Parameters("Insurance Name").Value = inputStr
Lines before it:
Set qfd = CurrentDb.QueryDefs("qryInsGrpRoster")
Dim inputStr As String
inputStr = InputBox("Enter Insurance")
'Supply the parameter value
qdf.Parameters("Insurance Name").Value = inputStr
inputStr definitely equals the value, it fails though.
The criteria line in the qry is:
Like "*" & [Insurance Name] & "*"
Do I need the likes and all that to set that parameter?
in Access 2010 and 2013
This uses DAO and might be of interest
DIM MyQryDef as querydef
Dim a as string
a = ""
a = a & "PARAMETERS Parameter1 INT, Parameter2 INT; "
a = a & "SELECT f1, f2 FROM atable WHERE "
a = a & "f3 = [Parameter1] AND f4 = [Parameter2] "
a = a & ";"
Set MyQryDef = currentdb().CreateQueryDef("MyQueryName", a)
MyQryDef.Parameters("Parameter1").Value = 33
MyQryDef.Parameters("Parameter2").Value = 2
' You could now use MyQryDef with DAO recordsets
' to use it with any of OpenQuery, BrowseTo , OpenForm, OpenQuery, OpenReport, or RunDataMacro
DoCmd.SetParameter "Parameter1", 33
DoCmd.SetParameter "Parameter2", 2
DoCmd.Form YourFormName
' or
DoCmd.SetParameter "Parameter1", 33
DoCmd.SetParameter "Parameter2", 2
DoCmd.OpenQuery MyQryDef.Name
See here:
https://msdn.microsoft.com/en-us/library/office/ff194182(v=office.14).aspx
Harvey
The parameters property of an Access Query is read only.
You have basically two options here that I can think of right off.
The first is to just completely rewrite the SQL of the saved query each time you need to use it. You can see an example of this here: How to change querydef sql programmatically in MS Access
The second option is to manually set the RecordSource of the report each time it opens. Using this method you will not use a saved query at all. You'll need to set/store the entire SQL statement in your code when the report opens, ask for any input from the user and append the input you get to your SQL statement. You could setup a system where the base SQL is stored in a table instead but, for simplicity, that's not necessary to achieve what you're trying to do here.
MS Access does allow you to use parametrized queries in the manner you're attempting here (not the same code you have), but as far as I know, it would require you to use Stored Procedures in MS SQL Server or MySQL and then you'd need to use ADO. One big downside is that Access reports cannot be bound to ADO recordsets so this isn't really an option for what you're trying to do in this particular instance.
Seems like a typo. You're creating the object named 'qfd', and trying to use the object named 'qdf'
Set qfd = ...
and then
qdf.Para...
I like to put Option Explicit in my modules to help me find these types of issues.

Information about syntax of ADO recordset filter queries

I spent much time trying to figure out how to extract date part in ado recordset filter expressions connecting to Jet engine working with an mdb file. The problem is that many things mentioned about access flavor of sql (date function for example) don't work there raising errors. Formatting dates with #mm/dd/yyyy hh:mm:ss# in comparisons works but gives incorrect results. Is there reliable source of information of what kind of expressions work for filters and what functions I can use?
UPDATE
The version used is when I choose Microsoft JET 4.0 OLE DB Provider. Generally one would expect that filter criteria can use the same syntax as the parts of the queries coming after WHERE keyword in SQL queries. My task was to compare date parts of time stamps and I finally decided to use query instead of filtered table, but the following example works when it's the part of the sql query (after WHERE) and raises "The application is using arguments that are of the wrong type, are out of acceptable range, or are in conflict with one another" error when it's the contents of the filter
format(TimeStamp,"yyyy/mm/dd")=format(#04/11/2013#,"yyyy/mm/dd")
So I see there's obvious differences between WHERE and filter syntax, but I could not find detailed explanation what exactly are they.
I'm actually quite surprised that WHERE Format([TimeStamp]... works in an ADO query against the Access Database Engine (ACE), but apparently it does.
I certainly agree that specific details on using some Microsoft features can be difficult to find in Microsoft's documentation. I guess that helps keep sites like Stack Overflow in business. ;)
As for your .Filter question, using Format() in this context does fail, presumably because Format() is a VBA function and is not (always) available to an expression outside of the Access application itself. However, the following test shows that...
rst.Filter = "[TimeStamp] >= #2013/04/11# AND [TimeStamp]<#2013/04/12#"
...does work. (When no time is specified for a DateTime value then midnight - 00:00:00 - is assumed.)
Test data:
ID TimeStamp
1 2013-04-10 21:22:00
2 2013-04-11 02:34:56
3 2013-04-11 04:45:15
Test code:
Sub foo()
Dim con As ADODB.Connection, rst As ADODB.Recordset
Set con = New ADODB.Connection
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data source=C:\Users\Gord\Desktop\Database1.accdb;"
Set rst = New ADODB.Recordset
Debug.Print "Test 1: WHERE Format([TimeStamp]..."
rst.Open _
"SELECT * FROM [TimeStampData] " & _
"WHERE Format([TimeStamp], ""yyyy/mm/dd"") = Format(#2013/04/11#, ""yyyy/mm/dd"")", _
con, adOpenKeyset, adLockOptimistic
Debug.Print "Records returned: " & rst.RecordCount
rst.Close
Debug.Print
Debug.Print "Test 2: Filter"
rst.Open "SELECT * FROM [TimeStampData]", con, adOpenKeyset, adLockOptimistic
Debug.Print "Total records: " & rst.RecordCount
rst.Filter = "[TimeStamp] >= #2013/04/11# AND [TimeStamp]<#2013/04/12#"
Debug.Print "Filtered records: " & rst.RecordCount
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
End Sub
Test results:
Test 1: WHERE Format([TimeStamp]...
Records returned: 2
Test 2: Filter
Total records: 3
Filtered records: 2
A short note on the (VBA) ADO filter syntax (applies also to DAO):
The filter should be specified as: "[Fieldname] = "
Where Fieldname is an existing name of a field in the recordset and can be anything that can be represented by a string. A non-string is allways converted to a string as the filtervalue will be transformed into an explicit SQL WHERE statement (Allways a string).
Valid filters would be:
rst.Filter="[TimeStamp] = #2013/04/12#" '(Mind the hashes as a date is expected. Peculiarly all localised notations are accepted!)
rst.Filter="[TimeStamp] = #" & strDatevalue & "#" 'Where strDatevalue is a datevalue as text.
Hence this will work:
rst.Filter="[TimeStamp] = #" & format(#04/11/2013#,"mm/dd"/yyyy) & "#"
'Mind: Access expects here an American standard date format, i.e. month/day/year
'(In that case you could even leave the hashes away!)
IF

Access variable Field Names

In MS Access 2010, I am building an update query (using the Query Designer).
I would like to pass the name of the column to update as a variable, at run time.
I have tried writing the SQL and running the query in VBA. This seemed like the easiest way... however the SQL to complete the update becomes quite messy. I would prefer to do this in the query builder GUI .
Is it possible?
I have so far tried entering field names into the query builder:
expr1:[field_name]
Although Access prompts me for "Field_name" This results in "Cannot update 'field_name'; field not updateable.
Also, I tried this method:
Expr1: "'" & [field_name] & "'"
which results in "'" & [field_name] & "'" is not a valid name; check for punctuation.. etc
Below is a screen capture the query I am trying to build.
Access' db engine will not allow you to use a parameter as the name of the target field for your UPDATE statement.
If you try a user-defined function instead of a parameter to provide the field name, the result will be the same ... no joy.
It seems the db engine will not resolve object names when it executes a SQL statement. That limitation applies not just to field names, but table names as well. IOW, the following query will fail with an error message that it "cannot find the input table or query 'give me a table name'".
SELECT *
FROM [give me a table name];
While that isn't exactly the same as your situation, I suspect the reason may be. The db engine is too limited about resolving object names when it plans/executes queries.
Perhaps the best method is to use SQL, build your prompts and then assign these values to variables in VBA, then just add the variable value into your SQL.
So something along these lines. Your using Update query but same logic
Dim SQL as string
dim **FieldName** as string
SQL = "Select [table]![" & Chr(34) & **FieldName** & Chr(34) & "] from ........"
Check Here for SQL building tips
I use this method frequently - I know it's a very old post, but hope this helps someone - building on what David said:
Sub CreateQuery
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Set dbs = CurrentDb
Set qdf = dbs.CreateQueryDef("NameOfNewQuery")
strSQL = "Select " 'notice the space
strSQL = strSQL & "FROM " 'notice the sapce
strSQL = strSQL & "WHERE;"
qdf.SQL = strSQL
qdf.Close
Set qdf = Nothing
Set dbs = Nothing
End Sub

Access 2007 Runtime Error

I'm not sure if this is the right site to post this question, but here it goes...
In Access 2007 I get the error "Runtime Error '3061': Too few parameters. Expected 1" on this piece of VBA code:
Private Sub btnCheck_Click()
Dim rs As Recordset
Dim db As Database
Dim id As String
Dim query As String
MsgBox ("one")
Set db = CurrentDb()
id = Me.UniqueID.Value
query = "SELECT [Unique_ID] from tblPatients WHERE [Unique_ID] =" & id
MsgBox (id)
Set rs = db.OpenRecordset(query) <<<<<HIGHLIGHTED LINE
If IsNull(rs) Then
Me.lblCheck.Caption = "NEW"
Else
Me.lblCheck.Caption = "EXISTS"
End If
End Sub
The data source is a table, not a query. Any help would be much appreciated!
There is no field named Unique_ID in your table tblPatients. If you posted all of your code then that is the only possible explanation.
EDIT: Your comment confirmed my suspicions:
I just triple checked :P Table name: tblPatients Column name: Unique ID
You added an underscore in your code that did not exist in your field name. You are correct in using square brackets, but the correct code should be:
query = "SELECT [Unique ID] from tblPatients WHERE [Unique ID] =" & id
Please note the removed underscores. Alternatively (and I'd say preferably if you are in the early stages of design), you can rename the field in the table to either Unique_ID or UniqueID and save yourself a good deal of hassle.
A Few things can cause this error. A common error is misspelled table names and field names.
I would check tblPatients is spelled correctly or that there is no prior suffix like dbo.tblPatients required if the table is linked to a Server Connection.
As well we are assuming the id is a number and isn't a text field which would cause an error if you do not have the correct quotes. ie.
it would instead read
query = "SELECT [Unique_ID] from tblPatients WHERE [Unique_ID] = '" & id & "';"
Lastly, try to place ";" like I did in the line above.
I suggest you add a Debug.Print statement to your code like this:
query = "SELECT [Unique_ID] from tblPatients WHERE [Unique_ID] =" & id
Debug.Print "query: " & query
The reason for that suggestion is Debug.Print will print your SQL statement to the Immediate Window. (You can use the Ctrl+g keyboard shortcut to get to the Immediate Window.) Then you can view the completed string you're asking OpenRecordset to use. Often just seeing that string (rather than trying to imagine what it should look like) will let you spot the problem. If not, you can copy the string from the Immediate Window and paste it into SQL View of a new query ... the query designer can help you pinpoint syntax errors ... or in this case, I think it may alert you to which item in your query the database engine doesn't recognize and suspects must therefore be a parameter. And if that step still doesn't resolve the problem, you can paste the string into your question on Stack Overflow.
Finally, I think you may have a logic error with IsNull(rs) ... because rs has been declared a recordset, it will never be Null. In the following example, the SELECT statement returns no records. And the Debug.Print statement says IsNull(rs): False both before and after OpenRecordset.
Public Sub RecordsetIsNeverNull()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSql As String
strSql = "SELECT * FROM tblFoo WHERE 1 = 2;"
Set db = CurrentDb
Debug.Print "IsNull(rs): " & IsNull(rs)
Set rs = db.OpenRecordset(strSql)
Debug.Print "IsNull(rs): " & IsNull(rs)
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Edit: According to Problem names and reserved words in Access, query is an Access reserved word. I don't actually think that is the cause of your problem, but suggest you change it anyway ... perhaps strQuery.