具有 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" 正确?
你犯了一些错误:
- 所有可为 null 的参数必须定义为
Variant
。
If
必须用 End If
结束
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
我已经好几年没接触过 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" 正确?
你犯了一些错误:
- 所有可为 null 的参数必须定义为
Variant
。 If
必须用End If
结束
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