我有一个表,我想转换该对象中该表的每一行。
该对象将具有每列的属性。
我做了这个功能:
Public Function GetProducts() As Object
Set GetProducts = New Collection
Dim p As New ProductInfo
Dim rng As Range
Dim xRow As Range
Set rng = Sheet2.Range("A2:I" & Sheet2.Range("A2").End(xlDown).Row)
For Each xRow In rng.Rows
p.Id = xRow.Cells(1, 1).Value
p.Cod = xRow.Cells(1, 2).Value
p.Name = xRow.Cells(1, 3).Value
p.productType = xRow.Cells(1, 4).Value
p.norma = xRow.Cells(1, 5).Value
p.masina = xRow.Cells(1, 6).Value
p.masinaType = xRow.Cells(1, 7).Value
p.operatori = xRow.Cells(1, 8).Value
p.sectie = xRow.Cells(1, 9).Value
GetProducts.Add Item:=p, Key:=CStr(p.Id)
Next xRow
End Function
比我尝试用此Sub检查功能:
Public Sub CheckProducts()
Dim products As Collection
Dim p As ProductInfo
Set products = GetProducts()
For Each p In products
MsgBox p.Id
Next p
End Sub
msgbox总是返回20(我的表中有20个项目,最后一个ID为20)。
当我检查集合中的项目数时,与预期的一样,我得到了20个。
谁能帮助我理解为什么我不能迭代集合并获取每个项目的ID?
最佳答案
在GetProducts()
中,您需要编写代码:
Dim p As ProductInfo
并不是:
Dim p As New ProductInfo
然后在循环代码中:
Set p = New ProductInfo
这是一个例子:
数据
类别-
TestInfo
Private m_Id As String
Private m_Code As String
Private m_Name As String
Property Get Id() As String
Id = m_Id
End Property
Property Let Id(str As String)
m_Id = str
End Property
Property Get Code() As String
Code = m_Code
End Property
Property Let Code(str As String)
m_Code = str
End Property
Property Get Name() As String
Name = m_Name
End Property
Property Let Name(str As String)
m_Name = str
End Property
模组
Option Explicit
Sub Test()
Dim coll As Collection
Dim obj As TestInfo
Set coll = GetProducts
For Each obj In coll
MsgBox obj.Name
Next
End Sub
Public Function GetProducts() As Collection
Set GetProducts = New Collection
Dim rngData As Range
Dim lngCounter As Long
Dim obj As TestInfo '<--- do not use New here
Set rngData = ThisWorkbook.Worksheets("Sheet1").Range("A1:C7")
For lngCounter = 2 To rngData.Rows.Count
Set obj = New TestInfo '<--- use New here
obj.Id = rngData.Cells(lngCounter, 1).Value
obj.Code = rngData.Cells(lngCounter, 2).Value
obj.Name = rngData.Cells(lngCounter, 3).Value
GetProducts.Add obj
Next lngCounter
End Function
注意
而且我个人不会使用以下语句:
Set GetProducts = New Collection
相反,我会这样做:
Public Function GetProducts() As Collection
Dim coll As Collection
Dim rngData As Range
Dim lngCounter As Long
Dim obj As TestInfo
Set rngData = ThisWorkbook.Worksheets("Sheet1").Range("A1:C7")
Set coll = New Collection
For lngCounter = 2 To rngData.Rows.Count
Set obj = New TestInfo
obj.Id = rngData.Cells(lngCounter, 1).Value
obj.Code = rngData.Cells(lngCounter, 2).Value
obj.Name = rngData.Cells(lngCounter, 3).Value
coll.Add obj
Next lngCounter
Set GetProducts = coll
End Function
为什么?
关于stackoverflow的问答很多,您可以阅读并考虑以下内容:
VBA: Difference in two ways of declaring a new object? (Trying to understand why my solution works)
What's the difference between Dim As New vs Dim / Set
What is the reason for not instantiating an object at the time of declaration?
关于excel - 如何使函数返回VBA中的对象列表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42829202/