Search Query Works First Time but subsequent runs get run-time error 3075 extra ) in query expression - vba

I have gone through all previous questions asked and even tried the solutions but to no avail so here's my dilemna. I have used a search query from Allenbrowne which was initially great. However, I wanted to add to the search criteria which again I have done and when searching for the first time I got the results I was looking for. I now use a different code to remove all the search criteria and to unfilter the form (split form). Again everything works. Now I want to search again either using the same of different parameters and this time I get the run-time error 3075 stating that I have an extra ) in the query expression. I have even looked up the query to see where this extra ) is but to no avail. The code is as follows and it errors on Me.Filter = strWhere. I have also provided the reset filter when clearing the search screen and wanting to start a new search. Any help would really be appreciated.
Option Compare Database
Option Explicit
Private Sub cmdFilter_Click()
Dim strWhere As String 'The criteria string.
Dim lngLen As Long 'Length of the criteria string to append to.
'***********************************************************************
'Look at each search box, and build up the criteria string from the non-blank ones.
'***********************************************************************
If Not IsNull(Me.txtCustID) Then
strWhere = strWhere & "([Customer_ID] = " & Me.txtCustID & ") AND "
End If
If Not IsNull(Me.txtJobID) Then
strWhere = strWhere & "([Job_ID] = " & Me.txtJobID & ") AND "
End If
If Not IsNull(Me.txtName) Then
strWhere = strWhere & "([Name] Like ""*" & Me.txtName & "*"") AND "
End If
If Not IsNull(Me.TxtPostcode) Then
strWhere = strWhere & "([Postcode] = ""*" & Me.TxtPostcode & "*"") AND "
End If
If Not IsNull(Me.txtCompany) Then
strWhere = strWhere & "([CompanyName] Like ""*" & Me.txtCompany & "*"") AND "
End If
If Not IsNull(Me.txtLocation) Then
strWhere = strWhere & "([Location] Like ""*" & Me.txtLocation & "*"") AND "
End If
If Not IsNull(Me.CboStatus) Then
strWhere = strWhere & "([Status] = " & Me.CboStatus & ") AND "
End If
If Not IsNull(Me.CboSource) Then
strWhere = strWhere & "([EnquirySource] = " & Me.CboSource & ") AND "
End If
'See if the string has more than 4 characters (a trailng " AND ") to remove.
lngLen = Len(strWhere) - 4
If lngLen <= 0 Then 'Nah: there was nothing in the string.
MsgBox "No criteria", vbInformation, "Nothing to do."
Else 'Yep: there is something there, so remove the " AND " at the end.
strWhere = Left$(strWhere, lngLen)
'For debugging, remove the leading quote on the next line. Prints to Immediate Window (Ctrl+G).
Debug.Print strWhere
'Finally, apply the string as the form's Filter.
Me.Filter = strWhere
Me.FilterOn = True
End If
End Sub
Private Sub cmdReset_Click()
'Purpose: Clear all the search boxes in the Form Header, and show all records again.
Dim ctl As Control
'Clear all the controls in the Form Header section.
For Each ctl In Me.Section(acHeader).Controls
Select Case ctl.ControlType
Case acTextBox, acComboBox
ctl.Value = ""
Case acCheckBox
ctl.Value = False
End Select
Next
'Remove the form's filter.
Me.FilterOn = False
End Sub

See this ctl.Value = "" in cmdReset_Click()? I would guess that when you clear the controls, one of them is ending up a zero-length string, but your test in building the filter is for null, not zero-length strings, so something, most likely one of the numerics, is ending up somefield=<blank>. Try:
ctl.Value = Null
As an aside, there is no point in using equals with a wild card:
strWhere = strWhere & "([Postcode] = ""*" & Me.TxtPostcode & "*"") AND "
Should be:
strWhere = strWhere & "([Postcode] Like ""*" & Me.TxtPostcode & "*"") AND "
Or
strWhere = strWhere & "([Postcode] = """ & Me.TxtPostcode & """) AND "

Related

Filter form records by date range using two unbound text boxes

Good afternoon.
I have a continuous form which I want to allow the user to filter by using unbound boxes in the form header. See screenshot of form below:
Form Design View
I can filter error type (Unbound: cboErrorType) and responsibility (Unbound: cboResponsibility) without any issues, but I cannot get the date range to work (Records outside of the selected date range are being returned). Please see screenshot:
Form - filtered
Please see my code below:
Private Sub cmdFilter_Click()
Dim strWhere As String
Dim lngLen As Long
Const conJetDate = "\#dd\/mm\/yyyy\#"
If Not IsNull(Me.cboErrorType) Then
strWhere = strWhere & "([ErrorType] = """ & Me.cboErrorType & """) AND "
End If
If Not IsNull(Me.cboResponsibility) Then
strWhere = strWhere & "([Decision] = """ & Me.cboResponsibility & """) AND "
End If
If Not IsNull(Me.txtStartDate) Then
strWhere = strWhere & "([Date of Error] >= " & Format(Me.txtStartDate, conJetDate) & ") AND "
End If
If Not IsNull(Me.txtEndDate) Then
strWhere = strWhere & "([Date of Error] < " & Format(Me.txtEndDate + 1, conJetDate) & ") AND "
End If
lngLen = Len(strWhere) - 5
If lngLen <= 0 Then
MsgBox "No criteria", vbInformation, "Nothing to do."
Else
strWhere = Left$(strWhere, lngLen)
'Debug.Print strWhere
Me.Filter = strWhere
Me.FilterOn = True
End If
End Sub
I am removing the filters with the following code:
Private Sub cmdResetFilter_Click()
Dim ctl As Control
For Each ctl In Me.Section(acHeader).Controls
Select Case ctl.ControlType
Case acTextBox, acComboBox
ctl.value = Null
End Select
Next
Me.FilterOn = False
End Sub
Please can someone suggest a solution?
If further information is required, let me know and I will oblige.
Many thanks.
The date format must be either the "reverse" US format (mm/dd/yyyy) or the ISO format (which also works for ADO). So try:
Const conJetDate = "\#yyyy\/mm\/dd\#"

Opening a Report based on two date values on a form if they exist

I have a form (frmReports) that has two unbound textboxes which are used to enter dates. One is FROM, one is TO.
These are used to filter out a report (rptAllCommissions). If there are values in the textboxes, it filters. If there aren't, or if there's one date and not both, it creates a WHERE statement for opening the report. Here is the code:
Private Sub cmdCommissions_Click()
Dim strDateFrom As String
Dim strDateTo As String
Dim strWhere As String
Const strcJetDate = "\#mm\/dd\/yyyy\#"
strDateFrom = "[ClosingDate]"
If IsDate(Me.txtFrom) Then
strWhere = "(" & strDateFrom & " >=" & Format(Me.txtFrom, strcJetDate) & ")"
End If
If IsDate(Me.txtTo) Then
If strWhere <> vbNullString Then
strWhere = strWhere & " AND "
End If
strWhere = strWhere & "(" & strDateFrom & " <= " & Format(Me.txtTo + 1, strcJetDate) & ")"
End If
If CurrentProject.AllReports("rptAllCommissions").IsLoaded Then
DoCmd.Close acReport, "rptAllCommissions"
End If
Debug.Print strWhere
DoCmd.OpenReport "rptAllCommissions", acViewReport, strWhere
Exit_Handler:
Exit Sub
Err_Handler:
If Err.Number <> 2501 Then
MsgBox "Error" & Err.Number & ": " & Err.Description, vbExclamation, "Cannot Open Report!"
End If
Resume Exit_Handler
End Sub
The problem I'm having is no matter what I try, the report never filters the records based on the WHERE statement created by the above routine. Trying debugging, it outputs:
If two dates are entered: ([ClosingDate] >=#04/01/2019#) AND ([ClosingDate] <= #05/25/2019#)
If one date is entered: ([ClosingDate] >=#05/13/2019#)
That seems right to me, but it's not filtering. What the heck am I doing wrong?
EDIT: I should give credit the person who wrote the original routine, but I can't for the life of me find where I got it. Sorry! But whoever it was that originally wrote the routine, THANKS!
The WhereCondition should be the 4th argument in the OpenReport method. You have it in the FilterName argument's spot.
OpenReport

Using keywords to find records and list them in a listbox

I have a form (frmSearch) that I use several (4) comboboxes to filter out results for a listbox (lstCustomers). What I'm attempting to do now is create the ability to filter the listbox based on a text box of "keywords". Additionally, the column which the keyword box will search will be variable based on cboWhere which is a list of columns from tblContacts (the table qryContactWants uses)
I found a really nice Function set with the following code that will let me filter everything, but I'm not entirely sure how to turn this data around and use it to filter out my listbox.
This function organizes the keywords:
Public Function FindAnyWord(varFindIn, strWordList As String) As Boolean
Dim var
Dim aWords
aWords = Split(strWordList, ",")
For Each var In aWords
If FindWord(varFindIn, var) Then
FindAnyWord = True
Exit Function
End If
Next var
End Function
And this function actually performs the search:
Public Function FindWord(varFindIn As Variant, varWord As Variant) As Boolean
Const PUNCLIST = """' .,?!:;(){}[]-—/"
Dim intPos As Integer
FindWord = False
If Not IsNull(varFindIn) And Not IsNull(varWord) Then
intPos = InStr(varFindIn, varWord)
' loop until no instances of sought substring found
Do While intPos > 0
' is it at start of string
If intPos = 1 Then
' is it whole string?
If Len(varFindIn) = Len(varWord) Then
FindWord = True
Exit Function
' is it followed by a space or punctuation mark?
ElseIf InStr(PUNCLIST, Mid(varFindIn, intPos + Len(varWord), 1)) > 0 Then
FindWord = True
Exit Function
End If
Else
' is it precedeed by a space or punctuation mark?
If InStr(PUNCLIST, Mid(varFindIn, intPos - 1, 1)) > 0 Then
' is it at end of string or followed by a space or punctuation mark?
If InStr(PUNCLIST, Mid(varFindIn, intPos + Len(varWord), 1)) > 0 Then
FindWord = True
Exit Function
End If
End If
End If
' remove characters up to end of first instance
' of sought substring before looping
varFindIn = Mid(varFindIn, intPos + 1)
intPos = InStr(varFindIn, varWord)
Loop
End If
End Function
And here is the code that I typically use to filter the listbox using the comboboxes on frmSearch:
Dim column As String
SQL = "SELECT qryContactWants.ID, qryContactWants.FullName, qryContactWants.Type, qryContactWants.Make, qryContactWants.Model, qryContactWants.YearWanted, qryContactWants.Condition " _
& "FROM qryContactWants " _
& "WHERE 1=1 "
If cboType.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Type = '" & cboType.Value & "'"
End If
If cboMake.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Make = '" & cboMake.Value & "'"
End If
If cboModel.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Model = '" & cboModel.Value & "'"
End If
If cboYear.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.YearWanted = '" & cboYear.Value & "'"
End If
If cboCondition.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Condition = '" & cboCondition.Value & "'"
End If
SQL = SQL & " ORDER BY qryContactWants.Last"
Me.lstCustomers.RowSource = SQL
Me.lstCustomers.Requery
End Sub
What I would like to do is take the functions I found for searching keywords and apply it to my form and aid in returning a list of customers in lstCustomers
Ideally, having the keyword function return an SQL statement similar to those I'm using to filter out the listbox would be perfect. This would allow me to add a simple SQL = SQL & "AND qryContactWants.VARIABLECOLUMNHERE =SOMETHING
EDIT 1:
While using the following code, VBA is tossing a compile error on the second "End If" stating there isn't a Block If. There clearly is, so I'm not sure what's going on. Here is the code I'm using:
Public Function KeyWhere(strKeys As String, strColumn As String) As String
Dim b As Variant
strKeys = Replace(strKeys, vbCrLf, ",") ' remove all line returns
b = Split(strKeys, ",")
Dim strWhere As String
Dim v As Variant
For Each v In b
If Trim(b) <> "" Then
If strWhere <> "" Then strWhere = strWhere & " or "
strWhere = strWhere & strColumn & " like '*" & Trim(v) & "*'"
End If
End If
Next
strWhere = "(" & strWhere & ")"
KeyWhere = strWhere
End Function
And under the function RequerylistCustomers() I added the If IsNull (Me.txtSearch) = False Then code below:
Private Sub RequerylstCustomers()
Dim SQL As String
'Dim criteria As String
Dim column As String
SQL = "SELECT qryContactWants.ID, qryContactWants.FullName, qryContactWants.Type, qryContactWants.Make, qryContactWants.Model, qryContactWants.YearWanted, qryContactWants.Condition " _
& "FROM qryContactWants " _
& "WHERE 1=1 "
If cboType.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Type = '" & cboType.Value & "'"
End If
If cboMake.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Make = '" & cboMake.Value & "'"
End If
If cboModel.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Model = '" & cboModel.Value & "'"
End If
If cboYear.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.YearWanted = '" & cboYear.Value & "'"
End If
If cboCondition.Value & "" <> "" Then
SQL = SQL & " AND qryContactWants.Condition = '" & cboCondition.Value & "'"
End If
Dim strWhere As String
'Grab Keywords from txtSearch using cboWhere to search for those keywords
If IsNull(Me.txtSearch) = False Then
strWhere = KeyWhere(Me.txtSearch, Me.cboWhere)
SQL = SQL & " AND " & strWhere
End If
SQL = SQL & " ORDER BY qryContactWants.Last"
Me.lstCustomers.RowSource = SQL
Me.lstCustomers.Requery
End Sub
Are the keywords to be searched in a single column (say a comments or memo column?). If yes, then you should be able to optional "add" the one additional criteria to your current "set" of combo box filters.
Are we to assume that the keywords can appear anywhere in that memo column to search?
So, if there are "key words entered into that text box, then you call KeyWhere.
eg this routine:
Public Function KeyWhere(strKeys As String, strColumn As String) As String
Dim b As Variant
strKeys = Replace(strKeys, vbCrLf, ",") ' remove all line returns
b = Split(strKeys, ",")
Dim strWhere As String
Dim v As Variant
For Each v In b
if trim(v) <> "" then
If strWhere <> "" Then strWhere = strWhere & " or "
strWhere = strWhere & strColumn & " like '*" & Trim(v) & "*'"
end if
Next
strWhere = "(" & strWhere & ")"
KeyWhere = strWhere
End Function
We assume each key word is separated by a comma (could be space, but comma is better).
So, if I type in the following command in debug window to test the above?
? keywhere("Generator, Water maker, Battery","Notes")
OutPut:
(Notes like '*Generator*' or Notes like '*Water maker*' or Notes like '*Battery*')
So, we just append the above results to your final SQL.
eg:
dim strWhere as string
if isnull(me.KeyWordBox) = False then
strWhere = keyWhere(me.KeyWordBox,me.cboColumnToSearch)
SQL = SQL & " AND " & strWhere
end if
so, the above converts all keywords into a valid SQL condition for the column to search. It is likely that column is some kind of notes column, but it would work for other description type field to search.

MS Access filter form to open report to specific records

I'm trying to create a form, ReportSearch that has multiple comboboxes and textboxes that will allow the user to narrow down the results shown on the report. Not all fields would have to be used in the search.
On click the following code will ask for the parameter value to be entered for the specific IDs used. If I just click OK without entering anything in the MsgBox the report will be opened with no records.
Private Sub cmdFilter_Click()
Dim strWhere As String
Dim lngLen As Long
Const conJetDate = "\#mm\/dd\/yy\#"
If Not IsNull(Me.cboSearchJob) Then
strWhere = strWhere & "(Job.id = " & Me.cboSearchJob & ") AND "
End If
If Not IsNull(Me.cboSearchEmployee) Then
strWhere = strWhere & "(Employee.ID = " & Me.cboSearchEmployee & ") AND "
End If
If Not IsNull(Me.cboSearchService) Then
strWhere = strWhere & "(Service.ID = " & Me.cboSearchService & ") AND "
End If
If Not IsNull(Me.tboStartDate) Then
strWhere = strWhere & "(DateWorked >= " & Format(Me.tboStartDate, conJetDate) & ") AND "
End If
If Not IsNull(Me.tboEndDate) Then
strWhere = strWhere & "(DateWorked < " & Format(Me.tboEndDate + 1, conJetDate) & ") AND "
End If
lngLen = Len(strWhere) - 5
If lngLen <= 0 Then
MsgBox "No Results", vbInformation, "No Search Available."
Else
strWhere = Left$(strWhere, lngLen)
DoCmd.OpenReport "JobReport", acViewPreview
Reports!JobReport.Filter = strWhere
Reports!JobReport.FilterOn = True
End If
End Sub
For the report I'm using
SELECT [Employees].[FirstName] & " " & [Employees].[LastName] AS EmployeeName, Jobs.JobName, Equipment.Model, Service.Service, Labor.Labor, EmployeeWorkLog.LaborHours, EmployeeWorkLog.EquipmentHours, EmployeeWorkLog.Notes, EmployeeWorkLog.DateWorked, Service.ID
FROM Service RIGHT JOIN (Labor RIGHT JOIN (Jobs RIGHT JOIN (Equipment RIGHT JOIN (Employees RIGHT JOIN EmployeeWorkLog ON Employees.ID = EmployeeWorkLog.EmployeeID) ON Equipment.ID = EmployeeWorkLog.EquipmentID) ON Jobs.ID = EmployeeWorkLog.JobID) ON Labor.ID = EmployeeWorkLog.LaborID) ON Service.ID = EmployeeWorkLog.ServiceID
ORDER BY [Employees].[FirstName] & " " & [Employees].[LastName];
At this point I'm at a complete loss.
Obviously there is something that I'm missing here. Let me know in what way I need to modify this code to get it to open my report JobReport filtered based on my form ReportSearch.
Thanks.
A report isn't dynamic like a form, you can't filter it after it has been opened. When a report is opened in print preview, it reads its data, does the layout and formatting, then it's completely static.
To open a report with filtered data, use the WhereCondition parameter of DoCmd.OpenReport:
DoCmd.OpenReport "JobReport", acViewPreview, WhereCondition:=strWhere

Ms-Access how to use a query with a parameter inside a form

I have an SQL query with a question(alert like) that pops up every time I open it...
For every value inserted in that question you get diffrent result.
I Want to be able to use that query in my form with a combo-box...
I don't know how to exceute the query with the parameter from within the form....
I have no problem using VBA, just tell me how to call the query with the parameter
Thanks,
Fingerman
I usually use my filtering forms using the following principles:
1) I first create a query that includes all the fields I want to display and all the fields I want to filter on. It can use more than one table. I do not set any criteria (WHERE clause) in this query unless there is a condition that always needs to be applied no matter what.
2) Next I create a datasheet form based on this query and I save it, giving it a name that indicates that it's a subform.
3) Next I create an unbound main form and add unbound controls such as textboxes, combos, listboxes, checkboxes, etc. that will be used to filter the different fields. One control can potentially allow a user to search on more than one field depending how you write your filtering routine in VBA.
4) Now it's time to write code on the main form to make this all work. Basically, the code needs to check to see if there are values in any of the controls and if so, it creates a WHERE clause (without the WHERE keyword) and at the very end it sets the subform's filter property and turns the subform's FilterOn property to TRUE.
Here's some example code. This was taken from the sample database I've made just to demonstrate filtering (see below). This example does not use fuzzy searches (asterisks) and each control on the main form only filters one field on the subform.
Private Sub cmdFilter_Click()
'You can also call the FilterSubForm function on a control's AfterUpdate event.
Call FilterSubform
End Sub
Private Sub FilterSubform()
Dim strFilter As String
'Note: We have to wrap field names in brackets if they contain spaces or
'special characters. These fields are in Northwind Traders 2007 from Microsoft
'I would never consider naming my fields with spaces or special characters
'in them.
'Company
If Nz(Me.txtCompany, "") <> "" Then
strFilter = strFilter & "Company = '" & PQ(Me.txtCompany) & "' And "
End If
'First Name
If Nz(Me.txtFirstName, "") <> "" Then
strFilter = strFilter & "[First Name] = '" & PQ(Me.txtFirstName) & "' AND "
End If
'Last Name
If Nz(Me.txtLastName, "") <> "" Then
strFilter = strFilter & "[Last Name] = '" & PQ(Me.txtLastName) & "' AND "
End If
'Business Phone
If Nz(Me.txtBusinessPhone, "") <> "" Then
strFilter = strFilter & "[Business Phone] = '" & PQ(Me.txtBusinessPhone) & "' AND "
End If
'City
If Nz(Me.cboCity, "") <> "" Then
strFilter = strFilter & "City = '" & PQ(Me.cboCity) & "' AND "
End If
'State/Province
If Nz(Me.cboStateProvince, "") <> "" Then
strFilter = strFilter & "[State/Province] = '" & PQ(Me.cboStateProvince) & "' AND "
End If
'Order Date
If Nz(Me.txtOrderDate, "") <> "" Then
If IsDate(Me.txtOrderDate) = True Then
strFilter = strFilter & "[Order Date] = #" & Me.txtOrderDate & "# AND "
End If
End If
'Ship Name
If Nz(Me.txtShipName, "") <> "" Then
strFilter = strFilter & "[Ship Name] = '" & PQ(Me.txtShipName) & "' AND "
End If
'Ship City
If Nz(Me.txtShipCity, "") <> "" Then
strFilter = strFilter & "[Ship City] = '" & PQ(Me.txtShipCity) & "' AND "
End If
'Ship State/Province
If Nz(Me.cboShipStateProvince, "") <> "" Then
strFilter = strFilter & "[Ship State/Province] = '" & PQ(Me.cboShipStateProvince) & "' AND "
End If
'Product Code
If Nz(Me.cboProductCode, "") <> "" Then
strFilter = strFilter & "[Product Code] = '" & PQ(Me.cboProductCode) & "' AND "
End If
'Quantity
If Nz(Me.txtQuantity, "") <> "" Then
If IsNumeric(Me.txtQuantity) = True Then
strFilter = strFilter & "Quantity = " & Me.txtQuantity & " AND "
End If
End If
If Right(strFilter, 5) = " AND " Then strFilter = Left(strFilter, Len(strFilter) - 5)
If strFilter <> "" Then
Me.subformOrderSearch.Form.Filter = strFilter
Me.subformOrderSearch.Form.FilterOn = True
Else
'Clear the filter
Me.subformOrderSearch.Form.Filter = ""
Me.subformOrderSearch.Form.FilterOn = False
End If
End Sub
Private Function PQ(s As String) As String
'This function is used to "pad quotes" for SQL
PQ = Replace(s, "'", "''")
End Function
I've put together a sample database that has several different examples all building on what I've posted here. You can download this database here:
http://www.utteraccess.com/forum/Search-filtering-Examples-t1968063.html
After some Searching, I have came across this:
http://www.techrepublic.com/blog/msoffice/run-a-parameter-query-within-an-access-form/701
It is not what I wanted, But it is a great solution...
I will wait, if no one gets a better answer, I'll accept my own (As much as I hate doing that).