Inicio / Excel / Excel Avanzado: Power User / VBA: eventos y automatización avanzada

VBA: eventos y automatización avanzada

Eventos de libro y hoja, temporizadores, emails y PDFs automáticos.

Avanzado
🔒 Solo lectura
📖

Estás en modo lectura

Puedes leer toda la lección, pero para marcar progreso, hacer ejercicios y ganar XP necesitas una cuenta Pro.

Desbloquear por $9/mes

VBA: eventos y automatización avanzada

Programa Excel para reaccionar automáticamente a acciones del usuario.

Eventos de libro (ThisWorkbook)

Al abrir el libro

Private Sub Workbook_Open()
    ' Ir al dashboard
    Sheets("Dashboard").Activate
    
    ' Actualizar datos
    ActiveWorkbook.RefreshAll
    
    ' Registro de uso
    Sheets("Log").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Value = Now
    Sheets("Log").Cells(Rows.Count, 1).End(xlUp).Offset(0, 1).Value = Environ("USERNAME")
End Sub

Antes de guardar

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    ' Actualizar fecha de última modificación
    Sheets("Config").Range("B1").Value = Now
    
    ' Ir a la primera hoja
    Sheets(1).Activate
    Range("A1").Select
End Sub

Antes de cerrar

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Dim resp As VbMsgBoxResult
    resp = MsgBox("¿Desea exportar el reporte antes de cerrar?", vbYesNo)
    
    If resp = vbYes Then
        Call ExportarReporte
    End If
End Sub

Eventos de hoja

Cambio de celda (Worksheet_Change)

Private Sub Worksheet_Change(ByVal Target As Range)
    ' Solo si cambia la columna A
    If Target.Column <> 1 Then Exit Sub
    If Target.Count > 1 Then Exit Sub  ' evitar pegado múltiple
    
    ' Registro automático de fecha/usuario
    Application.EnableEvents = False  ' evitar loop infinito
    
    Target.Offset(0, 5).Value = Now
    Target.Offset(0, 6).Value = Environ("USERNAME")
    
    Application.EnableEvents = True
End Sub

Validación en tiempo real

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("C2:C1000")) Is Nothing Then
        Application.EnableEvents = False
        
        If Not IsNumeric(Target.Value) And Target.Value <> "" Then
            MsgBox "Solo se permiten números", vbExclamation
            Target.ClearContents
            Target.Select
        ElseIf Target.Value < 0 Then
            MsgBox "No se permiten valores negativos", vbExclamation
            Target.ClearContents
        End If
        
        Application.EnableEvents = True
    End If
End Sub

Selección de celda (SelectionChange)

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    ' Resaltar fila y columna activa
    Cells.Interior.ColorIndex = xlNone
    
    If Target.Count = 1 Then
        Target.EntireRow.Interior.Color = RGB(230, 240, 255)
        Target.EntireColumn.Interior.Color = RGB(230, 240, 255)
    End If
End Sub

Temporizadores automáticos

Ejecutar cada X minutos

' En un módulo estándar
Dim proximaEjecucion As Date

Sub IniciarTemporizador()
    proximaEjecucion = Now + TimeValue("00:05:00")  ' cada 5 min
    Application.OnTime proximaEjecucion, "ActualizarDatos"
End Sub

Sub DetenerTemporizador()
    On Error Resume Next
    Application.OnTime proximaEjecucion, "ActualizarDatos", , False
    On Error GoTo 0
End Sub

Sub ActualizarDatos()
    ' Tu lógica de actualización
    ActiveWorkbook.RefreshAll
    Sheets("Config").Range("B2").Value = "Última actualización: " & Format(Now, "hh:mm:ss")
    
    ' Reprogramar
    Call IniciarTemporizador
End Sub

Automatizar emails con Outlook

Sub EnviarReportePorEmail()
    Dim olApp As Object
    Dim olMail As Object
    
    Set olApp = CreateObject("Outlook.Application")
    Set olMail = olApp.CreateItem(0)
    
    With olMail
        .To = "gerencia@empresa.com"
        .CC = "equipo@empresa.com"
        .Subject = "Reporte de ventas - " & Format(Date, "dd/mm/yyyy")
        .HTMLBody = "<h2>Reporte automático</h2>" & _
                    "<p>Total ventas: $" & Format(Range("B1").Value, "#,##0") & "</p>" & _
                    "<p>Ver archivo adjunto para detalle.</p>"
        .Attachments.Add ThisWorkbook.FullName
        .Display  ' o .Send para enviar directamente
    End With
    
    Set olMail = Nothing
    Set olApp = Nothing
End Sub

Automatizar exportación PDF

Sub ExportarHojasAPDF()
    Dim ws As Worksheet
    Dim ruta As String
    ruta = ThisWorkbook.Path & "\Reportes\"
    
    ' Crear carpeta si no existe
    If Dir(ruta, vbDirectory) = "" Then MkDir ruta
    
    For Each ws In ThisWorkbook.Worksheets
        If Left(ws.Name, 4) = "Rpt_" Then
            ws.ExportAsFixedFormat _
                Type:=xlTypePDF, _
                Filename:=ruta & ws.Name & "_" & Format(Date, "yyyymmdd") & ".pdf", _
                Quality:=xlQualityStandard
        End If
    Next ws
    
    MsgBox "PDFs exportados a: " & ruta
End Sub

Barra de progreso personalizada

Sub ProcesoConProgreso()
    Dim total As Long: total = 10000
    Dim i As Long
    
    For i = 1 To total
        ' Tu proceso
        Cells(i, 1).Value = i
        
        ' Actualizar barra cada 100 iteraciones
        If i Mod 100 = 0 Then
            Application.StatusBar = "Procesando... " & _
                Format(i / total, "0%") & " (" & i & "/" & total & ")"
            DoEvents  ' permite cancelar
        End If
    Next i
    
    Application.StatusBar = False  ' restaurar
End Sub

Resumen

Los eventos VBA convierten a Excel en una aplicación reactiva. Worksheet_Change para validación y logging, Workbook_Open para inicialización, y Application.OnTime para tareas programadas. Combina con automatización de Outlook y PDF para workflows completos.

🔒

Ejercicio práctico disponible

Simulación de eventos automáticos

Desbloquear ejercicios
// Simulación de eventos automáticos
// Desbloquea Pro para acceder a este ejercicio
// y ganar +50 XP al completarlo

function ejemplo() {
    // Tu código aquí...
}

¿Te gustó esta lección?

Con Pro puedes marcar progreso, hacer ejercicios, tomar quizzes, ganar XP y obtener tu constancia.

Ver planes desde $9/mes