Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 类型不匹配尝试在集合中的对象中设置数据_Vba - Fatal编程技术网

Vba 类型不匹配尝试在集合中的对象中设置数据

Vba 类型不匹配尝试在集合中的对象中设置数据,vba,Vba,尝试更新集合中存储的对象时,出现运行时错误13。这里是一个最小的例子 要存储在集合中的对象的类(Class2) Option Explicit Private pHasA As Boolean Private pHasB As Boolean Private pSomeRandomID As String Property Get HasA() As Boolean HasA = pHasA End Property Property Get HasB() As Boolean

尝试更新集合中存储的对象时,出现运行时错误13。这里是一个最小的例子

要存储在集合中的对象的类(Class2)

Option Explicit

Private pHasA As Boolean
Private pHasB As Boolean
Private pSomeRandomID As String


Property Get HasA() As Boolean
    HasA = pHasA
End Property


Property Get HasB() As Boolean
    HasB = pHasB
End Property


Property Let HasA(propValue As Boolean)
    pHasA = propValue
End Property


Property Let HasB(propValue As Boolean)
    pHasB = propValue
End Property

Property Let RandomID(propValue As String)
    pSomeRandomID = propValue
End Property


Sub SetHasValues(key As String)
    Select Case key
        Case "A"
            pHasA = True
        Case "B"
            pHasB = True
    End Select
End Sub
复制错误的最小代码:

Option Explicit

Private Sub TestCollectionError()

Dim classArray As Variant
Dim classCollection As Collection
Dim singleClass2Item As Class2
Dim iterator As Long

    classArray = Array("A", "B", "C")
    Set classCollection = New Collection

    For iterator = LBound(classArray) To UBound(classArray)
        Set singleClass2Item = New Class2
        singleClass2Item.RandomID = classArray(iterator)
        classCollection.Add singleClass2Item, classArray(iterator)
    Next iterator

    Debug.Print "Count: " & classCollection.Count

    singleClass2Item.SetHasValues "A" ' <-- This code works fine.
    Debug.Print "New Truth values: " & singleClass2Item.HasA, singleClass2Item.HasB

    For iterator = LBound(classArray) To UBound(classArray)
        classCollection(classArray(iterator)).RandomID = classArray(iterator)
        classCollection(classArray(iterator)).SetHasValues classArray(iterator)  '<-- Type mismatch on this line.
    Next iterator

 '***** outputs
'''Count: 3
'''New Truth values: True      False
' Error dialog as noted in the comment above

End Sub
选项显式
私有子TestCollectionError()
Dim类数组作为变量
Dim classCollection作为集合
将单个Class2项目设置为Class2
等长迭代器
classArray=数组(“A”、“B”、“C”)
Set classCollection=新集合
对于迭代器=LBound(classArray)到UBound(classArray)
设置singleClass2Item=New Class2
singleClass2Item.RandomID=classArray(迭代器)
类集合。添加SingleClass2项,类数组(迭代器)
下一迭代器
Debug.Print“Count:”&classCollection.Count

singleClass2Item.SetHasValues“A”这是由于过程的参数
SetHasValues
是由ref隐式定义的


将其定义为ByVal将解决您的问题。

@ADJ这很烦人,但下面的示例可能会让您开始说明允许RubberDuck的理由

我使用从Ruberduck博客中获得的想法和概念升级了您的代码。代码现在编译得很干净,并且is(imho)由于更少的查找而不那么混乱

需要注意的要点是

  • 不依赖隐式类型转换
  • 将从集合中检索到的对象分配给要检索的类型的变量,以获取对该对象的intellisense的访问权限
  • 具有真正构造函数的VBA对象(类2中的Create和Self函数)
  • 封装类属性的支持变量,以提供一致(且简单)的命名和intellisense
  • 下面的代码确实包含Rubberduck注释(以“@”开头的注释)

    更新的第2类

    Option Explicit
    '@Folder("StackOverflowExamples")
    '@PredeclaredId
    
    Private Type Properties
    
        HasA                    As Boolean
        HasB                    As Boolean
        SomeRandomID            As String
    
    End Type
    
    Private p                   As Properties
    
    
    Property Get HasA() As Boolean
        HasA = p.HasA
    End Property
    
    
    Property Get HasB() As Boolean
        HasB = p.HasB
    End Property
    
    
    Property Let HasA(propValue As Boolean)
        p.HasA = propValue
    End Property
    
    
    Property Let HasB(propValue As Boolean)
        p.HasB = propValue
    End Property
    
    
    Property Let RandomID(propValue As String)
        p.SomeRandomID = propValue
    End Property
    
    
    Sub SetHasValues(key As String)
        Select Case key
            Case "A"
                p.HasA = True
            Case "B"
                p.HasB = True
        End Select
    End Sub
    
    
    Public Function Create(ByVal arg As String) As Class2
    
        With New Class2
    
            Set Create = .Self(arg)
    
        End With
    
    End Function
    
    
    Public Function Self(ByVal arg As String) As Class2
    
            p.SomeRandomID = arg
            Set Self = Me
    
    End Function
    
    更新的测试代码

    Private Sub TestCollectionError()
    
    Dim classArray                  As Variant
    Dim classCollection             As Collection
    Dim singleClass2Item            As Class2
    Dim my_item                     As Variant
    Dim my_retrieved_item           As Class2
    
        classArray = Array("A", "B", "C")
        Set classCollection = New Collection
    
        For Each my_item In classArray
    
            classCollection.Add Item:=Class2.Create(my_item), key:=my_item
    
        Next
    
        Debug.Print "Count: " & classCollection.Count
        Set singleClass2Item = classCollection.Item(classCollection.Count)
        Debug.Print "Initial Truth values: " & singleClass2Item.HasA, singleClass2Item.HasB
        singleClass2Item.SetHasValues "A" ' <-- This code works fine.
        Debug.Print "New Truth values: " & singleClass2Item.HasA, singleClass2Item.HasB
    
        For Each my_item In classArray
    
            Set my_retrieved_item = classCollection.Item(my_item)
            my_retrieved_item.RandomID = CStr(my_item)
            my_retrieved_item.SetHasValues CStr(my_item)
    
        Next
    
    End Sub
    
    私有子TestCollectionError()
    Dim类数组作为变量
    Dim classCollection作为集合
    将单个Class2项目设置为Class2
    将my_项目设置为变体
    将我的\u检索到的\u项目设置为类2
    classArray=数组(“A”、“B”、“C”)
    Set classCollection=新集合
    对于classArray中的每个my_项
    classCollection.additem:=Class2.Create(my\u Item),key:=my\u Item
    下一个
    Debug.Print“Count:”&classCollection.Count
    设置singleClass2Item=classCollection.Item(classCollection.Count)
    Debug.Print“初始真值:&singleClass2Item.HasA,singleClass2Item.HasB
    
    singleClass2Item.SetHasValues“A”您还可以安装Rubberduck加载项。这个奇妙的VBA外接程序的代码检查功能将向您展示您对代码所做的大量不可见的假设。@Freeflow:很遗憾,无法在工作中安装Rubberduck,这就是完整代码所在。我们这里有一个非常快速的过程。