Error setting variable to Null Value - ms-access

I'm trying to write a module in a form that auto-fills an ExpiryDate control based on a user-input IssueDate control and a DaysValid field in a related table. If there is no data in DaysValid, it treats the record as one that never expires, and leaves ExpiryDate blank.
Here's the module as it currently stands:
Private Sub IssueDate_AfterUpdate()
If Not IsNull(IssueDate) Then
Dim DysVld As Integer
DysVld = DLookup("[DaysValid]", "tblInduction", "[ID] = " & Me.Induction)
If IsNull(DysVld) Then
Exit Sub
End If
ExpiryDate.Value = DysVld + IssueDate
End If
End Sub
If there is no value in tblInduction.DaysValid, I get run time error 94 - invalid use of Null. From this I infer that I'm not allowed to set a variable to a Null value... I could put the following if clause earlier, but that seems more cumbersome than should be necessary. What's best practice on dealing with this? An error handler?

Prevent the error.
Only variant variable can hold Null. The DysVld variable is declared as integer. Either declare it as Variant or change code.
DysVld = Nz(DLookup("[DaysValid]", "tblInduction", "[ID] = " & Me.Induction),0)
If DysVld <> 0

Related

#Error in DLookup Function

I am using a function in MS Access to return a Query field value with a DLookup. The function passes a value to strPersonType from an existing field in the query.
The function works fine when there is a value present in that field, however when there is no value present it returns #Error. In that case I would like it to return a Null or blank value.
I have tried error handling and If statements (like the one below) and I have been unable to fix it thus far.
No matter what I try the field value comes up as #Error.
Function LookUpPersonType2(strPersonType As String)
'Used to look up Person Type2 in the "Person Type Key" table given PERSON_TYPE
'Returns original supplied name if no variation
If IsNull(strPersonType) Or strPersonType = "" Then
LookUpPersonType2 = ""
Else
If IsNull(DLookup("[Person Type2]", "[Person Type Key]", "[PERSON_TYPE] ='" & strPersonType & "'")) Then
LookUpPersonType2 = strPersonType
Else
LookUpPersonType2 = DLookup("[Person Type2]", "[Person Type Key]", "[PERSON_TYPE] ='" & strPersonType & "'")
End If
End If
Debug.Print LookUpPersonType2 & ","
End Function
I realized that I needed to change the passed parameter to a Variant variable type since there is a possibility that the value will be NULL. Originally it was string variable type and strings cannot be NULL. Thanks!

VBA: need to default control value if only 1 possible result or show list if more than possible result

I'm trying to write a bit of code, in VBA, that would restrict the possible values in a select list if certain criteria are met or, if only one possible value, default the value in the control to that one possible value or return a null list if no possible values.
To be more specific, in a form, I have an EventDate and ProtocolID. The protocols have a BeginImplementationDate and EndImplmentationDate. If the EventDate falls between the BeginImplementationDate and EndImplementationDate (which can be null, if the protocol is still active) of more than 1 protocol, I need to show all the ProtocolIDs for those protocols in the drop-down list. If only 1 protocol meets that criteria, the field needs to default to the ProtocolID that qualifies. If zero protocols meet the criteria, the drop-down list will be empty.
You could set the DefaultValue of the combobox with a small subfunction which you, for example, could call when opening the form:
Private Sub Form_Load()
Call SetDefaultProtocol
End Sub
Private Sub SetDefaultProtocol()
Dim DefaultValue As String
With Me!ComboProtocol
If .ListCount = 1 + Abs(.ColumnHeads) Then
DefaultValue = .ItemData(Abs(.ColumnHeads))
End If
.DefaultValue = DefaultValue
End With
End Sub
The following is what I did to resolve the problem.
Private Sub txtEventDate_AfterUpdate()
Dim intProtocolCount As Integer
Dim intProtocolID As Integer
intProtocolCount = DCount("ID", "lu_Protocol", "BeginImplementationDate<=#" & Me.EventDate & "# and Nz([EndImplementationDate],Date())>=#" & Me.EventDate & "#")
If intProtocolCount = 1 Then
intProtocolID = DLookup("ID", "lu_Protocol", "BeginImplementationDate<=#" & Me.EventDate & "# and Nz([EndImplementationDate],Date())>=#" & Me.EventDate & "#")
Me.cmbProtocol = intProtocolID
Me.cmbProtocol.Requery
ElseIf intProtocolCount = 0 Then
MsgBox ("No Protocol is active for this Event Date. If Event Date is correct, please contact the Data Manager to update the Protocol list in the database.")
Me.cmbProtocol.Requery
Else
Me.cmbProtocol.Requery
End If
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)

Table completely ignoring variable

Private Sub Form_Current()
Dim bytoffcut As Byte
Dim strCriteria
strCriteria = "[WOID] = " & Forms![frmAddStockBooking]![MouldWO]
bytoffcut = Nz(DMax("OffcutNo", "dbo_tblOffcuts", strCriteria), 0) + 1
MsgBox bytoffcut
Me.txtOffcut.Value = bytoffcut
Me.WOID.Value = Forms![frmAddStockBooking]![MouldWO]
Me.txtdate.Value = Now()
End Sub
Can anyone tell me why this is not working? The variable is behaving as expected where bytoffcut increments by one when i create a new record. But when I check the table the field bound to txtOffcut the field reads 1 instead of the incremented value.
EDIT: This code is being used in the On current property of the form. When I create a new record using a button on the form Dmax is used to find the highest offcut No value in a table and add one to it.
This appear to work in the form as the offcut no txtbox increments. But when i look at the table instead of having records with an increasing offcut no Instead all records read 1
Try sending your where clause in the DMax like this, assuming the WOID field in the table is an number type and not text or date.
"[WOID] = " & Forms![frmAddStockBooking]![MouldWO]
It would be better to evaluate your DMax() expression only once, especially if dbo_tblOffcuts is a large linked table without a usable index on [WOID].
If your DMax() expression can return a Null, use Nz() to transform the Null to zero. Then add one.
Dim bytoffcut As Byte
Dim strCriteria
strCriteria = "[WOID] = " & Forms![frmAddStockBooking]![MouldWO]
'Debug.Print strCriteria '
bytoffcut = Nz(DMax("OffcutNo", "dbo_tblOffcuts", _
strCriteria), 0) + 1
MsgBox bytoffcut
Me.txtOffcut.value = bytoffcut
This may not give you what you want when other users are editing dbo_tblOffcuts.
I have managed to solve the issue of multiple records being updated by creating a primary key for the table I am writing to.
I think that because Access could not uniquely identify the record it would edit all the records that met the criteria or something of the ilk. I am not entirely sure myself.

If [ComboBox] Is Null Statement in VBA/Access 2007

I have a form with one ComboBox (YearToBeBuilt) and two textBox fields (Cost and YearofExpenditureCost). All controls are linked to a main table and the table is updated once the selections/entries have been made on the form.
I have written a procedure in VB called ReCalcIt()which performs the following procedure when called:
Private Sub ReCalcIt()
If Me.YearToBeBuilt = "" Then
Me.YearofExpenditureCost = Me.Cost
Else
Me.YearofExpenditureCost = Me.Cost * (1 + 0.031) ^ (Me.YearToBeBuilt - 2010)
End If
End Sub
When I wrote this I thought that this would do the following:
If the ComboBox [YearToBeBuilt] is blank (e.g.-no selection made) then
the textbox [YearOfExpenditureCost] will return the value of the TextBox [Cost]. Else, the calculation for YearofExpenditureCost is performed.
But this is not working the way it should
What am I doing wrong? I am a VBA n00b so perhaps my syntax is incorrect?
Try it with
If Len(Me.YearToBeBuilt & vbNullString) = 0
So the code will look like this:
Private Sub ReCalcIt()
If Len(Me.YearToBeBuilt & vbNullString) = 0 Then
Me.YearofExpenditureCost = Me.Cost
Else
Me.YearofExpenditureCost = Me.Cost * (1 + 0.031) ^ (Me.YearToBeBuilt - 2010)
End If
End Sub
The usual way is to say:
If IsNull(MyControl) Then
See also: Access VBA: If Form Value <> NULL then run query else, end if. - not doing anything
It seems to me that this might be dependent on the format of the combo box? If it's a number, then
If Len(Me.YearToBeBuilt & vbNullString) = 0
doesn't work. Because the Me.YearToBeBuilt has a value of 0, and so the above returns 1.
I'm wondering if there is a more robust method? Maybe
Me.YearToBeBuilt.ListIndex = -1