🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA GoTo en Excel — Saltar a una etiqueta y por qué casi nunca deberías

|

VBA GoTo en Excel — Saltar a una etiqueta y por qué casi nunca deberías

TL;DR — GoTo label salta la ejecución a una línea marcada con label: en el mismo procedimiento, sin ninguna condición. Tiene exactamente un lugar al que aún pertenece en el VBA moderno: On Error GoTo para 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 GoTo llega hasta ella
  • El único lugar donde GoTo pertenece de verdad hoy: el manejo de errores con On 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 GoTo para fingir un Continue que VBA no tiene, y la alternativa limpia
  • Por qué no puedes hacer GoTo a 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