我目前正在尝试将旧的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中没有任何问题。
该错误的原因是什么,如何预防?
答案 0 :(得分:1)
重要的是要记住,使用这样的功能:
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
是只读操作,因此在锁定方面应该相同。