
Userform Properties not available in MSForms.Userform
Wessel,
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.
Quote:
> 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
Quote:
> SunflowerWhen I define an object as MSForms.Userform, it appears as if it is
> not the same object as an Userform in the Userforms collection. Properties
> like Name and Width also does not seem to be available with the
> MSForms.Userform type. Any ideas why this is so, and how to overcome the
> limitation if I wanted to use e.g. the Name property of a Userform, where it
> is required to define the type as a Userform?