In VBA, GoTo is a statement, not a function: it transfers execution to a labeled line in the same procedure. It is also part of VBA error handling, as in On Error GoTo HandleError; for ordinary branching, though, an If statement or loop is usually easier to follow.
What GoTo Means in VBA
A GoTo statement changes the next line of code VBA runs. The destination is a label: a name followed by a colon, placed on its own line inside the same Sub or Function. The code can then jump to that label when it reaches a GoTo statement. Labels are not variables, and they do not return a value, which is one reason GoTo is not a function.
VBA has two closely related uses that can cause confusion. A plain GoTo LabelName branches to a label when that line of code runs. By contrast, On Error GoTo LabelName installs an error handler: VBA transfers to the label if a run-time error occurs in the procedure. The second form is common in macros, but it is an error-handling instruction rather than a general-purpose jump triggered by an error-free condition.
Labels only work within the procedure where they are defined. A GoTo in one Sub cannot jump into another Sub, and a label does not make code reusable. For reusable work, write a separate procedure and call it by name.
Syntax and a Simple Example
The basic pattern is GoTo LabelName, followed by a label written as LabelName:. The label can have a descriptive name, and VBA does not require a number. Choose names that explain the destination, such as SkipRow or HandleError, rather than vague names such as Here.
This example copies nonblank entries from column A to column B, skipping blank cells with GoTo. It assumes a worksheet named Data and ordinary values in A1:A10; it is included to show the jump, not to suggest that a jump is the best way to filter data.
Sub CopyNonblankValues()
Dim ws As Worksheet
Dim sourceCell As Range
Dim outputRow As Long
Set ws = ThisWorkbook.Worksheets("Data")
outputRow = 1
For Each sourceCell In ws.Range("A1:A10").Cells
If Len(CStr(sourceCell.Value2)) = 0 Then GoTo SkipRow
ws.Cells(outputRow, 2).Value = sourceCell.Value2
outputRow = outputRow + 1
SkipRow:
Next sourceCell
End Sub
When a blank cell is encountered, VBA jumps to SkipRow:, then continues with the next iteration of the For Each loop. A nonblank cell is copied to the next available row in column B. Because the sample converts values to text, avoid using it unchanged on a range containing Excel error values such as #N/A; converting an error value with CStr can itself raise an error.
Before running a macro, save a copy of the workbook. VBA changes cannot be undone with Ctrl+Z, and the sample writes into column B. In Excel for Microsoft 365 on Windows, open the Visual Basic Editor with Alt+F11, add a standard module through Insert > Module, and run the procedure with F5 while the cursor is inside it. On a Mac, use Tools > Macro > Visual Basic Editor to open the editor; keyboard shortcuts can differ by keyboard and system settings. Excel for the web cannot create, edit, or run VBA macros.
GoTo in Error Handling
The most familiar reason to use a GoTo label in VBA is to handle an error. On Error GoTo HandleError tells VBA where to transfer control if a later statement in the procedure fails. The handler can display a useful message, record details, or direct the procedure to a controlled exit. A handler should not silently hide an error that the user or workbook owner needs to know about.
Here is a small example that tries to read a cell on a worksheet named Data. If the sheet is missing or the reference fails, VBA runs the handler instead of stopping with an unhandled error.
Sub ShowDataValue()
Dim target As Range
On Error GoTo HandleError
Set target = ThisWorkbook.Worksheets("Data").Range("A1")
MsgBox CStr(target.Value2)
Exit Sub
HandleError:
MsgBox "Could not read Data!A1: " & Err.Description, vbExclamation
End Sub
The Exit Sub before the handler label matters. Without it, a successful run would continue down into the handler code even though no error occurred. In a Function, use an appropriate Exit Function before the handler. Larger procedures may also have a cleanup section for closing files or restoring application settings; keep the normal exit and error exit clear so cleanup is not accidentally skipped.
Once VBA has entered an error handler, the handler is considered active. If another error occurs before the procedure resumes or exits, that second error may not be handled as a fresh error by the same active handler. Keep handler code simple, and avoid continuing as if an operation succeeded when it did not. If the procedure needs to preserve or re-raise an error, capture its number, description, and source before doing cleanup that could change the current error information.
GoTo 0, GoTo -1, and Resume
The meaning of GoTo 0 is different from jumping to a label named zero. Used as On Error GoTo 0, it disables the current procedure’s enabled error handler and restores normal run-time error behavior. If a later statement raises an error, VBA will not use the earlier handler. This is useful when a limited section has special handling and the rest of the procedure should not inherit it.
On Error GoTo -1 is another error-handling form in VBA. It clears the current procedure’s active error state; it is not a destination label and is not interchangeable with On Error GoTo 0. These details matter most in procedures that handle more than one error condition. For a simple macro, a single handler and a clear exit are generally easier to maintain than repeated resets.
Inside an error handler, Resume returns to the statement that caused the error, Resume Next continues with the statement after the one that failed, and Resume LabelName continues at a specified label. These choices have different consequences. Retrying a failed statement can repeat a problem, while continuing after a failed assignment can leave later code working with an empty or outdated value. Use Resume Next only when the next statement is genuinely safe and the code checks whether the expected operation succeeded.
When to Use GoTo and When to Avoid It
For normal program flow, structured statements usually communicate intent better than jumps. Use If...Then...Else to choose between conditions, For or For Each to repeat a known sequence, and Do While or Do Until when repetition depends on a condition. A short conditional can replace the earlier skip label:
If Len(CStr(sourceCell.Value2)) > 0 Then
ws.Cells(outputRow, 2).Value = sourceCell.Value2
outputRow = outputRow + 1
End If
This version keeps the action beside its condition and avoids transferring execution to a distant line. For more substantial work, move a coherent task into a separate Sub or Function. That can make the code easier to test, name, and reuse without adding a maze of labels.
GoTo can still be appropriate for error handling, where VBA’s built-in pattern explicitly uses a label. It can also be a practical way to reach a shared cleanup section in a procedure with several possible exits, provided the paths are clearly documented and all required cleanup runs. It is less suitable for scattered jumps that skip initialization, skip important checks, or make the order of operations difficult to trace.
Common Problems and Debugging Tips
A common compile error is a misspelled or missing label. The name after GoTo must match a label in the same procedure, including its spelling. Another common mistake is putting the colon after a GoTo statement rather than after the destination name. The jump is written as GoTo SkipRow; the label is written as SkipRow:.
- Code falls into the handler: Put
Exit SuborExit Functionbefore the handler label on the normal path. - The macro skips too much: Check where the label appears. A jump resumes at the label and then runs subsequent lines, so a label placed after cleanup or output code can bypass that work.
- An error seems to disappear: Look for
On Error Resume Nextor a handler that reports no details. CheckErr.NumberandErr.Descriptionwhere appropriate instead of assuming the operation succeeded. - A later error is not caught: Check whether execution is still inside an active error handler and whether it has resumed or exited correctly.
To debug, set a breakpoint by clicking the margin beside a line in the Visual Basic Editor, then run the macro and step through it. Watch which line is highlighted after a jump and inspect variable values in the Locals window or with the Immediate window. These checks make the actual route through the procedure visible, which is especially useful when a label is far from its GoTo statement.
Excel-Specific Considerations
GoTo is a VBA language feature, not an Excel worksheet function. You cannot enter it into a cell like =SUM(A1:A5). It runs only inside VBA code, such as a macro stored in a macro-enabled workbook. To retain VBA code in Excel, save the file in a macro-supporting format such as Excel Macro-Enabled Workbook (.xlsm); saving as an ordinary .xlsx workbook does not preserve VBA project code.
Macros may be blocked by Excel’s security settings or by an organization’s policy. Do not enable macros from an untrusted workbook just to test a GoTo example, and do not reduce macro security globally as a workaround. The examples here use workbook references and simple message boxes, but a real macro can alter cells, files, or application settings. Review what it does and keep a backup before running it. VBA is available in desktop Excel for Windows and Mac, with platform-specific limitations; it is not available for execution in Excel for the web.
Frequently Asked Questions
Is GoTo a function in VBA?
No. GoTo is a language statement that transfers execution to a label. A function is a procedure that can return a value, and GoTo does not return one.
How do I write a GoTo statement in VBA?
Write GoTo LabelName where the jump should happen, then place LabelName: on a line in the same procedure. The destination must be a valid label in that Sub or Function.
What does On Error GoTo 0 do?
It disables the enabled error handler in the current procedure. It does not jump to a label called zero. Afterward, an unhandled run-time error follows VBA’s normal error behavior.
Can GoTo jump to another Sub?
No. A GoTo destination must be in the same procedure. To run code in another procedure, call that Sub or Function by name instead.
Should I use GoTo in Excel macros?
Use it where VBA’s error-handling pattern calls for a handler label, or for a clearly designed cleanup route. For ordinary branching and loops, structured statements are usually more readable and less error-prone.
Related
- Excel Data Validation for Dates: Rules and Examples
- Data Validation Checks in Excel: Rules and Examples
- Data Validation Checklist for Excel: What to Check
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- Excel VBA: Copy and Paste Values Without FormulasTo copy a range’s results without its formulas in Excel VBA, copy the source range and use PasteSpecial…
- Excel VBA: Copy the End Part of a String with RightTo copy the last characters of a string in Excel VBA, use the Right$ function: assign Right$(text, numberOfCharacters)…
- Excel VBA Find a Substring in a StringIn Excel VBA, use InStr to find a substring inside a string: it returns the position of the…
- VBA Select, Copy and Paste in Excel: Practical GuideIn Excel VBA, you can select a range, copy it, and paste it elsewhere, but most macros work…
- Excel VBA: Set the Active Workbook as a VariableIn Excel VBA, declare a variable as a Workbook and assign the active workbook with Set wb =…
- Excel Macro For Loop: Examples and Common FixesAn Excel macro for loop is a VBA loop that repeats instructions for a set of items or…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.