Как заставить код класса VBA исполняться только на одном экземпляре объекта? - PullRequest
1 голос
/ 14 марта 2019

Ниже приведен упрощенный код, для которого я не могу объяснить поведение.Я использую 3 разных класса.Объект Dot, а также объект cls_Trace и объект cls_DataSet, содержащий один массив с именем AllTraces()

В cls_DataSet, я вызываю подпункт объекта cls_Trace.Это Corners Sub использует 1 Dot, содержащийся в объекте типа tDot.Подставка относится только к одному (1) экземпляру объекта Trace.Тем не менее, после выполнения One (1) только вызова из One (1) только объекта Trace все остальные объекты Trace, хранящиеся в массиве AllTraces(), будут затронуты так же.

That Sub Corners предполагается редактировать значения XY для объекта Dot UpperLeft и 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 Sub вызывается с одной переменной типа cls__Dot

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

Проще говоря, это будет выглядеть так:

call MyTrace.Corners(MyDot, True)

В коде отладки я перечисляю все 25 объектов Traces значения XY, а также значения XY UpperLeft и LowerRight.В целом я вижу все значения XY 3 точек, записанные в каждом экземпляре трассировки.Всего это 25 x 6 значений в окне отладки VBA.

На каждой итерации i я буду читать все эти 150 значений.XY всегда останется неизменным, поскольку они являются исходными данными.Каждые 25 строк будут отображать значение XY для каждого Dot.Но на каждой итерации i значения Dot UpperLeft и LowerRight будут изменяться, но все 25 объектов увидят, что значения LowerRight и Upperleft станут одинаковыми, где предполагаемое поведение будетчто каждая точка LowerRight и UpperLeft должна принимать разные значения для каждого экземпляра одного Trace в массиве.

Где моя ошибка в этом коде? Отладка файла MSExcel2007 Связь со всеми определениями кода и класса VBA

Дальнейшие исследования привели меня к выводу, что в модуле VBA MainMod Sub FillClassDataSet определение экземпляра для объекта переменной
Set currentPoint = New cls__Dot Set currentTrace = New cls_TraceЕсли я сместил определение currentTrace в цикле i, то я создам новый экземпляр этой переменной для каждой итерации i.Это исправит проблему.Код тогда работает нормально.Сейчас я нахожусь на уровне, где я должен понять, почему это так.Он не должен работать лучше, поскольку в определении класса cls_Trace уже есть функция .copy, которая должна позаботиться о том, чтобы был создан новый экземпляр этой трассировки.

Кроме того, в cls_DataSet class Public Sub AppendTrace здесь также есть вызов .copy, когда этот новый экземпляр трассировки добавляется в массив.

Итак, теперь возникает вопрос: почему новый экземпляр должен создаваться, когда в моем определении класса я создаю новый систематически?

Спасибо за вашу помощь, ребята:)

...