Содержание
- Excel VBA — Using GoSub without Return
- 2 Answers 2
- GoSub. Оператор Return
- Синтаксис
- Замечания
- Пример
- См. также
- Поддержка и обратная связь
- Excel VBA — Использование GoSub без возврата
- 2 ответа
- Excel vba return without gosub
- Answered by:
- Question
- Answers
- All replies
- GoSub. Return statement
- Syntax
- Remarks
- Example
- See also
- Support and feedback
Excel VBA — Using GoSub without Return
I have a situation where I’d like to use GoSub within a Subroutine and in some situations Return, but in others I would not have it Return. This will be in a large be For Loop and GoSub without Return could happen potentially hundreds of times. If I do not Return will this build up in memory and cause any issues?
I suppose my question boils down to: does GoSub stack? And will a large enough stack of un-returned GoSub’s cause problems?
If it does stack, I can change the code to use GoTo in the instances where I do not want to Return, but for simplicity’s sake I’d rather not.
Also thank you in advance for not lecturing me on GoTo/GoSub not being best practice 🙂
2 Answers 2
As plenty of others said: Don’t do it. I am now programming (for a living) since 30 years and never had the need to use GoSub/Return except as a substitute when a programming language didn’t provide any subroutines.
That said — I was curious about how VBA handles this. First thing: I assume that there must be a kind of stack. You can have multiple GoSub/Return in one routine and it is handled correctly:
So the return statements jumps after the correct GoSub — this is for sure handled with a kind of stack.
However, it seems that this stack is cleared once a Subroutine is left. The following routine has a GoSub , but no Return . So it leaves an open GoSub on the «stack». But when called a 2nd time and issues a Return without an GoSub , it throws an runtime error 3 «Return without GoSub`.
Источник
GoSub. Оператор Return
Переходит в подпрограмму и возвращается из подпрограммы в процедуре.
Синтаксис
ЛинияGoSub
. Линии
Линии .
Вернуться
Замечания
Используйте GoSub и Return в любом месте процедуры, но GoSub и соответствующая инструкция Return должны находиться в одной процедуре. Подпрограмма может содержать более одного оператора Return, но первый встреченный оператор Return заставляет поток выполнения перейти обратно в оператор сразу же после самого последнего выполненного оператора GoSub.
Нельзя входить в процедуры Sub или выходить из них с помощью GoSub. Return.
Создание отдельных вызываемых процедур может обеспечить более структурированную альтернативу использованию GoSub. Return.
Пример
В этом примере используется GoSub для вызова подпрограммы в процедуре Sub. Оператор Return вызывает возобновление выполнения на операторе, который сразу же следует за оператором GoSub. Инструкция Exit Sub используется для предотвращения случайного попадания элемента управления в подпрограмму.
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Excel VBA — Использование GoSub без возврата
У меня есть ситуация, когда я хотел бы использовать GoSub в подпрограмме и в некоторых ситуациях Return, но в других я бы не получил его Return. Это будет в большой степени For Loop, а GoSub без возврата может произойти сотни раз. Если я не вернусь, накопится ли это в памяти и вызовет ли какие-либо проблемы?
Полагаю, мой вопрос сводится к следующему: складывается ли GoSub? И вызовет ли проблемы с достаточно большим стеком невозвращенных GoSub?
Если он делает стек, я могу изменить код, чтобы использовать GoTo в тех случаях, когда я не хочу возвращаться, но для простоты я бы не стал этого делать.
Также заранее спасибо за то, что не читал мне лекции о GoTo / GoSub, что не является лучшей практикой 🙂
2 ответа
Как говорили многие другие: Не делайте этого . Сейчас я программирую (зарабатываю на жизнь) уже 30 лет, и у меня никогда не было необходимости использовать GoSub / Return, кроме как в качестве замены, когда язык программирования не предоставляет никаких подпрограмм.
Тем не менее — мне было любопытно, как VBA справляется с этим. Первое: я предполагаю, что должен быть какой-то стек. У вас может быть несколько GoSub / Return в одной подпрограмме, и она обрабатывается правильно:
Таким образом, операторы return перескакивают после правильного GoSub — это наверняка обрабатывается своего рода стеком.
Однако кажется, что этот стек очищается, когда остается подпрограмма. В следующей подпрограмме есть GoSub , но нет Return . Таким образом, в «стеке» остается открытый GoSub . Но когда вызывается второй раз и выдает Return без GoSub , он выдает ошибку времени выполнения 3 «Возврат без GoSub».
P.S .: Я упоминал об этом: Не делай этого!
Ярлык для просмотра стека в VBE: Ctrl + E . Как видите, не складывается:
Однако не используйте GoSub или GoTo в VBA. Это считается очень плохой практикой. GoTo может использоваться для обработки ошибок, например On Error GoTo ErrorHandler .
Источник
Excel vba return without gosub
This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.
Answered by:
Question
On a form that worked for weeks, I’m getting a «Return without GoSub» error. It makes no sense whats so ever. The code it is happening on is extremely simple:
I recently had this happen to another form and solved it by simply copying the form’s controls to a new form. It happens I believe only after compacting.
The database must be currupted somehow. Does that sound true?
If so, what should I do to fix it? Please be specific as I’m not good with the technical stuff.
Answers
> An Error occured while loading ‘Job01ResultsforStersub’. Do you want to continue loading the project? By the way, when I open a module for code, all the modules open up behind it. I believe there is a way to have only the single module open, right? How is that done? Daniel van den Berg | Washington, USA | «Anticipate the difficult by managing the easy»
I don’t think the code is the issue. The code is on the Mouse Move of a label and reads, in full:
That is it. This worked for two weeks and now fails for no reason. Another form had an unbound Combo named «BatchNumberChosen». I have a query that filters to it with:
I’ve been using that filter format for over 10 years. This one worked for 4 days or so. Then I compacted and then it didn’t work. No reason. I changed the name of the filter control to BatchNumberChosen1, and changed the query filter and it worked again. Then I compacted. Then it broke again. So I then moved all controls to a new form and it worked again. It even worked after compacting.
So forms are getting weird for no reason, or usual reason. There is something messy, corrupted about it, I believe. Doesn’t this all sound as if something is funny beyond the code? Is the Return without GoSub a usual error when a database gets corrupted? I don’t know.
I just heard something else is now failing that has worked for 8 months!
If C&R did not work, however you did not indicate the version of Access and what service pack was installed.
It could be that your Access installation is corrupted, maybe a re-install with service pack might solve the problem.
You might try to Decompile your Access Database and see if that works for you:
And try to create known names for you Label, while Label35 doesnt ring a bell after several years later.
Daniel van den Berg | Washington, USA | «Anticipate the difficult by managing the easy»
The database has yet another error. In a module that has been working for months, it says it is misnamed or something—I forgot the actual message—and won’t let me in at all. I had to copy the same module into it from an old version and rename it for the functions within it to work. Now it works very well.
So does all these issues sound as if I need to decompile?
The above link about decompiling is too old. I have Access 2007. What are the steps to take? I’ll google in the meantime but I would like some more input about this. I’m very nervous.
PS: By the way, the label on mouse move issue above was just a silly bit of code in the start up form just for fun. I put 40 or so labels on the page with the same word in each—very faintly seen and stylish, you see. When you move your mouse over them, which you will likely do to open some forms, they disappear. But some, after disappearing, will become visible again too. The trick is to get them all to disappear. It is seemingly impossible, but possible owing to one hidden label placed in a secret location. So I didn’t bother naming the labels. It’s not the fact that I can easily fix this issue but that issues are popping up on important things as well now and then.
Источник
GoSub. Return statement
Branches to and returns from a subroutine within a procedure.
Syntax
GoSub line
. line
line .
Return
Use GoSub and Return anywhere in a procedure, but GoSub and the corresponding Return statement must be in the same procedure. A subroutine can contain more than one Return statement, but the first Return statement encountered causes the flow of execution to branch back to the statement immediately following the most recently executed GoSub statement.
You can’t enter or exit Sub procedures with GoSub. Return.
Creating separate procedures that you can call may provide a more structured alternative to using GoSub. Return.
Example
This example uses GoSub to call a subroutine within a Sub procedure. The Return statement causes the execution to resume at the statement immediately following the GoSub statement. The Exit Sub statement is used to prevent control from accidentally flowing into the subroutine.
See also
Support and feedback
Have questions or feedback about Office VBA or this documentation? Please see Office VBA support and feedback for guidance about the ways you can receive support and provide feedback.
Источник
Permalink
Cannot retrieve contributors at this time
title | keywords | f1_keywords | ms.prod | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|
Return without GoSub (Error 3) |
vblr6.chm1011266 |
vblr6.chm1011266 |
office |
396d3d0f-6af2-4709-bf3c-3a35668398d7 |
06/08/2017 |
medium |
A Return statement must have a corresponding GoSub statement. This error has the following cause and solution:
- You have a Return statement that can’t be matched with a GoSub statement. Make sure your GoSub statement wasn’t inadvertently deleted.
Unlike For…Next, While…Wend, and Sub…End Sub, which are matched at compile time, GoSub and Return are matched at run time.
For additional information, select the item in question and press F1 (in Windows) or HELP (on the Macintosh).
[!includeSupport and feedback]
Code that compiles can still run into errors, at run-time. This topic lists the most common ones, their causes, and how to avoid them.
# Run-time error ‘6’: Overflow
# Incorrect code
# Why doesn’t this work?
The Integer
data type is a 16-bit signed integer with a maximum value of 32,767; assigning it to anything larger than that will overflow the type and raise this error.
# Correct code
# Why does this work?
By using a Long
(32-bit) integer instead, we can now make a loop that iterates more than 32,767 times without overflowing the counter variable’s type.
# Other notes
See Data Types and Limits (opens new window) for more information.
# Run-time error ‘9’: Subscript out of range
# Incorrect code
# Why doesn’t this work?
foo
is an array that contains 10 items. When the i
loop counter reaches a value of 11, foo(i)
is out of range. This error occurs whenever an array or collection is accessed with an index that doesn’t exist in that array or collection.
# Correct code
# Why does this work?
Use LBound
and UBound
functions to determine the lower and upper boundaries of an array, respectively.
# Other notes
When the index is a string, e.g. ThisWorkbook.Worksheets("I don't exist")
, this error means the supplied name doesn’t exist in the queried collection.
The actual error is implementation-specific though; Collection
will raise run-time error 5 «Invalid procedure call or argument» instead:
# Run-time error ’13’: Type mismatch
# Incorrect code
# Why doesn’t this work?
VBA is trying really hard to convert the "42?"
argument into a Date
value. When it fails, the call to DoSomethingElse
cannot be executed, because VBA doesn’t know what date to pass, so it raises run-time error 13 type mismatch, because the type of the argument doesn’t match the expected type (and can’t be implicitly converted either).
# Correct code
# Why does this work?
By passing a Date
argument to a procedure that expects a Date
parameter, the call can succeed.
# Run-time error ’91’: Object variable or With block variable not set
# Incorrect code
# Why doesn’t this work?
Object variables hold a reference, and references need to be set using the Set
keyword. This error occurs whenever a member call is made on an object whose reference is Nothing
. In this case foo
is a Collection
reference, but it’s not initialized, so the reference contains Nothing
— and we can’t call .Add
on Nothing
.
# Correct code
# Why does this work?
By assigning the object variable a valid reference using the Set
keyword, the .Add
calls succeed.
# Other notes
Often, a function or property can return an object reference — a common example is Excel’s Range.Find
method, which returns a Range
object:
However the function can very well return Nothing
(if the search term isn’t found), so it’s likely that the chained .Row
member call fails.
Before calling object members, verify that the reference is set with a If Not xxxx Is Nothing
condition:
# Run-time error ’20’: Resume without error
# Incorrect code
# Why doesn’t this work?
If the DoSomethingElse
procedure raises an error, execution jumps to the CleanFail
line label, prints the error number, and the Resume Next
instruction jumps back to the instruction that immediately follows the line where the error occurred, which in this case is the Debug.Print
instruction: the error-handling subroutine is executing without an error context, and when the Resume Next
instruction is reached, run-time error 20 is raised because there is nowhere to resume to.
# Correct Code
# Why does this work?
By introducing an Exit Sub
instruction before the CleanFail
line label, we have segregated the CleanFail
error-handling subroutine from the rest of the procedure body — the only way to execute the error-handling subroutine is via an On Error
jump; therefore, no execution path reaches the Resume
instruction outside of an error context, which avoids run-time error 20.
# Other notes
This is very similar to Run-time error ‘3’: Return without GoSub (opens new window); in both situations, the solution is to ensure that the normal execution path cannot enter a sub-routine (identified by a line label) without an explicit jump (assuming On Error GoTo
is considered an explicit jump).
# Run-time error ‘3’: Return without GoSub
# Incorrect Code
# Why doesn’t this work?
Execution enters the DoSomething
procedure, jumps to the DoThis
label, prints «Hi!» to the debug output, returns to the instruction immediately after the GoSub
call, prints «Hi!» again, and then encounters a Return
statement, but there’s nowhere to return to now, because we didn’t get here with a GoSub
statement.
# Correct Code
# Why does this work?
By introducing an Exit Sub
instruction before the DoThis
line label, we have segregated the DoThis
subroutine from the rest of the procedure body — the only way to execute the DoThis
subroutine is via the GoSub
jump.
# Other notes
GoSub
/Return
is deprecated, and should be avoided in favor of actual procedure calls. A procedure should not contain subroutines, other than error handlers.
This is very similar to Run-time error ’20’: Resume without error (opens new window); in both situations, the solution is to ensure that the normal execution path cannot enter a sub-routine (identified by a line label) without an explicit jump (assuming On Error GoTo
is considered an explicit jump).
- Remove From My Forums
-
Question
-
I have a form that has a subform. whenever, I attempt to add records to this subform I receive the following message: The LinkMaster Fields Property setting has produced this error: «Return without GoSub» How can I correct this?
Answers
-
Hi NoviceVBAuser1775,
«Return without GoSub» means that
you have a Return statement that can’t be matched with a GoSub statement.
Make sure your GoSub statement wasn’t inadvertently deleted.You can get more detail about this error from link below:
Return without GoSub (Error 3)This error is runtime error and it is a code issue. It means that complie will not address this issue. I suggest that you check code to see whether the code is correctly. For example, the code below will throw this error if we commnet the code «Exit
Sub»:Sub TestError() Debug.Print "begin.." GoSub label1 Exit Sub 'comment this line will cause this issue label1: Debug.Print "1" label2: Debug.Print "2" Return End Sub
If you still have problem fixing this issue, I suggest that you share with us the code snippet you are developing with.
Hope it is helpful.
Regards & Fei
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click
HERE to participate the survey.-
Edited by
Friday, April 10, 2015 6:45 AM
-
Marked as answer by
Fei XueMicrosoft employee
Wednesday, April 15, 2015 12:23 PM
-
Edited by
Example
Incorrect Code
Sub DoSomething()
GoSub DoThis
DoThis:
Debug.Print "Hi!"
Return
End Sub
Why doesn’t this work?
Execution enters the DoSomething
procedure, jumps to the DoThis
label, prints «Hi!» to the debug output, returns to the instruction immediately after the GoSub
call, prints «Hi!» again, and then encounters a Return
statement, but there’s nowhere to return to now, because we didn’t get here with a GoSub
statement.
Correct Code
Sub DoSomething()
GoSub DoThis
Exit Sub
DoThis:
Debug.Print "Hi!"
Return
End Sub
Why does this work?
By introducing an Exit Sub
instruction before the DoThis
line label, we have segregated the DoThis
subroutine from the rest of the procedure body — the only way to execute the DoThis
subroutine is via the GoSub
jump.
Other notes
GoSub
/Return
is deprecated, and should be avoided in favor of actual procedure calls. A procedure should not contain subroutines, other than error handlers.
This is very similar to Run-time error ’20’: Resume without error; in both situations, the solution is to ensure that the normal execution path cannot enter a sub-routine (identified by a line label) without an explicit jump (assuming On Error GoTo
is considered an explicit jump).