#ms-access #vba
#ms-access #vba
Вопрос:
Я пытаюсь написать функцию VBA, которая получает значение из таблицы Access с помощью запроса SELECT. Вот код:
Function getTableValue(uniqueID As Long, tableName As String, _
idField As String, tableField As String) As Variant
Dim db As Database
Dim rs As Recordset
Dim selectSQL As String
selectSQL = "select * from " amp; tableName amp; " where " amp; idField amp; "=" amp; uniqueID
Set db = OpenDatabase(dbPath)
Set rs = db.OpenRecordset(selectSQL)
If rs.RecordCount > 0 Then
rs.MoveLast
rs.MoveFirst
getTableValue = rs.Fields(tableField)
End If
End Function
Когда поле, указанное с помощью tableField
, является типом даты / времени, а поле пустое, getTableValue()
возвращает ошибку «Недопустимое использование Null». Я думал, что функция, возвращающая вариант, позволит мне возвращать значения Null; что мне делать для обработки этих пустых дат?
Комментарии:
1. Похоже, что вы дублируете функцию DLookup (также доступна онлайн в виде набора функций, которые начинаются с t вместо d, например, tLookup). Возможно, вместо этого вам придется использовать такой код: If IsNull(rs.Fields(tableField)) Тогда getTableValue = Null . Я предлагаю вам также проверить, действительно ли ошибка возникает внутри этой функции. Вы уверены, что на самом деле не возвращаете значение Null, а неправильно обрабатываете его в вызывающей функции? В качестве примечания, я думаю, вам нужно переместить ваш rs.MoveLast и rs.MoveFirst код для запуска перед тестированием RecordCount.
2. @HK1, ошибка возникает в этой функции; Я тестировал ее изолированно. Если я вызову . Перемещение по набору записей с .recordcount=0 Я получу сообщение об ошибке, поэтому сначала я должен проверить recordcount .
3. Вы действительно должны сделать что-то подобное вместо этого: Если нет (rs.BOF и rs.EOF), то
4. Таким образом, сама функция работает без ошибок; ошибка заключается в том, что вы присваиваете возвращаемое значение функции переменной даты / времени. И он прерывается, когда функция возвращает Null. Пожалуйста, отредактируйте свой вопрос, чтобы включить этот пункт. На самом деле я думаю, что это тоже ответ, возможно, вам следует представить его как таковой.
5. @hansup, спасибо за предложение, ответ представлен ниже.
Ответ №1:
Оказывается, что значение Null функции передавалось в переменную даты / времени. Я исправил это, используя следующее:
dim myDate as date
dim myVar as variant
myVar=getTableValue(idNum,"thisTable","idField", "valueField")
if isNull(myVar) then
myDate=0
else
myDate=myVar
endif
Хотя он не проверяет myVar
, возвращает ли дату, valueField
значения имеют тип Date / Time, так что все в порядке.
Ответ №2:
Посмотрите на эту ссылку
Вариант не может содержать значение null, возвращенное из базы данных. Вам нужно будет проверить значение null и вернуть эквивалент vbNull (не знаю, можете ли вы использовать vbNull в VBA).
HTH
Комментарии:
1. На самом деле, по ссылке, которую вы разместили, написано: «Только вариант может быть нулевым (другие типы будут ошибочными.)»
2. Я всегда понимал, что переменные типа variant могут быть нулевыми.
Ответ №3:
Может быть, с помощью Nz? getTAbleValue = Nz(rsFields(tableField), SomeReplacementDate)
Я думаю, дело в том, что при использовании возвращаемого значения из этой функции. Либо вы всегда возвращаете что-то правильное, либо вам нужно проверить возвращаемое значение этой функции.
Я должен признать, что я не знаю, что может означать нулевая дата. И хорошо, у вас есть идея, что это может быть?
Комментарии:
1. У меня нулевые даты, потому что я отслеживаю действие, которое может иметь или не иметь дату завершения. Пока он не будет завершен, поле даты пусто. И я не могу использовать Nz(), потому что я вызываю эту функцию из Excel, используя DAO, который не понимает Nz() .
2. Как вы можете видеть, код используется в Access. Это нужно для создания некоторой допустимой даты. Вы можете использовать, например, дату 1.1.1900 как указание на то, что там ничего нет. В любом случае вам нужно либо убедиться, что вы просто возвращаете действительные даты, либо проверяете наличие Null в вашем коде, вызывающем эту функцию.
Ответ №4:
Я бы изменил функцию, чтобы возвращать строку. Затем используйте nz()
для обработки null, сделав строку нулевой длины.
getTableValue = nz(rs.Fields(tableField),"")
Комментарии:
1. Смотрите Мой ответ на ответ Фридриха — я не могу использовать
Nz()
, потому что он вызывается из Excel.