View Full Version : Caller Userform (xld - question about your code)

01-10-2008, 07:08 AM
I have a userform (called Alert) that can be called from 8 other userforms. The Alert form basically just unloads the form that called it and then terminates execution of the program. I am looking for a neat way to tell which form called Alert so that it doesn't attempt to unload forms that are not loaded.

I found the following code from xld at the link below

In userform

Public Caller As String

Private Sub UserForm_Activate()
MsgBox Caller
End Sub

in module

Public Sub ShowMyForm()
Dim myForm As UserForm1
Set myForm = New UserForm1
With myForm
.Caller = Application.Caller
End With
End Sub

However I don't really understand how it works and how I need to adapt it to make it specific to my program. If Xld or anyone else could explain it to me it would be appreciated

01-10-2008, 07:23 AM
It is based upon the fact that the worksheet has many buttons that could launch the form, and it passes the button details to the form, so it (the form) can process according to the caller.

What exactly are you tryig to do?

01-10-2008, 07:39 AM
As a bit more information

Basically at several points in the execution of the program the user may be required to enter data in which case the appropriate userform is shown. If the user choses to Cancel rather than enter the data my serform called Alert is shown. This form warns the user that the program can not continue without their input and gives them the choice of returning to the userform they were on or exiting the program.

If they choose to exit the program, Alert then unloads itself and whichever form called it and terminates the program.

Currently I am using

In Alert

Public FromAlert as Boolean
FromAlert = True
Unload Coords
Unload panel

' some other stuff

This doesn't error but loads every userform that is not already loaded before unloading it, not only does this seem like a waste of resorces and processing power, the initialisation events on many of the form involve variables that may not have been defined but the point that Alert is called, which obviously causes the program to crash. I have got round this by in each form affected by adding a FromAlert variable that stops the initialisation events being performed if the the variable is set to True which is done in the alert form, so in each affected userform the code is as follows

If FromAlert = False
'Initialisation events
End If
fromAlert = False

This all seems very messy and ineficient, and I hope it explains why it would be better if I could determine which form called the Alert form so that I only try and unload that form. The idea situation would be something along the lines of:

In Alert

Select Case caller
Case Coords: Unload Coords
Case Panel: Unload Panel
End Select

01-10-2008, 08:17 AM
Create a public variable in the Alert userform, and prior to showing Alert, load it with the caller userform, similar to what I am doing. So in Alert, before any event procedures you would declare

Public Caller As String

Then, for instance, in Coords you would have code like

Alert.Caller = "Coords"

In Panel,

Alert.Caller = "Panel"

Then in the Alert Activate event

Private Sub Userform_Activate()

Select Case Caller

case "Coords": Unload Coords
Case "Panel": Unload Panel
End Select
End Sub

Better would be to hide it before here, and on the Alert exit, re-show the same caller form, and exit there cleanly. Just more structured IMO.

01-10-2008, 08:39 AM
Better would be to hide it before here, and on the Alert exit, re-show the same caller form, and exit there cleanly. Just more structured IMO.

I would like the user to be able to see the form while alert is shown, just my own personal preference.

If I unload the form from within itself after the actions on the alert form were performed I would still need a variable to tell me which command button on the alert form was used as I only want to unload the original form if [Exit] is selected and not if the user selects [Back]. This would be easy enough to do but I can't really see the advantage of it over closing the from from the alert [Exit] command. I am happy to be wrong but it seems like a neater solution to me to keep all the exit instructions in the same place.

01-10-2008, 08:58 AM
Okay, well I've implemented your code, I was finding that it wasn't assigning any value to Caller, so I have changed it that Caller is defined as a public variable in a module and in each form instead of.

Alert.Caller = "Coords"

I just have

Caller = "Coords"

And it's working properly. Thanks for the help and advice, I'm sure a lot of my program is not writen in the best way but I think I am slowly getting better. If you can think why your version wasn't working for me then I would be interested to know, else I will stick with my variation.

01-10-2008, 09:05 AM
In Alert, how do you know which vrariable to read?

Without seeing the code, I would only be guessing.

01-10-2008, 09:09 AM
Sorry, am a bit confused by what you're asking there. The code I have in the Alert form is as follows

Private Sub Back_Click()
Unload Me
End Sub

Private Sub Exit_Click()

Unload Me
On Error Resume Next 'This is because one or both of these sheets may not exist
On Error GoTo 0

' Change IERROR to true
' This is the tracking variable used to tell the program to exit

' Unload whichever userform is open
Select Case Caller
Case "Satelitte": Unload SpacecraftForm
Case "GCError": Unload GlobalCoordsError
Case "GC": Unload GlobalCoords
Case "Panel": Unload PanelError
Case "Clamp": Unload NoClamp
Case "Flange": Unload NoFlange
Case "SB": Unload NoSparkBend
Case "WGCheck": Unload WGCheck
End Select
End Sub

I only ever use Caller to asign the name of the other userforms

The code in the other userforms is in the above post

01-10-2008, 09:14 AM
But presumably the other code has changed to load Caller?

Did you precede Caller with Alert in the calling form?

01-10-2008, 09:37 AM
I believed I've figured out the problem.

If I use Alert.Caller to record the to form that called Alert then this variable is forgotten by the program as soon as the Alert form is unloaded and I was unloading the alert form before the code that needed to use the Caller variable.

If I just hide the alert form initially I can then use the variable to unload the caller form and then unload the Alert form after this action has taken place.