2010-05-06 3 views
5

Я стучу головой о стену на этом. Я смотрел на некоторых старых отчетов базы данных кода, написанного в VB6 и наткнулся на этой линии (код перемещения данных из базы данных «источник» в базу данных отчетов):«Недопустимое использование Null» при использовании Str() с полем Null Recordset, но Str (Null) отлично работает

rsTarget!VehYear = Trim(Str(rsSource!VehYear)) 

Когда rsSource!VehYear является Null, выше линии генерирует ошибку «Недопустимое использование Null» во время выполнения. Если я нарушу на строке выше и введите следующую команду в Immediate панели:

?rsSource!VehYear 

Он выводит Null. Хорошо, это имеет смысл. Далее я попытаюсь воспроизвести ошибку:

?Str(rsSource!VehYear) 

Я получаю сообщение об ошибке «Недопустимое использование Null».

Однако, если я печатаю следующее в открывшееся окно:

?Str(Null) 

Я не получаю сообщение об ошибке. Он просто выводит Null.

Если я повторю тот же эксперимент с Trim() вместо Str(), все будет хорошо. ?Trim(rsSource!VehYear) возвращение товара Null, как и ?Trim(Null). Ошибок во время выполнения нет.

Итак, мой вопрос, как может Str(rsSource!VehYear) возможно бросить «Недопустимое использование» ошибка при Str(Null) не происходит, когда я знаю, что rsSource!VehYear равно Null?


Update: Если я печатаю следующее в открывшееся окно, он работает, как ожидалось (ошибка не происходит):

?Str(rsSource!VehYear.Value) 

Это выводит Null. Теперь я знаю, что rsSource!VehYear фактически является экземпляром ADODB.Field, но Value является свойством по умолчанию, поэтому Str должен работать на Value (Null). Даже сообщение об ошибке («Недопустимое использование Null») указывает, что Str принимает параметр Null, но как он может обрабатывать Null по-разному в одном случае, а не в другом?

Мое единственное предположение - внутренняя реализация Str() как-то не позволяет получить свойство по умолчанию, а ошибка «Недопустимое использование Null» происходит по другой причине (что-то иное, кроме параметра, вызывает «Недопустимое использование Null ", возможно, когда он пытается получить свойство по умолчанию из объекта Field).

У кого-нибудь есть более подробное техническое объяснение того, что на самом деле происходит здесь?

Короче:

?Str(rsSource!VehYear) 

бросает "Недопустимое использование" ошибка при rsSource!VehYear является Null, но

?Str(rsSource!VehYear.Value) 

возвращается Null.

Однако, оба Trim(rsSource!VehYear) и Trim(rsSource!VehYear.Value) возвращение Null.

ответ

5

Функция Str специально проверит, было ли передано значение Null и соответствующим образом обработано. Когда вы проходите объект, он пытается преобразовать результат метода по умолчанию в String. Результат метода по умолчанию не передается в метод Str, но объект Field - это, поэтому проверка на исходный Null завершится неудачно. Функция Str продолжит проверять тип параметра для типов данных, которые он поддерживает, когда он понимает, что у него есть объект, он попытается получить значение по умолчанию. Он не пытается повторно использовать значение по умолчанию, как это было сделано с аргументом, переданным в аргументе, поэтому попытка вернуть Null в качестве строки приведет к ошибке. Кажется, MS не ожидала, что значение по умолчанию будет Null или любое другое недопустимое значение для Str. Например, Str также не поддерживает пустую строку.

+0

Это проясняет ситуацию. Кстати, спасибо за SimplyVBUnit;) –

0

Из памяти нулевые поля базы данных: Nothing (или, возможно, vbNull), которые не имеют таких же правил, которые применяются к ним как Null. Вы просто должны быть в состоянии сделать быструю проверку:

If (rsSource!VehYear Is Nothing) Then 
    ' Null 
Else 
    ' Not null 
End If 
+0

Хорошее предложение, но поле, безусловно, равна 'Null'. Я проверил, нависая над ним в IDE, и распечатав его в окне Immediate. –

1

Это был мой обходной путь в VB6 дни:

rsTarget!VehYear = Trim(Str(rsSource!VehYear & "")) 

& «» будет убедиться, что всегда находится по крайней мере, пустая строка для работы.

+0

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

6

Если вам нужно значение, отличное от строки, попробуйте использовать вместо IsNull:

rsTarget!VehYear = IIf(IsNull(rsSource!VehYear), 0, rsSource!VehYear) 

'Примечание 0 Значение по умолчанию:

Смежные вопросы