在自定义类中使用自定义类数组的VBA Excel问题

时间:2018-12-17 09:47:22

标签: arrays excel vba class oop

这令人沮丧。我觉得我在做一些愚蠢的事情,但无法解决,因此任何帮助表示赞赏。我当然是新手,所以我希望我犯了一个基本错误。

问题是:

我创建了两个看似简单的自定义类。第一个定义了五个字段(字符串,整数和货币)的记录,第二个定义了第一个类中定义的记录对象的数组,并添加了一些简单的引用字段。 (字符串等,没什么复杂的)

我有一个简单的测试程序。它首先声明一个记录数组(50),然后在Initialize Sub的For循环中通过“ Set ... = New”创建所有对象。到目前为止(显然)还不错。

测试代码将3条(垃圾)记录写入Array。经过试验之后,现在的测试顺序为:将记录添加到阵列(位置(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)以上的记录,它们将为空。

我在做什么错?似乎我对Array的最新写入始终被写入到我先前写入的所有位置,而不仅仅是写入的位置。

相关代码为:

在数组类声明中:

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

AddRecord子为:

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.

clsTransRecord类的LoadRecord代码为

 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

下面是clsTransRecord的Initialize Sub。

 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 :(得分:0)

问题是您更改了名为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