如何使VBA类代码仅在一个对象的单个实例上执行?

时间:2019-03-14 04:28:45

标签: excel vba class scope instance

下面是一个简化的代码,我无法解释其行为。我正在使用3个不同的类。对象Dot,对象cls_Trace和对象cls_DataSet包含一个称为AllTraces()

的数组

cls_DataSet中,我称为对象cls_Trace的子对象。该Corners子对象使用Dot类型的对象中包含的1个tDot。该子对象仅属于对象Trace的One(1)实例。但是,执行完One(1)之后,仅从One(1)进行调用,只有对象Trace以及存储在数组Trace中的所有其他对象AllTraces()都会受到相同的影响。

该子Corners应该为Dot对象UpperLeft编辑值XY,而LowRight包含其唯一变量myTrace。但是,执行后,数组Trace中的所有单个AllTraces()都继承了属于该单个Trace对象的值。

那是VBA的细微错误吗?还是我的代码中有一个细微的错误(最有可能)?但是,我已经花了数小时试图找出问题所在。


在名为cls_DataSet的类定义中

Dim AllTraces() As cls_Trace  

Public Sub CreateInterDot()
    Dim i As Long
    SpreadCount = 30
    CNT = UBound(AllTraces)
    For i = 3 To CNT - 1
       PointAddress = AllTraces(i).LPo
       BezelCount = SpreadCount - 1

       Call DebugAllDots
       Call AllTraces(PointAddress).Corners(AllTraces(PointAddress - 1).LXY, True)
       Call DebugAllDots
       Call AllTraces (PointAddress).Corners(AllTraces (PointAddress).LXY, False)
       Call DebugAllDots
    Next i
End Sub

在名为cls_Trace的类定义中

Private Type tDot
    Po As Long
    Ra As Double
    CT As clsDot        ' Center XY value
    XY As clsDot        ' XY value for this point
    UperLeft As clsDot  ' One Dot define the Upper Left  corner
    LowRight As clsDot  ' One Dot define the Lower Right
End Type

Dim myTrace As tDot
Dim X As Double, Y As Double

Property Get LXY() As cls__Dot        ' Server for the Dot object
    Set LXY = myTrace.XY
End Property

Public Sub Corners(DotOne As cls__Dot, First As Boolean)
    With myTrace
        X = DotOne.XY(Y)
        If First Then
            Let .UperLeft.XY(Y) = X:     Let .LowRight.XY(Y) = X
            ULX = X: ULY = Y: LRX = X: LRY = Y
        Else
            ULX = IIf(X < ULX, X, ULX): ULY = IIf(Y > ULY, Y, ULY)  ' Upper
            LRX = IIf(X > LRX, X, LRX): LRY = IIf(Y < LRY, Y, LRY)  ' Lower
            Let .UperLeft.XY(ULY) = ULX:     Let .LowRight.XY(LRY) = LRX
        End If
    End With
End Sub

在名为cls__Dot的类定义中

Private Type XY
    X As Double     ' X value for the point
    Y As Double     ' Y value for the point
End Type

Dim MyXY As XY

Property Let XY(Y As Double, X As Double)   ' Assigne les valeurs X Y au point
    MyXY.X = X: MyXY.Y = Y
End Property

Property Get XY(Y As Double) As Double     ' Serveur X Y de ce point
    XY = MyXY.X: Y = MyXY.Y
End Property

cls_DataSet中,此Corners子对象使用类型为cls__Dot的一个变量来调用

Call AllTraces(PointAddress).Corners(AllTraces(PointAddress - 1).LXY, True)

更简单的是,看起来像这样

call MyTrace.Corners(MyDot, True)

在Debug代码中,我列出了所有25个对象Traces的XY值以及UpperLeftLowerRight的XY值。总之,我可以看到在每个跟踪实例中记录的3个点的所有XY值。在“ VBA调试”窗口中,总共有25 x 6个值。

i的每次迭代中,我将读取所有这150个值。 XY将始终保持不变,因为它们是原始数据。每25行将显示每个Dot的XY值。但是在i的每次迭代中,DotUpperLeft的{​​{1}}值都会改变,但是所有25个对象都会看到其LowerRight和{{1} }值变为相同,其中预期的行为将是,对于数组中单个LowerRight的每个实例,每个UpperleftLowerRight Dot应该采用不同的值。

我在此代码中的错误在哪里? Debug MSExcel2007 file Link with all the VBA code and class definitions

进一步的研究使我发现,在VBA模块MainMod Sub FillClassDataSet中,变量对象的实例定义
UpperLeft ,如果我在i循环内替换了currentTrace定义,则将为每个i迭代创建该变量的新实例。这样可以解决问题。该代码然后正常工作。现在,我必须了解为什么会这样。它应该不会工作得更好,因为在Trace类定义中嵌入了一个Set currentPoint = New cls__Dot Set currentTrace = New cls_Trace函数,该函数应该用来确保创建该跟踪的新实例。

此外,在cls_Trace内,当将新的跟踪实例添加到数组时,这里也有一个.copy调用。

所以现在的问题是:当我在类定义中确实系统地创建一个新实例时,为什么必须创建一个新实例?

感谢您的帮助:)

0 个答案:

没有答案