Microsoft Access VBA DLookup with multiple criteria - vba

Sorry for any dumb questions, I am very green with Access and VBA.
I am creating a form for employees to input their hourly output. It goes to a table called tracking, where there are 4 fields; Shift, Operator, Date_Field, and Machine. These fields are a unique index, and I want it to work so that if the person filling out the form adds a date/shift/worker/machine combo that already exists it will just take them to that record.
This code runs On Change after each combobox is selected but it obviously has issues. Please let me know what I am doing wrong and how I could implement this.
Dim int_ID As Integer
If IsNull(DLookup("[ID]", "Tracking", "[Shift]='" & [Forms]![Tracking Form]![ShiftCbo] & "'" And "[Operator]='" & [Forms]![Tracking Form]![OpCbo] & "'" And "[Date_Field]='" & [Forms]![Tracking Form]![DateBox] & "'" And "[Machine]='" & [Forms]![Tracking Form]![MachineCbo] & "'")) = False Then
int_ID = DLookup("[ID]", "Tracking", "[Shift]='" & [Forms]![Tracking Form]![ShiftCbo] & "'" And "[Operator]='" & [Forms]![Tracking Form]![OpCbo] & "'" And "[Date_Field]='" & [Forms]![Tracking Form]![DateBox] & "'" And "[Machine]='" & [Forms]![Tracking Form]![MachineCbo] & "'")
DoCmd.GoToRecord acDataTable, "Tracking", acGoTo, int_ID
End If
End Sub

Use AfterUpdate instead of Change event.
First off, the AND operator needs to be within quote marks as it is literal text. If code is behind [Tracking Form], don't need full form reference. Code expects value of comboboxes to be text, not numbers, therefore fields must be text type. However, you have one field that appears to be date type and date parameters are defined with #.
Dim int_ID As Integer
With Me
int_ID = Nz(DLookup("ID", "Tracking", "Shift='" & .ShiftCbo & _
"' And Operator='" & .OpCbo & "' And Date_Field=#" & .DateBox & _
"# And Machine='" & .MachineCbo & "'"), 0)
End With
If int_ID <> 0 Then
DoCmd.GoToRecord acDataTable, "Tracking", acGoTo, int_ID
End If

Related

ACCESS 365 and INSERT INTO not inserting data from FORM

I am updating a small medical database. So far all new products have been added manually / directly to a Products- table. I am creating a form to do that.
Even it is in a way very simple to do, I am facing up a problem that data is inserted correctly only if all fields have something typed in form, if any of the input boxes are left empty no new records are made.
Additionally a simple check for minimum fields is not working. It will step thru all controls correctly but does not stop even a field is left empty and its Tag has *-sign in it.
Insert into includes all fields which a defined in that table there is not any extra field in table except first field is autonumbered ID field. No need to type something in every field each time.
Pr
Private Function CheckAllFields() As Boolean
Dim Ctrl As Control
CheckAllFields = False
'Go through the controls in Form
'If control has tag (*) and it null (no value) then show alert
For Each Ctrl In Me.Controls
MsgBox Ctrl.Name
If Ctrl.Tag = "*" And IsNull(Ctrl) Then
Dim FieldName As String
FieldName = Ctrl.Name
'Show notification if field was not filled and move focus to that field
MsgBox "A required Field has not been filled."
Ctrl.SetFocus
CheckAllFields = True
Exit For
End If
Next Ctrl
MsgBox "Check fileds done"
End Function
Private Sub AddProduct_Click()
Dim strSQL As String
'SQL to insert Product
strSQL = "INSERT INTO Products([Product name],[Product description],[Finnish name],[Finnish description],[Matrix2012], " & _
"[Additional Info], [Unit], [Licence],[Remarks],Narcotic,[Asset], " & _
"[ATC], [Cathegory], [EIC code], [EIC name])" & _
" VALUES ('" & Me.txtProductName & "','" & Me.txtProductDesc & "','" & Me.txtFinnishName & "','" & Me.txtFinnishDesc & "','" & Me.ComboMatrix & "'," & _
"'" & Me.txtAdditionalInfo & "','" & Me.ComboUnit & "','" & Me.CheckLicense & "'," & _
"'" & Me.txtRemarks & "','" & Me.CheckNarcotic & "','" & Me.CheckAsset & "'," & _
"'" & Me.txtATC & "','" & Me.txtCathegory & "','" & Me.txtEICcode & "','" & Me.txtEICName & "')"
'' MsgBox strSQL
'Check the all fields have valid format
If CheckAllFields = False Then
'Execute SQL in database - insert new batch
' MsgBox "Step into Check all fields"
CurrentDb.Execute strSQL
MsgBox "A new product inserted !"
End If
Here is a debug output of my insert into command:
Debug output
Here is another output debug, now the new product is inserted correctly.
Correctly working version
Problem solved. As Craig pointed this way of incuding parameters is prone to fail.
Here is good way to solve this. Did not believe it but after I tried it worked ultimate.
MS access running SQL doesn't insert data, no error
strSQL = "INSERT INTO Products([Product name],[Product description],[Finnish name],[Finnish description],[Matrix2012], " & _
"[Additional Info], [Unit], [Licence],[Remarks],Narcotic,[Asset], " & _
"[ATC], [Cathegory], [EIC code], [EIC name])" & _
" VALUES (ptxtProductName, ptxtProductDesc,ptxtFinnishName,ptxtFinnishDesc,pComboMatrix, ptxtAdditionalInfo,pComboUnit, pCheckLicense, ptxtRemarks, pCheckNarcotic, pCheckAsset, ptxtATC, ptxtCathegory, ptxtEICCode, ptxtEICName);"
Set db = CurrentDb
Set qdf = db.CreateQueryDef(vbNullString, strSQL)
With qdf
.Parameters("ptxtProductName").Value = Me.txtProductName.Value
.Parameters("ptxtProductDesc").Value = Me.txtProductDesc.Value
.Parameters("ptxtFinnishName").Value = Me.txtFinnishName.Value
.Parameters("ptxtFinnishDesc").Value = Me.txtFinnishDesc.Value
.Parameters("pComboMatrix").Value = Me.ComboMatrix.Value
.Parameters("ptxtAdditionalInfo").Value = Me.txtAdditionalInfo.Value
.Parameters("pComboUnit").Value = Me.ComboUnit.Value
.Parameters("pCheckLicense").Value = Me.CheckLicense.Value
.Parameters("ptxtRemarks").Value = Me.txtRemarks.Value
.Parameters("pCheckNarcotic").Value = Me.CheckNarcotic.Value
.Parameters("pCheckAsset").Value = Me.CheckAsset.Value
.Parameters("ptxtATC").Value = Me.txtATC.Value
.Parameters("ptxtCathegory").Value = Me.txtCathegory.Value
.Parameters("ptxtEICCode").Value = Me.txtEICcode.Value
.Parameters("ptxtEICName").Value = Me.txtEICName.Value
.Execute dbFailOnError
End With
Debug.Print db.RecordsAffected
That check for empty fields is mystery, it works in another form so it has to be some sort of reference problem. Anyway to keep things simple this works perfectly:
If txtProductName.Value = "" Or ComboMatrix.Value = "" Or ComboUnit.Value = "" Then
'Show notification if field was not filled and move focus to that field
MsgBox "A required Field has not been filled."

Run-Time Error '13' Type Mismatch - ACCESS DATABASE

I am trying to compare two text fields txtTrailerNumber and txtSealNumber to the database table Tab_TrailerDetails. [TrailerNumber] and [SealNumber] as listed in the table.
I am trying to get the database to look at the trailer number entered into the form, and if it finds a duplicate value it then looks at the seal number entered into the form. If both values have a duplicate found in the table it should throw up the Msg_Box error code.
Private Sub txtSealNumber_AfterUpdate()
Dim NewTrailer, NewSeal As String
Dim stLinkCriteria As String
'Assign the entered Trailer Number and Seal Number to a variable
NewTrailer = Me.txtTrailerNumber.Value
NewSeal = Me.txtSealNumber.Value
stLinkCriteria = ("[TrailerNumber]='" & NewTrailer & "'" And "[SealNumber]='" & NewSeal & "'")
If Me.txtTrailerNumber = DLookup("[TrailerNumber]", "Tab_TrailerDetails", stLinkCriteria) Then
MsgBox "This trailer, " & NewTrailer & ", has already been entered in database," _
& vbCr & vbCr & "along with seal " & NewSeal & "" _
& vbCr & vbCr & "Please make sure Trailer and Seal are not already entered.", vbInformation, "Duplicate information"
'undo the process and clear all fields
Me.Undo
End If
End Sub
The cause of the error is that you have a logical keyword, notably AND inside a string expression. Change your code to
stLinkCriteria = ("[TrailerNumber]='" & NewTrailer & "' And [SealNumber]='" & NewSeal & "'")

Filtering subform by date cant get it to accept date format

I have subform filters by VBA on user filling out text boxes, it works by building the recordsource where statement.
It loops through the controls but when it comes to the date controls I am specifically the control to have it recognize 2 text boxes (from , to) for a single date field in the subform.
The issue I am having is its filtering on MM/DD/YY not DD/MM/YY and nothing I am trying seems to solve this. I have tried adding formatting in the code to the sauce and to the text box value . also tried playing with the actual text box format but nothing seems to be making a difference and im pulling my hair out.
The relevant section of code is
Dim strFilter As String
Dim ctL As Access.Control
For Each ctL In Me.Controls
If ctL.Name = "Raised_For_From" Then
If Not IsNull(Raised_For_From) Then
strFilter = strFilter & " AND " & "Raised_For" & " > " & "#" & Me.Raised_For_From & "#"
End If
Else
If ctL.Name = "Raised_For_To" Then
If Not IsNull(Raised_For_to) Then
strFilter = strFilter & " AND " & "Raised_For" & " < " & "#" & Me.Raised_For_to & "#"
End If
Else
You should always work with MM/DD/YY format in the SQL, and thus force the format of your dates accordingly :
strFilter = strFilter & " AND " & "Raised_For" & " > " & "#" & Format(Me.Raised_For_From,"MM/DD/YYYY") & "#"
If you don't get the proper results, chances are high that the dates in this table are wrong because when you INSERTED them you did not applied the format MM/DD

Microsoft Access passing variables to VB from Form

I built a form with 2 combo boxes, one for Event and one for People. The two queries for the boxes include the Event_id and People_id but are not shown. The idea is to select the event from a drop down then add a person to attend the event. My problem is passing these two ID to the SQL update script.
Below is the VB; I receive a 424 error and calls the SQL as the area.
What's wrong?
Private Sub Command15_Click()
Dim dbs As DAO.Database, sql As String, rCount As Integer
Set dbs = CurrentDb
sql = "INSERT INTO Whos_Going (Event_ID, Who_is_invited) " _
& "VALUES(" & Event_id.Text & ", " & People_id.Text & ")"
dbs.Execute sql, dbFailOnError
rCount = dbs.RecordsAffected
If rCount > 0 Then
MsgBox "Person Added to Event"
'update listbox
conInfo.Requery
End If
End Sub
With VBA you need to construct the valid sql statement. All string literals must be enclosed into ', all dates must be enclosed into #. In addition to that, if your string variable contains an apostrophe it needs to be replaced with ''. The correct syntax will be:
sql = "INSERT INTO Whos_Going (Event_ID, Who_is_invited) " _
& "VALUES('" & Replace(Event_id.Text, "'", "''") & "', '" _
& Replace(People_id.Text, "'", "''") & "')"

RecordSource in Access SQL

I have a form which allows the user to view all records with the LinkRef field equal to a specified value and also either the Clearance Applying For or Clearance Level a certain value.
LinkRef is a user ID which is pulled in using OpenArgs from the previous form. The code for the form_load I have presently is:
Private Sub Form_Load()
'MsgBox Me.OpenArgs
Me.C_LinKRef = Me.OpenArgs
Me.chbToggleEdit.Value = False
'MsgBox Me.C_LinKRef
Dim mySQL As String
mySQL = _
"Select * " & _
"From TabClearDetail " & _
"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
"And ([Clearance Applying For] = 'BPSS' " & _
"Or [Clearance Applying For] = 'BPSS (EDF)' " & _
"Or [Clearance Applying For] = 'BPSS (Magn)' " & _
"Or [Clearance Applying For] = 'BPSS (Sella)' " & _
"Or [Clearance Applying For] = 'BPSS Equiv' " & _
"Or C_ClearanceLevel = 'BPSS' " & _
"Or C_ClearanceLevel = 'BPSS (EDF)' " & _
"Or C_ClearanceLevel = 'BPSS (Magn)' " & _
"Or C_ClearanceLevel = 'BPSS (Sella)' " & _
"Or C_ClearanceLevel = 'BPSS Equiv' " & _
"Or C_ClearanceLevel = 'DESTROYED' " & _
"Or C_ClearanceLevel = 'Lapsed' " & _
"Or C_ClearanceLevel = 'NOT_FLWDUP' " & _
"Or C_ClearanceLevel = 'NOT_SPECIFIED' " & _
"Or C_ClearanceLevel = 'Refused' " & _
"Or C_ClearanceLevel = 'Withdrawn');"
Me.RecordSource = mySQL
'MsgBox Me.RecordsetClone.RecordCount
End Sub
mySQL seems to behave as it should when there are matching records. But sometimes there won't be any records because the specified person doesn't have any of these clearance levels and hasn't applied for them, then I would like the form to come up blank or a message to appear saying that there is no matching records.
Presently though if there is no matching records the form will pull in the LinkRef but fill all the other text boxes with values from a completely different record (it seems to be the last record I viewed). Not to sure how to remedy this, I tried to use the RecordsetClone.RecordCount to say if it is equal to 0 then msgbox, but it seems to late to do that as it always seems to find at least 1 entry, as even if there should be 0 it has already populated the textboxes with data from another field so 1 is found.
The LinkRef textbox is populated from OpenArgs. All other textboxes are populated using a query which looks in the TabClearDetail table and pulls the values in. I'm starting to think I'd be better either just using Queries or just using Code, but I wasn't sure how to use OpenArgs in a query and for some things it's so much quicker to make a query than code.
Here is the code for my save dialog I refer to in reply to #Roland post. This code is called in the Form_Close() sub.
Private Sub SaveDialog()
Dim Msg, Style, Title As String
Dim Response As Integer
Msg = "Would you like to save your changes?"
Style = vbYesNoCancel
Title = "Save Changes"
On Error GoTo Err_BackFromAddBPSSButton_Click
Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
'DoCmd.Close
DoCmd.OpenForm ("Basic Personal Information")
Else
If Response = vbNo Then
Me.Undo
'DoCmd.Close
DoCmd.OpenForm ("Basic Personal Information")
End If
End If
Exit_BackFromAddBPSSButton_Click:
Exit Sub
Err_BackFromAddBPSSButton_Click:
MsgBox Err.Description
Resume Exit_BackFromAddBPSSButton_Click
End Sub
Apologies for the very wordy question, hopefully all the detail is necessary and it makes sense, any suggestions HUGELY appreciated!
Try changing the order of events:
Don't set the TextBox value first. Pass the OpenArgs to the mySql string. With mySql open a recordset in VBA (OpenRecordset) and do a RecordCount. If it is zero then set the Recordsource to SELECT * FROM TabClearDetail WHERE 1=2 . Else set mySQl as the Recordsource (or pass the Recordset). Only then set the TextBox and CheckBox.
Private Sub Form_Load()
Dim i as Integer
i = Me.OpenArgs
Dim mySQL As String
mySQL = _
"Select * " & _
"From TabClearDetail " & _
"Where (C_LinKRef = " & Me.C_LinKRef & ") " & _
"And ([Clearance Applying For] IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS Sella)','BPSS Equiv') " & _
"Or C_ClearanceLevel IN ('BPSS','BPSS (EDF)','BPSS (Magn)','BPSS (Sella)','BPSS Equiv','DESTROYED','Lapsed','NOT_FLWDUP','NOT_SPECIFIED','Refused','Withdrawn'));"
Dim rst as Recordset
Set rst = CurrentDB.OpenRecordset(mySQL)
rst.MoveLast
rst.MoveFirst
If rst.RecordCount = 0 then
Me.RecordSource = "SELECT * FROM TabClearDetail WHERE 1=2"
Me.C_LinKRef = ""
Me.chbToggleEdit.Value = False
Else
Me.RecordSource = mySQL
Me.C_LinKRef = i
Me.chbToggleEdit.Value = False
End If
rst.Close
Set rst = Nothing
End Sub
Sorry, cannot test it here so may be a little buggy. If any problems I will check tomorrow
Using a query and passing [Forms]![BPSS Clearance].[OpenArgs] into that as well as the conditions on C_ClearanceLevel and Clearance Applying For has worked for me. No idea why the code didn't work because in theory it's doing the same thing, but I've got a solution so I'm happy. Thanks for all the suggestions