TL;DR —
GoTo labelsalta la ejecución a una línea marcada conlabel:en el mismo procedimiento, sin ninguna condición. Tiene exactamente un lugar al que aún pertenece en el VBA moderno:On Error GoTopara el manejo de errores. Para todo lo demás —bucles, saltarse iteraciones, ramificar— un salto es más difícil de seguir que las herramientas estructuradas (If,Exit For,Exit Sub,Do), y saltar dentro o fuera de un bucle corrompe el bucle en silencio. Aprende la sintaxis para poder leer código antiguo; recurre a la versión estructurada cuando escribas código nuevo.
Sub GoToBasics()
Dim x As Long
x = 5
If x > 0 Then GoTo Positive
Debug.Print "zero or negative"
Exit Sub ' parar antes de caer en la etiqueta de abajo
Positive: ' una etiqueta - nombre seguido de dos puntos
Debug.Print "positive"
End Sub
GoTo es la herramienta de control de flujo más antigua que existe: mueve la ejecución a una etiqueta con
nombre, sin condiciones y en la dirección que elijas. VBA aún lo admite, y una función moderna —On Error GoTo—
está construida sobre él. Pero para el flujo corriente, un salto produce código que no puedes leer de arriba
abajo, y por eso casi todo GoTo en código nuevo debería ser en su lugar un Exit o
un If.
Lo que aprenderás
- La sintaxis de etiqueta y salto: cómo escribes una etiqueta y cómo
GoTollega hasta ella - El único lugar donde
GoTopertenece de verdad hoy: el manejo de errores conOn Error GoTo - Por qué saltar dentro o fuera de un bucle corrompe el contador del bucle y deja el trabajo a medias
- Cómo se abusa de
GoTopara fingir unContinueque VBA no tiene, y la alternativa limpia - Por qué no puedes hacer
GoToa una etiqueta de otro procedimiento - Los reemplazos estructurados que se leen mejor que cualquier salto
El modelo mental: un salto incondicional de sentido único
Una etiqueta es un nombre seguido de dos puntos, solo en una línea; GoTo label mueve la ejecución
directamente hasta ella:
GoTo CleanUp ' saltar adelante (o atras) a la linea marcada con CleanUp:
' ... cualquier linea de aqui se salta ...
CleanUp: ' <-- la ejecucion se reanuda aqui
Dos propiedades hacen a GoTo poderoso y peligroso a partes iguales. Es incondicional —por sí solo siempre
salta, así que ramificar exige envolverlo en un If— y es un movimiento de sentido único que no deja
rastro: nada marca de dónde vino el control, así que un lector que sigue el código tiene que recorrer el
procedimiento entero para encontrar cada GoTo que pudiera aterrizar en una etiqueta. Una sentencia
estructurada como Exit For te dice exactamente adónde va el control (justo después de Next); un GoTo puede
venir de cualquier parte. Esa diferencia es todo el argumento en su contra.
El único lugar al que pertenece GoTo: On Error GoTo
Aquí está la excepción, y es una de verdad. El manejo de errores de VBA está construido sobre GoTo:
On Error GoTo le dice a VBA a qué etiqueta saltar cuando ocurre un error de ejecución. Esto es idiomático,
esperado y no tiene alternativa estructurada en el lenguaje:
Sub SafeOpen()
On Error GoTo Failed
Workbooks.Open "C:\reports\data.xlsx"
Exit Sub
Failed:
MsgBox "Could not open the file."
End Sub
Fíjate en el Exit Sub antes de la etiqueta Failed:: sin él, el camino normal caería dentro del manejador
de errores aun cuando no haya salido nada mal. Esa caída es el clásico error del código con etiquetas de GoTo,
y se aplica a toda etiqueta, no solo a los manejadores de errores. Para el mecanismo completo, mira
VBA On Error. Fuera de On Error, un GoTo es una señal de advertencia, no una
herramienta.
La trampa: saltar dentro o fuera de un bucle
Lo peor que puedes hacer con GoTo es saltar a través de la frontera de un bucle For o Do. Salta fuera de
un bucle con GoTo y te saltas la salida normal del bucle: el contador queda en el valor que tuviera, y todo lo
que el bucle debía terminar se omite. Salta al medio de un bucle y el resultado es peor: el contador nunca se
inicializó, así que el comportamiento es indefinido:
' NO hagas esto - saltar fuera de un bucle con GoTo
For i = 1 To 100
If Cells(i, 1).Value = "X" Then GoTo AfterLoop ' se salta la salida limpia del bucle
Next i
AfterLoop:
La línea de arriba resulta que funciona, pero la versión honesta es Exit For, que abandona el bucle por su
puerta adecuada y hace el propósito evidente. Todo «saltar fuera de un bucle» se escribe mejor como
Exit For o Exit Do; todo «abandonar el procedimiento ahora» se escribe mejor como
Exit Sub. Esos nombran la estructura que abandonan y hacen aterrizar el control en un lugar predecible; un
GoTo no hace ninguna de las dos cosas.
Fingir Continue con GoTo, y la alternativa limpia
VBA no tiene una sentencia Continue para saltar a la siguiente iteración del bucle, así que el código antiguo
a menudo la simula colocando una etiqueta justo antes de Next y saltando a ella:
' la forma GoTo de "continue" - funciona, pero es un salto
For i = 1 To n
If Cells(i, 1).Value = "" Then GoTo NextRow
' ... procesar la fila ...
NextRow:
Next i
Esto funciona, pero le pide al lector que salte de un lado a otro para entender un bucle. La versión
estructurada simplemente invierte la comprobación para que las iteraciones omitidas no hagan nada y caigan hasta
Next:
' la forma estructurada - sin etiqueta, sin salto
For i = 1 To n
If Cells(i, 1).Value <> "" Then
' ... procesar la fila ...
End If
Next i
El mismo comportamiento, leído de corrido hacia abajo. Cuando la condición de salto es una sola comprobación,
el If siempre gana. Guarda el patrón de la etiqueta-antes-de-Next para el raro caso en que la lógica de
salto sea demasiado enrevesada para un solo If; e incluso entonces, plantéate separar el cuerpo en su propio
procedimiento.
No puedes hacer GoTo entre procedimientos
Una etiqueta es local al procedimiento en el que vive. GoTo solo puede saltar a una etiqueta del mismo
Sub o Function; no puedes saltar de un procedimiento a otro (VBA lanza un error de compilación,
«Label not defined»). Si te descubres queriendo saltar a otro procedimiento, lo que en realidad quieres es
llamarlo —MyCleanup o Call MyCleanup—, lo que te devuelve el control después, exactamente lo que un salto
no puede hacer. Esta limitación es una virtud: mantiene cada salto dentro de una sola unidad legible.
Cuándo un salto es de verdad la opción menos mala
La honestidad exige una concesión: salir de bucles profundamente anidados es la única situación de control
de flujo donde un GoTo a una etiqueta más allá del bucle externo puede ser más limpio que las alternativas,
porque VBA no puede hacer Exit de más de un nivel de bucle a la vez. Incluso aquí, extraer los bucles anidados
a una Function y usar Exit Function suele ser más claro. La regla general: si estás recurriendo a GoTo y
no es On Error GoTo, detente y pregúntate si un Exit, un If o un pequeño procedimiento auxiliar dirían lo
mismo sin un salto. Noventa y nueve de cada cien veces, lo harán.
Cómo te ayuda ExcelMaster
GoTo es fácil de escribir y difícil de leer, que es justo la combinación que produce macros que nadie puede
mantener seis meses después. Los dos errores que muerden son la caída dentro de una etiqueta cuando falta un
Exit Sub previo, y los saltos a través de las fronteras de un bucle que dejan los contadores y el trabajo en
un estado indefinido.
ExcelMaster escribe flujo que puedes leer de
arriba abajo: Exit For donde un bucle debe detenerse, cláusulas de guarda donde un procedimiento debe
retirarse, y On Error GoTo solo donde corresponde —en el manejo de errores, con el Exit Sub que mantiene el
camino normal fuera del manejador—. Tú conservas el libro y el código.
Preguntas frecuentes
¿Qué hace GoTo en VBA?
GoTo label transfiere la ejecución de forma incondicional a una línea marcada con label: en el mismo
procedimiento. Una etiqueta es un nombre seguido de dos puntos en su propia línea. Como GoTo siempre salta,
ramificar exige envolverlo en un If, como en If x < 0 Then GoTo Negative. La ejecución continúa entonces
desde la etiqueta en adelante.
¿Es GoTo una mala práctica en VBA?
Para el control de flujo corriente, sí: un salto es más difícil de seguir que las sentencias estructuradas, y
saltar dentro o fuera de un bucle puede corromper el contador del bucle. La excepción importante es
On Error GoTo, que es la forma idiomática y esperada de encaminar los errores de ejecución a un manejador.
Aprende GoTo para leer código antiguo; prefiere Exit, If y los bucles Do cuando escribas código nuevo.
¿Cómo escribo una etiqueta para GoTo?
Pon un nombre seguido de dos puntos en su propia línea, como CleanUp:, y salta a ella con GoTo CleanUp. Las
etiquetas no distinguen mayúsculas de minúsculas y son locales al procedimiento. Coloca siempre un Exit Sub
antes de una etiqueta situada al final de un procedimiento, o el camino normal caerá dentro del código
etiquetado aun cuando no se pretendiera ningún salto.
¿Puede GoTo saltar a otro Sub o Function?
No. Un GoTo solo puede alcanzar una etiqueta del mismo procedimiento; saltar a otro Sub o Function es un
error de compilación. Para ejecutar código de otro procedimiento, llámalo por su nombre: la llamada te devuelve
el control cuando termina, que es lo que normalmente quieres y lo que un salto nunca puede hacer.
¿Cómo salgo de un bucle sin GoTo?
Usa Exit For para un bucle For o Exit Do para un bucle Do: ambos abandonan el bucle por su salida
adecuada y continúan en la línea siguiente. Para saltarte una sola iteración en lugar de abandonar el bucle,
envuelve el cuerpo en un If para que las pasadas omitidas no hagan nada. Mira
VBA Exit For para el conjunto completo.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 24/09/2026.
Guías relacionadas: VBA Exit For · VBA End · VBA On Error · VBA For Loop · VBA If Then Else
