Checking if record exists using DLookup (With Multiple Criteria) - ms-access

Im trying to create a function in my VBA where if the record they are trying to insert already exists however it returns a type mismatch.
EventCombo is a integer
MedalCombo is string
Private Sub MyCombo_BeforeUpdate(Cancel As Integer)
If Not IsNull(DLookup("RacerID", "Medals", "RaceID = " + EventCombo.Value _
+ " AND Medal = '" + MedalCombo.Value + "'" )) Then
MsgBox "Record Exists"
End If.
End Sub
What this does (or is supposed to do) is make sure no one else has the same medal in the same race.
What am I doing wrong?

With combo boxes in Access, you need to make sure that .value is really what you want. Often the first column is hidden which is .value while what is visible on the drop down box is not .value. When using a combo box to eliminate confusion I use the .columns property.
Also, to make sure the result from the combo box is a number and not text (as you did not use quotes in your example) I used the val() function to convert the combobox data to a number. If it already is a number, this will have no effect. Otherwise, if it is a digit stored as a string, it will convert it to a number. This might not be strictly necessary but it eliminates another possible problem. If the combobox column has a value which is some text which cannot convert to a number it will return 0 which you can test for in your code.
I cleaned up your code a bit with the following
I replaced the + with & like Remou said
changed .value to .columns(0). If the column you are looking for is not the first one, change 0 to the appropriate value
value() function
removed line continuation _. (Personal preference, feel free to ignore)
Private Sub MyCombo_BeforeUpdate(Cancel As Integer)
If Not IsNull(DLookup("RacerID", "Medals", "RaceID = " & Val(EventCombo.Columns(0)) & " AND Medal = '" & MedalCombo.Columns(0) & "'")) Then
MsgBox "Record Exists"
End If
End Sub

Related

Look for duplicate records before adding a record

I clipped this from another post, since it is similar to what I need. Instead of using me.ID, etc, I need to reference a field in another table, specifically [Formdate] in a table named Brief Sheet.
I tried many variations, such as table "Brief Sheet".Formdate but no luck
What would be the proper syntax?
rst.FindFirst "[ID] <> " & Me.ID & _
" AND [TitleText] = '" & Me.TitleText & _
"' AND [UnitCode] = " & Me.UnitCode & _
" AND [AcademicYear] = " & Me.AcademicYear & _
" AND [Titleofchapterjournalarticle] = '" & Me.Titleofchapterjournalarticle & "'"
Use Dlookup. In the snippet you posted, the coder has already instantiated a recordset and is using recordset methods to find a record within it. What you said you want to do is actually a little simpler.
Below is a test procedure to illustrate getting your date value from your table.
You didn't clarify what criteria you would use to select the proper FormDate from the table "Brief Sheet", so I included "ID=3", which will select the FormDate record, whose ID=3. Adjust that as necessary.
Also, if your table name really is "Brief Sheet", and you have the ability to rename it, I highly recommend establishing some naming convention rules for your tables, first not having any spaces. Even Brief_Sheet would make your life easier down the road.
Public Sub Test1()
'dimension a variable to hold the date value
Dim datFormDate As Date
'fill the variable with the value you need to reference
datFormDate = DLookup("FormDate", "Brief Sheet", "ID = 3")
'Print the value to the "immediate" pane (just for testing)
Debug.Print datFormDate
'If you're running this code from within your form module, you can assign
'the value in your variable to a field in your table as such:
me.DateFieldtxtbx = datFormDate
End Sub

Run Time Error 424 Object Required

I been working on the following code to when the user click on the button to save and go new record that Access locates the highest client id used by set location and then adds 1 to it. Prior to saving the record and moving on to new record. While work through other errors, but I can not get past error object required on this line. "Me.ClientID = IIf(DMax("[ClientID]", "tClientinfo", "[CorpsName]=" & "'defaultcorps'") Is Null, 0, DMax("[ClientID]", "tClientinfo", "[CorpsName]=" & "'defaultcorps'")) + 1"
The more i look at the similar questions more confused I get as to what is wrong with the code. Thank you in advance for any suggestions David
Private Sub Save_Record_Click()
'declare variables for default values
Dim defaultinterviewr As String
Dim defaultcorps As String
'Variables get their values
defaultinterviewr = Me.Interviewer.Value
defaultcorps = Me.Corps.Value
'Check to see if ClientID field is Blank.
If IsNull(Me.ClientID) Then
'Check that Corps field is filled in
If IsNull(Me.Corps) Then
MsgBox "Corps must be entered before saving record.", vbOKOnly
Me.Corps.SetFocus
'set client id base on corps by finding the highest id and adding 1 to that number
Else
Me.ClientID = IIf(DMax("[ClientID]", "tClientinfo", "[CorpsName]=" & "'defaultcorps'") Is Null, 0, DMax("[ClientID]", "tClientinfo", "[CorpsName]=" & "'defaultcorps'")) + 1
End If
End If
MsgBox "Done", vbOKOnly
'save record
'DoCmd.RunCommand acCmdSaveRecord
'Me.stateidnum1 = ""
'open new record
'DoCmd.GoToRecord , , acNewRec
'set field default value
'Me.Interviewer.Value = defaultinterviewr
'Me.Corps.Value = defaultcorps
'Me.Child_Subform.Form.AllowAdditions = True
End Sub
I think you need to start off by figuring out if your DMAX() statement is correctly producing results. The next thing I see and which is probably your main culprit is the fact that you are using the Expression IIf() inside VBA. The IIf() expression you are using will work inside a query or in a textbox but VBA has it's own If statement block which you are correctly using in the lines preceding it.
I would actually use the Nz Function to simplify it even more as follows:
UPDATED Based off of your comment below I re-looked at your overall code and noticed that "defaultcorps" is a variable and not a value I originally thought you were trying to filter by. You were wrapping the variable in quotes. My updated answer should work for you.
Me.ClientID = (Nz(DMax("[ClientID]", "tClientinfo", "[CorpsName]= '" & defaultcorps & "'"),0)+1)

Warning of duplicates in MS-Access

I am working on a MS-Access database to keep track of last names and addresses and several other records. I am making a table and would like for it to be updated by the user by inputting info from a form. The question I have is can I have several key items that would warn if a duplicate is found. Mainly if a duplicate is found in the last name and the address fields. I need the form to accept the duplicate because how the info is being obtained duplicates are possible but need to be able to enter the duplicate and warn the user while entering the data that a previous entry has already been made that is similar.
Is this possible in Access, and easy to implement that many different users may be entering the data? I haven't used Access for some time, sorry if I'm not using the correct terms, as I'm still learning the basics of Access, as I mainly work in Excel. Excel is the current solution that is being used, but finding quickly that a better solution is needed.
Thanks
Names aren't good candidates for primary keys and it seems that you have set the name as the primary key of one of your tables. You should either use a better candidate key (social insurance number, for example) or create a surrogate (artificial, if you want) key with no meaning other than being a key for your table.
Without more detail about your table structure it's hard to be more specific.
Warn the user but allow her to proceed if she wishes?
If so, a key constraint would be too, ahem, constraining. Just check for the duplicates manually (by explicitly querying existing data from your code). You may wish to index the field(s) being searched.
Yes, you can validate through this code:
If Nz(DCount("FieldName", "table", "FieldName= '" & Me.FieldName.Value & "'"), 0) > 0 Then
If MsgBox("The FieldName already exist", vbOKCancel, "Duplicate Warning") = vbCancel Then Cancel = True
Me.Undo
Exit Sub
End If
End If
In general terms, Access (and relational databases generally) are about preventing duplicate data from being entered in the first place. If you merely want to 'warn', then it will take a bit of custom code. So, say the table is called Customers and it has fields such as CustomerID (AutoNumber, primary key) and LastName (Text). The form then has a text box called txtLastName that is bound to the LastName field. In this situation, you could handle the text box's BeforeUpdate event like this:
Option Compare Database
Option Explicit
Const DuplicateWarningTitle = "Duplicate Record"
Const DuplicateValueWarning = "A record already exists with " + _
"the value you have entered. Are you sure you want to continue?"
Function GetSQLLiteral(Value As Variant) As String
Select Case VarType(Value)
Case vbNull
GetSQLLiteral = "Null"
Case vbString
GetSQLLiteral = "'" + Replace(Value, "'", "''") + "'"
Case Else
GetSQLLiteral = CStr(Value)
End Select
End Function
Sub HandleKeyFieldBeforeUpdate(Control As Access.TextBox, Cancel As Integer)
Dim RS As DAO.Recordset
Set RS = CurrentDb.OpenRecordset( _
"SELECT 1 FROM Customers " + _
"WHERE " + Control.ControlSource + " = " + GetSQLLiteral(txtLastName.Value) + _
" AND CustomerID <> " & Me.CustomerID)
If Not RS.EOF Then
Select Case MsgBox(DuplicateValueWarning, vbExclamation + vbYesNo, DuplicateWarningTitle)
Case vbYes
' just proceed
Case vbNo
Cancel = True
Control.Undo ' if desired!
End Select
End If
End Sub
Private Sub txtLastName_BeforeUpdate(Cancel As Integer)
HandleKeyFieldBeforeUpdate txtLastName, Cancel
End Sub
By pushing the duplicate checking code into a generic helper routine, other key fields can be handled in the same way easily:
Private Sub txtAddress_BeforeUpdate(Cancel As Integer)
HandleKeyFieldBeforeUpdate txtAddress, Cancel
End Sub

Adding logic to a sub form in Access?

I have a sub form in Access:
The CopyNo is a combobox that lets me select from the MovieCopies table. When I select one, I want the Title field to show the correct movie title associated to that copy's movie ID. I also want the format to show. When I select from DaysRented combobox, if I select 1 and the movie is New, I want it to display the price, if it is regular for 3 days display the correct price etc.
I'm just not sure how to give logic to the comboboxes.
If anyone could point me in the right direction of how to do this sort of thing in Access 2007 I'd really appreciate it.
Thanks
Something like this:
Private Sub cboCopyNo_AfterUpdate()
If Nz(Me.cboCopyNo, "") <> "" Then
Me.txtTitle = DLookup("Title", "MovieMaster", "MovieID = " & Me.cboCopyNo)
End If
End Sub
Private Sub cboDaysRented_AfterUpdate()
If Nz(Me.cboDaysRented, 0) > 0 Then
Dim strType as String
strType = DLookup("[Type]", "MovieMaster", "MovieID = " & Me.cboCopyNo)
If Me.cboDaysRented = 1 Then
Me.txtPrice = DLookup("Price1Day", "Price", "[Type] = '" & strType & "'")
Else
Me.txtPrice = DLookup("Price3Day", "Price", "[Type] = '" & strType & "'")
End If
End If
End Sub
Couple notes. Some of your field names are reserved words in certain databases, such as "Type". I highly recommend you try to use field names that are not reserved words in Access or SQL server.
DLookups are not necessarily the fastest way to lookup data but will likely be fast enough for what you're trying to do here. Sometimes I create my own DAO recordset and lookup the values I want rather than using DLookup. It's basically like writing your own DLookup function.
DLookup uses SQL language so your syntax in the third argument, the WHERE clause, needs to match SQL. If the field in your WHERE clause is text/string you'll need to use a single quote on either side of the value (as shown above around the strType variable). If it is a number field you will not need the quotes. If it's a date you'll need hash signs (#).

Inaccuracies using TextWidth() in VBA

I'm trying to get the length of a string in order to format a report using VBA in Access 2000. Yes I know this old but it's what I've been asked to do. I want to get the width of the string when printed; exactly what TextWidth() is meant to return. What I'm finding is that for strings ranging for 4-20 characters the returned value can range from exactly the right length to the correct length plus about an inch. This is too inaccurate for the formatting I wish to do. Is this common? I can't find any reference to this as a common problem but I've gone over and over the code and I'm fairly certain the function is just inaccurate ratehr than there being a logic problem.
Check the report's FontName and FontSize properties. If they are different than the field you are working with, you'll get wildly different results.
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
MsgBox (Me.FontName & " ," & Me.FontSize)
MsgBox (TextWidth("Test"))
Me.FontName = Me.f2.FontName 'ariel
Me.FontSize = Me.f2.FontSize '8
MsgBox (Me.FontName & " ," & Me.FontSize)
MsgBox (TextWidth("Test"))
Me.FontName = Me.f1.FontName 'ariel
Me.FontSize = Me.f1.FontSize '16
MsgBox (Me.FontName & " ," & Me.FontSize)
MsgBox (TextWidth("Test"))
End Sub
I'm still not sure how to set the report's font name and size though, I don't see anything in it's properties.