¿Qué es una macro en Excel (VBA)?
VBA (Visual Basic for Applications) es el lenguaje de programación integrado en Excel que permite automatizar tareas repetitivas y manipular datos mediante código.
Sub MiPrimeraMacro()
' Todo el código va entre Sub y End Sub
MsgBox "¡Hola desde VBA!"
End Sub
Para abrir el editor VBA: presiona
Alt + F11.
Estructura básica
Sub NombreDeLaMacro()
' 1. Declarar variables
Dim miVariable As Integer
' 2. Lógica del programa
miVariable = 10
' 3. Resultado o acción
MsgBox miVariable
End Sub
Variables
| Tipos de datos principales | Asignación de valores |
|---|---|
| Dim n As Integer ' -32768 a 32767 | n = 42 |
| Dim l As Long ' entero grande | l = 1000000 |
| Dim d As Double ' decimal | d = 3.14 |
| Dim s As String ' texto | s = "Hola mundo" |
| Dim b As Boolean ' True / False | b = True |
| Dim dt As Date ' fecha | dt = #01/15/2025# |
| Dim v As Variant ' cualquier tipo |
Usa siempre Dim para declarar variables. Evita Variant cuando sepas el tipo: ocupa más memoria y es más lento.
Constantes y ámbito
' Constante: valor fijo que no cambia
Const PI As Double = 3.14159
' Variable de módulo (accesible en todas las Sub del módulo)
Dim contador As Integer ' al inicio del módulo, fuera de Sub
' Variable pública (accesible en todo el proyecto)
Public nombreApp As String
Condicionales
If / Then / Else
Dim nota As Integer
nota = 75
If nota >= 90 Then
MsgBox "Sobresaliente"
ElseIf nota >= 60 Then
MsgBox "Aprobado"
Else
MsgBox "Reprobado"
End If
Select Case
Ideal cuando hay múltiples condiciones sobre la misma variable.
Dim dia As Integer
dia = Weekday(Now)
Select Case dia
Case 1: MsgBox "Domingo"
Case 2: MsgBox "Lunes"
Case 3 To 6: MsgBox "Martes a Viernes"
Case 7: MsgBox "Sábado"
Case Else: MsgBox "Desconocido"
End Select
Operadores de comparación
' = igual <> distinto < menor > mayor
' <= menor o igual >= mayor o igual
' And (ambas) Or (una) Not (negación)
If x > 0 And x < 100 Then
' x está entre 0 y 100
End If
Bucles
For Next — repetir N veces
Dim i As Integer
For i = 1 To 10
Cells(i, 1).Value = i * 2 ' escribe en columna A
Next i
' Con Step (salto de 2 en 2)
For i = 0 To 10 Step 2
' i = 0, 2, 4, 6, 8, 10
Next i
For Each — recorrer colecciones
Ideal para iterar sobre rangos de celdas u hojas sin conocer el tamaño exacto.
Dim celda As Range
' Recorre todas las celdas de A1:A10
For Each celda In Range("A1:A10")
If celda.Value < 0 Then
celda.Value = 0 ' reemplaza negativos con 0
End If
Next celda
Do While / Do Until
' Do While: ejecuta MIENTRAS la condición sea True
Dim i As Integer
i = 1
Do While i <= 10
Cells(i, 1).Value = i
i = i + 1
Loop
' Do Until: ejecuta HASTA QUE la condición sea True
i = 1
Do Until i > 10
Cells(i, 2).Value = i
i = i + 1
Loop
Usa Exit For o Exit Do para salir de un bucle antes de que termine.
Rangos y Celdas
Leer y escribir celdas
' Leer el valor de una celda
Dim valor As Double
valor = Range("B2").Value
' Escribir en una celda
Range("B4").Value = valor * 2
' Usar Cells(fila, columna) — más dinámico en bucles
Cells(1, 1).Value = "Encabezado" ' A1
Cells(2, 3).Value = 42 ' C2
Propiedades útiles del objeto Range
Dim rng As Range
Set rng = Range("A1:C10")
rng.Value ' contenido
rng.Formula ' fórmula como texto: "=SUMA(A1:A5)"
rng.Font.Bold = True
rng.Interior.Color = RGB(255, 255, 0) ' fondo amarillo
rng.ClearContents ' borra solo el contenido
rng.Clear ' borra contenido y formato
rng.Select ' selecciona el rango
rng.Rows.Count ' número de filas
rng.Columns.Count ' número de columnas
Rango dinámico — última fila con datos
Dim ultimaFila As Long
ultimaFila = Cells(Rows.Count, "A").End(xlUp).Row
' Recorrer solo celdas con datos en columna A
Dim i As Long
For i = 1 To ultimaFila
Debug.Print Cells(i, 1).Value
Next i
Debug.Print imprime valores en la ventana Inmediato (Ctrl+G en el editor VBA). Muy útil para depurar.
Hojas y Libros
Referirse a hojas y libros
' Hoja activa
ActiveSheet.Range("A1").Value = "Dato"
' Hoja por nombre
Worksheets("Ventas").Range("A1").Value = "Dato"
' Hoja por índice (la primera hoja)
Worksheets(1).Activate
' Libro activo vs libro específico
ThisWorkbook.Worksheets("Hoja1").Range("A1").Value = 100
Proteger y desproteger hojas
' Desproteger para escribir
ActiveSheet.Unprotect Password:="contraseña"
' Configurar qué celdas quedan bloqueadas
Range("B2").Locked = False ' siempre editable
Range("B4").Locked = True ' siempre protegida
' Proteger — UserInterfaceOnly permite que macros
' escriban sin necesidad de desproteger cada vez
ActiveSheet.Protect Password:="contraseña", _
UserInterfaceOnly:=True
Operaciones comunes con hojas
' Añadir hoja nueva
Worksheets.Add.Name = "NuevaHoja"
' Copiar hoja al final del libro
Worksheets("Hoja1").Copy After:=Worksheets(Worksheets.Count)
' Recorrer todas las hojas
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Name
Next ws
Manejo de Errores
On Error — capturar errores
Sub EjemploErrores()
On Error GoTo ManejadorError
' código que podría fallar
Dim valor As Double
valor = Range("B2").Value / Range("B3").Value
MsgBox valor
Exit Sub ' evita que se ejecute el manejador
ManejadorError:
MsgBox "Error " & Err.Number & ": " & Err.Description
End Sub
On Error Resume Next — ignorar errores
' Ignora el error y continúa con la siguiente línea
On Error Resume Next
Range("B4").Value = Range("B2").Value / Range("B3").Value
On Error GoTo 0 ' restaura el manejo normal de errores
' Verificar si hubo error
If Err.Number <> 0 Then
MsgBox "Ocurrió un error: division por cero"
Err.Clear
End If
Usa Resume Next con cuidado: puede ocultar errores que necesitas ver. Siempre restaura con On Error GoTo 0.
Ejemplo completo de código
Macro completa — área de rectángulo con celda protegida
El ejemplo que construimos a lo largo de la conversación, con todos los conceptos aplicados:
Sub CalcularAreaRectangulo()
' 1. Declarar variables
Dim ws As Worksheet
Dim valorA As Double
Dim valorB As Double
Dim area As Double
' 2. Referencia a la hoja activa
Set ws = ActiveSheet
' 3. Validar que B2 y B3 tengan valores numéricos
If Not IsNumeric(ws.Range("B2").Value) Or _
Not IsNumeric(ws.Range("B3").Value) Then
MsgBox "B2 y B3 deben contener valores numéricos.", _
vbExclamation
Exit Sub
End If
' 4. Leer los valores (celdas siempre desprotegidas)
valorA = ws.Range("B2").Value
valorB = ws.Range("B3").Value
' 5. Calcular el área
area = valorA * valorB
' 6. Desproteger hoja, escribir resultado, reproteger
ws.Unprotect Password:="tu_contraseña"
ws.Range("B2").Locked = False ' editable
ws.Range("B3").Locked = False ' editable
ws.Range("B4").Locked = True ' protegida
ws.Range("B4").Value = area
ws.Protect Password:="tu_contraseña", _
UserInterfaceOnly:=True
' 7. Mostrar resultado
MsgBox "Área = " & area, vbInformation, "Resultado"
End Sub
