2010-05-06 16 views
5

Me estoy golpeando la cabeza contra la pared en este caso. Estaba buscando en algún viejo código de informe de base de datos escrito en Visual Basic 6 y me encontré con esta línea (el código se está moviendo datos desde una base de datos "fuente" en una base de datos de informes):"Uso no válido de nulo" cuando se utiliza Str() con un campo Null Recordset, pero Str (nulo) funciona bien

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

Cuando rsSource!VehYear es Null, la línea anterior genera un error de tiempo de ejecución "Uso no válido de nulo". Si rompo en la línea de arriba y escriba lo siguiente en el panel Inmediato:

?rsSource!VehYear 

emite Null. Bien, eso tiene sentido. A continuación, intento reproducir el error:

?Str(rsSource!VehYear) 

Aparece el mensaje "Uso no válido de nulo".

Sin embargo, si escribo lo siguiente en la ventana Inmediato:

?Str(Null) 

no recibo un error. Simplemente salidas Null.

Si repito el mismo experimento con Trim() en lugar de Str(), todo funciona bien. ?Trim(rsSource!VehYear) devuelve Null, al igual que ?Trim(Null). Sin errores de tiempo de ejecución.

Por lo tanto, mi pregunta es, ¿cómo Str(rsSource!VehYear) posiblemente lanzar un "uso no válido de null" error al Str(Null) no, cuando saben quersSource!VehYear es igual a Null?


Actualización: Si escribo lo siguiente en la ventana Inmediato, funciona como se esperaba (se produce ningún error):

?Str(rsSource!VehYear.Value) 

Esto da salida a Null. Ahora, sé que rsSource!VehYear es en realidad una instancia ADODB.Field, pero Value es su propiedad predeterminada, por lo que Str debería estar operando en la propiedad Value (que es Null). Incluso el mensaje de error ("Uso no válido de nulo") sugiere que Str está recibiendo un parámetro Null, pero ¿cómo puede tratar Null de manera diferente en un caso y no en el otro?

Mi única conjetura es que la implementación interna de Str() de alguna manera falla al obtener la propiedad predeterminada, y el error "Uso no válido de nulo" ocurre por una razón diferente (algo que no sea el parámetro está causando el "uso inválido de Nulo ", tal vez cuando intenta recuperar la propiedad predeterminada del objeto Field).

¿Alguien tiene una explicación técnica más detallada de lo que está sucediendo aquí?

En resumen:

?Str(rsSource!VehYear) 

lanza un "uso no válido de null" error al rsSource!VehYear es Null, pero

?Str(rsSource!VehYear.Value) 

vuelve Null.

Sin embargo, tanto Trim(rsSource!VehYear) como Trim(rsSource!VehYear.Value) devuelven Null.

Respuesta

5

La función Str comprobará específicamente si se pasa un valor nulo y lo tratará en consecuencia. Cuando pasas un objeto, intenta convertir el resultado de un método predeterminado en una Cadena. El resultado del método predeterminado no se pasa al método Str, pero el objeto Field es, por lo que fallará una verificación para el Null inicial. La función Str continuará verificando el tipo de parámetro para los tipos de datos que admite cuando se da cuenta de que tiene un objeto, intentará recuperar el valor predeterminado. No vuelve a intentar tratar con el valor predeterminado como lo hizo con el argumento pasado, por lo que el intento de devolver un valor nulo como una cadena fallará. Parece que MS no esperaba que un valor predeterminado fuera nulo o cualquier otro valor no válido para Str. Por ejemplo, Str tampoco admite una cadena vacía.

+0

Eso aclara las cosas. Por cierto, gracias por SimplyVBUnit;) –

0

De memoria, los campos de base de datos nula son Nothing (o posiblemente vbNull), que no tienen las mismas reglas aplicadas a ellos como Null. Usted sólo debe ser capaz de hacer una comprobación rápida:

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

Buena sugerencia, pero el campo es, sin duda igual a 'null'. Lo comprobé pasando el cursor sobre él en el IDE e imprimiéndolo en la ventana Inmediato. –

1

Esta fue mi solución en los VB6 días:

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

la & "" va a asegurarse de que no siempre se encuentra al menos una cuerda vacía para trabajar.

+0

Sé que puedo evitar el problema y, en este caso, puedo simplemente eliminar las llamadas a 'Trim' y' Str' en total ya que el campo de la base de datos es en realidad un campo numérico. Estoy más interesado en las razones técnicas por las cuales el código en la pregunta no funciona como se esperaba. –

6

Si necesita un valor distinto de una cadena, trate de usar EsNulo lugar:

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

'Nota 0 es el valor predeterminado

Cuestiones relacionadas