我目前正在尝试将旧的ADP项目从Access 2010 x64升级到Access 2019 x64。我已设法将其转换为.accdb文件,但现在我的VBA代码出现错误。
请考虑以下功能:
Public Function GetSystemSetting(sKey As String, vValue As Variant) As Boolean
Dim cnTemp As ADODB.Connection, rsTemp As ADODB.Recordset
Dim sSQL As String
On Error GoTo LAB_Error
sSQL = "SELECT T_Value FROM INT_SystemSettings WHERE (T_Key = '" & sKey & "')"
Set cnTemp = New ADODB.Connection
Set rsTemp = New ADODB.Recordset
cnTemp.CursorLocation = adUseServer
cnTemp.Open CurrentProject.BaseConnectionString
rsTemp.Open sSQL, cnTemp, adOpenForwardOnly, adLockReadOnly
If (rsTemp.EOF) Then GoTo LAB_Error
vValue = Nz(rsTemp![T_Value])
rsTemp.Close
cnTemp.Close
On Error GoTo 0
GetSystemSetting = True
Exit Function
LAB_Error:
vValue = Null
If (rsTemp.State <> adStateClosed) Then rsTemp.Close
If (cnTemp.State <> adStateClosed) Then cnTemp.Close
GetSystemSetting = False
End Function
我知道这段代码在很多方面都值得怀疑,但我想专注于这条线
vValue = Null
执行此行时,会引发运行时错误:
Invalid use of Null
我已经阅读了几十篇关于各种网站上的错误消息的文章,包括这个,但它总是归结为OP没有使目标变量成为variant
。但就我而言,目标变量vValue的类型为variant
。此外,该代码运行了8年,在Access 2010 x64中没有任何问题。
这个错误的原因是什么,我该如何防止它?
重要的是要记住这样的功能:
Public Function GetSystemSetting(sKey As String, vValue As Variant) As Boolean
vValue = Null
除非您指定ByVal
,否则参数将传递给ByRef
,因此您实际上是在调用函数时写入用作参数的变量。
如果该变量不是变量,则会触发错误。
Dim str As String
If GetSystemSetting("non-existing", str) Then ' KA-BOOM!
与DLookup
的替代方案如下。除非您具有NULL的有效SystemSettings,否则它应该表现完全相同。
Public Function GetSystemSetting(sKey As String, vValue As Variant) As Boolean
' DLookup returns NULL if no record is found
vValue = DLookup("T_Value", "INT_SystemSettings", "T_Key = '" & sKey & "'")
GetSystemSetting = Not IsNull(vValue)
End Function
DLookup
是一个只读操作,因此锁定应该是相同的。