在将Null明确分配给variant类型的变量时

时间:2019-03-24 13:09:20

标签: vba ms-access access-vba

我目前正在尝试将旧的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中没有任何问题。

该错误的原因是什么,如何预防?

1 个答案:

答案 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是只读操作,因此在锁定方面应该相同。