Access Hangs on Subform recordsource set to SQL from VBA
-
14-07-2021 - |
Question
I have a "Search" form in my database that takes in a string, explodes it into an array and builds an SQL string based on a selected join type ("Or", "And", or "Exact Phrase" radio buttons). My code works perfectly 95% of the time, but every once and while the database hangs when I switch between the different join types and requery. I have confirmed that the SQL is being created properly and I think that the problem stems from trying to change the subform's recordsource while it is still loading.
The exact way that my search form works is as follows:
- The user puts a search term/phrase in a text box
- On the "After Update" event of the textbox, VBA creates an SQL string and stores it in a hidden text field (dubbed "ModifiedSearchValue")
- If the user changes the join type (radiobuttons with options "Or", "And", Or "Exact Phrase") the "After Update" event on the group evokes the VBA sub (as in #2) and VBA creates an SQL string which it stores in the hidden text field (dubbed "ModifiedSearchValue")
When the user hits the "Search" button, VBA sets the RecordSource of the subform to the value of "ModifiedSearchValue" by:
Me!Results.Form.RecordSource = Me.ModifiedSearchValue
Again, this works perfectly most of the time, but if you enter the search term, click "Search", then change the join type and hit "Search" again, it causes the database to hang approximately 5% of the time.
My main VBA code is as follows
Private Sub SearchString()
Dim SearchString, SearchStringTitle, SearchStringName, SearchStringDescription, SearchStringInvestigator, JoinValue, j, SQLString As String, SearchArray, varValue As Variant
SearchString = Trim(Me.SearchValue)
If Not IsNull(SearchString) Then
SearchArray = Split(SearchString, " ")
SQLString = "SELECT tbl_Studies.StudyID, tbl_Studies.Study_Short_Title, tbl_Studies.Study_Name, tbl_Studies.Study_Description, [qry_General:FullName_FMLD].FullName AS Investigator, tbl_Studies.Project_Type, IIf([Project_Type]=1,[tbl_Studies:Status]![Status],[tbl_Studies:NR_Status]![NR_Status]) AS Overall_Status, tbl_Studies.Date_Submitted, tbl_Studies.Date_Updated, tbl_Studies.Results_Summary, tbl_Studies.Inactive " & _
"FROM ([tbl_Studies:NR_Status] RIGHT JOIN ([tbl_Studies:Status] RIGHT JOIN tbl_Studies ON [tbl_Studies:Status].StatusID = tbl_Studies.Status) ON [tbl_Studies:NR_Status].NR_StatusID = tbl_Studies.NR_Status) LEFT JOIN [qry_General:FullName_FMLD] ON tbl_Studies.Investigator = [qry_General:FullName_FMLD].PersonID " & _
"WHERE "
If Me.Join_Type <> 3 Then
If Me.Join_Type = 1 Then
JoinValue = "OR"
ElseIf Me.Join_Type = 2 Then
JoinValue = "AND"
Else
JoinValue = " "
End If
'--
SearchStringTitle = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringTitle = SearchStringTitle & "(tbl_Studies.Study_Short_Title) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringTitle = SearchStringTitle & " " & JoinValue & " "
End If
Next varValue
SearchStringTitle = SearchStringTitle & "))"
'--
SearchStringName = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringName = SearchStringName & "(tbl_Studies.Study_Name) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringName = SearchStringName & " " & JoinValue & " "
End If
Next varValue
SearchStringName = SearchStringName & "))"
'--
SearchStringDescription = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringDescription = SearchStringDescription & "(tbl_Studies.Study_Description) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringDescription = SearchStringDescription & " " & JoinValue & " "
End If
Next varValue
SearchStringDescription = SearchStringDescription & "))"
'--
SearchStringInvestigator = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringInvestigator = SearchStringInvestigator & "([qry_General:FullName_FMLD].FullName) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringInvestigator = SearchStringInvestigator & " " & JoinValue & " "
End If
Next varValue
SearchStringInvestigator = SearchStringInvestigator & "))"
SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
Else
SearchStringTitle = "(((tbl_Studies.Study_Short_Title) Like ""*" & SearchString & "*""))"
SearchStringName = "(((tbl_Studies.Study_Name) Like ""*" & SearchString & "*""))"
SearchStringInvestigator = "((([qry_General:FullName_FMLD].FullName) Like ""*" & SearchString & "*""))"
SearchStringDescription = "(((tbl_Studies.Study_Description) Like ""*" & SearchString & "*""))"
SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
End If
SearchString = SQLString & SearchString & ";"
Me.ModifiedSearchValue.Value = SearchString
End If
End Sub
Again, my theory is that the hanging is caused by changing the RecordSource of the subform before it has finished loading from the previous search, but I can't seem to determine any workaround.
Thanks in advance for any and all insight/help!
Solution
As per Olivier's suggestions, the true cause of the problem was VBA being called as part of the query [qry_General:FullName_FMLD]
; switching to [qry_General:FullName_FML]
(which doesn't call any VBA) eliminated all problems. I am guessing that the root of the problem was that the form was attempting to apply the filter before the query had returned a result thereby creating a corrupt filter string.
Here is the updated code using a filter method and replacing all bangs with dots:
Private Sub Search_Click()
On Error GoTo Err_Search_Click
Dim SearchString, SearchStringTitle, SearchStringName, SearchStringDescription, SearchStringInvestigator, JoinValue, j, SQLString As String, SearchArray, varValue As Variant
Me.Results.Form.FilterOn = True
SearchString = Trim(Me.SearchValue)
If Not IsNull(SearchString) Then
SearchArray = Split(SearchString, " ")
If Me.Join_Type <> 3 Then
If Me.Join_Type = 1 Then
JoinValue = "OR"
ElseIf Me.Join_Type = 2 Then
JoinValue = "AND"
Else
JoinValue = " "
End If
'--
SearchStringTitle = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringTitle = SearchStringTitle & "(tbl_Studies.Study_Short_Title) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringTitle = SearchStringTitle & " " & JoinValue & " "
End If
Next varValue
SearchStringTitle = SearchStringTitle & "))"
'--
SearchStringName = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringName = SearchStringName & "(tbl_Studies.Study_Name) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringName = SearchStringName & " " & JoinValue & " "
End If
Next varValue
SearchStringName = SearchStringName & "))"
'--
SearchStringDescription = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringDescription = SearchStringDescription & "(tbl_Studies.Study_Description) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringDescription = SearchStringDescription & " " & JoinValue & " "
End If
Next varValue
SearchStringDescription = SearchStringDescription & "))"
'--
SearchStringInvestigator = "(("
For Each varValue In SearchArray
j = Trim(varValue)
SearchStringInvestigator = SearchStringInvestigator & "([qry_General:FullName_FML].FullName) Like ""*" & j & "*"""
If varValue <> SearchArray(UBound(SearchArray)) Then
SearchStringInvestigator = SearchStringInvestigator & " " & JoinValue & " "
End If
Next varValue
SearchStringInvestigator = SearchStringInvestigator & "))"
SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
Else
SearchStringTitle = "(((tbl_Studies.Study_Short_Title) Like ""*" & SearchString & "*""))"
SearchStringName = "(((tbl_Studies.Study_Name) Like ""*" & SearchString & "*""))"
SearchStringInvestigator = "((([qry_General:FullName_FML].FullName) Like ""*" & SearchString & "*""))"
SearchStringDescription = "(((tbl_Studies.Study_Description) Like ""*" & SearchString & "*""))"
SearchString = SearchStringTitle & " OR " & SearchStringName & " OR " & SearchStringDescription & " OR " & SearchStringInvestigator
End If
Me.Results.Form.Filter = SearchString
End If
Exit_Search_Click:
Exit Sub
Err_Search_Click:
MsgBox ("There are no active records to review.")
Resume Exit_Search_Click
End Sub
Again, the credit for this solution belongs to Olivier Jacot-Descombes - thanks for all your help and suggestions!