【问题标题】:Invalid use of Null when explicitly assigning Null to a variable of type variant将 Null 显式分配给变体类型的变量时无效使用 Null
【发布时间】:2019-03-25 03:09:35
【问题描述】:

我目前正在尝试将旧 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。此外,该代码在 Access 2010 x64 中运行了 8 年,没有出现任何问题。

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

【问题讨论】:

  • 你是怎么调用这个函数的? vValue 不是局部变量,它是(ByRef)来自调用函数的变量,不一定是 Variant。
  • 另外,你可以用一个简单的DLookup 调用来替换整个函数。
  • @Andre 非常感谢!这就是问题所在......不知道我怎么会错过它(我的最后一个 VBA 编码是几年前的......)。关于DLookup,我不确定它是否完全按照函数原作者的意图进行锁定;一般来说,我想在这个野兽中尽可能少地改变(那里有很多代码......)。您介意让您的 cmets 成为答案吗?

标签: ms-access vba


【解决方案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 的替代方案如下。它的行为应该完全相同,除非您的有效 SystemSettings 为 NULL。

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是一个只读操作,所以在锁定方面应该是一样的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-28
    • 2017-01-15
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 2018-10-02
    相关资源
    最近更新 更多