Проблема оценки NULL в операторе IIF (доступ) - PullRequest
3 голосов
/ 01 мая 2010

Элемент в наборе записей rstImportData («Плоский размер») = Нуль

С этим, учитывая следующее утверждение:

IIF(IsNull(rstImportData("Flat Size")), Null, cstr(rstImportData("Flat Size")))
Result: Throws error 94: Invalid use of Null

Если я изменю оператор, удалив преобразование типов при ложном сравнении:

IIF(IsNull(rstImportData("Flat Size")), Null, 0)
Result: Null

Возвращает Null, как и должно быть в первый раз. Похоже, что я не могу выполнить преобразование типов в IIF, если переданное значение должно когда-либо быть нулевым, даже если оно проходит тест IIF, оно все еще пытается оценить его как при истинном, так и при ложном ответе. Единственная причина, по которой я использую IIF таким образом, заключается в том, что у меня есть 25-строчное сравнение, чтобы сравнить данные из импорта с сопоставляемой записью в базе данных, чтобы узнать, нужно ли мне добавить предшествующий журнал.

Есть мысли? При импорте данных будут нулевые даты, и если импорт электронной таблицы выполняется в строковом формате, я должен преобразовать любую сторону в другую, чтобы правильно сравнить значения, но если любая из сторон равна нулю, возникает это исключение: (*

EDIT Пример того, почему я использовал IIF (и рассматривал возможность использования универсальной функции)

If master("one") <> import("one") Or _
   master("two") <> import("two") Or _
   master("date") <> import("date") Or _  //import("date") comes from a spreadsheet, it comes in as string, CAN be a null value
   master("qty") <> import("qty") Or _    //import("qty") comes from spreadsheet, comes in as a string can CAN be null
   master("etc") <> import("etc") Then

....stuff....

End If

Этот код расширяется примерно на 20 столбцов для сравнения в базе данных. Я бы предпочел проверить как часть заявления. Я могу придумать несколько решений, но они включают в себя добавление гораздо большего количества кода. Если это так, то я не из тех, кто так легко сдается.

Опции, которые я вижу:

  • Создание временных переменных для выполнения работы перед сравнением и использованием этих новых переменных вместо набора записей
  • Создание объекта для передачи записи в предварительное форматирование и работы с ней, хотя дополнительная работа предоставит эту функциональность каждому типу импорта, поскольку существуют разные файлы с похожими полями

Я здесь для идей, и я открыт для любых интересных вещей, которые могут быть мне предложены, когда я решаю, как это сделать, я ищу наиболее многоразовый подход.

Ответы [ 2 ]

3 голосов
/ 01 мая 2010

Очень помогает простой способ изменения значения в строку. Хитрость заключается в том, что обрезка строки, которая является NULL, получит нулевую строку. Которым затем можно оперировать, как будто это не база данных null.
Я часто использую форму:

CInt("0" & Trim(SomeVariant & " "))

Чтобы получить действительный номер без необходимости проходить через кучу шуток. Нуль - это ничто для этой проблемы.

3 голосов
/ 01 мая 2010

Поведение, которое вы описали, является стандартным способом работы IIf под VBA. Это часть того, что Access 2003 Help говорит об этом:

" IIf всегда оценивает оба значения truepart и falsepart , даже если возвращает только один из них Из-за этого вы должны следить за нежелательными побочными эффектами. Например, если оценка falsepart приводит к ошибке деления на ноль, возникает ошибка, даже если expr is True . "

Однако, если вы используете оператор IIf в запросе, оценки замыкаются после truepart , когда expr равно True --- falsepart в этом случае не оценивается. К сожалению, эта информация бесполезна для вас ... если вы не можете включить запрос в сравнение.

Я не знаю другого способа избежать вашей ошибки с IIf. Я бы попытался добавить данные Excel в таблицу, структура которой совпадает со структурой таблицы, с которой вы будете сравнивать, что исключает необходимость выполнения преобразования строк в то же время, когда вы выполняете сравнение.

...