【问题标题】:Excel vba: Property let procedure not defined and property get procedure did not return an objectExcel vba:未定义属性让程序并且属性获取程序未返回对象
【发布时间】:2021-09-23 09:25:17
【问题描述】:

我有一个Client 课程。在那个类里面有一个数组losses。首先,我创建并使用客户端填充 clientsColl 数组。然后对于该数组中的每个客户端,我填充其losses 数组。

然后我尝试为每个客户端打印到调试losses 的第一个元素。但是,它不起作用并出现Property let procedure not defined and property get procedure did not return an object 错误。

同时,如果我只是尝试为第一个客户端显示losses的第一个元素,没有任何循环,它工作正常:

Dim clientsColl() As Client
clientsColl = getClients(dataWorkbook)

Dim clientCopy As Variant    

Debug.Print "first: " & clientsColl(1).getLosses(1) 'works fine
For Each clientCopy In clientsColl
    Debug.Print "in for each: " & clientCopy.getLosses(1) 'error here
Next

Client 类中:

Public Property Get getLosses()
    getLosses = losses
End Property

Private losses() As Double

losses 数组的填充方式:

Public Sub calculateFinancialResult()
    ReDim losses(1 To simulationCount)
    ReDim profits(1 To simulationCount)

    Dim i As Long
    For i = 1 To simulationCount
        If outcomes(i) = 1 Then
            losses(i) = totalLoss
            ...
        Else
            ...
        End If
    Next
 End Sub

为什么会发生这种情况以及如何解决?

编辑:更多主要子:

For Each clientCopy In clientsColl
        clientCopy.setSimulationCount = globals("SIMULATION_COUNT")
        ...
        clientCopy.calculateFinancialResult
        ...
Next

编辑:

同时一个简单的for 循环工作正常:

Debug.Print "first: " & clientsColl(1).getLosses(1)
For tempCount = LBound(clientsColl) To UBound(clientsColl)
    Debug.Print "in for each: " & _
                clientsColl(tempCount).getLosses(1)
Next

【问题讨论】:

  • 您是否尝试过单步执行并查看每个数组的上限是多少?您是否在 Client 的初始化事件中填充损失?
  • @Harassed Dad losses 在循环前几行填充。问题是,Debug 只打印first: 0。这意味着,至少对于第一个客户端,数组的第一个元素存在。同时出现了来自for each 循环的no 调试打印 - 虽然我们确定至少对于一个客户端来说它应该已经出现。
  • "损失在循环前几行填充。"您确定它实际上填充了所有客户端吗?如果那里有错误,它会解释它。 F8 是你的朋友。
  • 尝试将clientCopy 声明为Client。您不仅可以使用Variants 迭代for each。也解决了问题。
  • 因为它类似于早/晚绑定问题,vba 只是不知道对clientCopy.getLosses(1) 的期望,其中两个变量(clientCopygetLosses)都是Variants .如果您仍想执行这样的循环,请在循环中尝试此语句 (Debug.Print clientCopy.getLosses()(1))(或将clientCopy.getLosses() 的结果存储在内部某处)。

标签: arrays vba excel


【解决方案1】:

总结一下 cmets 中所说的内容:

您的问题(错误 451)通常在您尝试复合属性时出现。 为了表示这种情况,我们可以使用任何具有属性的对象的任何结构

让我们用集合数组来模拟它:

Option Explicit

Sub Test()
    Dim Arr As Variant
    Dim Col As Collection
    Dim i As Long
    Dim j As Long

    ReDim Arr(1 To 10)

    For i = 1 To 10
        Set Col = New Collection
        For j = 1 To 10
            Call Col.Add(j)
        Next

        Set Arr(i) = Col
    Next

    On Error Resume Next
    Debug.Print Arr(1).Item(1)
    Debug.Print Arr(1).Item()(1)
    On Error GoTo 0
End Sub

您的问题源于您将属性视为属性的事实。在不那么复合(或者当您的数组被显式声明为类实例数组时)级别上,由于早期绑定,它可以工作。但是当事情开始变得更复杂时——它就失败了,因为你的属性只是另一个功能。

因此,要实现你想要的,你应该用另一对括号显式调用它。

【讨论】:

    【解决方案2】:

    您的getLosses 属性不带参数,因此您的语法实际上是错误的,即使VBA 可以在早期绑定时处理它。您应该使用:

    Debug.Print "first: " & clientsColl(1).getLosses()(1) 'works fine
    For Each clientCopy In clientsColl
        Debug.Print "in for each: " & clientCopy.getLosses()(1) 'error here
    Next
    

    【讨论】:

    • 如果getLosses 是一个字段,而不是属性(即Public getLosses As Variant),也会发生同样的情况。而且解决方法也是一样的,添加(),现在看起来很奇怪,因为它不是方法或属性调用。
    【解决方案3】:

    我在使用复合属性创建自定义数组类时也遇到了这个问题。

    我通过在Property Get 代码中添加返回值的类语句解决了这个问题。正如@Rory 所说的那样。

    您可以在Client 类中尝试Public Property Get getLosses() As Double

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 2021-11-10
      相关资源
      最近更新 更多