A MSForms.Userform object exposes only a very limited set of properties.
Moreover, the UserForms collection only includes forms that have been loaded,
not all the forms that exist in a project.
The actual form that you access in code (e.g., UserForm1.Caption = "Test") is an
instance of the class that defines that form, e.g. UserForm1. VBA compiles code
that is essentially the same as
Dim UserForm1 As New UserForm1
The 'New' keyword declare the variable as an 'auto-instancing' variable, and
this tells VBA to emit code like
Set UserForm1 = New UserForm1
before any reference in code to 'UserForm1'. Therefore, your code
Debug.Print UserForm1.Name
actually is compiled as
If UserForm1 Is Nothing Then
Set UserForm1 = New UserForm1
End If
Debug.Print UserForm1.Name
When you use "UserForm1" in your code, you are actually dealing with the
variable UserForm1 (on the left side of the 'As') rather than the class
UserForm1 (on the right side of the 'As').
Properties such as Name and Width are properties of the class (and variable)
UserForm1, not of the UserForm variable that you access via the UserForms
collection object.
> where it is required to define the type as a Userform?
If you declare the index variable used to iterate through UserForms as a generic
object, rather than As MSForms.UserForm, you can reference all of the properties
you expect. For example,
Dim UF As msforms.UserForm
Dim Obj As Object
Load UserForm1
Load UserForm2
For Each Obj In UserForms
Debug.Print Obj.Caption, Obj.Width
Next Obj
For Each UF In UserForms
Debug.Print UF.Caption
Next UF
Here, the declaration 'As Object' gives you access what you expect, whereas 'As
MSForms.UserForm' does not. The difference is that they are referencing
different things at runtime.
In what circumstances do you require the variable to be declared As UserForm?
You may be able, depending on the circumstances, to declare the variable 'As
Object'. Then, you can with the form itself, to use the 'Me' reference to pass
a reference of the actual (running) Userform to another procedure. E.g.,
[in a standard code module]
Function Test(Obj As Object) As String
Test = Obj.Caption
End Function
[in a userform's code module]
Private Sub CommandButton1_Click()
MsgBox Test(Me)
End Sub
I think that the UserForm object actually refers to the client area inside what
you view as a form -- in other words, the title bar (where the caption and the
'X' button reside) is not part of the UserForm object itself. For example, the
Caption property of the MSForms.Userform object is not the same as the Caption
of the (loaded) user form. To see the difference, place two command button on a
user form, and then use the following code.
[in a standard code module]
Sub SetCaption(Obj As MSForms.UserForm)
Obj.Caption = "Some Text"
End Sub
Sub SetCaption2(Obj As Object)
Obj.Caption = "Some Text"
End Sub
[in a userform's code module]
Private Sub CommandButton1_Click()
SetCaption Me
End Sub
Private Sub CommandButton2_Click()
SetCaption2 Me
End Sub
You'll notice that the Caption property refers to different things depending on
how the argument to declared in the procedure.
I hope this had shed some light on the issue, and not made things more
confusing.
--
Cordially,
Chip Pearson
Microsoft MVP - Excel
Pearson Software Consulting, LLC
www.cpearson.com ch...@cpearson.com
"Wessel" <wva...@qatar.net.qa> wrote in message
news:#MqF0bI3BHA.2208@tkmsftngp05...
Thanks, your reply did shed a lot of light on the subject. The reason
why I originally wanted to specify MSForms.Userform, was to have in a
class module:
"Public WithEvents BaseForm as MSForms.Userform", where I wanted to
assign certain default actions to new UserForms added as VBComponents.
Your reply has however shown that it is not necessary to do this through
code, since I could use the class defined by UserForm1 (after I also
realized that events also differ - e.g. Layout instead of Resize).
There is still plenty that I do not understand - e.g. if I have defined
a prodecure requiring a parameter of MSForms.Userform, why do I not get
an error when passing Userform1 (or any other member of Userforms) as
parameter to this procedure?
e.g. Project containing Userform1
Example Module 1:
Sub Proc1(mForm as MSForms.Userform)
MsgBox (uForm.Caption)
End Sub
Sub Main
Call Proc1(UserForm1) ' I would have expected
' a "ByRef argument type mismatch" here
End Sub
In this example, since class UserForm1 is not the same as
MSForms.Userform, I would have expected an error when passing a
parameter type other than MSForms.UserForm to Sub Proc1?
Thanks again for the speedy detailed reply - it helped me a lot.
Wessel
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!