old retired guy with passion for databases (Access 2016)
Please help with error. Have tried in vain to find solution.
Thanks to all who responded.
Please see "new" edited code below.
Thanks to everyone for your comments.
I am updating the code basis comments received and new info learned from other StackOverFlow post. But, I continue to have issues with making an error handling routing work?
'====This Code works Ok:
'................Except: for Error Handler???????
'================================================
Private Sub comBut_CatTotals_Click()
On Error GoTo EH
Dim rst As DAO.Recordset
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim strSQL As String
Dim lonCatID() As Long
Dim lonCatTot() As Long
Dim i As Long
Dim t As Long
Dim iValue As Long
Dim tValue As Long
strSQL = "SELECT " & " qry_EventCategoryTotals_VBA_subquery.[CategoryName], Sum(tblWinnersItems.[Amount]) AS " & "CategoryTotals" & _
" FROM " & " qry_EventCategoryTotals_VBA_subquery" & _
" RIGHT " & " JOIN " & " tblWinnersItems" & " ON " & " qry_EventCategoryTotals_VBA_subquery.[ItemID] = tblWinnersItems.[ItemID] " & _
"GROUP" & " BY " & "qry_EventCategoryTotals_VBA_subquery.[CategoryName];"
'Debug.Print "strSQL: " & strSQL
'MsgBox strSQL
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", strSQL)
Set rst = qdf.OpenRecordset()
rst.MoveLast
If rst.RecordCount = 0 Then
MsgBox "No Winners recorded...Exiting", vbInformation
Exit Sub
End If
MsgBox "Number of records: " & rst.RecordCount
'intSize = rst.RecordCount
rst.MoveFirst
'... 6 ... records are shown ...
With rst
ReDim Preserve lonCatID(rst.RecordCount, 2)
ReDim Preserve lonCatTot(rst.RecordCount, 2)
Do While Not rst.EOF
i = 0
For i = i + 1 To rst.RecordCount - 1
lonCatID(1, 1) = rst.Fields(0)
iValue = lonCatID(1, 1)
Next i
t = 0
For t = t + 1 To rst.RecordCount - 1
lonCatTot(1, 2) = rst.Fields(1)
tValue = lonCatTot(1, 2)
Next t
rst.MoveNext
MsgBox " CategoryID = " & iValue & " Catagory Total = " & tValue, vbInformation, "Category Totals"
Loop
End With
MsgBox "Loop_Finished" '.....finishes OK
db.Close
Set rst = Nothing
Set qdf = Nothing
Set db = Nothing
Exit Sub
EH:
If Err.Number = 3021 Then
MsgBox "No Winners Entered...exiting", vbInformation
End If
MsgBox _
"There was an Error!" & vbCrLf & vbCrLf & _
"Number: " & Err.Number & vbCrLf & _
"Descriptionis: " & Err.Description, _
vbOKOnly + vbCritical, _
"Error!"
Exit Sub
End Sub
Related
I have a vba that can send out multiple emails to vendors, but I would like to change it so it embeds the query and only sends one email per vendor. Here is what I have so far:
Option Compare Database
Public Sub SendFollowUpEmail()
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim emailTo As String
Dim emailSubject As String
Dim emailText As String
Dim outApp As Outlook.Application
Dim outMail As Outlook.MailItem
Dim outlookStarted As Boolean
On Error Resume Next
Set outApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If outApp Is Nothing Then
Set outApp = CreateObject("Outlook.Application")
outlookStarted = True
End If
Set db = CurrentDb
strSQL = "SELECT qry002UnmatchedOpenInvoices.kyUnique, qry002UnmatchedOpenInvoices.[Vendor Nbr],qry002UnmatchedOpenInvoices.[Vendor Name], " & _
" qry002UnmatchedOpenInvoices.[Purchasing Document], qry002UnmatchedOpenInvoices.Item,qry002UnmatchedOpenInvoices.[Document Date], " & _
" qry002UnmatchedOpenInvoices.Material, qry002UnmatchedOpenInvoices.[Short Text],qry002UnmatchedOpenInvoices.[Material Group], " & _
" qry002UnmatchedOpenInvoices.[Invoice Sent], qry002UnmatchedOpenInvoices.[Order Quantity],qry002UnmatchedOpenInvoices.[Order Unit], " & _
" qry002UnmatchedOpenInvoices.[Quantity in SKU], qry002UnmatchedOpenInvoices.[Stockkeeping unit],qry002UnmatchedOpenInvoices.[Net price], " & _
" qry002UnmatchedOpenInvoices.Currency, qry002UnmatchedOpenInvoices.[Price Unit],qry002UnmatchedOpenInvoices.[Release status], " & _
" qry002UnmatchedOpenInvoices.[No of Positions], tblVendors.Vendor, tblVendors.Email " & _
" FROM qry002UnmatchedOpenInvoices LEFT JOIN tblVendors ON qry002UnmatchedOpenInvoices.[Vendor Nbr] =tblVendors.[Vendor Number] " & _
" WHERE (((qry002UnmatchedOpenInvoices.Material) Is Null) AND ((qry002UnmatchedOpenInvoices.[Invoice Sent]) Is Null));"
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
Do Until rs.EOF
emailTo = Trim(rs.Fields("Email").Value & "; tom.nguyen#flocorp.com;mike.huston#flocorp.com")
emailSubject = "Open Invoices"
emailText = Trim("Please send invoices of the below Purchase Orders:") & vbCrLf
emailText = emailText & _
"PO# " & rs.Fields("[Purchasing Document]").Value
Set outMail = outApp.CreateItem(olMailItem)
outMail.To = emailTo
outMail.Subject = emailSubject
outMail.Body = emailText
outMail.Send
'rs.Edit
'rs("FUP_Date_Sent") = Now()
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
If outlookStarted Then
outApp.Quit
End If
Set outMail = Nothing
Set outApp = Nothing
End Sub
What you need to do is to use two recordsets. The first selects the distinct vendors, and the second selects the invoices for that vendor. Something like:
Sub sSendFollowUpEMail()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsVendor As DAO.Recordset
Dim rsInvoice As DAO.Recordset
Dim objOL As New Outlook.Application
Dim objMail As Outlook.MailItem
Dim strSQL As String
Dim emailTo As String
Dim emailText As String
Set db = CurrentDb
strSQL = "SELECT DISTINCT V.[Vendor Number], V.EMail " _
& " FROM qry002UnmatchedOpenInvoices AS I LEFT JOIN tblVendors AS V ON I.[Vendor Nbr]=V.[Vendor Number] " _
& " WHERE I.Material IS NULL " _
& " AND I.[Invoice Sent] IS NULL;"
Set rsVendor = db.OpenRecordset(strSQL)
If Not (rsVendor.BOF And rsVendor.EOF) Then
Do
strSQL = "SELECT I.[Purchasing Document] " _
& " FROM qry2002UnMatchedOpenInvoices AS I " _
& " WHERE I.Material IS NULL " _
& " AND I.[Invoice Sent] IS NULL " _
& " AND I.[Vendor Nbr]=" & rsVendor("Vendor Number") _
& " ORDER BY I.[Purchasing Document] ASC;"
Set rsInvoice = db.OpenRecordset(strSQL)
If Not (rsInvoice.BOF And rsInvoice.EOF) Then
emailText = "Please pay:"
Do
emailText = emailText & vbCrLf & rsInvoice("Purchasing Document")
rsInvoice.MoveNext
Loop Until rsInvoice.EOF
End If
emailTo = rsVendor!EMail
Set objMail = objOL.CreateItem(olMailItem)
objMail.To = emailTo
objMail.Subject = EmailSubject
objMail.Body = emailText
objMail.Send
rsVendor.MoveNext
Loop Until rsVendor.EOF
End If
sExit:
On Error Resume Next
rsVendor.Close
rsInvoice.Close
Set rsVendor = Nothing
Set rsInvoice = Nothing
Set db = Nothing
Set objMail = Nothing
objOL.Quit
Set objOL = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbcrfl & "sSendFollowUpEMail", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
A few notes.
In your original recordset you were including a whole load of fields that were not used in this procedure, which is not recommended - only get data that you need as this will enhance performance;
Secondly, it appears that you are mixing early and late binding of Outlook;
Finally, I've used aliases for the query/table names in the SQL statements - this makes the SQL more manageable, and also if you need to change one of the original tables/queries it is a lot easier to change the name just once.
Regards,
I have been working on a project as a volunteer crime analyst, and I have run into issues on how to enter in multiple text boxes, a multi-valued combo box and how to make sure that if there are no entries made that those boxes are ignored in favor of those that have values in them. I have figured out how to have multiple multi-select list boxes return data from a data entry table, what I'm asking is for help on how to add in the rest of the components that are on the MS Access form that I have for a prototype database.
Here is my code, would like to have some advice on how and where the code for the text boxes and multi-valued combo box would go
Private Sub Command62_Click()
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Dim varItem As Variant
Dim strCriteria As String
Dim strCriteria1 As String
Dim strCriteria2 As String
Dim strCriteria3 As String
Dim strCriteria4 As String
Dim strCriteria5 As String
Dim strSQL As String
Set db = CurrentDb()
Set qdf = db.QueryDefs("qryMultiselect")
For Each varItem In Me!District.ItemsSelected
strCriteria = strCriteria & ",'" & Me!District.ItemData(varItem) & "'"
Next varItem
If Len(strCriteria) = 0 Then
MsgBox "You did not select anything in the Contract field." _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria = Right(strCriteria, Len(strCriteria) - 1)
For Each varItem In Me!MOMethodofEntry.ItemsSelected
strCriteria1 = strCriteria1 & ",'" & Me!MOMethodofEntry.ItemData(varItem) &
"'"
Next varItem
If Len(strCriteria1) = 0 Then
MsgBox "You did not select anything in the Name field." _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria1 = Right(strCriteria1, Len(strCriteria1) - 1)
For Each varItem In Me!MOLocation.ItemsSelected
strCriteria2 = strCriteria2 & ",'" & Me!MOLocation.ItemData(varItem) & "'"
Next varItem
If Len(strCriteria2) = 0 Then
MsgBox "You did not select anything in the Name field." _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria2 = Right(strCriteria2, Len(strCriteria2) - 1)
For Each varItem In Me!MOPointofEntry.ItemsSelected
strCriteria3 = strCriteria3 & ",'" & Me!MOPointofEntry.ItemData(varItem) &
"'"
Next varItem
If Len(strCriteria3) = 0 Then
MsgBox "You did not select anything in the Name field." _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria3 = Right(strCriteria3, Len(strCriteria3) - 1)
For Each varItem In Me!CircumstanceCode.ItemsSelected
strCriteria4 = strCriteria4 & ",'" & Me!CircumstanceCode.ItemData(varItem) &
"'"
Next varItem
If Len(strCriteria4) = 0 Then
MsgBox "You did not select anything in the Name field." _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria4 = Right(strCriteria4, Len(strCriteria4) - 1)
For Each varItem In Me!MOWeapon.ItemsSelected
strCriteria5 = strCriteria5 & ",'" & Me!MOWeapon.ItemData(varItem) & "'"
Next varItem
If Len(strCriteria5) = 0 Then
MsgBox "You did not select anything in the Contract field." _
, vbExclamation, "Nothing to find!"
Exit Sub
End If
strCriteria5 = Right(strCriteria5, Len(strCriteria5) - 1)
strSQL = "SELECT * FROM tblDataEntry " & _
"WHERE tblDataEntry.District IN(" & strCriteria & ") AND
tblDataEntry.MOMethodofEntry IN(" & strCriteria1 & ") AND
tblDataEntry.MOLocation IN(" & strCriteria2 & ") AND
tblDataEntry.MOPointofEntry IN (" & strCriteria3 & ") AND
tblDataEntry.CircumstanceCode IN (" & strCriteria4 & ") AND
tblDataEntry.MOWeapon IN(" & strCriteria5 & ");"
qdf.SQL = strSQL
DoCmd.OpenQuery "qryMultiselect"
Set db = Nothing
Set qdf = Nothing
End Sub
Also please let me know if I am doing anything wrong. Still a little new to this.
I am not sure what do you mean with "where the code for the text boxes and multi-valued combo box would go" but I can help you with writing better code. Put inside of your form this functions:
Private Function GetSelectedItems(combo As ListBox) As String
Dim result As String
Dim n As Integer
With combo
For n = .ListCount - 1 To 0 Step -1
If .Selected(n) Then
result = result & ",'" & .ItemData(n) & "'"
End If
Next n
End With
GetSelectedItems = Mid(result, 2)
End Function
Public Function IsEmptyOrNull(strValue As Variant) As Boolean
If Trim(strValue) = vbNullString Or IsNull(strValue) Then
IsEmptyOrNull = True
End If
End Function
and than you call the function like this:
strCriteria = GetSelectedItems(Me!District)
strCriteria1 = GetSelectedItems(Me!MOMethodofEntry)
…
After you fill in all your criteria create strFilter string:
If Not IsEmptyOrNull(strCriteria) Then
strFilter = IIf(Not IsEmptyOrNull(strFilter), strFilter & " AND ", "") & " District IN (" & strCriteria & ")"
End If
If Not IsEmptyOrNull(strCriteria1) Then
strFilter = IIf(Not IsEmptyOrNull(strFilter), strFilter & " AND ", "") & " MOMethodofEntry IN (" & strCriteria1 & ")"
End If
…
Something similar do with your text boxes:
If Not IsEmptyOrNull(Me.txtCaseNumber) Then
strFilter = IIf(Not IsEmptyOrNull(strFilter), strFilter & " AND ", "") & " CaseNumber= '" & Me.txtCaseNumber & "'"
End If
and after you add all your fields create your strSQL string:
strSQL = "SELECT * FROM tblDataEntry WHERE " & strFilter
I developed an access database to log jobs throughout a production process. Every record has an order, machine, start time, end time among other characteristics of the job. When an order is logged, it is saved in the database along with the machine name, start time and job status (running or idle). When the order is completed, the record is searched using a recordset and "end time" is saved. If the machine is not being utilized, like between shifts, the machine should have an "idle" status.
The purpose of OpenRecMassUpdate is to add an 'end time' to all the incomplete records (those with an order, start time but without end time). This code is used at the end of shift so that all the records could be closed with one click.
After executing this subroutine, the machines that were assigned to an order are now without a status. As a result, I needed another subroutine to add "idle" statuses to all these machines. That is the purpose of MassIdleUpdate. It creates an idle record for every machine that was previously used and status closed using OpenRecMassUpdate.
The problem I am facing is that MassIdleUpdate creates multiple records at random times. When I run analysis on the database, I found some records that were created 3, 4 or more times.
Option Compare Database
Dim dbsn As DAO.Database
Dim rstn As DAO.Recordset
Dim SQLqueryn As String
Dim recordcount As Integer
Dim tempstat As String
Dim stat1 As Integer
Public Sub OpenRecMassUpdate()
On Error GoTo ErrorHandler
recordcount = 1
tempstat = "Idle"
stat1 = 0
Set dbsn = CurrentDb
SQLqueryn = "SELECT * FROM kettleLog WHERE KettleStatus <> """ & tempstat & _
""" And KettleLogic = " & stat1
Set rstn = dbsn.OpenRecordset(SQLqueryn)
With rstn
If Not .BOF And Not .EOF Then
.MoveLast
.MoveFirst
While (Not .EOF)
.Edit
.Fields("KettleFinish") = Now()
.Fields("KettleLogic") = -1
.Fields("EndOfShift") = 1
.Update
.MoveNext
recordcount = recordcount + 1
Wend
MsgBox recordcount - 1 & " records were updated as a result of the end of the shift"
recordcount = 1
Else
End If
.Close
End With
dbsn.Close
ExitSub:
Set dbsn = Nothing
Set rstn = Nothing
Exit Sub
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
Resume ExitSub
End Sub
Public Sub MassIdleUpdate()
Dim tempKettle As String
On Error GoTo ErrorHandler
Set dbsn = CurrentDb
SQLqueryn = "SELECT * FROM kettleLog WHERE EndOfShift = 1"
Set rstn = dbsn.OpenRecordset(SQLqueryn)
With rstn
If Not .BOF And Not .EOF Then
.MoveLast
.MoveFirst
For i = 1 To FindRecordCount(SQLqueryn)
tempKettle = .Fields("Kettle")
.Edit
.Fields("EndOfShift") = 3
.Update
.AddNew
.Fields("Kettle") = tempKettle
.Fields("KettleStatus") = "Idle"
.Fields("WorkOrder") = 0
.Fields("KettleStart") = Now()
.Fields("KettleLogic") = 0
.Fields("EndOfShift") = 2
.Update
.MoveNext
Next
End If
.Close
End With
tempKetlle = ""
dbsn.Close
i = 1
ExitSub:
Set dbsn = Nothing
Set rstn = Nothing
Exit Sub
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
Resume ExitSub
End Sub
Instead of looping through all your records counting them and setting the values individually, do it all in one shot. An RDBMS (even Access) is designed for this kind of bulk update.
Public Sub OpenRecMassUpdate()
On Error GoTo ErrorHandler
Dim tempStat As String
tempStat = "Idle"
Dim stat1 As Long
stat1 = 0
Set dbsn = CurrentDb
Dim timeStamp As Date
timeStamp = Now()
SQLqueryn = "UPDATE KettleLog " & _
" SET KettleFinish = #" & timeStamp & "#, " & _
" KettleLogic = -1, " & _
" EndOfShift = 1 " & _
" WHERE KettleStatus <> """ & tempStat & """" & _
" AND KettleLogic = 0"
Set rstn = dbsn.OpenRecordset(SQLqueryn)
rstn.Close
SQLqueryn = "SELECT Count(*) " & _
" FROM KettleFinish " & _
" WHERE KettleFinish = #" & timeStamp & #", " & _
" AND KettleLogic = -1 " & _
" AND EndOfShift = 1"
Set rstn = dbsn.OpenRecordset(SQLqueryn)
If Not rstn.BOF And Not rstn.EOF Then
rstn.MoveLast
Dim recordcount As Long
recordcount = rstn.recordcount
End If
MsgBox recordcount & " records were updated as a result of the end of the shift"
rstn.Close
dbsn.Close
ExitSub:
Exit Sub
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
Resume ExitSub
End Sub
Note: I'm used to ADO syntax, not DAO, so there might be a minor tweak or two needed, but this should get you started
This will do what your OpenRecMassUpdate() procedure was doing in precisely 2 SQL queries instead of that time consuming loop.
You can also do the same thing to Sub MassIdleUpdate().
As a matter of fact, with a little creativity, you could probably combine the two of them into one, though keeping them separate reduces complexity, improves readability and, thus, future maintainability.
Thanks to #Freeman who guided me in the right direction. Here's my solution to the issue I had. The code has been tested in my sandbox using different scenarios and it works.
Public Sub OpenRecMassUpdate1()
On Error GoTo ErrorHandler
Dim tempStat As String
tempStat = "Idle"
Dim stat1 As Long
stat1 = 0
Set dbsn = CurrentDb
Dim timeStamp As Date
timeStamp = Now()
SQLqueryn = "UPDATE KettleLog " & _
" SET KettleFinish = #" & timeStamp & "#, " & _
" KettleLogic = -1, " & _
" EndOfShift = 1 " & _
" WHERE KettleStatus <> """ & tempStat & """" & _
" AND KettleLogic = 0"
dbsn.Execute SQLqueryn, dbFailOnError
SQLqueryn = "SELECT Count(*) " & _
"AS RecCount " & _
" FROM KettleLog " & _
" WHERE KettleLogic = -1 " & _
" AND EndOfShift = 1"
Set rstn = dbsn.OpenRecordset(SQLqueryn)
If Not rstn.BOF And Not rstn.EOF Then
Dim recordcount As Long
recordcount = rstn![RecCount]
End If
MsgBox recordcount & " records were updated as a result of the end of the shift"
rstn.Close
dbsn.Close
ExitSub:
Exit Sub
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
Resume ExitSub
End Sub
Public Sub MassIdleUpdate1()
On Error GoTo ErrorHandler
Dim TempKettle As String
Set dbsn = CurrentDb
SQLqueryn = "SELECT * " & _
" FROM KettleLog " & _
" WHERE EndOfShift = 1"
Set rstn = dbsn.OpenRecordset(SQLqueryn)
rstn.MoveLast
Dim rcrdcnt As Long
rcrdcnt = rstn.recordcount
ReDim machs(rcrdcnt) As String
'MsgBox rcrdcnt
rstn.MoveFirst
If Not rstn.BOF And Not rstn.EOF Then
For i = 0 To rcrdcnt - 1
machs(i) = rstn.Fields("Kettle")
rstn.MoveNext
Next
End If
SQLqueryn = "UPDATE KettleLog " & _
" SET EndOfShift = 3 " & _
" WHERE EndOfShift = 1 "
dbsn.Execute SQLqueryn, dbFailOnError
For j = 0 To rcrdcnt
SQLqueryn = "INSERT INTO KettleLog (Kettle, KettleStatus, WorkOrder, KettleStart,
KettleLogic, EndOfShift) " & _
" VALUES ( '" & machs(j) & "' , 'Idle', '0', #" & Now() & "#, '0', '2')"
MsgBox SQLqueryn
dbsn.Execute SQLqueryn, dbFailOnError
machs(j) = ""
Next
rstn.Close
dbsn.Close
ExitSub:
Exit Sub
ErrorHandler:
MsgBox "Error #: " & Err.Number & vbCrLf & vbCrLf & Err.Description
Resume ExitSub
End Sub
I am trying to use the value from a combo box to select which field will be searched when the text box is updated.
This code works but only allows for searching on PatientID:
Private Sub txtGoTo_AfterUpdate()
If (txtGoTo & vbNullString) = vbNullString Then Exit Sub
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[PatientID] =" & txtGoTo
If rs.NoMatch Then
MsgBox "Sorry, no such record '" & txtGoTo & "' was found.", _
vbOKOnly + vbInformation
Else
Me.Recordset.Bookmark = rs.Bookmark
End If
rs.Close
txtGoTo = Null
End Sub
This code DOES NOT work but should convey what I am trying to do (changes bold):
Private Sub txtGoTo_AfterUpdate()
**GCriteria = cboSearchField.Value & " LIKE '*" & txtSearchString & "*'"**
If (txtGoTo & vbNullString) = vbNullString Then Exit Sub
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[**Gcriteria**] =" & txtGoTo
If rs.NoMatch Then
MsgBox "Sorry, no such record '" & txtGoTo & "' was found.", _
vbOKOnly + vbInformation
Else
Me.Recordset.Bookmark = rs.Bookmark
End If
rs.Close
txtGoTo = Null
End Sub
I think it should be just that change from:
rs.FindFirst "[**Gcriteria**] =" & txtGoTo
To:
rs.FindFirst Gcriteria
As you have already set the condition before:
*GCriteria = cboSearchField.Value & " LIKE '*" & txtSearchString & "*'"**
My form takes the data the user entered, constructs a SQL statement and returns the results. I would like to have a message box pop up when there are no matches found.
My current code/idea:
If qdf.sql = 0 Then
MsgBox "No clients matching your information." & _
vbCrLf & "have been found. Please try again." & _
, vbCritical, "No Matches"
Else
DoCmd.OpenForm "frmSearchResults"
Me.Visible = False
End If
I'm having trouble figuring out the correct syntax for if qdf.sql = 0 .
UPDATE: Full query
Private Sub cmdSearch_Click()
'On Error GoTo cmdSearch_Click_err
Dim db As Database
Dim strSQL As String
Dim rs As DAO.Recordset
Dim qdf As QueryDef
Dim strClientID As String
Dim strLastName As String
Dim strFirstName As String
Dim strDOB As String
Set db = CurrentDb
Set rs = db.OpenRecordset(qdf.sql)
' call QueryCheck module to determine if query exists
If Not QueryExists("qrySearch") Then
Set qdf = db.CreateQueryDef("qrySearch")
Else
Set qdf = db.QueryDefs("qrySearch")
End If
' handle nulls in the user's entries
If IsNull(Me.txtClientID.Value) Then
strClientID = " Like '*' "
Else
strClientID = "='" & Me.txtClientID.Value & "' "
End If
If IsNull(Me.txtLastName.Value) Then
strLastName = " Like '*' "
Else
strLastName = " Like '" & Me.txtLastName.Value & "*' "
End If
If IsNull(Me.txtFirstName.Value) Then
strFirstName = " Like '*' "
Else
strFirstName = " Like '*" & Me.txtFirstName.Value & "*' "
End If
If IsNull(Me.txtDOB.Value) Then
strDOB = " Like '*' "
Else
strDOB = "='" & Me.txtDOB.Value & "' "
End If
strSQL = "SELECT Clients.* " & _
"FROM Clients " & _
"WHERE Clients.clientid" & strClientID & _
"AND Clients.namelast" & strLastName & _
"AND Clients.namefirst" & strFirstName & _
"AND Clients.birthdate" & strDOB & _
"ORDER BY Clients.namelast,Clients.namefirst;"
Debug.Print strSQL
' check to see if the results form is open and close if it is
DoCmd.Echo False
If Application.SysCmd(acSysCmdGetObjectState, acForm, "frmSearchResults") = acObjStateOpen Then
DoCmd.Close acForm, "frmSearchResults"
End If
' run SQL statment
qdf.sql = strSQL
' check for no matches found
If rs.RecordCount = 0 Then
MsgBox "No clients matching your information were found." & _
vbCrLf & "Please search again.", vbInformation, "No Matches"
Else
DoCmd.OpenForm "frmSearchResults"
Me.Visible = False
End If
'cmdSearch_Click_exit:
' DoCmd.Echo True
' Set qdf = Nothing
' Set db = Nothing
'Exit Sub
'cmdSearch_Click_err:
' MsgBox "An unexpected error has occurred." & _
' vbCrLf & "Please note of the following details and contact the EIIS support desk:" & _
' vbCrLf & "Error Number: " & Err.Number & _
' vbCrLf & "Description: " & Err.Description _
' , vbCritical, "Error"
' Resume cmdSearch_Click_exit
End Sub
The reason that If qdf.sql = 0 then won't perform a proper check is that qdf contains the information about your query such as the SQL text that you are checking in that statement but not the results.
To get the results of the query you need to assign it to a Recordset after you have build your query. So first build your query and then assign it to the record set.
Dim db as DAO.Database
Set db = CurrentDb
Dim qdf as DAO.Querydef
Set qdf = db.CreateQueryDef("qrySearch")
Dim rs as DAO.Recordset
Set rs = CurrentDb.OpenRecordset(qdf.sql)
You can then check what your record set has returned.
If rs.RecordCount = 0 then
So where you have your line ' run SQL statment you would want to place the Set rs line.
If you have any ADO experience you can use something like
dim strSQL as String
dim conn as Connection
dim cmd as Command
dim rs as Recordset
(set up connection/command here)
cmd.commandtext = (your select query)
set rs = Command.execute
if rs.eof then
(or if rs.recordcount = 0 however returning a recordcount requires the correct cursortype - usually adOpenStatic - to be used)
'msgbox no match
else
'do stuff
If any of this is alien, then post your actual query and I'll try and give you the code in full. Good luck!