【问题标题】:VBA Excel Problem Using an Array of Custom Classes in a Custom Class在自定义类中使用自定义类数组的 VBA Excel 问题
【发布时间】:2019-05-17 15:57:27
【问题描述】:

这令人沮丧。我觉得我在做一些愚蠢的事情,但无法确定,所以任何帮助表示赞赏。我当然是新手,所以我认为我犯了一个根本性错误。

问题是:

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

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

测试代码将 3 条(垃圾)记录写入数组。在试验之后,现在的测试顺序是:向数组添加一条记录(位置 (0) 到 (2))。在每次添加后立即从 Location (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

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

【问题讨论】:

  • 你在哪里声明intRcdCnt
  • 加载记录需要显示代码
  • intRcdCnt 在 clsTransArray 类的头部声明了其他类似的变量。
  • 抱歉,上面的回复略有删减。了解系统。回覆。 Freeflow 问题 LoadRecord 的代码将在大约 10 分钟内出现我希望..Rgds 和谢谢你们俩..

标签: arrays excel vba class oop


【解决方案1】:

问题是您更改了名为trcTest 的记录的同一实例。您添加此实例并再次更改它等等。所以您只需每次都在内存中添加和更改相同的位置。因此你有相同的结果。

如果你需要三个实例,那么你需要创建三个实例,例如像这样的东西。高温

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    相关资源
    最近更新 更多