5

I am trying to write a macro that has a portion that reacts differently depending on whether it is called directly from a button in the worksheet, or called indirectly from another macro. I also want to be able to have it react differently depending on which other macro has called it

In this case, if the macro is activated manually by the button or if it has been run by a particular other macro, it pops up a msgbox to let the user know that it has been completed successfully, but if the same macro is run by another macro, then I want to skip that step.

Is there a way do this?

Community
  • 1
  • 1
wrcathey
  • 53
  • 1
  • 4
  • 3
    Maybe `Application.Caller` can be used? [link](http://msdn.microsoft.com/en-us/library/ff193687.aspx) – Socii Oct 29 '14 at 16:15
  • @Sociithat: That is a valid answer. :) I was about to post an answer with that. You may want to post it as an answer. Include a sample code as well :D – Siddharth Rout Oct 29 '14 at 16:27
  • That won't give you the name of a calling macro though. – Rory Oct 29 '14 at 16:30
  • True @rory but the question is to determine what called it? Procedure or a shape – Siddharth Rout Oct 29 '14 at 16:31
  • @SiddharthRout That's only part of it: "I also want to be able to have it react differently depending on which other macro has called it" – Rory Oct 29 '14 at 16:32
  • @Rory: I think I may have misunderstood what OP wants here. What I understood is that if a procedure called it then perform some action and if a shape called it then perform some other action. But now since you have provided a different perspective, I guess I will have to wait to see what OP meant. – Siddharth Rout Oct 29 '14 at 16:35
  • Thanks @SiddharthRout. It's been a while since I used `Application.Caller` so didn't have any code to hand. Interesting link for the procedure stack also. – Socii Oct 29 '14 at 16:51
  • @wrcathey you might want to check [this](http://stackoverflow.com/questions/3792134/get-name-of-current-vba-function) post as well – Ioannis Oct 29 '14 at 19:50

2 Answers2

3

You could do this by passing arguments to the subroutines. Here's a very basic example:

Sub test(number, displayMessage)
MsgBox ("The number is " & number)
If displayMessage Then MsgBox ("You ran the B sub")
End Sub

Sub aSub()
Call test(4, False)
End Sub

Sub bSub()
Call test(7, True)
End Sub

Try running both aSub and bSub. Hope this helped.

quantum285
  • 1,032
  • 2
  • 11
  • 23
  • This is the way I prefer to do it. Have a separate entry procedure for each entry point rather than one procedure for each entry point. To me, it keeps the code cleaner and easier to maintain. – Dick Kusleika Oct 29 '14 at 18:23
  • I think I may have to do it this way. I suppose I was hoping that there was something similar to `Application.Caller` that would show the calling sub, but I'm starting to think it doesn't exist. – wrcathey Oct 29 '14 at 19:21
3

Here is one way which will work for Shapes/Procedures

Dim SSub As String

Sub Sample()
    On Error Resume Next
    SSub = Application.Caller '<~~ Already suggested by @Socii
    On Error GoTo 0

    Debug.Print "This procedure was called by " & SSub
End Sub

Sub Example()
    SSub = "Example" '~~> (Also see the link below)
    Sample
End Sub

You may also want to read THIS if you want to take it to a different level. :)

Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250