How do I pass a form to a function?

2367
9
03-31-2011 02:29 PM
JillFritz
New Contributor
How do I pass a form to a function?

Since I have multiple forms which each contain a combo box listing the same Editor names, I am trying to programmatically pass each form (at initialization) to a function which populates the Editor Names combo box with the desired values (from a standalone table). My code is below:


Private Sub UserForm_Initialize()[INDENT]PopulateEditorNameComboBox(thisForm) 'Call function from form[/INDENT]End Sub


Public Function PopulateEditorNameComboBox(passedForm as <?>)
[INDENT]For i = 1 to EditorNameCollection.Count
[INDENT]passedForm.cboEditor.AddItem (EditorNameCollection.item(i)) 'Add item to combo box on indicated form[/INDENT]
Next i[/INDENT]
End Function


Thanks, Jill USFS Region 6
0 Kudos
9 Replies
MichaelRobb
Occasional Contributor III
Well, not quite sure what you are trying to attempt.. but I see a few things.
a) There is NO need for a function, your not sending a return value.

so

as for the Form. IF its all in the same CLASS, just use me.
Are you suggesting that sub UserForm is a Different form than THISForm?



Private Sub UserForm_Initialize()

    PopulateEditorNameComboBox()

End Sub


Public Sub PopulateEditorNameComboBox()

    For i = 1 to EditorNameCollection.Count

        me.cboEditor.AddItem (EditorNameCollection.item(i)) 'Add item to combo box on indicated form

    Next i

End Function


There are many methods to pass data between forms if that is what you are doing...

Delegates / Properties /contructor / object
0 Kudos
JillFritz
New Contributor
If I only needed the function to load the combo box on one form, I could simply type FormName.cboEditor.AddItem and the function would work fine. The form name would be essentially "hard-coded" and I would not need to pass any argument. (I tested this and it works well).

I am trying to use my external function, named PopulateEditorNameComboBox (which is located in the Modules folder), to populate the same combo box located on several forms. In other words,

If Form1 calls the function, then the function performs Form1.cboEditor.AddItem.
If Form2 calls the function, then the function performs Form2.cboEditor.AddItem
If Form3 calls the function, then the function performs Form3.cboEditor.AddItem and so on.

A non-object variable, such as a string or variant variable named passedForm for example (passedForm.cboEditor.AddItem) returns an error of "Object doesn't support this object or method".

I am looking for help on what argument assignment (i.e. passedForm as <???>) to use to make this work.

@Mike.robb:
Thank you for responding to my post. "Me" is a VBA keyword that a form uses to refer to itself (I am more accustomed to using this in Excel or Access); so I would not expect this to work in an external function. Nevertheless, I attempted me.cboEditor.AddItem (AddressCollection.item(i)) which returned a "Compile error: Invalid use of Me keyword".

Regarding your statement that there is no need for a function: The function returns a boolean value which is not evident in the trimmed code I included in my post (extraneous code was not pertinent to my question)

Regarding your confusion about my use of UserForm and thisForm: UserForm_Initialize is built-in, default syntax for initialization of any form regardless of form name. In other words, if you have 3 forms (Form 1, Form 2, and Form 3), each form will have an initialization subroutine of "Private Sub UserForm_Intialize().

Thank you for the opportunity to better clarify what I need.
Regards, Jill USFS Region 6



Well, not quite sure what you are trying to attempt.. but I see a few things. 
a) There is NO need for a function, your not sending a return value. 

so 

as for the Form. IF its all in the same CLASS, just use me.  
Are you suggesting that sub   UserForm is a Different form than   THISForm



Private Sub UserForm_Initialize()

    PopulateEditorNameComboBox()

End Sub


Public Sub PopulateEditorNameComboBox()

    For i = 1 to EditorNameCollection.Count

        me.cboEditor.AddItem (EditorNameCollection.item(i)) 'Add item to combo box on indicated form

    Next i

End Function


There are many methods to pass data between forms if that is what you are doing... 

Delegates / Properties /contructor / object
0 Kudos
NeilClemmons
Regular Contributor III
Since the method is loading a combobox, pass in the combobox, not the form.  If you pass in the form then the method will not know which control on the form it should be loading.

Public Function LoadCombobox(comboBox As ComboBox) As Boolean
  ' do whatever.
End Function

' call the method from the form.
LoadComboBox(Me.theCombobox)
0 Kudos
JillFritz
New Contributor
Neil, using the following code with your recommended changes, I received an error "Object required". Did I misinterpret your instructions?

Private Sub UserForm_Initialize()
On Error GoTo EH

[INDENT] 'Load Editor combobox
PopulateComboBoxes (Me.cboEditor)
If cboEditor.ListIndex > 0 Then cboEditor.ListIndex = gi_Editor[/INDENT]
Exit Sub
EH:
MsgBox Err.Description, vbInformation, "Initialize Annotation Edit Form"
End Sub


Since the method is loading a combobox, pass in the combobox, not the form. If you pass in the form then the method will not know which control on the form it should be loading. 

Public Function LoadCombobox(comboBox As ComboBox) As Boolean
  ' do whatever.
End Function

' call the method from the form.
LoadComboBox(Me.theCombobox)
0 Kudos
NeilClemmons
Regular Contributor III
What does your PopulateComboboxes method look like now?  You should have changed the method definition to take a combobox as a parameter and also updated the code to reference this parameter.  Something like this:

Public Function PopulateComboxes(combobox as Combobox)
  combobox.AddItem("hello")
  combobox.AddItem("world")
End Function
0 Kudos
JillFritz
New Contributor
Public Function PopulateComboBoxes(cboEditor As ComboBox) as Boolean
                [INDENT]cboEditor.AddItem (AddressCollection.item(i))[/INDENT]
End Function

The error occurs in the UserForm_Initialize subroutine.


What does your PopulateComboboxes method look like now?  You should have changed the method definition to take a combobox as a parameter and also updated the code to reference this parameter.  Something like this:

Public Function PopulateComboxes(combobox as Combobox)
  combobox.AddItem("hello")
  combobox.AddItem("world")
End Function
0 Kudos
MichaelRobb
Occasional Contributor III
My apologies for mis-understanding, Jill.
I suggested My. as within a class, that works in .net for any form and yes, of course it would not work if the function is outside the form class.
I am aware every form will have an initialize, its Private Sub InitializeComponent() or your probably referring to FormLoad ? there is no Initialize as you put it that I see in vb.net for a declaration.

So the function is all on its own (separate class). Ok, which is calling a table.  Sorry, I would just have the function in each form class... not sure how this would be achieved.  Neil will hopefully guide you in the right direction and I will learn something.
0 Kudos
NeilClemmons
Regular Contributor III
Here's an mxd (version 9.3.1) that contains two user forms and module with a public method for loading a combobox.  Both of the forms call this method in their Initialize event.  Hopefully this will help!
0 Kudos
JillMasters
New Contributor
Thank you. Thank you, Neil!!

This did it (passing 3 combo boxes):

Private Sub UserForm_Initialize
[INDENT]PopulateComboBoxes cboEditor, cboForest, cboSourceCode 'Without the "me" or enclosing parentheses!![/INDENT]End Sub


Public Function PopulateComboBoxes(cboEditor as ComboBox, cboForest as ComboBox, cboSourceCode as ComboBox) as Boolean
[INDENT]do stuff[/INDENT]
End Function


Jill, USFS Region 6
ecohydrologist (ESRI Global Account)
previously known as "geophotog" (GIS Online Account)


Here's an mxd (version 9.3.1) that contains two user forms and module with a public method for loading a combobox. Both of the forms call this method in their Initialize event. Hopefully this will help!
0 Kudos