VALORES NULOS ACCESS

16- Valores Nulos

 

Autor: Medardo Santana, desde Ciudad de La Habana, Cuba

 

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]