【问题标题】:VBA class instancesVBA 类实例
【发布时间】:2022-01-08 07:47:58
【问题描述】:

我在 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

关于如何解决这个问题的任何想法?

我创建了一些显示问题的代码,请注意“CustomRow_Manager”类中的“rowArray”变量

宏文件 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

模块“模块1”

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

【问题讨论】:

  • 阅读例如this article 关于auto-instancing variable。通常,您应该避免自动实例化变量。 HTH

标签: vba class excel object


【解决方案1】:

您的问题正在使用

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

这显式地实例化了一个新的类实例

【讨论】:

  • 成功了!我什至没有想到这一点,因为我通常在 .NET 中编写代码,您可以在其中显式地在循环中创建新实例。
  • 我觉得这种特殊行为没有得到很好的记录。 Dim v As New ClassObjectDim v As ClassObject Set v = New ClassObject 之间有区别,但这是我发现它记录的唯一地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-25
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 2011-02-27
相关资源
最近更新 更多