Translate

miércoles, 14 de agosto de 2013

Formulario de entrada para hoja de excell: Macros en Visual Basic

Imaginemos una hoja de excell para la que queramos que un usuario dado pueda meter datos a partir de un formulario. La idea es presentar ese formulario donde meter los datos de manera que pulsando un botón en dicho formulario se pasen los datos a una tabla en la hoja de excell.

Necesitaremos crear un formulario parecido a este, los campos pueden ser validados de manera que solo se metan los datos correctos y/o seleccionar los datos de lista desplegables.


En este ejemplo el formulario está en la hoja "Ficha Entrada" del excell y tiene 4 botones asociados cada uno a una macro escrita en Visual Basic y que harían las siguientes tareas:

  • Hoy: Coloca la fecha del día en el campo fecha.
  • Ayer: Coloca la fecha de ayer.
  • Borrar datos: Borra todos los campos y pone los importes a cero.
  • Grabar: Comprueba que no falta la fecha, la Partido y que de Ingreso/Gasto se haya metido uno de los dos, con sus dos campos Concepto e Importe rellenados.
Una vez grabados los datos se pasan a otra hoja del mismo libro llamada "Registros", donde los datos se muestras de manera tabular. De esta hoja se podrán obtener consultas, gráficas, etc...


Hacer notar aquí que los datos se añaden por arriba, es decir la última fila de datos entrada es la primera, en esta caso la fila 4, se mantiene siempre la fila 3 vacía. Esto es así primero por comodidad, y segundo y más importante, para que las fórmulas que hagan cálculos sobre esta fila no sean modificadas automáticamente por excell cada vez que inserte una línea. Por ejemplo, imagina que tengo una fórmula que suma el total de la columna D. La formula que sumara debería ser SUMA(D3:D10000), si inserto una línea en la posición 3, para luego pegar ahí los datos del formulario, la fórmula será modificada automáticamente por SUMA(D4:D1000), y por lo tanto el dato añadido no será sumado. 
Si inserto en la 4 teniendo el rango de suma entre 3 y 10000, ese problema no se da.

Para poder poner botones en el formulario creado necesito agregar a la barra de herramientas el botón de control de formulario, para ello vamos al menú Archivo, Opciones y a Barra de herramientas de acceso rápido. dentro de los Comandos disponibles cogeremos la opción Todos los Comandos y en la lista de la izqda buscaremos el botón mencionado, lo seleccionamos y pulsamos a agregar y después a aceptar.



Una vez añadido el botón aparecerá en la barra superior izquierda. Pulsamos sobre el y podremos dibujar un contorno cuadrado que será el botón en sí. Una vez soltemos el ratón aparece el botón y un cuadro de diálogo donde se pide el nombre del botón, lo ponemos y pulsamos nuevo para crear la macro asociada al botón donde escribiremos el código asociado.


Si queremos mover o redimensionar el botón simplemente hacemos clic sobre el con el botón derecho (con el izqdo lanza la macro) y podremos hacerlo. También sale un menú con el que asignar macro, etc...

Ahora llega el turno de crear las macros. Se puede hacer de manera manual desde el menú Vista, Macros y  Grabar Macros, de manera que en el momento que hacemos clic ahí todos los pasos que hagamos sobre la hoja se graban de manera secuencial, hasta que en el mismo sitio pulsemos en Detener la grabación.
La otra forma de hacer y que te da mas control y mas posibilidades es programar a mano, eso si, necesitarás algo de conocimientos de programación para poder hacerlo. Para ello en el mismo menú anterior cogeremos la opción Ver Macros que nos muestra una pantalla donde aparecerá el macro antes creado cuando pusimos el botón. Lo seleccionamos y pulsamos sobre Modificar y se abrirá el Intérprete (es básic) de Visual Basic.




Esta misma operación se repetirá para cada botón, creando el código correspondiente para cada uno de ellos.
El código de cada botón será:

Botón Hoy


        Sheets("Ficha Entrada").Select
        Application.CutCopyMode = False
        Range("E3").Select
        ActiveCell.FormulaR1C1 = Date


Botón Ayer

        Sheets("Ficha Entrada").Select
        Application.CutCopyMode = False
        Range("E3").Select
        ActiveCell.FormulaR1C1 = Date - 1

Botón Borrar Datos

Hacer notar aquí que la forma de acceder a una celda puede ser mediante Range o mediante Cells al gusto de cada uno. En estos tres botones está hecho usando Range, en el último mediante Cells.

        Sheets("Ficha Entrada").Select
        Application.CutCopyMode = False
        Range("E3").Select
        ActiveCell.FormulaR1C1 = ""
        Range("E5").Select
        ActiveCell.FormulaR1C1 = ""
        Range("E9").Select
        ActiveCell.FormulaR1C1 = ""
        Range("G9").Select
        ActiveCell.FormulaR1C1 = "0"
        Range("I9").Select
        ActiveCell.FormulaR1C1 = ""
        Range("E13").Select
        ActiveCell.FormulaR1C1 = ""
        Range("G13").Select
        ActiveCell.FormulaR1C1 = "0"
        Range("I13").Select
        ActiveCell.FormulaR1C1 = ""

Botón Grabar

    Dim sigue As Boolean
    sigue = True
    
    'Compruebo que se ha metido la fecha
    Dim fecha As String
    fecha = Range("E3").Value
    
    If fecha = "" Then
        sigue = False
        MsgBox "No has puesto la FECHA del registro.", vbOKOnly, "Grabación Registro"
    End If
    
    'Compruebo que se ha metido el objeto
    If sigue Then
        Dim objeto As String
        objeto = Range("E5").Value
        If objeto = "" Then
            sigue = False
            MsgBox "No has seleccionado el OBJETO del registro.", vbOKOnly, "Grabación Registro"
        End If
    End If 'del sigue
    
    
    'Compruebo hay al menos uno de los campos ingreso o gasto y su correspondiente importe.
    If sigue Then
        Dim ingreso As Integer
        Dim gasto As Integer
        ingreso = 0
        gasto = 0
        Dim ConceptoI As String
        Dim ImporteI As Double
        Dim ConceptoG As String
        Dim ImporteG As Double
    
        ConceptoI = Range("E9").Value
        If ConceptoI <> "" Then
            ingreso = ingreso + 1
        End If
        
        ImporteI = Range("G9").Value
        If ImporteI <> 0 Then
            ingreso = ingreso + 1
        End If
    
        ConceptoG = Range("E13").Value
        If ConceptoG <> "" Then
            gasto = gasto + 1
        End If
        
        ImporteG = Range("G13").Value
        If ImporteG <> 0 Then
            gasto = gasto + 1
            'Lo pongo en negativo si no lo está
            If ImporteG > 0 Then
                Range("G13").Value = ImporteG * -1
            End If
        End If
        
        ' Para continuar ingreso o gasto debe ser 2 y el otro 0
        If (ingreso = 2 And gasto = 0) Or (ingreso = 0 And gasto = 2) Then
            sigue = True
        Else
            MsgBox "Revisa los conceptos e importes de ingresos y gastos", vbOKOnly, "Grabación de datos"
        End If
    End If 'del if sigue
  
    'Si todo está correcto, entonces grabo
    If sigue Then
        'Inserta fila completa en la posicion 4 al principio
        'Para evitar que las fórmulas cambién es necesario tener la fial 3 siempre vacia
        ' ya que es donde empieza el rango de la fórmulas
        Sheets("Registros").Select
        Rows("4:4").Select
        Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
        
        'Para evitar que parpadee la imagen
        Application.ScreenUpdating = False
        
        'Transfiero los datos del formulario en la hoja "Ficha Entrada" a la hoha "registros"
        Sheets("Registros").Select
        
        'Puedes usar Range o Cells para coger los datos como más te guste
        Range("A4").Value = Sheets("Ficha Entrada").[E3]
        'En este caso Range("A4") es igual a Cells(4,1)
        Cells(4, 2).Value = Sheets("Ficha Entrada").[E5]
        Cells(4, 9).Value = Sheets("Ficha Entrada").[I5]
        Cells(4, 3).Value = Sheets("Ficha Entrada").[E9]
        Cells(4, 4).Value = Sheets("Ficha Entrada").[G9]
        Cells(4, 5).Value = Sheets("Ficha Entrada").[I9]
        Cells(4, 6).Value = Sheets("Ficha Entrada").[E13]
        Cells(4, 7).Value = Sheets("Ficha Entrada").[G13]
        Cells(4, 8).Value = Sheets("Ficha Entrada").[I13]
                                
        'Vuelvo a ficha de entrada e inicializo los campos.
        Sheets("Ficha Entrada").Select
        Cells(3, 5).Value = ""
        Cells(5, 5).Value = ""
        Cells(9, 5).Value = ""
        Cells(9, 7).Value = "0"
        Cells(9, 9).Value = ""
        Cells(13, 5).Value = ""
        Cells(13, 7).Value = "0"
        Cells(13, 9).Value = ""
        
        MsgBox "registro grabado correctamente", vbOKOnly, "Grabación de datos"
        
        'Me situo en el campo fecha
        Range("E3").Select
        
        'Para evitar que parpadee la imagen se restituye
        Application.ScreenUpdating = True
        
    Else
        MsgBox "NO SE HA GRABADO EL REGISTRO", vbOKOnly, "Grabación de datos"
    End If





No hay comentarios: