lunes, 26 de noviembre de 2012

VBA: Barra de progreso con formulario.

Hoy toca un ejercicio con formularios (UserForm) y un poco de código VBA para conseguir que se muestre una barra de progreso proporcional al avance en la ejecución de una procedimiento.
El procedimiento consistirá en una sencilla macro que introduce hasta 24 valores correlativamente en la columna B de la hoja 1, y según avanza se muestra una barra de progreso porcentual.

Lo primero que haremos será construir nuestro formulario (UserForm) que será el que mostrará el avance porcentual del procedimiento.
Para ello insertamos un UserForm (que llamaremos 'FrmProg'), en el cual incluiremos lo siguiente. Tres etiquetas (labels) y un botón (CommandButton):
Etiq2 con Caption 'Numeración' (es una etiqueta literal, sin más)
EtiquetaProg con Caption 'Avance%' (es una etiqueta literal, sin más)
EtqAncho será la que modificaremos mediante programación para ir cambiándole la propiedad Width (Ancho) y represente el grado de avance
CmdCerrar botón (CommandButton) con Caption 'Cancelar proceso' que servirá para cancelar y detener el proceso.


Veamos la imagen del formulario, con la etiqueta 'EtqAncho' seleccionada, y su ventana Propiedades activa:

VBA: Barra de progreso con formulario.


Importante de esta etiqueta 'EtqAncho' son las propiedades de inicio:
Width = 0
BackColor = &H000000FF& (color rojo... para que resalte, podemos poner el color que queramos).


Asignamos funcionalidad al formulario, para ello haciendo doble clic en el CommandButton 'Cancelar proceso' e insertamos el código siguiente asociado a un evento Click :

Private Sub CmdCerrar_Click()
    'damos valor 1 a la variable pública definida
    CancelIt = 1
End Sub



Continuamos insertamos el siguiente código VBA en un módulo del Explorador de proyectos VBA:

Public CancelIt As Integer
Sub BarraAvance()
    'activamos la Hoja1
    'y limpiamos la columna B
    Sheet1.Activate
    Sheet1.Range("B:B").ClearContents
    Sheet1.Range("B1").Value = "Numeración..."
    'Damos valor a una constante que servirá para Salir del formulario y Proceso
    CancelIt = 0
    'Cuando un UserForm es modal, parámetro 0
    'el usuario debe responder antes mediante cualquier otra parte de la aplicación.
    'El código no subsiguiente se ejecuta hasta que se oculta o descarga el UserForm.
    'Aunque en la aplicación otros formularios estén deshabilitados cuando se muestra un UserForm,
    'otras aplicaciones no lo están.
    FrmProg.Show 0
    'Aseguramos que las etiquetas en el formulario (futurass barras) comienzan con un texto vacío...
    FrmProg.EtiquetaProg.Caption = ""
    'y un ancho de barra 0 para el grado de avance
    FrmProg.EtqAncho.Width = 0
    'El método Repaint es útil si el contenido o la apariencia de un objeto cambia de forma significativa
    'y no quieres esperar hasta que el sistema vuelva a dibujar el área automáticamente.
    FrmProg.Repaint
    'elijo el valor 24 que son +/- las filas visibles en pantalla
    totalfilas = 24
    
    For i = 1 To totalfilas
        'Recorremos el totalfilas asignando un valor
        Sheet1.Range("B1").Offset(i, 0).Value = i
        'Definimos el ancho de la barra de avance
        'en función al ancho de la etiqueta del formulario = 342
        AnchoNuevo = (i * (342 - 4)) / totalfilas
        'Asociamos los nuevos valores al formulario
        FrmProg.EtiquetaProg.Caption = "Grado avance: " & Format(i, "0,0") & " / " & _
        Format(totalfilas, "0,0") & " (" & Format(i / totalfilas * 100, "0.00") & "%)"
        FrmProg.EtqAncho.Width = AnchoNuevo
        FrmProg.Etiq2.Caption = "Número: " & i
        FrmProg.Repaint
        
        For j = 1 To 5000
            'Cede el control de la ejecución al sistema operativo, para que éste pueda procesar otros eventos
            'La función DoEvents devuelve un tipo Integer que representa el número de formularios abiertos
            'por una versión independiente de Visual Basic.
            'DoEvents devuelve 0 en el resto de las aplicaciones.
            DoEvents
            If CancelIt = 1 Then GoTo Cancelado
        Next j
    Next
    
    GoTo Salida
Cancelado:
    MsgBox "Proceso cancelado por el usuario..."
    Sheet1.Range("B1").Offset(i + 1, 0).Value = "Cancelado."
Salida:
    Unload FrmProg
End Sub


Con este código conseguimos, por un lado ir insertando en la hoja (en la columna B) una serie de valores de 1 hasta 24, condicionado mediante un Msgbox a una cancelación anticipada (mediante el CommandButton 'Cancelar proceso').
Por otro lado modificamos la etiqueta de nuestro formulario 'EtqAncho' en cuanto a su propiedad Caption y su propiedad Width, que dará el efecto de avance.

Podemos asociar nuestra macro 'BarraAvance' a un botón en la hoja de cálculo, y ejecutarla. Veríamos lo siguiente:

VBA: Barra de progreso con formulario.


Como se puede apreciar, según el procedimiento 'BarraAvance' actúa, el ancho-Width de la etiqueta se actualiza, aí como el texto-Caption que aparece.

2 comentarios:

  1. Hola.Podrias enviarme el archivo de ejemplo? Mi mail es yea_new_fer@yahoo.com.ar Gracias!

    ResponderEliminar
    Respuestas
    1. Hola Fer,
      lamentablemente cambié de equipo hace poco y los viejos archivos quedaron en el olvido. De todas formas el fichero tendría exactamente lo que se muestra y explica en el post.

      Slds y lo siento

      Eliminar