Valores Nulos

 

 

  • El siguiente articulo es una aportación de Medardo Santana, desde Ciudad de La Habana, Cuba

  • Gracias Medardo !

     

VALORES NULOS QUE SON ?

 

Después de ciertas investigaciones, análisis y pruebas, quisiera compartir con ustedes un resumen que realicé sobre este tema de los Null y los Vacíos. Ahí les va:

 

 

NULL significa que el valor :

-          es desconocido

-          no está definido

-          está ausente

-          está vacío

-          no tiene entrada

 

Conceptos prácticos en los que se ve involucrado el valor NULL :

-          Si el valor del campo es NULL (vacío, si aún no se ha introducido ningún valor) se devuelve un valor por defecto (0 para los campos numéricos, ''” para las cadenas).

-          Si suprimes el valor de un campo, el resultado es nulo.

-          Si agregamos algún campo a una tabla que ya contenía datos, aquellos campos en los que aún no hayamos ingresado los datos, contendrán un valor nulo.

 

Conceptos definitorios en los que se ve involucrado el valor NULL :

-          Si a un campo le decimos NULL, estamos indicando que aunque se quede vacío, no pasa nada.

-          Un valor NULL no es lo mismo que un valor cero. Por ejemplo, no es lo mismo que el resultado de un cálculo sea igual a NULL, lo que significa que aún no conocemos el resultado porque al menos, uno de los valores es aún Null, a que ese campo contenga un cero, lo que significa que el resultado del cálculo es igual a cero (0).

-          Null significa vacío, pero debemos distinguir vacío de espacios o de ceros. Un campo numérico con valor nulo es distinto que con valor cero y un campo de texto con valor nulo, es distinto que con espacios .

-          La comparación entre dos valores NULL, o entre un valor NULL y cualquier otro valor, tiene un resultado desconocido porque el valor de cada NULL es desconocido.

-          En un cálculo que contenga un valor Nulo, el resultado también será Null. Se desconoce el resultado de agregar un valor desconocido a un número.

 

Y ahora analicemos bien estos dos conceptos:

-          Dos valores Null no significan que sean iguales, ni que tengan el mismo valor, como tampoco pueden ser distintos, o sea, no tienen comparación, no se compara con nada.

-          Y después de tanto hablar de “valores” NULL, resulta que NULL no es un valor, es un estado que indica que un determinado valor no existe o se desconoce.

-          Por tanto, si tenemos en cuenta que el signo igual ‘=’, al usarse como operador de igualdad, solo compara valores, mientras que el operador ‘ is compara estados, entonces podemos llegar a la conclusión de que es incorrecto preguntar si un campo es igual a Null, como por ejemplo:

 

If MiCampo = Null Then …

Lo correcto sería:

If IsNull(MiCampo) Then … ó If Not IsNull(MiCampo) Then …

Estas comprobaciones devolverán siempre true o false sin errors.

 

 

Conceptos erróneos:

 

Null es igual que Empty

Empty es una variable tipo Variant que no se ha inicializado y, Null, es una variable que no contiene dato válido alguno. El valor de las variables Empty dependen del contexto en que se utilizan. Si es numérico, sería igual a 0 y, si se tratara de cadenas, sería igual a longitud cero (""). Por tanto, de ser igual a cero (0), no sería igual a Null, porque Null es un valor desconocido y, cero, no es desconocido, es, indudablemente, un valor.

 

Null es igual que Nothing

El valor Nothing no es un valor desconocido o ausente, simplemente desvincula una variable objeto del objeto real.

 

 

Otros acápites:

 

Null no se asigna a las variables, a menos que, se haga de manera explícita, o sea, declarándolo.

El valor Null indica que Variant contiene datos no válidos. O sea, podemos verificar la presencia de un Null, solo a través de una variable Variant, de lo contrario, daría error.

 

Hagamos algunas pruebas para entender esto.

 

Tenemos un campo llamado ‘Nombres’ como tipo String.

En un formulario tenemos un cuadro de texto llamado ‘txtNombres’ donde el usuario escribirá el nombre de una persona.

Suponiendo que ese cuadro de texto esté vacío, vamos a verificar si realmente lo está.

 

Ejemplos con cadenas:

Ejemplo 1

Si hacemos esto:

     If IsNull(txtNombres) Then

        MsgBox "Es Null"

    End If

 

El control se evalúa como una variable Variant y el resultado es True (verdadero). En este caso, se evalúa correctamente como Null y se muestra el mensaje.

 

Ejemplo 2

Si hacemos esto otro:

Dim nom      ‘(ó Dim nom As Variant)

nom = txtNombres

    If IsNull(nom) Then

        MsgBox "Es Null"

    End If

 

El resultado es el mismo que el anterior porque se está evaluando una variable tipo Variant.

 

Ejemplo 3

Pero si hacemos esto:

Dim nom As String

nom = txtNombres

    If IsNull(nom) Then

        MsgBox "Es Null"

    End If

 

Se producirá el siguiente error:

“Se ha producido el error ‘94’ en tiempo de ejecución:

Uso no válido de Null”

En este caso, no se evalúa porque Null devuelve un valor de tipo Boolean y una variable de tipo de cadena no se puede comparar con los valores booleanos True o False. Sin embargo, una variable Variant sí se puede comparar con una variable Boolean sin generar error, como sucedió en los ejemplos anteriores.

 

Pero, si cambiamos esta línea:

nom = txtNombres

por esta otra:

nom = txtNombres & ""

 

y mantenemos el resto, no se produce error, pero tampoco verifica si es Null porque, en este caso, hemos asignado una cadena vacía para en caso que sea Null. Por tanto, la función IsNull no nos serviría. Esto significa que Null = vacío, pero NO igual a “cadena vacía”. Esta es la razón por la que muchas veces utilizamos ambas sentencias para asegurarnos de evaluar un valor vacío, por ejemplo:

If IsNull(nom) Or nom = "" Then…

 

Sin embargo, vamos a ver esta misma sentencia evaluándola de la misma manera que los ejemplos anteriores:

 

Ejemplo 1

Si hacemos esto:

    If IsNull(txtNombres) Or txtNombres = "" Then

        MsgBox "Es Null"

    End If

 

El control se evalúa como una variable Variant y el resultado es True (verdadero). En este caso, se evalúa correctamente como Null y se muestra el mensaje.

 

Ejemplo 2

Si hacemos esto otro:

Dim nom      ‘(ó Dim nom As Variant)

nom = txtNombres

    If IsNull(nom) Or nom = "" Then

        MsgBox "Es Null"

    End If

 

El resultado es el mismo que el anterior porque se está evaluando una variable tipo Variant.

 

Ejemplo 3

Y si hacemos esto:

Dim nom As String

nom = txtNombres

    If IsNull(nom) Or nom = "" Then

        MsgBox "Es Null"

    End If

 

Se producirá también el mencionado error 94, porque no se trata de una variable Variant.

 

Pero si cambiamos esta línea:

nom = txtNombres

por esta otra:

nom = txtNombres & ""

 

En este caso SI verifica porque asignamos cadena vacía a la variable y la evaluamos como tal en una de las condiciones.

 

 

Cambiemos ahora el tipo de datos.

 

Tenemos un campo llamado ‘Cantidad’ y en el formulario un cuadro de texto llamado ‘txtCantidad’.

Suponiendo que ese cuadro de texto esté vacío, vamos a verificar realmente si lo está.

 

Ejemplos con numéricos:

Ejemplo 1

Si hacemos esto:

     If IsNull(txtCantidad) Then

        MsgBox "Es Null"

     End If

 

El control se evalúa como una variable Variant y el resultado es True (verdadero). En este caso, se evalúa correctamente como Null y se muestra el mensaje.

 

Ejemplo 2

Si hacemos esto otro:

Dim num      ' (ó Dim nom As Variant)

num = txtCantidad

    If IsNull(num) Then

        MsgBox "Es Null"

    End If

 

El resultado es el mismo que el anterior porque se está evaluando una variable tipo Variant.

 

Ejemplo 3

Pero si hacemos esto:

Dim num As Long     '(ó Dim num As Integer)

num = txtCantidad

    If IsNull(num) Then

        MsgBox "Es Null"

    End If

 

Se producirá también el mencionado error 94, igual que en el caso del String, porque no se trata de una variable Variant.

Como han podido percatarse, los resultados son los mismos que con los ejemplos de las cadenas.

 

Finalmente, existen varias soluciones:

 

Solución 1:

Definir la variable como un Variant .

No se recomienda. Access tratará de forma más eficiente los datos si declara la variable con el tipo de datos correspondiente. Por ejemplo, mejor se representa a través de String una variable que almacena nombres de personas, ya que un nombre está siempre compuesto de caracteres. Además, los Variant consumen más memoria. Claro, hay momentos en que sí son necesarios.

 

 

Solución 2:

Convertir el campo a cero (0) o vacío (" ") .

 

Un ejemplo para convertir a cero:

Cuando tiene campos que contienen valores Nulo, puede crear una expresión que convierte los Null a cero. Para convertir valores Null a cero, utilice la función Nz(). Por ejemplo:

 

Dim ConvCero

ConvCero = Nz(txtNombres, 0)

MsgBox ConvCero

 

Un ejemplo para convertir a vacío:

Dim ConvVacio

ConvVacio = IIf(IsNull(txtNombres), "", txtNombres)

MsgBox ConvVacio

 

Además de estos dos ejemplos, se considera muy eficiente la combinación de las funciones ‘Nz’ con la ‘Trim’, ya que esta última elimina espacios a la izquierda y/o derecha a la variable. Por ejemplo:

 

Verificar si una variable (o control) no está vacío:

If Trim(nz(txtNombres, "")) <> "" Then…

 

Al contrario, si queremos verificar si está vacío:

If Trim(nz(txtNombres, "")) = "" Then…

 

 

Solución 3:

Comprobar el valor , o sea, la entrada en la tabla. Asegurarse de que existe un valor válido. Aunque últimamente estoy utilizando mucho la opción anterior (Trim(nz…), considero ésta muy eficiente.

Quizás para algunos sea comprobando la longitud (Len) del campo, en este caso la cantidad de caracteres de una cadena, pero si está vacío, pudiera ocasionar el error 94 si no se tratase de un Variant, cuestión que tendríamos que tener en cuenta como en los ejemplos anteriores.

Sin embargo, con la propiedad ActualSize iríamos directamente a verificar el tamaño o longitud real del campo; además, el valor de una propiedad lleva implícito el tipo de datos.

Supongamos entonces que el campo ‘Nombres’ se encuentra en una tabla llamada ‘TablaNombres’.

 

Dim rst As New ADODB.Recordset

Dim cnn As New ADODB.Connection

Dim sizAct As Long

Set cnn = CurrentProject.Connection

 

rst.Open "SELECT * FROM TablaNombres", cnn, adOpenDynamic, adLockOptimistic

 

'para asegurarnos de que los datos están actualizados...

'salvamos

DoCmd.RunCommand acCmdSaveRecord

 

If rst.RecordCount > 0 Then

   sizAct = rst.Fields("Nombres").ActualSize

   MsgBox sizAct

   'If sizAct = 0 Then…

End If

 

De igual forma pudiéramos comprobar ese campo en toda la tabla, a través de un bucle:

 

If rst.RecordCount > 0 Then

   rst.MoveFirst

   Do While rst.EOF = False

       'Tamaño del dato en la fila actual

       sizAct = rst.Fields("Nombres").ActualSize

       MsgBox sizAct

'       If sizAct = 0 Then…

       rst.MoveNext

   Loop

End If

 

Interesante también es establecer a Sí las propiedades AllowZeroLength (PermitirLogitudCero) y Required (Requerido). Esto almacena una cadena de longitud cero en lugar del valor Nulo cuando se deja un campo en blanco, tanto al escribir una cadena de longitud cero, como al presionar la barra espaciadora, pero éste, solo se aplica a los campos de tipo texto, memorando e hipervínculo.

 

Algo más:

Hay quien dice que, al asignar una cadena vacía, antes de hacer esto:

Var = ""

 

es mejor:

Var = vbNullString

 

Se plantea que es más rápido y seguro, puesto que la constante vbNullString es una cadena estrictamente nula.

Lo cierto es que, si el tipo de datos es numérico, vbNullString lo convierte en Nulo y, si es String (de texto), lo convierte en cadena vacía (""). 

 

 

 

[Atrás]