Reputation: 8402
I haven't touched Access in several years, so my VBA is rusty. I'm trying to do a complex If/Then/Else function in Access, so I figured I'd turn it into a custom function instead of an overly complex IIF statement.
What I have for my function is this:
Option Compare Database
Option Explicit
Public Function fnM01Errors(AUTO_CLM_ID As String, MED_CLM_ROLL_IND As String, CLM_FWD_EFF_DT As Date, CLM_FWD_CAN_DT As Date, CCF_PKG_TY As String, CLM_FWD_APPLY_IND As String, MED_EFF_DATE As Date)
If [AUTO_CLM_ID] = "Y" And [MED_CLM_ROLL_IND] <> "R" Or ([AUTO_CLM_ID] = "N" Or [AUTO_CLM_ID] Like "*-*") And [MED_CLM_ROLL_IND] <> "N" Then
fnM01Errors = "AUTO CLM_FWD_IND does not match MED_CLM_ROLL_IND"
If CLM_FWD_EFF_DT <> Null And CLM_FWD_CAN_DT <> Null And CCF_PKG_TY = "HRA" And CLM_FWD_APPLY_IND = "Y" And MED_EFF_DATE >= CLM_FWD_CAN_DT And MED_CLM_ROLL_IND = "N" Then
fnM01Errors = "No Error"
If CLM_FWD_EFF_DT <> Null And CLM_FWD_CAN_DT <> Null And CCF_PKG_TY = "HSA" And CLM_FWD_APPLY_IND = "Y" And MED_EFF_DATE >= CLM_FWD_CAN_DT And MED_CLM_ROLL_IND = "N" Then
fnM01Errors = "INVALID_ePro_ERROR"
If CLM_FWD_EFF_DT <> Null And CLM_FWD_CAN_DT <> Null And CCF_PKG_TY = "HSA" And CLM_FWD_APPLY_IND = "Y" And MED_EFF_DATE >= CLM_FWD_CAN_DT And MED_CLM_ROLL_IND = "R" Then
fnM01Errors = "AUTO CLM_FWD_IND does not match MED_CLM_ROLL_IND"
End Function
And in my query, I'm calling it like this:
Error: fnM01Errors([AUTO-CLM-ID],[MED_CLM_ROLL_IND],Nz([CLM_FWD_EFF_DT],#12/31/2099#),Nz([CLM_FWD_CAN_DT],#12/31/2099#),[CCF-PKG-TY],[MED_CCF_IND],Nz([MED_EFF_DATE],#12/31/2099#))
It keeps giving me an error:
Data Type Mismatch in query expression
I assumed it was because it was finding NULL dates, of which there are a lot, so that's when I added the Nz() functions to the date fields. However, I'm not even sure if that's right.
Can anyone tell me if this code is "logically" correct before I go pulling apart the dataset to look for a needle in a haystack?
Upvotes: 0
Views: 2902
Reputation: 55841
You can reduce this:
Public Function fnM01Errors( _
AUTO_CLM_ID As String, _
MED_CLM_ROLL_IND As String, _
CLM_FWD_EFF_DT As Variant, _
CLM_FWD_CAN_DT As Variant, _
CCF_PKG_TY As String, _
CLM_FWD_APPLY_IND As String, _
MED_EFF_DATE As Variant)
If [AUTO_CLM_ID] = "Y" And [MED_CLM_ROLL_IND] <> "R" Or ([AUTO_CLM_ID] = "N" Or [AUTO_CLM_ID] Like "*-*") And [MED_CLM_ROLL_IND] <> "N" Then
fnM01Errors = "AUTO CLM_FWD_IND does not match MED_CLM_ROLL_IND"
ElseIf Not IsNull(CLM_FWD_EFF_DT + CLM_FWD_CAN_DT) Then
If CCF_PKG_TY = "HRA" And CLM_FWD_APPLY_IND = "Y" And MED_EFF_DATE >= CLM_FWD_CAN_DT And MED_CLM_ROLL_IND = "N" Then
fnM01Errors = "No Error"
ElseIf CCF_PKG_TY = "HSA" And CLM_FWD_APPLY_IND = "Y" And Nz(MED_EFF_DATE >= CLM_FWD_CAN_DT, False) Then
If MED_CLM_ROLL_IND = "N" Then
fnM01Errors = "INVALID_ePro_ERROR"
ElseIf MED_CLM_ROLL_IND = "R" Then
fnM01Errors = "AUTO CLM_FWD_IND does not match MED_CLM_ROLL_IND"
End If
End If
End If
End Function
Upvotes: 1
Reputation: 107642
Reconsider a pure SQL solution with nested IIF()
. Arguably it is not too overly complex just many logic clauses, plus you avoid type casting and adding another coding layer to setup:
SELECT
...
IIF([AUTO_CLM_ID] = 'Y'
AND [MED_CLM_ROLL_IND] <> 'R'
OR ([AUTO_CLM_ID] = 'N' OR [AUTO_CLM_ID] LIKE '*-*')
AND [MED_CLM_ROLL_IND] <> 'N',
'AUTO CLM_FWD_IND does not match MED_CLM_ROLL_IND',
IIF(CLM_FWD_EFF_DT IS NOT NULL
AND CLM_FWD_CAN_DT IS NOT NULL
AND CCF_PKG_TY = 'HRA'
AND CLM_FWD_APPLY_IND = 'Y'
AND MED_EFF_DATE >= CLM_FWD_CAN_DT
AND MED_CLM_ROLL_IND = 'N',
'No Error',
IIF(CLM_FWD_EFF_DT IS NOT NULL
AND CLM_FWD_CAN_DT IS NOT NULL
AND CCF_PKG_TY = 'HSA'
AND CLM_FWD_APPLY_IND = 'Y'
AND MED_EFF_DATE >= CLM_FWD_CAN_DT
AND MED_CLM_ROLL_IND = 'N',
'INVALID_ePro_ERROR',
IIF(CLM_FWD_EFF_DT IS NOT NULL
AND CLM_FWD_CAN_DT IS NOT NULL
AND CCF_PKG_TY = 'HSA'
AND CLM_FWD_APPLY_IND = 'Y'
AND MED_EFF_DATE >= CLM_FWD_CAN_DT
AND MED_CLM_ROLL_IND = 'R',
'AUTO CLM_FWD_IND does not match MED_CLM_ROLL_IND',
NULL)
)
)
) AS fnM01Errors
FROM myTable
Upvotes: 1
Reputation: 25262
You made a few mistakes:
Variant
. If
must be closed with End If
if x <> Null
does not work. Use If not IsNull(x) Then
instead. You could also use the construct:
If...then
ElseIf ...then
ElseIf...then
End if
Note that if your tables will have lots of data, an IIF() will be be much faster.
Upvotes: 3