I am trying to run a query from the Access Query designer that is working fine in Access but when I try to bring the statement across to VBA it is giving me this error message:
Run time error too few parameters. Expected 2.
I have printed the statement in the immediate window and run it in Access and it is running without asking for parameters. I have done a number of web searches the general consensus seems to be to declare it all in VBA, including the parameters -
Private Sub CmdAppend_Click()
Dim db1 As Database
Dim mystr As Recordset2
Dim UserName As String
Dim UpdateSQL As String
Dim SelectIDSQL As String
Dim checkstr As String
If Validate_Data = True Then
UserName = Environ$("Username")
SelectIDSQL = "Select Distinct ChecklistResults.[StaffID]" _
& " From ChecklistResults" _
& " Where (((ChecklistResults.[ClientID])=[Forms]![TeamLeader]![ComClientNotFin])" _
& " And ((ChecklistResults.[DateofChecklist])=[Forms]![TeamLeader]![ComDateSelect])" _
& " AND ((ChecklistResults.[ManagerID]) Is Null));"
Debug.Print SelectIDSQL
Set db1 = CurrentDb
Set mystr = db1.OpenRecordset(SelectIDSQL)
checkstr = mystr!StaffID
If checkstr <> UserName Then
I receive the above error message when I try to set mystr to the recordset. I think I can get the recordset by following the format below but is there a way of getting the above SQL statement/assignment to work?
Dim qdf1 As DAO.QueryDef
Set qdf1 = db1.QueryDefs("Get_StaffID")
qdf1.Parameters(0) = [Forms]![TeamLeader]![ComClientNotFin]
qdf1.Parameters(1) = [Forms]![TeamLeader]![ComDateSelect]
Set rst1 = qdf1.OpenRecordset(dbOpenDynaset)
As I look at this page, I see examples where the OpenRecordSet method takes two arguments. You have an error message that says something was expecting 2 parameters. Try changing this:
Set mystr = db1.OpenRecordset(SelectIDSQL)
to this:
Set mystr = db1.OpenRecordset(SelectIDSQL, dbOpenDynaset)
Thanks for the input, I used the following code to get the result I was looking for. It uses the query SelectClientID to return the ID of the person who completed the first stage of a checklist. it then checks the person who has done the second check and if they match it returns an error message. If two different people have completed it, it uses the SQL statement to update the previous record with the second checker's ID -
Private Sub CmdAppend_Click()
Dim rst1 As Recordset2
Dim db1 As Database
Dim mystr As Recordset2
Dim UserName As String
Dim UpdateSQL As String
Dim SelectIDSQL As String
Dim checkstr As String
Dim qdf1 As DAO.QueryDef
Set db1 = CurrentDb
Set qdf1 = db1.QueryDefs("SelectClientID")
qdf1.Parameters(0) = [Forms]![TeamLeader]![ComClientNotFin]
qdf1.Parameters(1) = [Forms]![TeamLeader]![ComDateSelect]
Set rst1 = qdf1.OpenRecordset(dbOpenDynaset)
If Validate_Data = True Then
UserName = Environ$("Username")
UpdateSQL = "UPDATE ChecklistResults" _
& " SET ChecklistResults.[ManagerID] = '" & UserName & "'" _
& " WHERE (((ChecklistResults.[ClientID])=[Forms]![TeamLeader]![ComClientNotFin])" _
& " AND ((ChecklistResults.[DateofChecklist])=[Forms]![TeamLeader]![ComDateSelect])" _
& " AND ((ChecklistResults.[ManagerID]) Is Null));"
checkstr = rst1!StaffID
If checkstr <> UserName Then
DoCmd.SetWarnings False
DoCmd.RunSQL UpdateSQL
DoCmd.SetWarnings True
DoCmd.Close
Else
MsgBox ("This Checklist was created by you and cannot therefore Checked by you")
End If
Else
Exit Sub
End If
End Sub
Related
I have made this form in Access and I am hoping to do the following task.
The list box here contains two columns, and can be multi-selected. I want to use the values second column (the right column) and pass them into a query that I set up for the "test2" button below.
And here is my VBA code for the on-click event for the button.
Private Sub test2_Click()
Dim db As dao.Database
Dim qdef As dao.QueryDef
Dim strSQL As String
Set db = CurrentDb
'Build the IN string by looping through the listbox
For i = 0 To Select_Counties2.ListCount - 1
If Select_Counties2.Selected(i) Then
strIN = strIN & "'" & Select_Counties2.Column(1, i) & "',"
End If
Next i
'Create the WHERE string, and strip off the last comma of the IN string
strWhere = " WHERE County_GEOID in " & "(" & Left(strIN, Len(strIN) - 1) & ")"
strSQL = strSQL & strWhere
Set qdef = db.CreateQueryDef("User query results", strSQL)
qdef.Close
Set qdef = Nothing
Set db = Nothing
DoCmd.OpenQuery "User query results", acViewNormal
End Sub
I was getting this error:
Can someone tell me what I did wrong in the code? Thank you!
In this example from microsoft they call application.refreshwindow without explanation.
https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/database-createquerydef-method-dao
What I think is going on is that your code fails because access cannot find the query that was just added to it's collection of queries. Also your generated sql is no longer valid.
So: replace my sql with your own valid sql
Private Sub test2_Click()
Dim db As DAO.Database
Dim qdef As DAO.QueryDef
Dim strSQL As String
strSQL = "PARAMETERS GEOID Number; " 'without valid sql this code doesn't run so
'replace my sql with your own.
strSQL = strSQL & "SELECT GEOID FROM Counties"
Set db = CurrentDb
For i = 0 To Select_Counties2.ListCount - 1
If Select_Counties2.Selected(i) Then
strIN = strIN & Select_Counties2.Column(1, i) & ","
End If
Next i
strWhere = " WHERE County_GEOID in " & "(" & Left(strIN, Len(strIN) - 1) & ")"
strSQL = strSQL & strWhere
Debug.Print strSQL
'now the important bit:
db.CreateQueryDef ("User query results") 'create the query
Application.RefreshDatabaseWindow 'refresh database window so access knows it has a new query.
'query will now be visible in database window. make sure to delete the query between runs
'Access will throw an error otherwise
Set qdef = db.QueryDefs("User query results")
qdef.SQL = strSQL
qdef.Close
Set qdef = Nothing
Set db = Nothing
DoCmd.OpenQuery "User query results", acViewNormal
End Sub
I'm trying to write some VBA to export filtered records from a subform. I've found a number of post related to this issue and I've cobbled the code below from those post.
When I run it I get a run-time error saying:
the Object '__temp' already exist.
When I click debug it highlights the line
Set qrydef = db.CreateQueryDef(strTempQryDef, strSQL)
Thank you for you help.
Private Sub ExportSubform()
Dim db As dao.Database
Dim qrydef As dao.QueryDef
Dim strSQL As String
Dim bolWithFilterOn As Boolean
Dim strTempQryDef As String
Dim strRecordSource As String
strTempQryDef = "__temp"
bolWithFilterOn = me.subsearch_frm.Form.FilterOn
strRecordSource = me.subsearch_frm.Form.RecordSource
If InStr(strRecordSource, "SELECT ") <> 0 Then
strSQL = strRecordSource
Else
strSQL = "SELECT * FROM [" & strRecordSource & "]"
End If
' just in case our sql string ends with ";"
strSQL = Replace(strSQL, ";", "")
If bolWithFilterOn Then
strSQL = strSQL & _
IIf(InStr(strSQL, "WHERE ") <> 0, " And ", " Where ") & _
me.subsearch_frm.Form.Filter
End If
Set db = CurrentDb
'create temporary query
Set qrydef = db.CreateQueryDef(strTempQryDef, strSQL)
db.QueryDefs.Append qrydef
Set qrydef = Nothing
DoCmd.TransferSpreadsheet TransferType:=acExport, _
SpreadsheetType:=acSpreadsheetTypeExcel12Xml, _
TableName:=strTempQryDef, _
FileName:=Replace(CurrentProject.Path & "\", "\\", "\") & strTempQryDef & ".xlsx"
' Delete the temporary query
db.QueryDefs.Delete strTempQryDef
Set db = Nothing
End Sub
Per the documentation:
If the object specified by name is already a member of the QueryDefs collection, a run-time error occurs.
As such, you should delete the temporary query before attempting to create it. To do this, you could use code along the lines of the following:
On Error Resume Next
DoCmd.DeleteObject acQuery, strTempQryDef
On Error GoTo 0
Also, per the documentation:
In a Microsoft Access workspace, if you provide anything other than a zero-length string for the name when you create a QueryDef, the resulting QueryDef object is automatically appended to the QueryDefs collection.
As such, you don't need this line:
db.QueryDefs.Append qrydef
im working with access and VBA. As for now, I am trying to create a query with a SQL statement.
I have a bunch of tables, all of them are named "innen" at the end and they vary at the start. Each of these tables contain the column name "OP" (also other field names). Now my goal is to select all tables with the name containing '%innen' and the column name "OP". So far i tried this:
Sub Aktuell()
Dim strSQL As String
Dim db As DAO.Database
Set db = CurrentDb
Dim qdf As QueryDef
strSQL = "SELECT [*].OP FROM MSysObjects WHERE TABLE_NAME LIKE '%innen' ORDER BY MAX;"
db.Execute strSQL
Set qdf = CurrentDb.CreateQueryDef("NewQuery8", strSQL)
DoCmd.OpenQuery qdf.Name
End Sub
i tried this here aswell:
strSQL = "SELECT * " & _
"FROM INFORMATION_SCHEMA.TABLES " & _
"WHERE COLUMN_NAME = 'OP_Datum';"
But i keep getting errors.
Any ideas? does it even work with a sql statement via vba?
Here is a VBA solution for you.
Option Compare Database
Function GetFieldList(TableName As String) As String()
On Error GoTo Er
Dim Flds() As String
Dim fc As Long
Dim I As Long
'Initialize Dynamic Flds() Array
Flds = Split("")
fc = CurrentDb.TableDefs(TableName).Fields.Count - 1
If fc >= 0 Then
ReDim Preserve Flds(fc)
For I = 0 To fc
Flds(I) = CurrentDb.TableDefs(TableName).Fields(I).Name
Next I
End If
Done:
GetFieldList = Flds
Erase Flds
Exit Function
Er:
Resume Done
End Function
Sub flTest()
Dim I As Long
Dim Fields As Variant
Fields = GetFieldList("Customers")
If UBound(Fields) = -1 Then
MsgBox "Table Not Found, or Table has no fields", vbCritical + vbOKOnly
Exit Sub
End If
For I = LBound(Fields) To UBound(Fields)
Debug.Print """" & Fields(I) & """"
Next I
End Sub
I'll bet there is a way to so the same thing using nothing but SQL. Although, Access is a unique animal. You can do this using SQL Server. I'm not 100% sure Access can handle it. Well, why not try it and see for yourself.
When pressing a button I would like to execute a SQL statement which uses a variable.
For example:
SELECT a, b,
FROM data
WHERE a IS NOT NULL
AND b = '&<Variable>&';
Then the result of the query shall be exported into a worksheet of an Excel file.
You might have to create a SQL on the fly and save it for the DoCmd.OutputTo method to do the export for you. Something like.
Option Compare Database
Option Explicit
Sub ExportQueryToExcel()
Dim dbObj As DAO.Database, qdObj As DAO.QueryDef
Dim filePath As String, sqlText As String, yourVariable As String
Set dbObj = CurrentDb
yourVariable = "Apple"
sqlText = "SELECT a, b, c WHERE a Is Not Null And b = '" & yourVariable & "'"
filePath = "C:\Users\P\Desktop\fileName.xlsx"
On Error Resume Next
With dbObj
.QueryDefs.Delete "tmpDataQry"
Set qdfNew = .CreateQueryDef("tmpDataQry", sqlText)
.Close
End With
On Error GoTo 0
DoCmd.OutputTo acOutputQuery, "tmpDataQry", acFormatXLSX, filePath
Set qdObj = Nothing
Set dbObj = Nothing
End Sub
Alright, I might be way off if what I've tried, but here goes. I am trying to execute a SQL query to return some records and then populate a listbox. Essentially, I want every record to display in a separate line. I have this in a separate module referencing the main form. I have heard some things about filling a datatable with the SQL results and then linking the listbox to that as well, but I'm not 100% sure what to do there either. I've just been trying to manually update the listbox with each result, but it doesn't seem to like it. I am using a recordset instead of a datatable, but like I said, it's because I'm unsure of how to use a datatable (haven't done it before but I am willing to learn)
Public Sub addCases()
'Uses windows login credentials to determine and return CSP's Manager's Name
'C
Dim i As Integer
Dim intX As Integer
Dim c As ADODB.Connection
Dim r As ADODB.Recordset
Dim strSQL As String, strManager As String
Set c = New ADODB.Connection
c.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Commit Tracker.accdb; Persist Security Info=False;"
strSQL = "SELECT "
strSQL = strSQL & "* "
strSQL = strSQL & "FROM "
strSQL = strSQL & "CommitTrk "
strSQL = strSQL & "WHERE "
strSQL = strSQL & "EMP_ID = '" & Username() & "'"
Set r = c.Execute(strSQL)
If r.EOF = False Then
intX = 0
vararray = r.GetRows()
For i = LBound(vararray) To UBound(vararray)
With frmCommitViewer.lstCases
.AddItem
.List(intX, 0) = r.Index(i)
End With
intX = intX + 1
Next i
End If
r.Close
c.Close
Set r = Nothing
Set c = Nothing
End Sub
I figured it out. Instead of the stupid array conversion, I'm still using the recordset directly.
If r.EOF = False Then
With frmCommitViewer.lstCases
.Clear
Do
.AddItem r![CASE_ID_NBR]
r.MoveNext
Loop Until r.EOF
End With
End If
Super simple. Thanks to http://www.fontstuff.com/vba/vbatut10pfv.htm.