Skip to main content

¿Qué es una macro en Excel (VBA)?

· 6 min read
Héctor Mansilla Arias
Artesano Digital

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 principalesAsignación de valores
Dim n As Integer ' -32768 a 32767n = 42
Dim l As Long ' entero grandel = 1000000
Dim d As Double ' decimald = 3.14
Dim s As String ' textos = "Hola mundo"
Dim b As Boolean ' True / Falseb = True
Dim dt As Date ' fechadt = #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