PDA

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



RECrerar
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
http://www.vbaexpress.com/forum/showthread.php?t=16645&highlight=caller

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
.Show
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

xld
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?

RECrerar
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
Unload...

' some other stuff
etc

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

xld
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"
Alert.Show


In Panel,



Alert.Caller = "Panel"
Alert.Show


Then in the Alert Activate event



Private Sub Userform_Activate()

Select Case Caller

case "Coords": Unload Coords
Case "Panel": Unload Panel
'etc
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.

RECrerar
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.

RECrerar
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"
Alert.Show

I just have

Caller = "Coords"
Alert.Show

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.

xld
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.

RECrerar
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
TempSheet.Delete
BracketSheet.Delete
On Error GoTo 0

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

' 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

xld
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?

RECrerar
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.