【问题标题】:Can UDT's be used as method parameters in any way?UDT 可以以任何方式用作方法参数吗?
【发布时间】:2016-11-16 14:35:15
【问题描述】:

多年来,我一直避免在 VBA 中使用 Public Type UDT,因为它们很难传递,而且我从来没有真正费心去理解为什么.. 直到现在 - 创建一个更容易类模块并使用实际对象代替。

但最近我试了一下,一旦我认为必须将它们传递给 ByRef(就像数组一样),事情开始看起来我可以开始使用它们了。

所以我在标准模块中定义了一个Public Type,得到了这个编译错误:

所以我把Public Type移动到一个类模块中,创建了PublicNotCreatable类,然后得到了这个编译错误:


这里有一些代码可以重现编译错误。

类模块“某事”:

Option Explicit
' cannot define a public user-defined type within an object module
Public Type TSomething
    Foo As Integer
End Type

Public Function Create(ByRef info As TSomething) As Something
End Function

如果您将TSomething 的定义移至标准模块,您将得到另一个编译器错误,告诉您必须在公共对象模块(即类模块)中定义公共UDT...带你回到第一格。


所以如果你不能在类模块中定义Public Type,为什么编译器会抛出一个合适甚至提及“在公共对象模块中定义的公共用户定义类型”如果这样的事情可以'不合法存在?

它是否在 VB6 中工作并且编译器消息是该版本的残余?或者是COM如何工作的原因?只是我还是两个错误消息相互矛盾?还是有什么我不明白的地方?

显然我在这里误用/滥用了 UDT。那么它们应该用于什么,如果不是将“记录”传递给某个方法呢?

【问题讨论】:

    标签: vba com vb6 user-defined-types


    【解决方案1】:

    从标准模块它可以正常工作,没有任何错误。以下代码没有报错。

    Public Type TEST_TYPE
        Prop1   As String
    End Type
    
    Public Function fTest(ByRef param1 As TEST_TYPE) As String
        param1.Prop1 = "Hello from function"
    End Function
    
    Public Sub sTest(ByRef param1 As TEST_TYPE)
        param1.Prop1 = "Hello from Sub"
    End Sub
    
    Public Sub caller()
    
        Dim p   As TEST_TYPE
    
        '/Call Sub
        Call sTest(p)
    
        MsgBox p.Prop1
    
        '/Call Function
        Call fTest(p)
    
        MsgBox p.Prop1
    
    End Sub
    

    UDT 的一个问题是关于前向引用。所以这不会编译,除此之外它与标准模块完美配合。

    Public Type TEST_TYPE
        Prop1   As String
        Prop2   As TEST_TYPE2 '/ Fails due to Forward referencing. TEST_TYPE2 should be declared before this UDT.
    End Type
    
    Public Type TEST_TYPE2
        Prop3   As String
    End Type
    

    编辑:

    但是,在课堂上使用 UDT 的解决方法是 Friend

    类的 VBA 代码

    '/ Using UDT in VBA-Class
    Private Type TEST_TYPE3
        Prop3   As String
    End Type
    
    Public Sub caller()
    
        Dim p As TEST_TYPE3
        p.Prop3 = "Hello from Class"
        Call testClassUDT(p)
    
    End Sub
    
    Friend Sub testClassUDT(p As TEST_TYPE3)
        MsgBox p.Prop3
    End Sub
    

    【讨论】:

    • 所以 UDT 可以是 procedurefunction(即标准模块中的过程代码)的参数,但不能是 方法(即类模块成员) - 为什么?为什么编译器会提及“在公共对象模块中定义的公共用户定义类型”,如果这些是完全非法的?
    • 老实说,我不知道这种行为背后的原因。但是要在课堂上使用 UDT,您可以 Friend 为您的子/功能。查看编辑。
    • 我不喜欢Friend,因为它使工厂方法无法用于引用项目,但现在我将使用它运行,因为它可以工作而且我不需要 this 暴露给其他 VBA 项目的代码。
    • 实际上,如果我为 UDT 成员公开一个 getter 属性,我会收到一个关于将 UDT 强制转换为 Variant 的新编译器错误。这是没有希望的。
    【解决方案2】:

    这是一个作为参数传递的类型一个类方法,并由一个类方法返回

    首先是 SomeClass 类(不需要是 PublicNotCreatable)

    Option Explicit
    
    Sub test(foo As TFooBar)
      Dim s As String
      s = foo.foo
    End Sub
    
    Function ReturnTFoo() As TFooBar
      ReturnTFoo.bar = "bar"
      ReturnTFoo.foo = " bar"
    End Function
    

    模块:

    Option Explicit
    
    Public Type TFooBar
      foo As String
      bar As String
    End Type
    
    Sub test()
      Dim c As SomeClass
      Set c = New SomeClass
      Dim t1 As TFooBar
      Dim t2 As TFooBar
      t1.bar = "bar"
      t1.foo = "Foo"
      c.test t1
    
      t2 = c.ReturnTFoo
    End Sub
    

    【讨论】:

    • 以为我已经编译过了,但不,它没有。
    猜你喜欢
    • 2011-11-09
    • 2013-10-19
    • 2010-11-07
    • 2014-09-11
    • 2015-12-29
    • 2023-03-29
    • 1970-01-01
    • 2016-07-02
    • 2021-10-29
    相关资源
    最近更新 更多