编译错误:只能将公共对象模块中定义的用户定义类型强制转换为变量或从变量强制转移或传递给后期绑定函数

时间:2017-09-05 07:58:00

标签: vba

我正在努力学习一点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添加到我的收藏中?

2 个答案:

答案 0 :(得分:1)

您似乎缺少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进行初始化。

答案 1 :(得分:1)

发生了完全相同的问题并浪费了很多时间,因为错误信息具有误导性。我想念List <>。

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

类型是一种结构(数组也是一种结构),因此,如果要它们的“列表”,最好使用数组及其附带的所有内容。

如果要使用Collection来存储“列表”,则需要为要处理的对象创建一个Class。

并不令人惊讶...但这就是该语言所能提供的。