2015-12-11 2 views
2

У меня проблема в VBA, где каждый элемент в массиве заменяется каждый раз, когда я добавляю что-то в этот массив.экземпляры класса VBA

Я пытаюсь пройти строки в заданном диапазоне и отнести каждую строку этого в пользовательский класс (с именем «CustomRow» в приведенном ниже примере). существует также класс менеджера (под названием «CustomRow_Manager» ниже), который содержит массив строк и имеет функцию для добавления новых строк.

Когда первая строка добавляется это работает отлично: https://drive.google.com/file/d/0B6b_N7sDgjmvTmx4NDN3cmtYeGs/view?usp=sharing

Однако, когда она петля вокруг второго ряда он заменяет содержимое первой строки, а также добавить вторую запись: https://drive.google.com/file/d/0B6b_N7sDgjmvNXNLM3FCNUR0VHc/view?usp=sharing

Любые идеи о том, как это можно решить?

Я создал немного кода, который показывает этот вопрос, смотрите переменную «rowArray» в классе «» CustomRow_Manager

макрофайл https://drive.google.com/file/d/0B6b_N7sDgjmvUXYwNG5YdkoySHc/view?usp=sharing

иначе код ниже :

данных

A B C 
1 X1 X2 X3 
2 xx11 xx12 xx13 
3 xx21 xx22 xx23 
4 xx31 xx32 xx33 

Модуль "Module1"

Public Sub Start() 
Dim cusRng As Range, row As Range 
Set cusRng = Range("A1:C4") 
Dim manager As New CustomRow_Manager 
Dim index As Integer 
index = 0 
For Each row In cusRng.Rows 
    Dim cusR As New CustomRow 
    Call cusR.SetData(row, index) 
    Call manager.AddRow(cusR) 
    index = index + 1 
Next row 
End Sub 

класса модуль "CustomRow"

Dim iOne As String 
Dim itwo As String 
Dim ithree As String 
Dim irowNum As Integer 


Public Property Get One() As String 
    One = iOne 
End Property 
Public Property Let One(Value As String) 
    iOne = Value 
End Property 

Public Property Get Two() As String 
    Two = itwo 
End Property 
Public Property Let Two(Value As String) 
    itwo = Value 
End Property 

Public Property Get Three() As String 
    Three = ithree 
End Property 
Public Property Let Three(Value As String) 
    ithree = Value 
End Property 

Public Property Get RowNum() As Integer 
    RowNum = irowNum 
End Property 
Public Property Let RowNum(Value As Integer) 
    irowNum = Value 
End Property 

Public Function SetData(row As Range, i As Integer) 
    One = row.Cells(1, 1).Text 
    Two = row.Cells(1, 2).Text 
    Three = row.Cells(1, 3).Text 
    RowNum = i 
End Function 

модуль класса "CustomRow_Manager"

Dim rowArray(4) As New CustomRow 
    Dim totalRow As Integer 

    Public Function AddRow(r As CustomRow) 
     Set rowArray(totalRow) = r 

     If totalRow > 1 Then 
      MsgBox rowArray(totalRow).One & rowArray(totalRow - 1).One 
     End If 
     totalRow = totalRow + 1 
    End Function 
+0

пользователя, например, [эта статья] (http://www.cpearson.com/excel/classes.aspx) о '' 'auto-instancing variable'''. В общем, вам следует избегать автоматических переменных. HTH – dee

ответ

3

Ваш вопрос с помощью

Dim cusR As New CustomRow 

внутри петли For. Эта строка фактически выполняется только один раз (обратите внимание, что когда вы одиночный F8 перешагиваете код, он не останавливается на этой строке)

Каждая итерация цикла For использует тот же экземпляр cusR. Поэтому все экземпляры manager добавлены к точке класса с тем же cusR

Заменить этот

For Each row In cusRng.Rows 
    Dim cusR As New CustomRow 

с этим

Dim cusR As CustomRow 
For Each row In cusRng.Rows 
    Set cusR = New CustomRow 

Это явно создает новый экземпляр класса

+0

Это сделало трюк! я даже не думал об этом, поскольку я обычно кодирую в .NET, где вы могли бы явно создавать новые экземпляры в цикле. – zaza

Смежные вопросы