VBA Excel Проблема с использованием массива пользовательских классов в пользовательском классе - PullRequest
0 голосов
/ 17 декабря 2018

Это расстраивает.Я чувствую, что делаю что-то глупое, но не могу это прибить, поэтому любая помощь приветствуется.Я, конечно, новичок, поэтому я ожидаю, что я делаю фундаментальную ошибку.

Проблема заключается в следующем:

Я создал два очевидно простых пользовательских класса.Первый определяет запись из пяти полей (String, Integer и Currency). Второй определяет массив объектов Record, определенных в первом классе, и добавляет несколько простых ссылочных полей.(Строка и т.д., ничего сложного)

У меня есть простая тестовая программа.Сначала он объявляет массив записей (50), затем создает все объекты с помощью «Set ... = New» в цикле For в Sub инициализации.Пока (очевидно) хорошо.

Тестовый код записывает 3 (мусорные) записи в массив.После эксперимента последовательность тестов теперь: Добавить запись в массив (местоположения (0) - (2)).Получить запись из Местоположение (0) (которое не должно изменяться, но изменяется) сразу после каждого добавления и печатать результат.После того как все три записаны, результаты снова печатаются для всех трех местоположений с использованием цикла For ... Next.Результаты показаны в выводе debug.print ниже:

 Record 0   A nice Bunch of Flowers     Bunch of Flowers    1   20  
 Record 1   A nsdfgh of Flowers         Bunch of Fgfffwers  4   23345  
 Record 2   A nsdf3 Also Flowers        BunchThirds         4   23345   

 Record 2   A nsdf3 Also Flowers        BunchThirds         4   23345   
 Record 2   A nsdf3 Also Flowers        BunchThirds         4   23345  
 Record 2   A nsdf3 Also Flowers        BunchThirds         4   23345`

т.е. Это Кажется , что - если перечитать во время записи, запись может быть восстановлена.- Как только будет записана следующая запись, все записи в массиве, вплоть до самого высокого, будут записаны как самые последние и (не показано выше) Если я попытаюсь прочитать записи выше (2), они будут пустыми.

Что я делаю неправильно?Похоже, что моя последняя запись в массив всегда записывается во все места, в которые я ранее записал, а не только в одну.

Соответствующий код:

В объявлениях класса массива:

Dim intSize As Integer 'The currently declared size of the Array
Dim trrRec(50) As clsTransRecord 'Shown hard coded to 50 here for test.

В инициализации класса массива:

Private Sub Class_Initialize()

Dim l As Integer 'Counter

intSize = 50 'The currently declared size of the Array

'Create the Objects
'==================
For l = 0 To intSize
Set trrRec(l) = New clsTransRecord
Next l

End Sub

В тестеКод: (загружает три записи с фиктивными данными и затем добавляет их в массив)

Private Sub CommandButton2_Click()

Dim trcTest As clsTransRecord
Dim trcTest2 As clsTransRecord

Set trcTest = New clsTransRecord
Set trcTest2 = New clsTransRecord

Dim j As Integer

Dim traTest As clsTransArray
Set traTest = New clsTransArray

trcTest.LoadRecord "Record 0", "Bunch of Flowers", "A nice Bunch of Flowers", 1, 20
traTest.AddRecord trcTest

Set trcTest2 = traTest.GetRecordAccount(0)
Debug.Print trcTest2.TrCat, trcTest2.TrDesc, trcTest2.TrItem, trcTest2.TrTransDay, trcTest2.TrValue

trcTest.LoadRecord "Record 1", "Bunch of Fgfffwers", "A nsdfgh of Flowers", 4, 23345
traTest.AddRecord trcTest

Set trcTest2 = traTest.GetRecordAccount(0)
Debug.Print trcTest2.TrCat, trcTest2.TrDesc, trcTest2.TrItem, trcTest2.TrTransDay, trcTest2.TrValue

trcTest.LoadRecord "Record 2", "BunchThirds", "A nsdf3 Also Flowers", 4, 23345
traTest.AddRecord trcTest

Set trcTest2 = traTest.GetRecordAccount(0)
Debug.Print trcTest2.TrCat, trcTest2.TrDesc, trcTest2.TrItem, trcTest2.TrTransDay, trcTest2.TrValue

Debug.Print

For j = 0 To 5
Set trcTest2 = traTest.GetRecordAccount(j)
Debug.Print trcTest2.TrCat, trcTest2.TrDesc, trcTest2.TrItem, trcTest2.TrTransDay, trcTest2.TrValue

Next

End Sub

Sub AddRecord Sub:

Public Sub AddRecord(clsNewRcd As clsTransRecord)

intRcdCnt = intRcdCnt + 1 'Increment the Record Counter
'Write the Record
'================
Set trrRec(intRcdCnt - 1) = clsNewRcd

End Sub

А функция GetRecordAccount:

'Gets an individual Record from the Object.
Public Function GetRecordAccount(k As Integer) As clsTransRecord

Set GetRecordAccount = trrRec(k)

End Function

код clsTransRecord показан ниже: Записи относятся к банковским записям и описаниям

Объявления:

 'clsTransRecord Variables

 Private strCat As String '- Category of Transaction. Allows Grouping of Items. Not always used
 Private strItem As String '- Describes the Item as it appears in the Budget Entry or Bank Statement. Used to compare Budheted to Actual
 'so can be difficult to read due to strange Bank Statements
 Private strDesc As String '- The longer, uderstandable, version of the Item Description.
 Private intTransDay As Integer '- The day of the month on which the transaction occurs
 Private curValue As Currency '- The Value of the Transaction. Positive for Income, Negative for Expenditure.

Код класса LoadRecord класса clsTransRecord равен

 Public Sub LoadRecord(strRecCat As String, strRecItem As String, strRecDesc As String, intRecTransDay As Integer, curRecValue As Currency)

 'Loads an individual Record

 strCat = strRecCat 'Record Category
 strItem = strRecItem 'Short Item Budget or Statement description.
 strDesc = strRecDesc 'Full Description of Item
 intTransDay = intRecTransDay 'Day on which the transaction happened/will happen
 curValue = curRecValue 'Value of the Transaction

 End Sub

Sub Initialize Sub для clsTransRecord находится ниже.

 Private Sub Class_Initialize()
 'Clears everything

 strCat = "" '- Category of Transaction.
 strItem = "" '- Describes the Item as it appears in the Budget Entry or Bank Statement
 strDesc = "" '- The longer, uderstandable, version of the Item Description.
 intTransDay = 0 '- The day of the month on which the transaction occurs
 curValue = 0 '- The Value of the Transaction

 End Sub

1 Ответ

0 голосов
/ 04 января 2019

Проблема в том, что вы изменяете тот же экземпляр записи с именем trcTest.Вы добавляете этот экземпляр, меняете его снова и т. Д. Таким образом, вы просто добавляете и меняете одно и то же место в памяти каждый раз .Поэтому у вас одинаковые результаты.

Если вам нужно три экземпляра, то вам нужно создать три экземпляра, например, что-то вроде этого.HTH

Private Sub CommandButton2_Click()

' Array wrapper
Dim traTest As clsTransArray
Set traTest = New clsTransArray

' New records
Dim trcTest0 As clsTransRecord
Dim trcTest1 As clsTransRecord
Dim trcTest2 As clsTransRecord

' Record for print
Dim trcTestPrint As clsTransRecord

Set trcTest0 = New clsTransRecord
Set trcTest1 = New clsTransRecord
Set trcTest2 = New clsTransRecord

' Firts record
trcTest0.LoadRecord "Record 0", "Bunch of Flowers", "A nice Bunch of Flowers", 1, 20
traTest.AddRecord trcTest0

Set trcTestPrint = traTest.GetRecordAccount(0)
Debug.Print trcTestPrint.TrCat, trcTestPrint.TrDesc, trcTestPrint.TrItem, trcTestPrint.TrTransDay, trcTestPrint.TrValue

' Second record
trcTest1.LoadRecord "Record 1", "Bunch of Fgfffwers", "A nsdfgh of Flowers", 4, 23345
traTest.AddRecord trcTest1

Set trcTestPrint = traTest.GetRecordAccount(1)
Debug.Print trcTestPrint.TrCat, trcTestPrint.TrDesc, trcTestPrint.TrItem, trcTestPrint.TrTransDay, trcTestPrint.TrValue

' Third record
trcTest2.LoadRecord "Record 2", "BunchThirds", "A nsdf3 Also Flowers", 4, 23345
traTest.AddRecord trcTest2

Set trcTestPrint = traTest.GetRecordAccount(2)
Debug.Print trcTestPrint.TrCat, trcTestPrint.TrDesc, trcTestPrint.TrItem, trcTestPrint.TrTransDay, trcTestPrint.TrValue

Debug.Print

Dim j As Integer
For j = 0 To 5
Set trcTestPrint = traTest.GetRecordAccount(j)
Debug.Print trcTestPrint.TrCat, trcTestPrint.TrDesc, trcTestPrint.TrItem, trcTestPrint.TrTransDay, trcTestPrint.TrValue

Next

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...