Este artículo pertenece a nuestra serie dedicada a UserForms. Si es el primero que has visto, te sugiero iniciar por la primera entrega: Introducción a UserForms

Artículo anterior: UserForms | Casillas de Selección

En la continuación de nuestra serie de artículos dedicados a UserForms, vamos trabajar sobre la integridad de nuestros datos, controlando el tipo de ingreso que un usuario puede hacer sobre los distintos campos de texto.

Cuando manejamos, creamos y mantenemos bases de datos, de cualquier tamaño y complejidad, uno de nuestros primeros y principales intereses es cuidar la integridad de los datos. Esto significa, entre otros aspectos, que cada uno de los campos siga una lógica establecida y predecible, sobre la que luego podamos realizar análisis y extraer información.

Por ejemplo, en el UserForm que venimos desarrollando, puede ocurrir que el usuario no sepa qué ingresar en el campo Edad:


Desde luego, si por ejemplo más tarde necesitamos extraer esta información y operar con ella (por ejemplo, podríamos querer estimar un promedio de las edades de los usuarios), Excel tendría grandes dificultades para interpretar correctamente el “valor” "treinta", y de integrarlo con otros números. Afortunadamente, con la ayuda de un poco de código y los controles de formulario, podemos mantener controlada esta situación y lograr que el usuario solo pueda ingresar números (¡aunque presione cualquier tecla!). Veamos cómo.

El código que vamos a desarrollar es el siguiente:

Private Sub txtEdad_Change()
Dim Texto As Variant
Dim Largo As Integer
Dim i As Integer
Dim Caracter As Variant
Texto = Me.txtEdad.Value
Largo = VBA.Len(Texto)
For i = 1 To Largo
Caracter = Mid(VBA.CStr(Texto), i, 1)
If Caracter < VBA.Chr(48) Or Caracter > VBA.Chr(57) Then
Texto = VBA.Replace(Texto, Caracter, "")
Me.txtEdad.Value = Texto
End If
Next i
End Sub

Parece complicado, ¿verdad? Prometo que valdrá la pena. Vamos analizando poco a poco en qué consiste:

  • Hemos declarado cuatro variables que utilizaremos en nuestro código:
    • Texto (que será el valor propiamente ingresado en el UserForm por el usuario)
    • Largo (que será el largo o cantidad de caracteres del valor ingresado en el UserForm, y cuya cantidad determinamos para luego iterar a lo largo del mismo)
    • i, una variable numérica que nos servirá para identificar cada una de las posiciones de los sucesivos caracteres de la variable Texto, iniciando por 1 como es lógico, hasta el final (el valor de Largo)
    • Caracter, que es el valor que asume el carácter de Texto en la posición i.
  • Empezamos por asignar las variables que serán fijas cada vez que se ejecute la subrutina en cuestión:

Texto = Me.txtEdad.Value

Largo = VBA.Len(Texto)

    • Recuerda que la propiedad VBA.Len nos permite obtener la cantidad de caracteres de su argumento, es decir, la previamente asignada “Texto”.
  • Luego, crearemos un ciclo For… Next, que realice una iteración a lo largo de cada carácter de la cadena de Texto, recorriendo los caracteres y verificando una condición (que veremos en el siguiente paso).
    • Sabemos el inicio: el primer carácter, que siempre valdrá 1. Sin embargo, la extensión puede variar y por lo tanto nos valemos de la variable Largo creada para saber cuál es el último carácter, y por lo tanto la última repetición que deberá hacer el ciclo. Con cada iteración, aumentaremos en +1 el valor de i, que es la posición de cada carácter en la cadena ingresada en el TextBox.

For i=1 To Largo

(…)

Next i

    • Para cada ciclo realizado, queremos asignar a la variable i, el valor del carácter que ocupa esta posición:

Caracter = Mid(VBA.CStr(Texto), i, 1)

    • La función Mid permite extraer de una cadena de texto (primer argumento), a partir de una posición inicial (segundo argumento), una porción de la cadena de extensión dada (por el tercer argumento). En este caso, nos interesa extraer de Texto, el carácter (uno solo), que ocupa la posición i. El método CStr nos ayuda a convertir cada carácter en un string, para luego trabajar con él.
  • Lo que queremos realizar ahora, es una verificación sobre el carácter extraído. Lo que nos interesa es únicamente si se trata de un número o no. Hay distintas formas de lograrlo, pero te propongo una que tal vez aún no conozcas: localizar la posición del carácter en la codificación ASCII (American Standard Code for Information Interchange), que puedes verificar en este enlace: https://elcodigoascii.com.ar/.
    • Este código asigna a cada carácter y símbolo un determinado valor. Si observas la tabla del enlace anterior, los valores numéricos del 0 al 9 ocupan las posiciones 48 a 57 en este estándar. La forma de obtener el equivalente en ASCII de un carácter cualquiera dado, es mediante la función VBA.Chr. Con una estructura condicional If, podemos verificar si el carácter según ASCII, NO se encuentra comprendido entre la posición 48 y 57 (y por lo tanto, no sería un número, y queremos deshacernos de él):

If Caracter < VBA.Chr(48) Or Caracter > VBA.Chr(57) Then

(…)

End If

  • De verificarse la condición anterior como verdadera, ¡quiere decir que el carácter i NO es un número! Gran avance.
  • Finalmente, lo que queremos lograr es borrar los caracteres que no sean números, dejando aquellos que sí lo sean, inalterados. Esto lo podemos lograr con la función VBA.Replace, reemplazando el carácter i (no-número), por “nada”. Para ello, asignamos la variable Texto a sí misma, pero modificada:

Texto = VBA.Replace(Texto, Caracter, "")

    • Y finalmente cargamos esta variable en el TextBox:

Me.txtEdad.Value = Texto

    • Con esto, finaliza nuestra estructura If, la iteración, y vuelve a ejecutarse todo hasta recorrer todo el texto.

De esta forma, por ejemplo, si el usuario ingresa: “treinta” en el formulario, queremos que la variable Texto sea precisamente toda la cadena, “treinta”, el Largo será de 7, y al iterar con i, cuando esta valga por ejemplo 6, queremos que Carácter almacene el valor “t”, el sexto carácter de la cadena. ¡Tómate unos segundos para reflexionarlo!

Si al código anterior lo asignamos al evento Change, asociado al txtEdad, lograremos que cada tecla presionada por el usuario desencadene la ejecución de esta subrutina. Normalmente, será tan rápido que, desde la perspectiva del usuario, ni siquiera verá reflejadas en pantalla las teclas ingresadas que no sean valores numéricos. Es decir: no podrá ingresar valores de texto, símbolos o espacio: ¡solo números!

Trabaja y experimenta sobre el archivo que hemos trabajado en esta oportunidad: Descargar el Libro con el UserForm

¡Continuamos la próxima semana!

Siguiente artículo:

Configuración de los campos de texto