Неверное использование Null при явном присвоении Null переменной типа option - PullRequest
1 голос
/ 24 марта 2019

В настоящее время я пытаюсь обновить старый проект 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 Ответ

1 голос
/ 24 марта 2019

Важно помнить, что с такими функциями:

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 - операция только для чтения, поэтому она должна быть такой же в отношении блокировки.

...