将userform声明为Object与MSForms.Userform之间的区别?

CBR*_*F23 5 vb6 vba userform

只是一个我似乎无法找到答案的问题.

我是以编程方式创建用户表单,我发现如果我将对象声明为"MSForms.Userform"类型,似乎无法设置高度和宽度,因为这些属性不存在,并且内部高度/ insidewidth是只读属性.

我发现如果我将它声明为通用类型"对象",我可以设置高度和宽度属性并完全按照我的意愿使用它.

因此,在我初始化对象后,我检查了本地窗口,差异似乎是:

  • 当声明为"object"类型时,它将初始化为"UserForm1"类型的实例
  • 当声明为"MSForms.Userform"类型时,它将初始化为"UserForm"类型的实例

所以我的问题是,使用不同的声明语句有什么区别?

谢谢!

编辑:添加了一些示例代码,以便您可以看到oject在声明方式不同时的行为方式.
(我无法正确显示此代码块 - 即使声明为基本语言)

Sub TestUserForm()  
'NOTE:  You need to add a reference to Microsoft Visual Basic
'       for Applications Extensibility 5.3  

'Declare variables  
    Dim oForm           As MSForms.UserForm  
    Dim oForm1          As Object  
    Dim oComp           As VBComponent  
    Dim oComp1          As VBComponent  

'Create new form objects in the VBA project programmatically  
Set oComp = Application.VBE.ActiveVBProject.VBComponents.Add(ComponentType:=vbext_ct_MSForm)  
Set oComp1 = Application.VBE.ActiveVBProject.VBComponents.Add(ComponentType:=vbext_ct_MSForm)  

'Initailize an object of each new form  
    Set oForm = VBA.UserForms.Add(oComp.Name)  
    Set oForm1 = VBA.UserForms.Add(oComp1.Name)  

'Compare what happends when trying to set the width and height properties  
    With oForm1     'This works  
        .Height = 200  
        .Width = 100  
    End With  

    With oForm1     'This does not work  
        .Properties("Width") = 100  
        .Properties("Height") = 200  
    End With  

    With oForm      'This does not work  
        .Height = 200  
        .Width = 100  
    End With  

    With oForm      'This does not work  
        .Properties("Width") = 100  
        .Properties("Height") = 200  
    End With  

'Remove the forms from the project  
    Application.VBE.ActiveVBProject.VBComponents.Remove oComp  
    Application.VBE.ActiveVBProject.VBComponents.Remove oComp1  
End Sub  
Run Code Online (Sandbox Code Playgroud)

Rub*_*uck 10

当您导入组件到项目中,将它命名UserForm1可能 UserForm2分别.

oForm == UserForm1

oForm1 == UserForm2

现在,查看对象MSDN文档,我们发现:

在过程运行之前,如果不知道特定对象类型,则可以使用Object数据类型声明对象变量.使用Object数据类型创建对任何对象的泛型引用.

你已经声明了这样的变量:

Dim oForm           As MSForms.UserForm  
Dim oForm1          As Object  
Run Code Online (Sandbox Code Playgroud)

因此,初始化对象时会发生的事情oForm被初始化为UserForm,而运行时确定Object oForm1是UserForm1的实例,这不是同一个事情.

尝试在初始化之前更改oForm1的组件名称,您应该很快就会发现它们之间存在差异.

现在,如果您希望将类型安全性声明为通用表单并且您想要访问该Width属性,则可以将UserForm强制转换为Object并像这样访问它.

Dim FormAsForm As UserForm
Dim FormAsObject As Object

Set FormAsForm = New UserForm1
Set FormAsObject = FormAsForm

FormAsObject.Width = 200

Debug.Print TypeName(FormAsForm)
Debug.Print TypeName(FormAsObject)
Run Code Online (Sandbox Code Playgroud)

这是我们在实现多个接口时经常使用的技巧.编译器只允许您使用在声明类对象的特定类型中定义的属性.


那有什么区别?实际上,在将事物声明为Object时,您没有智能感知.你也没有类型安全.这样做完全有效(虽然不推荐.)

Dim foo As New Baz
Dim bar As New Qux
Dim var As Object

Set var = foo
Set var = bar
Run Code Online (Sandbox Code Playgroud)

当您使用后期绑定时,对象确实非常方便,以避免添加对项目的引用.如果没有添加引用,您将被迫使用未知类型.

Dim xl As Object
Set xl = CreateObject("Excel.Application")
Run Code Online (Sandbox Code Playgroud)

另一个很大的区别是你将它留给运行时来确定变量将是什么类型的对象.正如您所发现的,它有时(很少,但有时)会产生令人惊讶的结果.