正在 class objects 的 collection 中加载 table 值
Loading table values inside a collection of class objects
我正在努力使用 vba class 语法。
我有一个 table 向我显示一种联系人簿,其中包含名称、姓氏、街道和邮编。当一个人有多个地址时,会有一个没有名字和姓氏但有新街道和邮编的新行。
我正在尝试将所有数据存储在 collection 中,其中包含人员和地址 class。
在我的模块中,我尝试在 collection 中加载 table。在第一个 if 分支 中,我确保该行的第一个单元格不为空,这意味着它是一个新人,所以我需要创建一个新的 collection物品。
在 else 分支 中,我在该行的第一个单元格为空时输入,这意味着它只是我需要添加到前一个 collection 项目的地址。
我做错了什么?
代码 运行 在我的 for 循环的第一次迭代中是正确的,但随后它卡在了循环的第二个 运行 上,在我的 class_terminate 上停止了人 class.
我在 collection 中存储数据的方式是否正确?
地址
Option Explicit
Private pStreet As String
Private pZip As Integer
Public Property Let Street(val As String)
pStreet = val
End Property
Public Property Get Street() As String
Street = pStreet
End Property
Public Property Let Zip(val As Integer)
pZip = val
End Property
Public Property Get Zip() As Integer
Zip = pZip
End Property
人
Private pName As String
Private pSurname As String
Private pAddresses As New Collection
Public Property Let Name(val As String)
pName = val
End Property
Public Property Get Name() As String
Name = pName
End Property
Public Property Let Surname(val As String)
pSurname = val
End Property
Public Property Get Surname() As String
Surame = pSurname
End Property
Private Sub Class_Initialize()
Set pAddresses = New Collection
End Sub
Private Sub Class_Terminate()
Set pAddresses = Nothing
End Sub
Public Sub addAddress(ByVal val As Address)
pAddresses.Add val
End Sub
Public Property Get Addresses() As Collection
Set Addresses = pAddresses
End Property
Public Property Get Address(ByVal Index As Long) As Address
Set Address = pAddresses(Index)
End Property
人物工厂
Option Explicit
Public Function Create(ByVal Name As String, ByVal Surname As String, ByVal Street As String, ByVal Zip As Integer) As person
Dim a As Address
Set Create = New person
Create.Name = Name
Create.Surname = Surname
Set a = New Address
a.Street = Street
a.Zip = Zip
Create.Addresses.Add a
Set Create = Nothing
Set a = Nothing
End Function
模块测试
Private Sub testFilter()
Dim nameCol, surnameCol, streetCol, zipCol As Integer
nameCol = 1
surnameCol = 2
streetCol = 3
zipCol = 4
Dim coll As New Collection
Sheets.Item("contacts").Select
For i = 2 To getLastRow
If Cells(i, nameCol).Value <> "" Then
k = k + 1
Dim pf As PersonFactory
Dim p As person
Set pf = New PersonFactory
Set p = pf.Create(CStr(Cells(i, nameCol).Value), CStr(Cells(i, surnameCol).Value), CStr(Cells(i, streetCol).Value), CInt(Cells(i, zipCol).Value))
coll.Add p
Set pf = Nothing
Set p = Nothing
Else
Dim addr As Address
Set addr = New Address
addr.Street = CStr(Cells(i, streetCol).Value)
addr.Zip = CInt(Cells(i, streetCol).Value)
coll.Add addr
Set addr = Nothing
End If
Next
End Sub
我对您的 test-module 进行了一些重构 - 查看内联评论
Option Explicit
Private Enum en_colTable
'value of enums are automatically increased by 1
'if you change the order the value changes as well
nameCol = 1
surnameCol
streetCol
zipCol
End Enum
Private Sub testFilter()
Dim colPersons As New Collection 'this name is more explicit about what the collection is
Dim ws As Worksheet
Set ws = Thisworkbook.Worksheets.Item("contacts") 'use a worksheet variable to be more explicit
Dim pf As personFactory
Dim p As person, addr As Address
Set pf = New personFactory 'you need to do this only once
Dim i As Long
With ws
For i = 2 To getLastRow
If .Cells(i, nameCol).Value <> "" Then
Set p = pf.Create(CStr(.Cells(i, nameCol).Value), _
CStr(.Cells(i, surnameCol).Value), CStr(.Cells(i, streetCol).Value), CInt(.Cells(i, zipCol).Value))
colPersons.Add p
Else
Set addr = New Address
addr.Street = CStr(.Cells(i, streetCol).Value)
addr.Zip = CInt(.Cells(i, streetCol).Value)
p.Addresses.Add addr 'add address to person
End If
Next
End With
End Sub
关于 ParentFactory:
您一定不能将那些创建的对象设置为空!!!
父工厂
Option Explicit
Public Function Create(ByVal Name As String, ByVal Surname As String, ByVal Street As String, ByVal Zip As Integer) As Person
Dim a As Address
Set Create = New Person
Create.Name = Name
Create.Surname = Surname
Set a = New Address
a.Street = Street
a.Zip = Zip
Create.Addresses.Add a
' Do not set these variables to nothing - if so they don't exist anylonger!!!!
' Set Create = Nothing
' Set a = Nothing
End Function
我正在努力使用 vba class 语法。 我有一个 table 向我显示一种联系人簿,其中包含名称、姓氏、街道和邮编。当一个人有多个地址时,会有一个没有名字和姓氏但有新街道和邮编的新行。
我正在尝试将所有数据存储在 collection 中,其中包含人员和地址 class。
在我的模块中,我尝试在 collection 中加载 table。在第一个 if 分支 中,我确保该行的第一个单元格不为空,这意味着它是一个新人,所以我需要创建一个新的 collection物品。 在 else 分支 中,我在该行的第一个单元格为空时输入,这意味着它只是我需要添加到前一个 collection 项目的地址。 我做错了什么?
代码 运行 在我的 for 循环的第一次迭代中是正确的,但随后它卡在了循环的第二个 运行 上,在我的 class_terminate 上停止了人 class.
我在 collection 中存储数据的方式是否正确?
地址
Option Explicit
Private pStreet As String
Private pZip As Integer
Public Property Let Street(val As String)
pStreet = val
End Property
Public Property Get Street() As String
Street = pStreet
End Property
Public Property Let Zip(val As Integer)
pZip = val
End Property
Public Property Get Zip() As Integer
Zip = pZip
End Property
人
Private pName As String
Private pSurname As String
Private pAddresses As New Collection
Public Property Let Name(val As String)
pName = val
End Property
Public Property Get Name() As String
Name = pName
End Property
Public Property Let Surname(val As String)
pSurname = val
End Property
Public Property Get Surname() As String
Surame = pSurname
End Property
Private Sub Class_Initialize()
Set pAddresses = New Collection
End Sub
Private Sub Class_Terminate()
Set pAddresses = Nothing
End Sub
Public Sub addAddress(ByVal val As Address)
pAddresses.Add val
End Sub
Public Property Get Addresses() As Collection
Set Addresses = pAddresses
End Property
Public Property Get Address(ByVal Index As Long) As Address
Set Address = pAddresses(Index)
End Property
人物工厂
Option Explicit
Public Function Create(ByVal Name As String, ByVal Surname As String, ByVal Street As String, ByVal Zip As Integer) As person
Dim a As Address
Set Create = New person
Create.Name = Name
Create.Surname = Surname
Set a = New Address
a.Street = Street
a.Zip = Zip
Create.Addresses.Add a
Set Create = Nothing
Set a = Nothing
End Function
模块测试
Private Sub testFilter()
Dim nameCol, surnameCol, streetCol, zipCol As Integer
nameCol = 1
surnameCol = 2
streetCol = 3
zipCol = 4
Dim coll As New Collection
Sheets.Item("contacts").Select
For i = 2 To getLastRow
If Cells(i, nameCol).Value <> "" Then
k = k + 1
Dim pf As PersonFactory
Dim p As person
Set pf = New PersonFactory
Set p = pf.Create(CStr(Cells(i, nameCol).Value), CStr(Cells(i, surnameCol).Value), CStr(Cells(i, streetCol).Value), CInt(Cells(i, zipCol).Value))
coll.Add p
Set pf = Nothing
Set p = Nothing
Else
Dim addr As Address
Set addr = New Address
addr.Street = CStr(Cells(i, streetCol).Value)
addr.Zip = CInt(Cells(i, streetCol).Value)
coll.Add addr
Set addr = Nothing
End If
Next
End Sub
我对您的 test-module 进行了一些重构 - 查看内联评论
Option Explicit
Private Enum en_colTable
'value of enums are automatically increased by 1
'if you change the order the value changes as well
nameCol = 1
surnameCol
streetCol
zipCol
End Enum
Private Sub testFilter()
Dim colPersons As New Collection 'this name is more explicit about what the collection is
Dim ws As Worksheet
Set ws = Thisworkbook.Worksheets.Item("contacts") 'use a worksheet variable to be more explicit
Dim pf As personFactory
Dim p As person, addr As Address
Set pf = New personFactory 'you need to do this only once
Dim i As Long
With ws
For i = 2 To getLastRow
If .Cells(i, nameCol).Value <> "" Then
Set p = pf.Create(CStr(.Cells(i, nameCol).Value), _
CStr(.Cells(i, surnameCol).Value), CStr(.Cells(i, streetCol).Value), CInt(.Cells(i, zipCol).Value))
colPersons.Add p
Else
Set addr = New Address
addr.Street = CStr(.Cells(i, streetCol).Value)
addr.Zip = CInt(.Cells(i, streetCol).Value)
p.Addresses.Add addr 'add address to person
End If
Next
End With
End Sub
关于 ParentFactory: 您一定不能将那些创建的对象设置为空!!!
父工厂
Option Explicit
Public Function Create(ByVal Name As String, ByVal Surname As String, ByVal Street As String, ByVal Zip As Integer) As Person
Dim a As Address
Set Create = New Person
Create.Name = Name
Create.Surname = Surname
Set a = New Address
a.Street = Street
a.Zip = Zip
Create.Addresses.Add a
' Do not set these variables to nothing - if so they don't exist anylonger!!!!
' Set Create = Nothing
' Set a = Nothing
End Function