The GoSub – Return statement | VBA Jump Statements

The GoSub – Return statement’s syntax. Square brackets, [ ], vertical bars, |, and curly braces, {}, indicate optional items, mutually exclusive items, and mere item groupings, respectively.
The GoSub – Return statement’s syntax. Square brackets, [ ], vertical bars, |, and curly braces, {}, indicate optional items, mutually exclusive items, and mere item groupings, respectively.
Here, you'll explore the GoSub – Return statement which unconditionally transfers control between a code-line and a subroutine in the same scope.

In this article:

4 minutes read

VBA programs execute code-lines in a sequential manner. However, situations often arise where you need to skip ahead or circle back to a code-line. That is where jump statements like the GoSub – Return statement come into play. They are of immense importance as they allow the non-sequential transfer of control (i.e., program execution).

Introducing the GoSub – Return Statement

The GoSub – Return statement is a blast from the past. It comes from the era of BASIC programs, VBA’s ancestor. Those days, you could only modularize programs by splitting procedures into subroutines.

Once broken up, GoSub statements unconditionally transferred control to these subroutines. Then Return statements, at the end of the subroutines, sent it back to the line right after the GoSub statement.

These subroutines differ from the Sub, Function, or Property procedures. Those procedures have opening and closing block declarations. In fact, these subroutines can only exist inside Sub, Function, or Property procedures. They do so as code-lines enveloped by labelled (top) and Return statements (bottom).

The GoSub – Return statement is like the GoTo statement in many ways. One of those is that it must be in the same Sub, Function, or Property procedure as its subroutine and labelled statement.

The header image above illustrates the statement’s syntax. Moreover, the flowchart below shows its logic flow.

Flowchart showing the GoSub – Return statement’s logic flow
Flowchart showing the GoSub – Return statement’s logic flow

Salient Points on Usage

There are several important things to note about the GoSub – Return statement:

  • It must be in the same procedure as the labelled statement it jumps control to. So, you can’t use it to get into or out of Sub, Function, or Property procedures. The Call and Exit statements handle those tasks.
  • An Exit statement must always follow the GoSub statement. And it should be right before the subroutine’s labelled statement. Otherwise, execution “falls through” the subroutine. That is, the subroutine runs again after its Return statement sends control back to the line after its GoSub statement. When that occurs, the Return statement runs again, after the subroutine’s new run. However, this time it has no GoSub statement to work with as it wasn’t triggered by one. As a result, a “Return without GoSub” runtime error occurs.

It serves as a backward compatibility enabler. So, while its use is perfectly valid, and not necessarily considered bad practice, you should avoid using it. Instead, convert its subroutines into separate Sub, Function, or Property procedures. Then invoke them using Call or Assignment statements.

The GoSub – Return Statement in Action

The sample code below shows the GoSub – Return statement in use. It also illustrates the salient points discussed above.

The Sub procedure in the sample code above does the following:

  • Declares a Byte variable, byt_Tracker, to hold a tracking number (code window line #7);
  • Sets byt_Tracker’s value to ‘2’ in the labelled statement, line1 (line #9);
  • GoSub line3 statement (line #11) skips control to the subroutine starting at the labelled statement, line3 (line #21);
  • Triples byt_Tracker‘s value to ‘6’ (line #23);
  • Prints the result to the Immediate window using the Debug.Print statement (line #22);
  • The Return statement (line #25) jumps control to the line right after the GoSub line3 statement. That would be the GoSub line2 statement (line #12);
  • The GoSub line2 statement skips control to the subroutine starting at the labelled statement, line2 (line #15);
  • Doubles byt_Tracker‘s value to ‘12’ (line #17);
  • Prints the result to the Immediate window using the Debug.Print statement (line #18);
  • The Return statement (line #19) jumps control to the line right after the GoSub line2 statement. That would be the Exit Sub statement (line #14);
  • The Exit Sub statement, right before both subroutines, immediately ends the Sub procedure.
Sample code illustrating the GoSub – Return statement’s usage – unconditionally doubling and tripling numbers before displaying them in the Immediate window.
Sample code illustrating the GoSub – Return statement’s usage – unconditionally doubling and tripling numbers.

The Exit statement, right before all subroutines in the Sub procedure, is crucial. Without it, the subroutine at line2 (line #15) would run again, after the tripling and doubling. However, that subroutine’s Return statement throws a runtime error since it was not invoked by a GoSub statement.

The results of the sample code above can also be achieved using the GoTo statement. However, as most people would probably agree, the GoSub – Return statements approach is more elegant.

5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Keep Learning

Related Articles

Keep Learning

Related Articles