Moving Through Records Access VBA - ms-access

I have a list of names in a subform, and on my main form I have a button that allows the user to view the "profile" of a given contact. Once in a profile, I would like there to be a button that allows the user to move to the next name in the subform (while staying the "profile" view) by clicking "next user".
In addition, the DB asks the user whether she/he wants to save changes (vbYesNo) to the profile before moving to the next user's profile. For some reason, my code works the when the user clicks "next contact" and "yes" the first time, but it will not scroll to the next contact each subsequent time the user clicks "next contact" and "yes". Note that the "next user" button works fine if the user selects "no" for when she/he does not want to save changes made to the profile.
Here is the code:
Private Sub Command65_Click()
Dim strFirstName As String
Dim strLastName As String
Dim strIndustry As String
Dim strCountry As String
Dim strState As String
Dim strCity As String
Dim strCompany As String
Dim strTitle As String
Dim strStatus As String
Dim strPhone As String
Dim strEmail As String
Dim strOwner As String
Dim DateNow As String
Dim rs As DAO.Recordset
'Allow user to leave some fields blank. User must fill in certain fields.
Dim VisEnable
intMsg = MsgBox("Would you like to save the current contact's information?", vbYesNo)
If intMsg = 6 Then
If IsNull(Me.txtFirstName) Then
MsgBox ("Please add First Name for this Prospect")
Me.txtFirstName.SetFocus
Exit Sub
End If
If IsNull(Me.txtLastName) Then
MsgBox ("Please add Last Name for this Prospect")
Me.txtLastName.SetFocus
Exit Sub
End If
If IsNull(Me.cboIndustry) Then
Me.cboIndustry = ""
Exit Sub
End If
If IsNull(Me.cboGeo) Then
Me.cboGeo = ""
End If
If IsNull(Me.cboInfluence) Then
Me.cboInfluence = ""
End If
If IsNull(Me.cboSchool) Then
Me.cboSchool = ""
End If
If IsNull(Me.cboTier) Then
Me.cboTier = ""
End If
If IsNull(Me.cboCompany) Then
Me.cboCompany = ""
End If
If IsNull(Me.txtTitle) Then
Me.txtTitle = ""
End If
If IsNull(Me.cboStatus) Then
Me.cboStatus = ""
Exit Sub
End If
If IsNull(Me.cboOwner) Then
Me.cboOwner = ""
End If
If IsNull(Me.txtPhone) Then
Me.txtPhone = ""
End If
If IsNull(Me.txtEmail) Then
MsgBox ("Please add Email for this Prospect")
Me.txtEmail.SetFocus
Exit Sub
End If
If IsNull(Me.txtNotes) Then
Me.txtNotes = ""
Exit Sub
End If
If IsNull(Me.txtInitialProspectEmailSentDate) Then
Me.txtInitialProspectEmailSentDate = ""
End If
If IsNull(Me.txtNextTouchPoint) Then
Me.txtNextTouchPoint = ""
End If
strFirstName = Me.txtFirstName
strLastName = Me.txtLastName
strIndustry = Me.cboIndustry
strCompany = Me.cboCompany
strTitle = Me.txtTitle
strStatus = Me.cboStatus
strPhone = Me.txtPhone
strEmail = Me.txtEmail
strNotes = Me.txtNotes
strOwner = Me.cboOwner
dtEmailSent = Me.txtInitialProspectEmailSentDate
dtNextTouchPoint = Me.txtNextTouchPoint
strRegion = Me.cboGeo
strSoR = Me.cboTier
strInfluence = Me.cboInfluence
strClient = Me.ckClient
strCoworker = Me.ckCoworker
strSchool = Me.cboSchool
strSQL = "Update tblProspect Set FirstName = " & """" & strFirstName & """" & ",LastName = " & """" & strLastName & """" & ",Industry = " & """" & strIndustry & """" & "" & _
",Geography = " & """" & strRegion & """" & ",StrengthofRelationship = " & """" & strSoR & """" & ",School = " & """" & strSchool & """" & ",Company = " & """" & strCompany & """" & "" & _
",Title = " & """" & strTitle & """" & ",Status = " & """" & strStatus & """" & ", InfluenceLevel = " & """" & strInfluence & """" & ", FormerClient = " & strClient & ", FormerCoWorker = " & strCoworker & "" & _
",Email = " & """" & strEmail & """" & ",Phone = " & """" & strPhone & """" & ",ProspectOwner = " & """" & strOwner & """" & ",Notes = " & """" & strNotes & """" & ""
If dtNextTouchPoint <> "" Then
strSQL = strSQL & " ,NextTouchPoint = #" & dtNextTouchPoint & "#"
End If
If dtEmailSent <> "" Then
strSQL = strSQL & " ,LastEmailDate = #" & dtEmailSent & "#"
End If
strSQL = strSQL & " WHERE Email = " & """" & strEmail & """" & ""
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
intRecord = Me.txtRecord + 1
Set rs = CurrentDb.OpenRecordset("qselProspects")
If rs.RecordCount <> 0 Then
rs.MoveLast
If intRecord = 1 Then
intRecord = rs.RecordCount + 1
End If
End If
If rs.RecordCount <> 0 Then
rs.MoveFirst 'Unnecessary in this case, but still a good habit
Do Until rs.EOF = True
If intRecord = rs.AbsolutePosition Then
Me.txtRecord = intRecord
Me.txtFirstName = rs!FirstName
Me.txtLastName = rs!LastName
Me.txtTitle = rs!Title
Me.cboCompany = rs!Company
Me.cboIndustry = rs!Industry
Me.cboGeo = rs!Geography
Me.cboTier = rs!StrengthofRelationship
Me.cboIndustry = rs!InfluenceLevel
Me.cboSchool = rs!School
Me.ckClient = rs!FormerClient
Me.ckCoworker = rs!FormerCoWorker
Me.cboStatus = rs!Status
Me.cboOwner = rs!ProspectOwner
Me.txtEmail = rs!Email
Me.txtPhone = rs!Phone
Me.txtNextTouchPoint = rs!NextTouchPoint
Me.txtNotes = rs!Notes
Me.txtInitialProspectEmailSentDate = rs!LastEmailDate
End If
rs.MoveNext
Loop
End If
'''///If you choose No it works, but if you choose Yes it does not...very strange
Else
intRecord = Me.txtRecord + 1
Set rs = CurrentDb.OpenRecordset("qselProspects")
If rs.RecordCount <> 0 Then
rs.MoveLast
If rs.RecordCount = intRecord Then
intRecord = 0
End If
End If
If rs.RecordCount <> 0 Then
rs.MoveFirst
Do Until rs.EOF = True
If intRecord = rs.AbsolutePosition Then
Me.txtRecord = intRecord
Me.txtFirstName = rs!FirstName
Me.txtLastName = rs!LastName
Me.txtTitle = rs!Title
Me.cboCompany = rs!Company
Me.cboIndustry = rs!Industry
Me.cboGeo = rs!Geography
Me.cboTier = rs!StrengthofRelationship
Me.cboIndustry = rs!InfluenceLevel
Me.cboSchool = rs!School
Me.ckClient = rs!FormerClient
Me.ckCoworker = rs!FormerCoWorker
Me.cboStatus = rs!Status
Me.cboOwner = rs!ProspectOwner
Me.txtEmail = rs!Email
Me.txtPhone = rs!Phone
Me.txtNextTouchPoint = rs!NextTouchPoint
Me.txtNotes = rs!Notes
Me.txtInitialProspectEmailSentDate = rs!LastEmailDate
End If
rs.MoveNext
Loop
End If
End If
End Sub
Thanks to whoever can figure this out! This has eaten up too many hours as it is.

This is not an answer, but I write it here because it does not fit in a comment. A few advises that if you have applied, would have spared you all this head-ache.
1) your code follows the pattern
If User_Says_Yes Then
Save
Fetch_Next_Record
Else
Fetch_Next_Record
Endif
This is problematic because the Fetch_Next_Record is a lot of code and it is duplicated, and you spend a lot of time to see where it differs. duplicating code is generally a very bad idea. Try to rewrite it with the following pattern:
If User_Says_Yes Then
Save
Endif
Fetch_Next_Record
2) Try to make your code shorter, by moving as much as you can to private subroutines. for example, write some Function like BuildSQL() as String, a subroutine like updateFormFromRs(rs as Recordset). In General, when any of your routines or functions get too long, say more than 20 or 30 lines, you should think of migrating some code to subroutines and functions
3) Indent your code. It is so difficult to follow your code without it.. just to see where was the Else that starts when the user says no...
4) You fetch a whole table in the recordset, just to scroll it and find one record to display that matches if intRecord = rs.AbsolutePosition? Why not use a SQL statement with a WHERE clause and load just the desired record? This is something you need to apply in any serious application with a decent amount of data.
5) statements like If rs.EOF = True Then: Simply If rs.EOF Then.
The additional = True will not make the test more strict whatsoever. as if without it we check if the condition was almost true.
Finally, even if you have possibly inherited this code from someone else, I am sure that you will have to rewrite it completely and improve it, the sooner the better. And yes, I am sure that if you follow these guidelines, you will be able to debug you code very easily.
Friendly :)

Related

Duplicate records when running a DAO recordset

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

Build VBA Sql statement using 3 multi-select Listboxes and a date range in MS Access 2016 32 bit

I have three listboxes and a date range on a parameter form. I am able to pass all of the Listbox selections with no problem. I cannot seem to find a way or answer to adding a date range to the where clause.
The Date field is Course_Date, and the textbox control names for the dates are Start_Date and End_Date
Option Compare Database
Option Explicit
Private Sub cmdPreviewReports_Click()
On Error GoTo cmdPreviewReports_Err
Dim blnQueryExists As Boolean
Dim cat As New ADOX.Catalog
Dim cmd As New ADODB.Command
Dim qry As ADOX.View
Dim varItem As Variant
Dim strInstructors As String
Dim strCourseType As String
Dim strCourseTypeCondition As String
Dim strRoleType As String
Dim strRoleTypeCondition As String
Dim strCourse_Date As Date
Dim strDateRange As String
Dim strSql As String
' Check for the existence of the stored query
blnQueryExists = False
Set cat.ActiveConnection = CurrentProject.Connection
For Each qry In cat.Views
If qry.Name = "q_Parameter_Form" Then
blnQueryExists = True
Exit For
End If
Next qry
' Create the query if it does not already exist
If blnQueryExists = False Then
cmd.CommandText = "SELECT * FROM q_jt_MCR_Instructor_Roles"
cat.Views.Append "q_Parameter_Form", cmd
End If
Application.RefreshDatabaseWindow
' Turn off screen updating
DoCmd.Echo False
' Close the query if it is already open
If SysCmd(acSysCmdGetObjectState, acQuery, "q_Parameter_Form") = acObjStateOpen Then
DoCmd.Close acQuery, "q_Parameter_Form"
End If
' Build criteria string for Instructors
For Each varItem In Me.lst_Instructors.ItemsSelected
strInstructors = strInstructors & "," & Me.lst_Instructors.ItemData(varItem) & ""
Next varItem
If Len(strInstructors) = 0 Then
strInstructors = "Like '*'"
Else
strInstructors = Right(strInstructors, Len(strInstructors) - 1)
strInstructors = "IN(" & strInstructors & ")"
End If
' Build criteria string for CourseType
For Each varItem In Me.lst_Course_Type.ItemsSelected
strCourseType = strCourseType & "," & Me.lst_Course_Type.ItemData(varItem) & ""
Next varItem
If Len(strCourseType) = 0 Then
strCourseType = "Like '*'"
Else
strCourseType = Right(strCourseType, Len(strCourseType) - 1)
strCourseType = "IN(" & strCourseType & ")"
End If
' Get CourseType condition
If Me.optAndCourseType.Value = True Then
strCourseTypeCondition = " AND "
Else
strCourseTypeCondition = " OR "
End If
' Build criteria string for RoleType
For Each varItem In Me.lst_Role.ItemsSelected
strRoleType = strRoleType & "," & Me.lst_Role.ItemData(varItem) & ""
Next varItem
If Len(strRoleType) = 0 Then
strRoleType = "Like '*'"
Else
strRoleType = Right(strRoleType, Len(strRoleType) - 1)
strRoleType = "IN(" & strRoleType & ")"
End If
' Get RoleType condition
If Me.optAndRoleType.Value = True Then
strRoleTypeCondition = " AND "
Else
strRoleTypeCondition = " OR "
End If
'Build Criteria String for Course_Date
strDateRange = strSql And " Between Me.[Start_Date] AND Me.[End_Date]"
' Build SQL statement
strSql = "SELECT q_jt_MCR_Instructor_Roles.* FROM q_jt_MCR_Instructor_Roles " & _
"WHERE q_jt_MCR_Instructor_Roles.[InstructorID] " & strInstructors & _
strCourseTypeCondition & "q_jt_MCR_Instructor_Roles.[Course_TypesID] " & strCourseType & _
strRoleTypeCondition & "q_jt_MCR_Instructor_Roles.[Roles_ID] " & strRoleType & ";"
' Apply the SQL statement to the stored query
cat.ActiveConnection = CurrentProject.Connection
Set cmd = cat.Views("q_Parameter_Form").Command
cmd.CommandText = strSql
Set cat.Views("q_Parameter_Form").Command = cmd
Set cat = Nothing
' Open the Query
If Not IsNull(cboReports) And cboReports <> "" Then
DoCmd.OpenReport cboReports, acViewPreview ' use acNormal to print without preview
Else
MsgBox ("Please make a Label selection first from the dropdown list to the left.")
cboReports.SetFocus
End If
cboReports = ""
' If required the dialog can be closed at this point
' DoCmd.Close acForm, Me.Name
'Restore screen updating
cmdPreviewReports_Exit:
DoCmd.Echo True
Exit Sub
cmdPreviewReports_Err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description:" & Err.Description _
, vbCritical, "Error"
Resume cmdPreviewReports_Exit
End Sub
I am also able to provide the database to look at if you wish?
Thank you for helping !!!!!!
William
It could be:
'Build Criteria String for Course_Date.
strDateRange = " And Course_Date Between #" & Format(Me![Start_Date].Value, "yyyy\/mm\/dd") & "# AND #" & Format(Me![End_Date].Value, "yyyy\/mm\/dd") & "#"
strSql = strSql & strDateRange

How to combine two strings on a report filter?

I'm writing VBA code for an application in Access for the first time and have created two separate strings to filter a report. The first of these strFilter filters the reports based on criteria in a list box. The second strWhere has been set up to filter the report based on a date input into a pair of text boxes. Both of these string filters work perfectly when used separately.
What I want to know is if there is a way to combine the two strings easily so that the user an filter the report based on both the criteria in the list box and the date they have entered in the text boxes.
The code I have for the listbox filter when it is added to the reports filter currently looks like this:
With Reports![rptFaultRecords]
.Filter = strFilter
.FilterOn = True
I want to add the string to filter by date strWhere next to the strFilter so the report can be filtered by both date and list criteria. All the code I've entered when attempting to do this has given me a run time error 3075. Is it possible for these two strings to be combined easily and if so how can I do it?
The rest of the code I've written is below if you need to see it:
Private Sub btnAllFaultsFilter_Click()
Dim varItem As Variant
Dim strRoom As String
Dim strFilter As String
Dim strDevice As String
Dim strCat As String
Dim strStatus As String
Dim strDateField As String
Dim strWhere As String
Const strcJetDate = "\#mm\/dd\/yyyy\#"
strDateField = "[f_datereported]"
If IsDate(Me.txtStartDate) Then
strWhere = "(" & strDateField & " >= " & Format(Me.txtStartDate, strcJetDate) & ")"
End If
If IsDate(Me.txtEndDate) Then
If strWhere <> vbNullString Then
strWhere = strWhere & " AND "
End If
strWhere = strWhere & "(" & strDateField & " < " & Format(Me.txtEndDate + 1, strcJetDate) & ")"
End If
For Each varItem In Me.lstRoom.ItemsSelected
strRoom = strRoom & ",'" & Me.lstRoom.ItemData(varItem) & "'"
Next varItem
If Len(strRoom) = 0 Then
strRoom = "Like '*'"
Else
strRoom = Right(strRoom, Len(strRoom) - 1)
strRoom = "IN(" & strRoom & ")"
End If
For Each varItem In Me.lstDevice.ItemsSelected
strDevice = strDevice & ",'" & Me.lstDevice.ItemData(varItem) & "'"
Next varItem
If Len(strDevice) = 0 Then
strDevice = "Like '*'"
Else
strDevice = Right(strDevice, Len(strDevice) - 1)
strDevice = "IN(" & strDevice & ")"
End If
For Each varItem In Me.lstCategory.ItemsSelected
strCat = strCat & ",'" & Me.lstCategory.ItemData(varItem) & "'"
Next varItem
If Len(strCat) = 0 Then
strCat = "Like '*'"
Else
strCat = Right(strCat, Len(strCat) - 1)
strCat = "IN(" & strCat & ")"
End If
For Each varItem In Me.lstStatus.ItemsSelected
strStatus = strStatus & ",'" & Me.lstStatus.ItemData(varItem) & "'"
Next varItem
If Len(strStatus) = 0 Then
strStatus = "Like '*'"
Else
strStatus = Right(strStatus, Len(strStatus) - 1)
strStatus = "IN(" & strStatus & ")"
End If
strFilter = "[c_roomid] " & strRoom & " AND [f_computername] " & strDevice & " AND [f_faultcategory] " & strCat & " AND [f_faultstatus] " & strStatus
With Reports![rptFaultRecords]
'.Filter = strFilter
.Filter = strFilter
.FilterOn = True
End With
End Sub

Cannot update a textbox on a form in Access vba

I am working on an Access DB that sorts and tracks my firm's business contacts. We have a form called "Contact Profile" whereby the user can select a given contact and view all of his information: First Name, Last Name, Company, Title, Email Address, etc.
On the profile, the user can update a contact's information with the "Update Info" button.
Every single field updates just fine--with the exception of Email Address. For example, I can change Joseph Smith, Programmer at Google to Joe Smith, Program Manager at GOOG with no issues.
But if I try to change joesmith#google.com to jsmith#google.com, the change does not save. Code is posted below. Could someone please take a look and let me know if they have any suggestions? Thanks!
Private Sub Command61_Click()
Dim strFirstName As String
Dim strLastName As String
Dim strIndustry As String
Dim strCountry As String
Dim strState As String
Dim strCity As String
Dim strCompany As String
Dim strTitle As String
Dim strStatus As String
Dim strPhone As String
Dim strEmail As String
Dim strOwner As String
Dim DateNow As String
'Allow user to leave some fields blank. User must fill in certain fields.
Dim VisEnable
If IsNull(Me.txtFirstName) Then
MsgBox ("Please add First Name for this Prospect")
Me.txtFirstName.SetFocus
Exit Sub
End If
If IsNull(Me.txtLastName) Then
MsgBox ("Please add Last Name for this Prospect")
Me.txtLastName.SetFocus
Exit Sub
End If
If IsNull(Me.cboIndustry) Then
Me.cboIndustry = ""
End If
If IsNull(Me.cboGeo) Then
Me.cboGeo = ""
End If
If IsNull(Me.cboInfluence) Then
Me.cboInfluence = ""
End If
If IsNull(Me.cboSchool) Then
Me.cboSchool = ""
End If
If IsNull(Me.cboTier) Then
Me.cboTier = ""
End If
If IsNull(Me.cboCompany) Then
Me.cboCompany = ""
End If
If IsNull(Me.txtTitle) Then
Me.txtTitle = ""
End If
If IsNull(Me.cboStatus) Then
Me.cboStatus = ""
End If
If IsNull(Me.cboOwner) Then
Me.cboOwner = ""
End If
If IsNull(Me.txtPhone) Then
Me.txtPhone = ""
End If
If IsNull(Me.txtEmail) Then
MsgBox ("Please add Email for this Prospect")
Me.txtEmail.SetFocus
Exit Sub
End If
If IsNull(Me.txtNotes) Then
Me.txtNotes = ""
End If
If IsNull(Me.txtInitialProspectEmailSentDate) Then
Me.txtInitialProspectEmailSentDate = ""
End If
If IsNull(Me.txtNextTouchPoint) Then
Me.txtNextTouchPoint = ""
End If
strFirstName = Me.txtFirstName
strLastName = Me.txtLastName
strIndustry = Me.cboIndustry
strCompany = Me.cboCompany
strTitle = Me.txtTitle
strStatus = Me.cboStatus
strPhone = Me.txtPhone
strEmail = Me.txtEmail
strNotes = Me.txtNotes
strOwner = Me.cboOwner
dtEmailSent = Me.txtInitialProspectEmailSentDate
dtNextTouchPoint = Me.txtNextTouchPoint
strRegion = Me.cboGeo
strSoR = Me.cboTier
strInfluence = Me.cboInfluence
strClient = Me.ckClient
strCoworker = Me.ckCoworker
strSchool = Me.cboSchool
strSQL = "Update tblProspect Set FirstName = " & """" & strFirstName & """" & ",LastName = " & """" & strLastName & """" & ",Industry = " & """" & strIndustry & """" & "" & _
",Geography = " & """" & strRegion & """" & ",StrengthofRelationship = " & """" & strSoR & """" & ",School = " & """" & strSchool & """" & ",Company = " & """" & strCompany & """" & "" & _
",Title = " & """" & strTitle & """" & ",Status = " & """" & strStatus & """" & ", InfluenceLevel = " & """" & strInfluence & """" & ", FormerClient = " & strClient & ", FormerCoWorker = " & strCoworker & "" & _
",Email = " & """" & strEmail & """" & ",Phone = " & """" & strPhone & """" & ",ProspectOwner = " & """" & strOwner & """" & ",Notes = " & """" & strNotes & """" & ""
If dtNextTouchPoint <> "" Then
strSQL = strSQL & " ,NextTouchPoint = #" & dtNextTouchPoint & "#"
End If
If dtEmailSent <> "" Then
strSQL = strSQL & " ,LastEmailDate = #" & dtEmailSent & "#"
End If
strSQL = strSQL & " WHERE Email = " & """" & strEmail & """" & ""
DoCmd.SetWarnings False
DoCmd.RunSQL strSQL
DoCmd.SetWarnings True
Dim ctl As Control
For Each ctl In Me.Controls
Select Case ctl.ControlType
Case acTextBox, acComboBox, acListBox, acCheckBox
If ctl.ControlSource = "" Then
ctl.Value = Null
End If
Case Else
End Select
Next ctl
Me.Visible = False
DoCmd.OpenForm "frmProspectAdmin", acNormal, , , acFormEdit, acWindowNormal
DoCmd.RunCommand acCmdSaveRecord
Form_frmProspectProfile.Refresh
Form_frmProspectAdmin.Refresh
End Sub
It comes out exactly likely I want it to in Debug.Print, but it does not save that way in the contact profile.
Debug.Print strSQL
Update tblProspect Set FirstName = "Jon",LastName = "Snow",Industry = "Other",Geography = "",StrengthofRelationship = "",School = "",Company = "",Title = "",Status = "Dead", InfluenceLevel = "", FormerClient = 0, FormerCoWorker = 0,Email = "jsnow#winterfell",Phone = "",ProspectOwner = "",Notes = ""

Millisecond time: Filter form by date

I am trying to implement millisecond timestamping in Access 2010/13 using this method;
MS Access Can Handle Millisecond Time Values--Really - See more at:
The Millisecond value is queried by;
SELECT DateValueMsec([DateTimeMs]) AS DateOnly FROM - to provide a date only control to sort the form from a textbox.
Any filter applied programmatically on DateOnly yeilds 0 results.
Private Sub BuildFilter()
Dim strFilter As String
Dim ctl As Control
strFilter = ""
'add selected values to string
For Each ctl In Me.FormHeader.Controls
With ctl
If .ControlType = acTextBox Or .ControlType = acComboBox Then
If Nz(.Value) <> "" Then
If InStr(.Name, "Date") <> 0 Then
If Nz(StartDate) <> "" And Nz(EndDate) <> "" And InStr(strFilter, "DateOnly") = 0 Then
strFilter = strFilter & "[DateOnly] BETWEEN #" & Me.StartDate.Value & "# AND #" & Me.EndDate.Value & "# AND "
ElseIf Nz(StartDate) <> "" And InStr(strFilter, "DateOnly") = 0 Then
strFilter = strFilter & "[DateOnly] >= #" & DateValueMsec(Me.StartDate.Value) & "# AND "
' strFilter = strFilter & "[DateOnly] >= #" & Me.StartDate.Value & "# AND "
ElseIf Nz(EndDate) <> "" And InStr(strFilter, "DateOnly") = 0 Then
strFilter = strFilter & "[DateOnly] <= #" & Me.EndDate.Value & "# AND "
End If
ElseIf InStr(.Name, "ID") <> 0 Then
strFilter = strFilter & "[" & .Name & "] = " & .Value & " AND "
Else
strFilter = strFilter & "[" & .Name & "] = '" & .Value & "' AND "
End If
End If
End If
End With
Next ctl
'trim trailing
strFilter = TrimR(strFilter, 5)
Debug.Print strFilter
With Me.subfrmzzAuditTrailDisplay
.Form.Filter = strFilter
.Form.FilterOn = True
End With
End Sub
Answer! From #pathDongle
Time is stored as Millisecond UTC;
!DateTimeMS = GetTimeUTC()
And restored by;
Public Function UTCtoTimeLocal(dSysUTC As Date) As Date
'Dim sysTime As SYSTEMTIME
Dim DST As Long
Dim tzi As TIME_ZONE_INFORMATION
DST = GetTimeZoneInformation(tzi)
UTCtoTimeLocal = dSysUTC - TimeSerial(0, tzi.Bias, 0) + IIf(DST = 2, TimeSerial(1, 0, 0), 0)
End Function
Query;
SELECT tblzzAuditTrail.DateTimeMS, FormatDate(UTCtoTimeLocal([DateTimeMS])) AS DateTimeLocal
Which can be filtered on as a String.
Private Sub BuildFilter()
Dim strFilter As String
Dim ctl As Control
strFilter = ""
'add selected values to string
For Each ctl In Me.FormHeader.Controls
With ctl
If .ControlType = acTextBox Or .ControlType = acComboBox Then
If Nz(.Value) <> "" Then
If InStr(.Name, "Date") <> 0 Then
If Nz(StartDate) <> "" And Nz(EndDate) <> "" And InStr(strFilter, "DateTimeLocal") = 0 Then
strFilter = strFilter & "[DateTimeLocal] BETWEEN '" & FormatDate(Me.StartDate.Value) & "' AND '" & FormatDate(Me.EndDate.Value) & "' AND "
ElseIf Nz(StartDate) <> "" And InStr(strFilter, "DateTimeLocal") = 0 Then
strFilter = strFilter & "[DateTimeLocal] > '" & FormatDate(Me.StartDate.Value) & "' AND "
ElseIf Nz(EndDate) <> "" And InStr(strFilter, "DateTimeLocal") = 0 Then
strFilter = strFilter & "[DateTimeLocal] <= '" & FormatDate(Me.EndDate.Value) & "' AND "
End If
ElseIf InStr(.Name, "ID") <> 0 Then
strFilter = strFilter & "[" & .Name & "] = " & .Value & " AND "
Else
strFilter = strFilter & "[" & .Name & "] = '" & .Value & "' AND "
End If
End If
End If
End With
Next ctl
'trim trailing And
strFilter = TrimR(strFilter, 5)
Debug.Print strFilter
With Me.subfrmzzAuditTrailDisplay
.Form.Filter = strFilter
.Form.FilterOn = True
End With
End Sub
Resulting Filter String;
[UserID] = 2 AND [DateTimeLocal] BETWEEN '06/01/2015 00:00:00.000' AND '07/01/2015 00:00:00.000'
As per my other question;
millisecond-time-msec2-incorrect-return