【问题标题】:Compile error: Only user-defined types defined in public object modules can be coerced to or from a variant or passed to late-bound functions编译错误:只有在公共对象模块中定义的用户定义类型才能被强制转换为变体或从变体强制转换或传递给后期绑定函数
【发布时间】:2017-09-05 07:58:00
【问题描述】:

我正在为一点点 VBa 和 Excel 苦苦挣扎。我需要在 VBa 中创建一个结构,即Type。我遇到的问题是,当我尝试执行代码时收到错误消息!我觉得我需要解释一下我是如何到达这里的,以防我犯了错误。

我已经读过要创建一个类型,它需要被公开。因此,我创建了一个新类(在类模块下)。在Class1,我写了

Public Type SpiderKeyPair
    IsComplete As Boolean
    Key As String
End Type

ThisWorkbook 内我有以下内容

Public Sub Test()    
    Dim skp As SpiderKeyPair
    skp.IsComplete = True
    skp.Key = "abc"    
End Sub

没有其他代码。我遇到的问题是我收到错误消息

无法在对象模块中定义公共的用户定义类型

如果我将类型设为私有,则不会出现该错误,但我当然无法访问该类型的任何属性(使用 .NET 术语)。

如果我将代码从 Class1 移到 Module1 中,它可以工作,但是,我需要将它存储到一个集合中,这就是它出错的地方,也是我卡住的地方。

我已将我的Test 更新为

Private m_spiderKeys As Collection 

Public Sub Test()                
    Dim sKey As SpiderKeyPair
    sKey.IsComplete = False
    sKey.Key = "abc"            
    m_spiderKeys.Add (sKey)    'FAILS HERE            
End Sub

只有在公共对象模块中定义的用户定义类型才能被强制转换为变体或从变体强制转换或传递给后期绑定函数

我对此进行了调查,但我不明白我需要做什么...如何将 SpiderKeyPair 添加到我的收藏中?

【问题讨论】:

    标签: vba


    【解决方案1】:

    遇到完全相同的问题并浪费了大量时间,因为错误信息具有误导性。我想念 List。

    在 Visual Basic 中,您不能真正将所有内容都视为对象。您的结构和类在内存分配上有所不同:https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/structures-and-classes

    Type 是一种结构(数组也是如此),所以如果你想要它们的“列表”,你最好使用 Array 以及它附带的所有东西。

    如果你想用一个Collection来存储一个“List”,你需要为要处理的对象创建一个Class。

    并不令人惊奇...但这是该语言可用的。

    【讨论】:

      【解决方案2】:

      您似乎缺少OOP 的基本知识,或者误认为VBAVB.NET。或者我不明白你想做什么。无论如何,请尝试以下操作:

      在一个模块中这样写:

      Option Explicit
      
      Public Sub Test()
      
          Dim skpObj          As SpiderKeyPair
          Dim m_spiderKeys    As New Collection
          Dim lngCounter      As Long
      
          For lngCounter = 1 To 4
              Set skpObj = New SpiderKeyPair
              skpObj.Key = "test" & lngCounter
              skpObj.IsComplete = CBool(lngCounter Mod 2 = 0)
              m_spiderKeys.Add skpObj
          Next lngCounter
      
          For Each skpObj In m_spiderKeys
              Debug.Print "-----------------"
              Debug.Print skpObj.IsComplete
              Debug.Print skpObj.Key
              Debug.Print "-----------------"
          Next skpObj
      
      End Sub
      

      在名为SpiderKeyPair 的类中写下:

      Option Explicit
      
      Private m_bIsComplete   As Boolean
      Private m_sKey          As String
      
      Public Property Get IsComplete() As Boolean
          IsComplete = m_bIsComplete
      End Property
      
      Public Property Get Key() As String
          Key = m_sKey
      End Property
      
      Public Property Let Key(ByVal sNewValue As String)
          m_sKey = sNewValue
      End Property
      
      Public Property Let IsComplete(ByVal bNewValue As Boolean)
          m_bIsComplete = bNewValue
      End Property
      

      当您在模块中运行 Test Sub 时,您会得到:

      Falsch
      test1
      -----------------
      -----------------
      Wahr
      test2
      

      注意你如何初始化新对象。它发生在New这个词上。集合是对象,也应该使用 New 进行初始化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 1970-01-01
        • 2011-06-23
        • 2016-10-13
        • 1970-01-01
        相关资源
        最近更新 更多