具有 NULL 日期值的访问函数

Access function with NULL date values

我已经好几年没接触过 Access 了,所以我的 VBA 生疏了。我正在尝试在 Access 中执行一个复杂的 If/Then/Else 函数,所以我想我应该将它变成一个自定义函数而不是一个过于复杂的 IIF 语句。

我的函数是这样的:

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

在我的查询中,我这样称呼它:

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#))

它一直给我一个错误:

Data Type Mismatch in query expression

我认为这是因为它正在查找 NULL 日期,其中有很多,所以那时我将 Nz() 函数添加到日期字段。但是,我什至不确定这是否正确。

在我拆开数据集大海捞针之前,谁能告诉我这段代码是否 "logically" 正确?

你犯了一些错误:

  1. 所有可为 null 的参数必须定义为 Variant
  2. If 必须用 End If
  3. 结束
  4. if x <> Null 不起作用。请改用 If not IsNull(x) Then

您还可以使用结构:

If...then
ElseIf ...then
ElseIf...then
End if

请注意,如果您的表将包含大量数据,IIF() will be be much faster

重新考虑带有嵌套 IIF() 的纯 SQL 解决方案。可以说它并不过分复杂,只是很多逻辑子句,而且你避免了类型转换并在设置中添加了另一个编码层:

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

你可以减少这个:

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