This is probably the dumbest question I’ve ever asked here, but it’s hard to find answers to things like this.
I have a program with a bunch of modules/subs that each calculate a different variable. They’re pretty complex, so I like to keep them separate. Now I want an earlier module to skip to another module based on user input. I thought I could use the
call (sub name) method for this, but then the program returns to where the call line was and continues on that module from where it left off.
Sub NewPracticeSub() Call otherpracticesub MsgBox ("We've gone back to this sub... :(") End Sub
Sub otherpracticesub() MsgBox ("We're in the other practice sub!") End Sub
I don’t want it to return to Module 1. What can I do to have it switch control to Module 2 without it then returning to complete Module 1 upon completion of Module 2?
I feel like I just used the most confusing language possible to explain all of this, but thank you for your help anyways!!
Edit: I know I used the words module and sub interchangeably, and I know they’re different. I like to keep each sub (which are each very large in my program) in their own modules because it’s easier to keep track of them, and easier to explain/demonstrate the application flow to other people.
Other than using the ugly
End statement which I will describe below (and strongly recommend you to avoid), I’m not aware of any way to circumvent the call stack. Even John’s response necessarily returns to the calling procedure, and evaluates another statement to determine whether to proceed or end.
This may yield undesirable outcomes, which is why I hesitate to recommend it, in favor of properly structuring your code, loops, etc., with respect to the call stack.
In any case, here is how you can use the
End statement within your child subroutines, without needing any sort of public/global variables. This still allows you the flexibility to decide when & where to invoke the
End statement, so it need not always be invoked.
Sub NewPracticeSub() Call otherpracticesub, True MsgBox ("We've gone back to this sub... :(") End Sub Sub otherpracticesub(Optional endAll as Boolean=False) MsgBox ("We're in the other practice sub!") If endAll then End '## Only invoke End when True is passed to this subroutine End Sub
“Note The End statement stops code execution abruptly, without
invoking the Unload, QueryUnload, or Terminate event, or any other
Visual Basic code. Code you have placed in the Unload, QueryUnload,
and Terminate events of forms and class modules is not executed.
Objects created from class modules are destroyed, files opened using
the Open statement are closed, and memory used by your program is
freed. Object references held by other programs are invalidated.
The End statement provides a way to force your program to halt. For
normal termination of a Visual Basic program, you should unload all
forms. Your program closes as soon as there are no other programs
holding references to objects created from your public class modules
and no code executing.”
I think all you’re looking for is the command
Exit Sub which will make the program leave the subroutine without continuing any further, But the way you usually want to do this is, rather than calling a
Sub, rather call a
Function that returns a boolean value.
So, for example:
Public Function MyFunc() as Boolean .... If [good] MyFunc = True Else MyFunc = False End Function
Then you could do something along the lines of:
Sub MyCallingSub() ... If MyFunc = True then Exit Sub Else ... End Sub
It just adds in A LOT more felxibility and ability to choose whether you want to continue further in your sub or not.
Hope that makes sense.
It will always return but that doesn’t mean its a problem. I suggest you use Exit Sub as follows:
Call otherpracticesub **Exit Sub** 'Nothing more can execute here so its no longer a worry
MsgBox ("We're in the other practice sub!")