【问题标题】:How to write a VBA collection to an Excel sheet [duplicate]如何将 VBA 集合写入 Excel 工作表 [重复]
【发布时间】:2013-08-16 04:21:52
【问题描述】:

我正在修改一些现有代码。此代码从预先存在的工作表表中创建行集合。它创建了一个大型二维集合,每列中都有不同的信息。有一个单独的类模块来声明每一列的数据类型。

代码通过依次遍历每个项目将二维集合写入新工作表。我以前从未使用过集合,并且想一次性将集合写入工作表。当表有很多记录时,当前代码需要很长时间。

有没有办法将整个集合转换为二维数组,或者这样我就可以一次编写二维数组?或者有没有办法将整个集合写入工作表,就像使用二维数组一样?我试图搜索这个并且到目前为止没有成功。任何一般点将不胜感激!

这是一些示例代码,以粗体显示 cmets,用于说明如何使用集合。

定义类模块,命名为 TableEntry

Public Item1 As String
Public Item2 As String
Public Item3 As String
Public Item4 As Integer
Public Item5 As Integer

主要例程 - 创建集合、填充集合、将集合写入工作表

Sub MainRoutine()

Dim table As Collection
Set table = New Collection

Call FillCollection(File As String, ByRef table As Collection)

Call WriteCollectionToSheet(ByRef table As Collection)

子程序 1 - 填充集合

Dim wb As Workbook
Set wb = Workbooks.Open(File)

Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets

Dim R As Range
Set R = ws.Range("A2")

  Dim e As TableEntry
  For i = 1 To 20

    Set e = New TableEntry

    e.Item1 = R.Offset(i + 1, 0).Offset(0, 0)
    e.Item2 = R.Offset(i + 1, 0).Offset(0, 1)
    e.Item3 = R.Offset(i + 1, 0).Offset(0, 2)
    e.Item4 = R.Offset(i + 1, 0).Offset(0, 3)
    e.Item5 = R.Offset(i + 1, 0).Offset(0, 4)

    table.Add e

  Next i

Next ws

子例程 2 - 将集合写入工作表

【问题讨论】:

  • 谢谢破布。我应该自己找到这个
  • 上面链接中的答案使用数组而不是集合。这是我应该做的,还是有办法将集合转移到数组,或者确实一次性编写集合?
  • 其实,如果你关闭屏幕更新和计算,它会足够快,即使你使用循环。
  • @psychonomics 感谢您更新问题。现在它使它更清楚了。你能详细说明这一行Set e = New TableEntry100613 吗?我认为那条线就这样失败了。您是否在动态创建类类型?整个事情看起来就像你有一个包含 5 个项目的自己的类的集合。
  • @psychonomics 如果您要重写,我建议从一开始就直接使用数组。类的使用可以很容易地与Types 交换,除非您创建的每个类都接收一个唯一标识符,以便您可以遍历 Collection Of Collections。

标签: arrays excel vba collections


【解决方案1】:

我认为将字典打印到 Excel 电子表格最简单的方法是使用 WorksheetFunction.Transpose(Variant type @ 987654324@)

以下代码

  • 使用键和项创建示例字典
  • 创建两个数组(keys, items)并用elements填充它们 从字典一口气
  • 使用WorksheetFunction.Transpose(VariantArray) 打印数组 一口气

Option Explicit

' 添加对 Microsoft 脚本运行时的引用 ' >> 工具 >> 参考 >> Microsoft 脚本运行时

Sub CollectionToArrayToSpreadSheet()
    Cells.ClearContents
    ' think of this collection as
    '   key     =   cell.row
    '   item    =   cell.value
    Dim dict As New Dictionary
    dict.Add Key:=1, Item:="value1"
    dict.Add Key:=2, Item:="value2"
    dict.Add Key:=3, Item:="value3"

    ' THIS WAY
    'Range("A1:A" & UBound(dict.Keys) + 1) = WorksheetFunction.Transpose(dict.Keys)
    'Range("B1:B" & UBound(dict.Items) + 1) = WorksheetFunction.Transpose(dict.Items)

    ' OR
    Range("A1").Resize(UBound(dict.Keys) + 1, 1) = WorksheetFunction.Transpose(dict.Keys)
    Range("B1").Resize(UBound(dict.Items) + 1, 1) = WorksheetFunction.Transpose(dict.Items)

End Sub


更新:

你的情况...

如果这是你想要做的(note table 是一个集合

Range("A1:A" & table.Count) = WorksheetFunction.Transpose(table)

很遗憾,答案是否定的。

如果不遍历集合,您就无法将集合转置到电子表格中。

你可以做些什么来加快这个过程:

  • 关闭Application.ScreenUpdating
  • 遍历集合并将值复制到数组中, 然后使用WorksheetFunction.Transpose() 打印 一次性完成所有工作使用从一开始的逻辑 部分答案

跟进:

在您的情况下,您可以像这样重写Sub WriteCollectionToSheet(ByRef table As Collection)代码看起来有点难看,但效率应该还可以

Sub WriteCollectionToSheet(ByRef table As Collection)

    Dim dict1 As New Dictionary
    Dim dict2 As New Dictionary
    Dim dict3 As New Dictionary
    Dim dict4 As New Dictionary
    Dim dict5 As New Dictionary

    Dim i As Long
    For i = 1 To table.Count
        dict1.Add i, table.Item(i).Item1
        dict2.Add i, table.Item(i).Item2
        dict3.Add i, table.Item(i).Item3
        dict4.Add i, table.Item(i).Item4
        dict5.Add i, table.Item(i).Item5
    Next i

    Range("A1:A" & UBound(dict1.Items) + 1) = WorksheetFunction.Transpose(dict1.Items)
    Range("B1:B" & UBound(dict2.Items) + 1) = WorksheetFunction.Transpose(dict2.Items)
    Range("C1:C" & UBound(dict3.Items) + 1) = WorksheetFunction.Transpose(dict3.Items)
    Range("D1:D" & UBound(dict4.Items) + 1) = WorksheetFunction.Transpose(dict4.Items)
    Range("E1:E" & UBound(dict5.Items) + 1) = WorksheetFunction.Transpose(dict5.Items)

End Sub

有关 VBA 集合迭代和打印到工作表 @vba4all.com 的更多详细信息

【讨论】:

  • 谢谢@mehow。一次转换为数组并打印听起来不错。如果集合被指定为New Collection 而不是New Dictionary,我还能一次性用元素填充数组吗?
  • @psychonomics 看到,在这种情况下,我不明白你是如何拥有一个 2D 集合的。它是如何实现的以及它是如何工作的,因为您可以从集合中获得的唯一东西是.Item(index)。您能否展示您的 Collection 是如何实现和使用的代码?然后我可以更新我的答案以 100% 匹配您的情况
  • 我已更新我的问题以包含示例代码。这应该清楚地说明 Collection 是如何实现和使用的。如果没有,请告诉我。在这里感谢您的帮助!
  • @psychonomics 我已根据您的更新更新了我的答案。
  • 在这里感谢您的帮助,非常感谢
【解决方案2】:

如果我想将我在代码中填充的二维数组写入工作表,我会使用此代码。它非常有效,因为它只与工作表“对话”一次

Dim r as Range
Dim var_out as Variant
Set r = Range("OutputValues")  
r.clear
var_out = r.value

'Then use code to appropriately fill the new 2D array var_out, such as your subroutine 1 above

r.value = var_out

您首先确定要打印数组的工作簿中的范围。在此示例中,我假设我将输出范围命名为“OutputValues”。

r.value 对 var_out(我打算填充的数组变量)的第一次赋值根据范围的大小设置数组变量的维度。 (它还会读取范围内的任何现有值,因此如果您不希望这样做,请清除我在此处显示的范围。)

数组变量的第二次赋值将值写回工作表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    相关资源
    最近更新 更多