I currently have a main excel macro which calls a bunch of functions. Basically:
Sub main()
'Long code
Call init
End Sub
Private Function init()
'Long Code
End Function
Some of these pieces of code are quite long and take some time to process, which is not great because I am constantly testing pieces of the code here and there.
I know that pressing esc multiple times ends an excel macro, and clumping all my code into the main Sub main() works fine. So my two questions are:
If I call a function from my main sub, will the main sub continue to run, or will it wait for a return signal from the function?
Is there a way for me to halt all subs and functions with one keypress? Currently, it seems that although the main sub ends when I spam esc, the function which has been called keeps running.
Cheers!
CTRL + Break will stop any running loops.
The main sub will wait for the return value from another function unless you run it asynchronously.
EDIT:
Misleading VBA does not support asynchronous programming.
Related
I've looked on some similar question of "Object required on calling sub", but None of them seems to help with my problem. I want to call a sub(for example, in sheet2) from a sub in sheet1 like
Private Sub Worksheet_Activate()
ThisWorkbook.ActiveSheet.Cells.Clear
Call sheet2.generate <== where the error comes from
End Sub
where generate is the sub name on sheet2 which don't require any parameter
but it tells me that Object required and sendback an error.
I've tried:
without using call
sheet2.generate
without sheet name
generate
call generate
and adding a useless parameter for calling( also added to generate sub)
call sheet2.generate(1)
but it's not working too, so i detele that parameter as it have no use in the code.
there is no problem on generate sub(which i test for many time)
still, all of the above do not work for me, can someone provide a vaild way to solve this?
I've found that the problem is not at calling function,but instead, stuffs INSIDE function have problem, and debug arrow goes function and says "error 1004", after fixing some variable problem of the function, the problem no longer shows.
BRUH
Problem
I have an excel file with a quite complicated VBA code behind and I am having some problems to track back and debug the errors.
Sometimes a function B gets a value that it should not get and crashes, but at this point it is not possible for me to know which other funciton called that function B, and the anylys process to finding it out is very much time consuming.
My solution
The solution could be transform all the functions I have in the following way:
Sub foo1(variable1 as string)
'do whatever
End Sub
into
Sub foo1(variable1 as string, inforvariable as string)
'do whatever
End Sub
Infovariable being the name of the function calling.
This is obviously very time consuming (refactoring everything). Besides I dont know neither how to access the name of the "sub" of funcion of the code calling, something like:
infovariable = self.name
call foo1(variable1, inforvariable)
Does not seems to exists in VBA
Some ideas?
I have a look here, here, and here
Debug your macro, put a breakpoint on the line with the problem (in case the line gets called too often, add a condition only to break upon that condition), and view the call stack (keyboard shortcut Ctrl+L).
New to VBA but years of experience with assembler, C and C#. I have created a Private Sub called CPScenarioData(wsname as String, rownum As Integer). When I call the procedure using the statement:
CPScenarioData(wsname, l)
I get an error 'Compile error: Expected =', however when I preceded the statement with Call no error occurs, why is this. I have other Private subs that I call without using Call that work fine. I am sure there is a simple answer or mistake I have made and will feel very sheepish when I see the answer but that's life. I am using Excel 2013 VBA. Thank you for your help.
It's a quirk (feature according to taste) of VB. To call a sub, you don't include brackets. So simply type:
CPScenarioData wsname, 1
Normally brackets are used to denote a Function, which returns a value. In VB you must provide a variable to receive the returned value. (Hence the compile error for missing =; it is expecting a = CPScenario(wsname, 1)).
Adding the word Call enables you to keep the brackets for Subs (equivalent of c# void).
For VBA functions and most programming in general i understand general program execution to occur something like this...
Inside a sub procedure if you call a function (it should return a value), in this case it would return a value to variable num.
To expand this means that execution reaches the line where I call the function, and should then skip down to where the function is written, and go through executing each line inside that function.
This is how it has worked for me previously when I use the F8 key to highlight and follow the code execution line by line.
The problem
The problem is when execution reaches the line inside the sub procedure where the function is called the function is just skipped over and execution doesn't go inside the function and run each line inside it.
(and I should say when this happened I had 95% of a working program, and i've tried re-writing the function, calling other functions).
But whenever a function is called execution of the code doesn't go into the function itself it just skips over it, and the variable that holds the result of the function therefore is left empty.
I've tried creating breakpoints at the beginning of the function and when the function is called in the sub procedure however this hasn't worked.
At the very least execution should get to the definition of the function (Function FirstRow() etc) and throw and error but it's not doing that.
Sub Main
Dim num as double
Dim sheet_name as string
num = FirstRow(sheet_name)
End Sub
Function FirstRow(sheet as string) as double
select case sheet '<<----- execution never gets inside the function
case "sheet"
FirstRow = 8
case "sheet2"
FirstRow = 12
end select
End Function
Put a value in sheet_name and try again.
What caused some functions to stop working (and execution of code to not reach the function definition or move inside it) was unloading the form.
All the functions and sub procedures were defined in a module which is part of the form.
Therefore you can only access this module by clicking on the controls on the form.
This meant that I only had one folder FORMS - which had one form inside it, and didn't have a Modules Folder which would normally appear in the VBA Project section.
Therefore I can either:
1) wait until all the data processing has been done before unloading the form right at the last minute
or
2) move the functions to a new module (External to the Form in the MODULES folder) so when the fuctions and sub procedures are called they don't rely on the form being open.
I have a spreadsheet, with the following two subroutines in it (there's a lot more to them, but I've stripped out all the code not directly relevant to the question):
Sub HF_Reset()
Feats_Reset
End Sub
Sub Feats_Reset()
Range("TblAllFeatsSelected").Value = CVErr(xlErrNA)
Range("Test").Value = "Success"
Range("Test2").Value = 1
End Sub
Test is a single cell, Test2 is a two-cell range, TblAllFeatsSelected is a large range.
If I call Feats_Reset, it executes absolutely fine, does what it's intended to do. If I call HF_Reset, then Testgets "Success" put into it, and Test2 is filled with 1s, but TblAllFeatsSelected doesn't change. I have absolutely no clue what's going on - any ideas?
For debugging purposes, I've also tried setting Range("TblAllFeatsSelected").Value = 1 and Range("TblAllFeatsSelected").Value = 0, and again it works fine when calling Feats_Reset but not when calling HF_Reset.
EDIT: I've played some more, and traced the problem to another subroutine called in Feats_Reset. I suspect I'm not going to be able to provide enough information here to get a useful answer - it's a complicated sheet, and there's a lot of interactions that could be the problem. Bother.
EDIT2: Found the problem. The subroutine was setting TblAllFeatsSelected to the value of another range, which when calling from HF_Reset needed to have an Application.Calculate or it would justset it back to what it used to be.
Is there any way I can delete this question as not useful? It's such a specific thing, I doubt it could help anyone else.
Problem Exists Between Keyboard and Chair. I was missing an Application.Calculate in a completely different part of the code.