I have a rather large VBA project and now I need to know what sub is calling the function.
example:
sub first()
RunSomeCode
end sub
sub second()
RunSomeCode
end sub
Function RunSomeCode()
' here I need to know if the calling sub is first() or second()
end function
The only way I know of is to pass a string with the functioncall in first and second sub with the calling sub name.
But this function is called from everywhere and I wanted to know if there is a simpler way to do it.
I need to get a string of what sub called the RunSomeCode, to just get it in debugging is not enough.
Ctrl+L is the shortcut for the Call Stack in VBA. You may see the stack. As you see in the screenshot below, the function was called from the Sub Second:
Assuming you only need it in First and Second then probably this could help
Option Explicit
Sub first()
RunSomeCode "First"
End Sub
Sub second()
RunSomeCode "Second"
End Sub
Sub third()
RunSomeCode
End Sub
Function RunSomeCode(Optional Caller As String)
' here I need to know if the calling sub is first() or second()
If Len(Caller) > 0 Then
Debug.Print Caller
End If
End Function
Related
My problem is so simple that it's ridiculous...
If I create a Module like:
Sub Check_TextBox(ByVal CheckThisBox As TextBox)
'With anything. Even if I leave this blank..
End sub
And try to call it on a UserForm like:
Private Sub CommandButton1_Click()
Call Check_TextBox(Me.TextBox1)
End Sub
It simply gives me "Incompatible Types Error"... I have no clue about what's going on. "TextBox1" IS a TextBox and I declare it as one on the Sub.
Need to be a bit more explicit about the parameter type:
Sub Check_TextBox(CheckThisBox As msforms.TextBox)
Debug.Print CheckThisBox.Text
End Sub
I have an UserForm in Excel VBA with different Objects like CheckBox, RadioButtons, TextEdit Box etc. Each Object has different event functions, but i want to call the some event functions in user defined sub function like UserForm_Init() function in order to re-utilize the same code written in them.
Example:
Private Sub CheckBox1_Click() [Later changed to public also]
If CheckBox1.Value Then
--- Code
End If
End Sub
Private Sub CheckBox2_Click()
If CheckBox2.Value Then
--- Code
End If
End Sub
Private Sub RadioButton1_Click()
If RadioButton1.Value Then
--- Code
End If
End Sub
' User Defined Function
Sub UserForm_Init()
CheckBox1_Click()
CheckBox2_Click()
RadioButton1_Click()
End Sub
But when i am trying to compile it is showing compile error, how can i execute these object event functions within user-defined sub function.
I know I can write individual functions within Event functions and call these individual functions for user-defined sub function. But in this case, it will be too-difficult to re-change entire code. I have only option of calling these event-functions in an sub-function for execution.
How can i perform these actions, call event functions with in the user defined sub function [UserForm_Init()]?
VBA doesn't use curly braces. This code won't compile with those. VBA requires Sub and End Sub to define the procedures.
Sub CheckBox1_Click()
if CheckBox1.Value Then
--- Code
end if
End Sub
Sub CheckBox2_Click()
if CheckBox2.Value Then
--- Code
end if
End Sub
Sub RadioButton1_Click()
if RadioButton1.Value Then
--- Code
End If
End Sub
Sub UserForm_Init()
CheckBox1_Click()
CheckBox2_Click()
RadioButton1_Click()
End Sub
NOTE: If your custom function UserForm_Init is not in the Form's code module, you'll need to qualify the procedure names, e.g.:
Sub UserForm_Init()
UserForm1.CheckBox1_Click()
UserForm1.CheckBox2_Click()
UserForm1.RadioButton1_Click()
End Sub
Additional complexity may arise based on your implementation, but I hope this will get you started.
You're missing parts of code in your example; it's hard to determine what you're trying to do without a clear picture. It is possible to call an event procedure from another, it's a bad idea for a number of reasons.
Instead of calling a private procedure like you're trying to, sort of like this:
Private Sub myEvent()
'event code here
End Sub
Sub mySub()
myEvent()
End Sub
...you're better off to move the code that you need to be shared to a shared module, kind of like this:
Public Sub mySubInSharedModule()
'event code here
End Sub
Private Sub myEvent()
Call mySubInSharedModule()
End Sub
Public Sub mySub()
Call mySubInSharedModule()
End Sub
There are numerous articles explaining this further, on this site and others. To get you started, see this search as well as this Stack Overflow question.
First time poster but long time reader. I finally have a question that is either not here or I simply can't phrase it correctly enough to return an answer.
What I'm trying to achieve is to have a single sub that I can call from other subs, that is 90% the same for everything and only changes the last 10% based on the sub that called it (possibly via an IF statement)
maybe something like:
Sub A()
Call Main
End Sub
Sub B()
Call MAIN
End Sub
Sub MAIN()
If Sub A called Sub MAIN Then
Answer = 1
elseif: Sub B called Sub MAIN Then
Answer = 2
Endif
End sub
I'm thinking this may not be possible but would be great to use something like this rather than writing a heap of almost identical subs.
Any advice is appreciated!
Just pass an optional parameter if it's called from a specific location:
Sub A()
MAIN
End Sub
Sub B()
MAIN True
End Sub
Sub MAIN(Optional fromB As Boolean = False)
If fromB Then
Answer = 2
Else
Answer = 1
End If
End Sub
Please take a look at the code:
'' the sub I can call manually to see if the whole thing works
'' (and it does)
Sub ManualSubTest()
Call SendNotification
End Sub
'' this is the function I need to refer to from the IF formula
'' when I do, Ontime does not work
Function SendNotification()
SendNotificationAction
Debug.Print ("first step...")
End Function
'' the main sub that will perfom the action
Private Sub SendNotificationAction()
'' do something here
Application.OnTime Now + TimeValue("0:00:05"), "SendNotificationCallback"
End Sub
'' this is the callback that normally triggers the action code again
Private Sub SendNotificationCallback()
''SendNotificationAction
'' or
''Call SendNotificationAction
Debug.Print ("OK!")
End Sub
Everything works fine when I call the ManualSubTest sub manually from the macro menu. As you can see, all it does is trigger the SendNotification function. In the end result I see the "OK!" message in the Immediate Window.
But I need that SendNotification function to work when I call it from a worksheet IF condition, i.e. =If($A$1=1; SendNotification(); ""), and for some reason it does not. It just stops right before the Ontime call.
What's the difference? Do the Functions vs. Subroutines limitations apply? Please help. Thanks
try to add a
application.enableevents=true
in the function, just before the onaction
When using Sub's, if I'm not returning a value, is it necessary to use:
Public Sub whatever()
...
Exit Sub
End Sub
instead of just
Public Sub whatever()
...
End Sub
Do I gain anything (memory, speed, etc.) by using "Exit"?
Does the Sub exit anyway when it is done even if I don't use the "Exit" statement?
Thanks.
In this particular case Exit Sub is completely unnecessary. It can be used there but is generally considered bad style. The statement is necessary when you want to prematurely leave the method. For example if you detect a specific condition is met and you don't want to execute the rest of the method
Public Sub Example()
If SomeCondition Then
Exit Sub
End If
' Do other work
End Sub