Syntax for DAO 'Like' Select Query - sql

I'm sorry for bothering you all for what is probably a really simple problem.
I use DAO Select queries fairly frequently but have never needed to filter using 'Like' based on a form field.
The attached code, which should filter based on a combobox (comboRes), throws up a
Syntax error (missing operator) in query expression error.
I'm guessing the error lies in the Like '*' " & strRes & " '*' but I've tried lots of combinations with no joy.
Could someone please straighten out my syntax/code?
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Set db = CurrentDb
Dim strRes As String
strRes = Me.comboRes
Set qdf = db.QueryDefs("qryInst")
strSQL = "SELECT tblInst.*, tblInst.ResList " & _
"FROM tblInst " & _
"WHERE (((tblInst.ResList) Like '*' " & strRes & " '*'t ));"
qdf.SQL = strSQL
DoCmd.OpenQuery "qryInst"
qdf.Close
db.Close
Set qdf = Nothing
Set db = Nothing

You need to concatenate the string variable to the LIKE clause,
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Set db = CurrentDb
Dim strRes As String
strRes = Me.comboRes
Set qdf = db.QueryDefs("qryInst")
strSQL = "SELECT tblInst.*, tblInst.ResList " & _
"FROM tblInst " & _
"WHERE tblInst.ResList Like '*" & strRes & "*';"
qdf.SQL = strSQL
DoCmd.OpenQuery "qryInst"
qdf.Close
db.Close
Set qdf = Nothing
Set db = Nothing
So if your strRes is Paul, your SQL will translate to.
SELECT tblInst.*, tblInst.ResList FROM tblInst WHERE tblInst.ResList Like '*Paul*';"

Your SQL needs to be changed somewhat. The like operator takes a string, and the wildcard character depends on the ANSI Query Mode - see here - so you may need to use % instead of *. So to match the contents of strRes anywhere in tblInst.ResList, use the following:
"WHERE tblInst.ResList Like '*" & strRes & "*';"
Note that you are vulnerable to SQL injection when you use this style of code.

Related

Access VBA run query with values passed from a list box

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

Access Export Subform to excel

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

Vba Access error 91

I try to run this code
Public Sub Production_UpdateStatus(ByVal lngProductionId As Long, _
ByVal NewProductionStatus As eProductionStatus)
Dim oDb As DAO.Database
Dim oRst As DAO.Recordset
Dim StrSql As String
Dim strProductionStatus As String
On Error GoTo Err_Infos
GetCurrentProductionStatusString NewProductionStatus, strProductionStatus
Set oDb = CurrentDb
'Mise a jour du staut de production
StrSql = "UPDATE tProduction SET tProduction.Statut= '" & strProductionStatus & "'" _
& " WHERE (tProduction.IdProduction=" & lngProductionId & ");"
oDb.Execute StrSql
'Fermeture des connexions
oRst.Close
oDb.Close
Set oDb = Nothing
Set oRst = Nothing
Exit_currentSub:
Exit Sub
Err_Infos:
MsgBox "Erreur #" & Err.Number & " : " & Err.Description
Resume Exit_currentSub
End Sub
This code work but give me error 91.
Object variable or With block variable not set
It generate the following SQL query :
UPDATE tProduction SET tProduction.Statut= 'Nouvelle' WHERE (tProduction.IdProduction=2);
When I test direct query, I do not have any error. Could you help me to eliminate this error ?
Thanks
You are closing a recordset object, oRst, that was never initialized with Set. Because you run an action query you do not need a recordset and it may have lingered from prior code versions.
On that same note, because you are passing literal values to an SQL query, consider parameterizing with DAO QueryDef parameters that avoids concatenation and quote enclosures:
Dim oDb As DAO.Database, qdef As DAO.QueryDef
Dim StrSql As String, strProductionStatus As String
GetCurrentProductionStatusString NewProductionStatus, strProductionStatus
Set oDb = CurrentDb
StrSql = "PARAMETERS strProductionStatusParam Text(255), lngProductionIdParam Long;" _
& " UPDATE tProduction SET tProduction.Statut = [strProductionStatusParam]" _
& " WHERE (tProduction.IdProduction = [lngProductionIdParam]);"
Set qdef = oDb.CreateQueryDef("", StrSql)
qdef!strProductionStatusParam = strProductionStatus
qdef!lngProductionIdParam = lngProductionId
qdef.Execute dbFailOnError
Set qdef = Nothing
Set oDb = Nothing
Try to remove the oRst related code lines. This variable is not initialized and not used.

Access VBA - qdf parameters item not found - error 3265

I can't seem to understand what I've done wrong here. I'm getting an error 3265 (Item not found in this collection) at the three lines starting with "qdf.Parameters..." My understanding is that I define the where clause of my sql statement here, but maybe I'm wrong? Pretty new to vba with access so a little confused.
Sub Save_Invoices_Meet_Criteria()
Dim FileName As String
Dim FilePath As String
Dim myStmt As String
Dim Db As DAO.Database
Dim myrs As DAO.Recordset
Set Db = CurrentDb()
Dim qdf As DAO.QueryDef
Set qdf = Db.QueryDefs("qryCreateInvoicesApproved")
qdf.Parameters("[Forms]![frmAccountingDatabaseInput]![Invoice_approved]") = [Forms]![frmAccountingDatabaseInput]![Invoice_approved]
qdf.Parameters("[Forms]![frmAccountingDatabaseInput]![invoice_date]") = [Forms]![frmAccountingDatabaseInput]![Combo272]
qdf.Parameters("[Forms]![frmAccountingDatabaseInput]![Invoice_Type}") = [Forms]![frmAccountingDatabaseInput]![Combo274]
Set myrs = CurrentDb.OpenRecordset("SELECT distinct [reference] from qryCreateInvoicesApproved", 2)
Do Until myrs.EOF
FileName = Me.reference
foldername = Format(Now(), "YYYY-MM-DD")
FilePath = "C:\Users\company\Desktop\Invoicing Database\Save_Test\" & foldername & "\" & FileName & ".pdf"
DoCmd.OpenReport "RPTInvoice", acFormatPDF, FilePath
'DoCmd.OutputTo acOutputReport, , acFormatPDF, FilePath
DoCmd.Close
myrs.MoveNext
Loop
myrs.Close
Set myrs = Nothing
End Sub
My sql statement:
SELECT tblAccountingDatabase.*
FROM tblAccountingDatabase
WHERE (((tblAccountingDatabase.Invoice_approved)=Yes) And ((tblAccountingDatabase.invoice_date)=Forms!frmAccountingDatabaseInput!Combo272) And ((tblAccountingDatabase.Invoice_Type)=Forms!frmAccountingDatabaseInput!Combo274));
Simply add a PARAMETERS line at the beginning of your stored query which you then reference in the VBA querydef object. Then use the Querydef.OpenRecordset() method to pass parameterized query into a recordset object. Right now you are passing named parameters that do not exist:
SQL
PARAMETERS [Approveparam] YesNo, [Dateparam] Datetime, [Typeparam] String;
SELECT DISTINCT [reference]
FROM tblAccountingDatabase
WHERE (((tblAccountingDatabase.Invoice_approved) = [Approveparam])
AND ((tblAccountingDatabase.invoice_date) = [Dateparam])
AND ((tblAccountingDatabase.Invoice_Type) = [Typeparam]));
VBA
...
Dim qdf As DAO.QueryDef
Set qdf = Db.QueryDefs("qryCreateInvoicesApproved")
qdf!Approveparam = [Forms]![frmAccountingDatabaseInput]![Invoice_approved]
qdf!Dateparam = [Forms]![frmAccountingDatabaseInput]![Combo272]
qdf!Typeparam = [Forms]![frmAccountingDatabaseInput]![Combo274]
Set myrs = qdf.OpenRecordset()
...
To pass parameters to a form/report/macro that uses the same paramterized query use DoCmd.SetParameter method. And yes, you need to wrap every value with quotes hence the quote escaping. Also use DoCmd.OutputTo to convert report to PDF:
DoCmd.SetParameter "Approveparam", _
"""" & [Forms]![frmAccountingDatabaseInput]![Invoice_approved] & """"
DoCmd.SetParameter "Dateparam", _
"""" & [Forms]![frmAccountingDatabaseInput]![Combo272] & """"
DoCmd.SetParameter "Typeparam", _
"""" & [Forms]![frmAccountingDatabaseInput]![Combo274] & """"
DoCmd.OpenReport "RPTInvoice", acViewPreview
DoCmd.OutputTo acOutputReport, "RPTInvoice", acFormatPDF, FilePath
It kind of looks like you're trying to force yourself to use a parameter query but not really committed to it. If you don't want to truly use one you can change your SQL structure to use generic parameter names - and then use the qdf.Parameters method to fill the values from your form.
But I think this is the easiest for what you have now.
Replace these lines:
Dim qdf As DAO.QueryDef
Set qdf = Db.QueryDefs("qryCreateInvoicesApproved")
qdf.Parameters("[Forms]![frmAccountingDatabaseInput]![Invoice_approved]") = [Forms]![frmAccountingDatabaseInput]![Invoice_approved]
qdf.Parameters("[Forms]![frmAccountingDatabaseInput]![invoice_date]") = [Forms]![frmAccountingDatabaseInput]![Combo272]
qdf.Parameters("[Forms]![frmAccountingDatabaseInput]![Invoice_Type}") = [Forms]![frmAccountingDatabaseInput]![Combo274]
Set myrs = CurrentDb.OpenRecordset("SELECT distinct [reference] from qryCreateInvoicesApproved", 2)
With this line to open your recordset
Set myrs = qdf.OpenRecordset("SELECT * from qryCreateInvoicesApproved", 2)
Change your query to:
SELECT DISTINCT [reference]
FROM tblAccountingDatabase
WHERE (tblAccountingDatabase.Invoice_approved=[Forms]![frmAccountingDatabaseInput]![Invoice_approved])
AND (tblAccountingDatabase.invoice_date=Forms!frmAccountingDatabaseInput!Combo272)
AND (tblAccountingDatabase.Invoice_Type=Forms!frmAccountingDatabaseInput!Combo274);

Error 3075-Run Query after multi select listbox is utilized

have a search form in Access 2010 that filters FYs and Quarters based on certain criteria and opens them in a query. One of the criteria is an unbound multi-select list box, SelectTime (Where a person selects "FY15-Q1 and FY15 Q2, for example. The data are stored in a query, z_Basis_QSReport5_Proposal Details. I keep getting an error 3075. Can someone help me with the code?
Private Sub Command56_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strSQL As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("z_Basis_QSReport5_Proposal Details_For_Report")
For Each varItem In Me!SelectTime.ItemsSelected
strCriteria = strCriteria & ",'" & Me!SelectTime.ItemData(varItem) & "'"
Next varItem
If Len(strCriteria) = 0 Then
MsgBox "You did not select anything from the list" _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria = Right(strCriteria, Len(strCriteria) - 1)
strSQL = "SELECT * FROM z_Basis_QSReport5_Proposal Details " & _
"WHERE z_Basis_QSReport5_Proposal Details.CriteriaFY IN(" & strCriteria & ");"
qdf.SQL = strSQL
DoCmd.OpenQuery "z_Basis_QSReport5_Proposal Details_For_Report"
Set db = Nothing
Set qdf = Nothing
End Sub
I agree with #LiamH that you need to surround your query names with square brackets.
Also it looks like you're trying to change the SQL of a query on the fly - and then call the query before you've saved the changes
qdf.SQL = strSQL
**qdf.close**
DoCmd.OpenQuery "z_Basis_QSReport5_Proposal Details_For_Report"
That being said I think you should be looking at parameter queries or just opening the SQL directly.
When creating query, table, and field names; it is best practice to avoid spaces. However, there is a solution.
When you use SQL and you have a table name with spaces you need to encapsulate it in square brackets. like so:
"SELECT * FROM [z_Basis_QSReport5_Proposal Details] & _
"WHERE [z_Basis_QSReport5_Proposal Details].CriteriaFY .....
EDIT
Before, I mentioned that you should maybe put square brackets around the query name, but if you look at the example here you will see that spaces are acceptable in this instance.
If we go back to your query, strcriteria is a string and therefore you need to put single quotes around it:
strSQL = "SELECT * FROM [z_Basis_QSReport5_Proposal Details] " & _
"WHERE [z_Basis_QSReport5_Proposal Details].CriteriaFY IN('" & strCriteria & "');"
Also, you will need to close your query before you can run it. So qdf.close is required before the docmd.openquery().