Validación de datos
Hacer una macro o programa libre de errores no es un tema menor y cuanto más grande sea el código, la probabilidad de que presente errores aumenta considerablemente.
Una fuente frecuente de errores son los propios datos con que un usuario alimenta a un programa. Por supuesto, es nuestra responsabilidad como programadores minimizar este tipo de errores.
Para lograrlo deberemos filtrar los datos que el usuario introduce, es decir validar los datos.
La validación de datos consume muchas líneas de código, a veces, muchas más que el proceso en si, por ello es un tema muy importante en programación. OOo Basic cuenta con algunas funciones que nos ayudan a validar datos. Veamos algunas de ellas, teniendo en cuenta que son sólo guías, pues las opciones son tantas y tan variadas como programadores las implementen.
Conversión de tipos
Para el mejor aprovechamiento de este tema, tienes que saber que los lenguajes Basic son muy nobles en la conversión de datos de un tipo a otro; muchas de estas conversiones las puede hacer el lenguaje de forma directa, lo que se conoce como conversión implícita. Sin embargo es más recomendable que las controlemos desde nuestro código, siempre que sea posible, lo que se conoce como conversión explicita. Para conseguirlo nos apoyamos en varias funciones de OOo Basic.
Por ejemplo, la instrucción MsgBox requiere un argumento llamado Mensaje de tipo String (cadena de texto).
<nowiki>MsgBox Mensaje As String, [Tipo As Integer], [Titulo As String]</nowiki>
Veamos el siguiente ejemplo:
Option Explicit
Sub Mensajes1()
Dim dFecha As Date
Dim iNumero As Integer
dim bOpcion As Boolean
dFecha <nowiki>=</nowiki> DateSerial(74,1,15)
iNumero <nowiki>=</nowiki> 2008
bOpcion <nowiki>=</nowiki> True
MsgBox dFecha
MsgBox iNumero
MsgBox bOpcion
End Sub
Aunque le pasemos un número, una fecha o incluso un valor booleano, la instrucción MsgBox sigue trabajando, ya que el lenguaje realiza internamente (de forma implícita) una conversión de tipos; mientras le sea posible, el propio lenguaje convierte el argumento del tipo que recibe al tipo requerido (string). Lo ideal es que nosotros realicemos esta conversión de forma explicita, como en el siguiente ejemplo:
Sub Mensajes2()
Dim dFecha As Date
Dim iNumero As Integer
dim bOpcion As Boolean
dFecha <nowiki>=</nowiki> DateSerial(74,1,15)
iNumero <nowiki>=</nowiki> 2008
bOpcion <nowiki>=</nowiki> True
MsgBox '''CStr'''( dFecha )
MsgBox '''CStr'''( iNumero )
MsgBox '''CStr'''( bOpcion )
End Sub
En el ejemplo hacemos uso de la función CStr(valor) que convierte el tipo del argumento valor a una cadena de texto (String). De esta forma, casi podemos asegurar que no se producirá un error inesperado.
Conversión de variables
OOo Basic cuenta con funciones para convertir la mayoría de los tipos de variables.
CStr(valor) | Convierte a cadena de texto (String) |
CByte(valor) | Convierte a tipo Byte |
CInt(valor) | Convierte a tipo entero (Integer) |
CLng(valor) | Convierte a tipo entero largo (Long) |
CSng(valor) | Convierte a tipo simple (Single) |
CDbl(valor) | Convierte a tipo doble (Double) |
CBool(valor) | Convierte a tipo booleano (Boolean) |
CDate(valor) | Convierte a tipo fecha (Date) |
Conocer el tipo de dato contenido
OOo Basic cuenta con otras funciones que nos ayudan a conocer qué tipo de dato contiene una variable:
Cuando necesites saber si una variable contiene un número usamos IsNumeric.
Option Explicit
Sub EsNumero()
Dim sDato As String
sDato <nowiki>=</nowiki> Trim( InputBox( "Introduce un numero" ) )
If '''IsNumeric'''( sDato ) Then
MsgBox "Es un numero"
Else
MsgBox "No es un numero"
End If
End Sub
Cuando necesites saber si una variable contiene una fecha usamos IsDate.
Sub EsFecha()
Dim sDato As String
sDato <nowiki>=</nowiki> Trim( InputBox( "Introduce una fecha" ) )
If '''IsDate'''( sDato ) Then
MsgBox "Es una fecha"
Else
MsgBox "No es una fecha"
End If
End Sub
Y cuando necesites saber si una variable es una matriz usamos IsArray.
Sub EsMatriz()
Dim mDato As Variant
If '''IsArray'''( mDato() ) Then
MsgBox "Es una matriz"
Else
MsgBox "No es una matriz"
End If
mDato <nowiki>=</nowiki> Array(1,2,3,4,5)
If '''IsArray'''( mDato() ) Then
MsgBox "Es una matriz"
Else
MsgBox "No es una matriz"
End If
End Sub
Ejemplos de validaciones
Veamos algunos ejemplos de validaciones comunes como referencia; no son todas las posibles, ya que deberás adaptarlas y complementarlas según tus necesidades.
- El usuario introduce un dato y validamos que no sea una cadena vacía.
Sub Validar1()
Dim sDato As String
Dim bSalir As Boolean
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce los datos") )
If sDato <nowiki><></nowiki> "" Then
bSalir <nowiki>=</nowiki> True
End If
Loop Until bSalir
End Sub
En el ejemplo anterior aún si el usuario presiona Cancelar de nuevo le invitamos a introducir un dato. Sin embargo, lo habitual es proporcionar siempre al usuario una forma de cancelar un proceso.
Sub Validar2()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce los datos") )
If sDato <nowiki><></nowiki> "" Then
'Aquí va tu código para manipular los datos
bSalir <nowiki>=</nowiki> True
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no escribiste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
- Ahora el usuario introduce una cadena de texto, y validamos que no sea número ni fecha.
Sub Validar3()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce los datos") )
If sDato <nowiki><></nowiki> "" Then
If Not(IsDate(sDato)) And Not(IsNumeric(sDato)) Then
'Aquí va tu código para manipular los datos
MsgBox "Es una cadena" & Chr(13) & Chr(13) & sDato
bSalir <nowiki>=</nowiki> True
Else
MsgBox "Valor NO valido"
End If
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no escribiste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
- Que sólo introduzca números.
Sub Validar4()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce un numero") )
If sDato <nowiki><></nowiki> "" Then
If IsNumeric(sDato) Then
'Aquí va tu código para manipular los datos
MsgBox "Es un numero" & Chr(13) & Chr(13) & sDato
bSalir <nowiki>=</nowiki> True
Else
MsgBox "Valor NO valido"
End If
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no escribiste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
- Que introduzca una fecha.
Sub Validar5()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce una fecha") )
If sDato <nowiki><></nowiki> "" Then
If IsDate(sDato) Then
'Aquí va tu código para manipular los datos
MsgBox "Es una fecha" & Chr(13) & Chr(13) & sDato
bSalir <nowiki>=</nowiki> True
Else
MsgBox "Valor NO valido"
End If
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no capturaste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
- Un número, con un rango definido (por ejemplo entre 50 y 100).
Sub Validar6()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce un numero") )
If sDato <nowiki><></nowiki> "" Then
If IsNumeric(sDato) And Val(sDato)>=50 And Val(sDato)<nowiki><=100</nowiki> Then
'Aquí va tu código para manipular los datos
MsgBox "Es un numero, en el rango 50-100" & Chr(13) & Chr(13) & sDato
bSalir <nowiki>=</nowiki> True
Else
MsgBox "Valor NO valido"
End If
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no capturaste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
- Una fecha que no sea fecha futura.
Sub Validar7()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce una fecha") )
If sDato <nowiki><></nowiki> "" Then
If IsDate(sDato) Then
If CDate(sDato) <nowiki><=</nowiki> Date() Then
'Aquí va tu código para manipular los datos
MsgBox "Es una fecha valida" & Chr(13) & Chr(13) & sDato
bSalir <nowiki>=</nowiki> True
Else
MsgBox "Es una fecha futura"
End If
Else
MsgBox "Valor NO valido"
End If
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no capturaste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
- Pedimos al usuario que introduzca solo vocales, validando para que no introduzca otra cosa.
Sub Validar8()
Dim sDato As String
Dim bSalir As Boolean
Dim iRes As Integer
Dim co1 As Integer
Dim sLetra As String
Dim sTmp As String
Dim pos As Integer
Do
sDato <nowiki>=</nowiki> Trim( InputBox("Introduce solo vocales") )
If sDato <nowiki><></nowiki> "" Then
If Not(IsDate(sDato)) And Not(IsNumeric(sDato)) Then
'Aquí va tu código para manipular los datos
For co1 <nowiki>=</nowiki> 1 To Len(sDato)
'Tomamos una por una cada letra capturada
sLetra <nowiki>=</nowiki> Mid(sDato,co1,1)
'Averiguamos si es una vocal mayúscula o minúscula
pos <nowiki>=</nowiki> InStr(1,"aeiouAEIOU",sLetra)
'Si encuentra la letra en la lista de vocales InStr te
'devuelve la posición, con que sea mayor a cero sabemos
'que ha sido encontrada
If pos > 0 Then
sTmp <nowiki>=</nowiki> sTmp & sLetra
End If
Next
MsgBox sTmp
bSalir <nowiki>=</nowiki> True
Else
MsgBox "Valor no valido"
End If
Else
iRes <nowiki>=</nowiki> MsgBox( "Parece que no capturaste nada, ¿Deseas salir?", 32 + 4, "Salir" )
If iRes <nowiki>=</nowiki> 6 Then
bSalir <nowiki>=</nowiki> True
End If
End If
Loop Until bSalir
End Sub
En esta macro tenemos dos nuevas instrucciones de OOo Basic: Mid, que nos sirve para extraer una cadena de otra, e InStr que encuentra la posición de una cadena en otra.
Conclusión
La validación combinada con el control de errores minimizan el riesgo de fallos en las aplicaciones, si no en un 100%, en un porcentaje bastante alto.
Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO, o quieres ampliar la información, no dudes en dirigirte al Foro Oficial en español de Apache OpenOffice para Macros y API UNO |