24 septiembre, 2023

GRABAR REGISTROS EN EXCEL CON UN FORMULARIO Y VBA

Hola a todos!.

Hace unos días me pedían que escribiese un post explicando como grabar registros a través de un formulario (userform) en excel con en el editor de VBA.

Bien, aunque tenéis un ejemplo excelente en esta web que se denomina «Gestión de Clientes» donde además de grabar registros, los modifico, los exporto y los elimino. Creo que es interesante hacer una parada y analizar detenidamente el código que os voy a proponer.

Antes de realizar la programación conviene diseñar el formulario, sobre este punto no me voy a extender, para este ejemplo usaré un userform con 6 textbox y un botón de comando:

Serán los siguientes campos: el ID, Nombre, Primer Apellido, Segundo Apellido, Ciudad y Último ID (aunque los campos que se grabarán serán los 5 primeros).

Para dotar de funcionalidad al formulario vamos a incorporar el siguiente código al evento click del botón de comando:

Option Explicit
Private Sub CommandButton1_Click()
    'Declaramos variables
    Dim i           As Long, j As Long, Dupli As Long, control As Variant
    With ThisWorkbook.Sheets("Hoja1")
        i = Application.CountA(.Range("A:A")) + 1
        Dupli = Application.WorksheetFunction.CountIf(.Range("A1:A" & i), ALTAS.TextBox1)
        'Si el campo ID no es numérico o está vacio, salimos del proceso
        If ALTAS.TextBox1 = "" Or Not IsNumeric(ALTAS.TextBox1) Then
            MsgBox ("EL CAMPO ID DEBE SER NUMÉRICO Y NO ESTAR VACÍO"), vbCritical, "CAMPO ID"
            Exit Sub
        End If
        'Si existen duplicados salimos del proceso
        If Dupli > 0 Then
            MsgBox ("YA EXISTE EL MISMO ID EN LA Base DE DATOS"), vbCritical, "ID DUPLICADO"
            Exit Sub
        End If
        'Grabamos los datos del formulario
        For j = 1 To 5
            .Cells(i, j) = UCase(Me.Controls("Textbox" & j))
        Next
        'Borramos todos los textbox
        For Each control In Me.Controls
            If TypeName(control) = "TextBox" Then control.Text = Empty
        Next
        ALTAS.TextBox6 = .Cells(i, 1).Value
    End With
End Sub

y este otro código en el formulario dentro del evento Activate:

Private Sub UserForm_Activate()
    Dim i           As Long
    With ThisWorkbook.Sheets("Hoja1")
        i = Application.CountA(.Range("A:A"))
        ALTAS.TextBox6 = IIf(i > 1, .Cells(i, 1).Value, "")
    End With
End Sub

Ahora vamos a analizar detenidamente el código: Antes de proceder a realizar la grabación de los datos es importante tener en cuenta qué es lo que no debemos grabar:

  • Registros sin ID.
  • Registros con ID no numéricos.
  • Registros con ID duplicados.

Para esto utilizaremos las siguientes líneas de código. Para identificar si el campo ID está vacío o no es numérico lo haremos con esta sencilla condición:

If ALTAS.TextBox1 = "" Or Not IsNumeric(ALTAS.TextBox1) Then
            MsgBox ("EL CAMPO ID DEBE SER NUMÉRICO Y NO ESTAR VACÍO"), vbCritical, "CAMPO ID"
            Exit Sub
        End If

Para verificar si el ID que vamos a grabar está duplicado utilizaremos este código:

Dupli = Application.WorksheetFunction.CountIf(.Range("A1:A" & i), ALTAS.TextBox1)
        If Dupli > 0 Then
            MsgBox ("YA EXISTE EL MISMO ID EN LA Base DE DATOS"), vbCritical, "ID DUPLICADO"
            Exit Sub
        End If

Así es, estamos contando las veces que existe el registro que vamos a grabar, si es superior a 0, salimos del proceso y mostramos mensaje.

Una vez que pasamos estos filtros procedemos a grabar la información:

For j = 1 To 5
            .Cells(i, j) = UCase(Me.Controls("Textbox" & j))
        Next

En este caso como serán los 5 primeros textbox a grabar y además se sitúan en columnas consecutivas, podemos programar la grabación en un loop.

A continuación para dejar en blanco los textbox utilizaremos otra rutina:

For Each control In Me.Controls
            If TypeName(control) = "TextBox" Then control.Text = Empty
        Next

y finalmente, el textbox 6 que nos va a mostrar el último ID que se ha grabado, para poder ponerlo en el textbox1 en el siguiente registro que se grabe.

ALTAS.TextBox6 = .Cells(i, 1).Value

Por último, el código que incluimos en el formulario en el evento «activate»:

Private Sub UserForm_Activate()
    Dim i           As Long
    With ThisWorkbook.Sheets("Hoja1")
        i = Application.CountA(.Range("A:A"))
        ALTAS.TextBox6 = IIf(i > 1, .Cells(i, 1).Value, "")
    End With
End Sub

Es para mostrar continuamente el contenido del textbox6.

Esta es una muestra de la grabación:

Y esto es todo, espero que os sea de utilidad. Este sistema es válido para grabar cualquier elemento, ya sean clientes, empleados, o materiales de un inventario.

¿Te ha resultado de interés?, puedes apoyar a Excel Signum con una pequeña donación.

Donate Button with Credit Cards

¡¡Muchas gracias!!

Mediante la suscripción al blog, la realización comentarios o el uso del formulario de contacto estás dando tu consentimiento expreso al tratamiento de los datos personales proporcionados según lo dispuesto en la ley vigente (LOPD). Tienes más información al respecto en esta página del blog: Política de Privacidad y Cookies

Comparte este post

4 comentarios en «GRABAR REGISTROS EN EXCEL CON UN FORMULARIO Y VBA»

  1. Hola, muy buen ejemplo, solo aclarando que los textbox deben de llevar el correlativo Textbox1,Textbox2,Textbox3… ya que si eliminas uno por error y agregar otro se saltaria el correlativo y la macro no funcionaria correctamente. o estare equivocado?

    1. Hola Carlos:

      Efectivamente, el formulario está diseñado para descargar los datos en columnas consecutivas. Una vez que tenemos la posibilidad de diseñar nuestro propio proceso podemos hacerlo a medida. Así se puede programar la grabación de todo el contenido con un loop en unas pocas líneas, evitando así el tener que estar igualando el contenido de cada textbox a cada columna de forma independiente. (esto lo hago, por ejemplo en Gestión de clientes (post), pero para este he decidido compartir cómo suelo hacerlo y diseñarlo en mis proyectos.

      Como todo, requiere análisis previo para montarlo y programarlo, pero jugando con el inicio y fin del for se puede sincronizar con cualquier text vox consecutivo. Si no se desea, utilizar el método más habitual igualando textbox a cada fila de cada columna.

      Espero haberte contestado. Saludos

      1. Me parece muy interesante y me ha servido de mucho. Una pregunta, ¿se podría pasar de un registro completado a uno en blanco sin necesidad de hacer CLICK en el CommandButton?

Si te ha gustado o tienes alguna duda, puedes dejar aquí tu comentario.

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies