【问题标题】:Speeding up data extraction to Excel加快数据提取到 Excel
【发布时间】:2012-07-27 03:48:40
【问题描述】:

我目前正在使用 VBA 来运行存储过程和已提取到表中的存储数据。然后,VBA会相应地查询数据中的所有数据,并放入excel中。

这里的问题是,VBA 需要很长时间才能将所有数据(大约 10 万行数据)提取到 excel 中。有没有其他方法可以加快这个过程?以下是我的代码的一部分。粗体部分是插入到excel代码中。

'Row number where data inserting starts
        Do
            current_sheet = owb.ActiveSheet

            With current_sheet
                'Insert header to worksheet in first row, ie. A1, B1, C1
                For i = 0 To data_cols.GetLength(0) - 1
                    cell = data_cols(i, 0) & header_row_num 'Change to header_row_num
                    .Range(cell).Value = data_cols(i, 1)
                Next i
            End With

            row_count = header_row_num + 1 'Change the first row count to a row after header_row_num
            'Insert data to worksheet
            While rs.EOF = False

                With current_sheet
                    'Set format of specic columns before inserting data

                    .Columns("A").NumberFormat = "@"

                    .Columns("B").NumberFormat = "@"

                    .Columns("C").NumberFormat = "@"

                    .Columns("D").NumberFormat = "@"

                    .Columns("E").NumberFormat = "@"

                    .Columns("F").NumberFormat = "@"

                    .Columns("G").NumberFormat = "@"

                    .Columns("H").NumberFormat = "@"

                    .Columns("I").NumberFormat = "@"

                    .Columns("J").NumberFormat = "@"

                    .Columns("K").NumberFormat = "@"

                    .Columns("L").NumberFormat = "@"

                    .Columns("M").NumberFormat = "@"

                    .Columns("N").NumberFormat = "@"

                    .Columns("O").NumberFormat = "@"

                    .Columns("P").NumberFormat = "@"

                    .Columns("Q").NumberFormat = "@"

                    .Columns("R").NumberFormat = "@"

                    .Columns("S").NumberFormat = "@"

                    **'Start inserting data
                    For i = 0 To data_cols.GetLength(0) - 1
                        'Get the cell name
                        cell = data_cols(i, 0) & row_count
                        'Populate data to the cell
                        If IsDBNull(rs.Fields(data_cols(i, 2)).Value()) Then
                            .Range(cell).Value = " "
                        Else
                            .Range(cell).Value = rs.Fields(data_cols(i, 2)).Value()
                        End If
                    Next i
                End With
                rs.MoveNext()
                'Indicates next row
                row_count += 1**

                If row_count > 60000 Then
                    owb.Worksheets.Add(, current_sheet)
                    need_new_sheet = True
                    Console.WriteLine("Added new sheet to workbook...")
                    Exit While
                Else
                    need_new_sheet = False
                End If

            End While
        Loop While (need_new_sheet And rs.EOF = False)

如果您需要知道某些变量。

row_count = header_row_num + 1 'Change the first row count to a row after header_row_num

oxl = CreateObject("Excel.Application")
    oxl.Visible = False
    owb = oxl.Workbooks.Add

Dim data_cols(,) As String = {{"A", "Name", "NAME"}, _
                           {"B", "Age", "AGE"}}  (Not real columns, example)

任何建议或想法将不胜感激。在此先感谢:)

【问题讨论】:

  • 如果您使用 100,000 行,Excel 电子表格似乎不是放置它们的好地方。
  • @SteveJorgensen:我知道,但由于它的报告数据提取和 Excel 为我提供了样式和格式,我只认为它是放置它的一种选择。

标签: excel vba


【解决方案1】:

在 Excel 中填写 10 万行肯定需要时间。

这是你可以做的,以尽量减少时间

  1. 在宏的开头使用oxl.ScreenUpdating = False,最后设置为True
  2. 您可能希望将数据存储在数组中,然后最后将数组一次性写入 Excel。这肯定会减少执行时间
  3. Excel 2007 及更高版本 Excel 的行数限制为 1048576 行,因此如果您超过该限制,您可能需要考虑这一点。
  4. Console.WriteLine("Added new sheet to workbook...") 是 VB.net。如果您使用 VBA,请使用 Debug.print
  5. 顺便说一句,这不会对速度产生显着影响,但您可以编写以下代码

这是

.Columns("A").NumberFormat = "@"
.Columns("B").NumberFormat = "@"
'
'
'
.Columns("R").NumberFormat = "@"
.Columns("S").NumberFormat = "@"

作为

.Columns("A:S").NumberFormat = "@"

【讨论】:

  • GetLength 也看起来像 .NET。这是 vb.net 而不是 VBA?这可以解释 CreateObject 和缺少 Set....
  • 这可以解释为什么它也超级慢 - COM 编组开销或在逐个单元格操作时 NET 和 Excel 之间的任何内容。使用 VBA 会更快!
  • 再次正确。在这种情况下,用户有两个选择。 1) 写入数组,然后写入 Excel 或 2) 写入文本文件 (CSV),这样会快得多。
  • @Siddharth Rout:CSV 不是一个选项,因为我在 Excel 中进行了一些格式化和样式,而 CSV 无法做到这些。顺便说一句,如果我要将数据存储到动态数组中,我究竟是如何将其写入 excel 的?不是和我们一个个一个个地插入一样吗?
  • @TimWilliams:是的,它的 VB.net ......抱歉混淆了
【解决方案2】:

最快的方法是CopyFromRecordset

来自 MSDN:


expression.CopyFromRecordset(Data, MaxRows, MaxColumns)

expression:必填。返回 Range 对象的表达式。

Data:必需的变体。要复制到的 Recordset 对象的名称 范围。

MaxRows:可选变体。要复制到的最大记录数 工作表。如果省略此参数,则 Recordset 对象被复制。

MaxColumns:可选变体。要复制的最大字段数 到工作表上。如果省略此参数,则 Recordset 对象被复制。


例如,在您的情况下,只需键入:

Range("A2").CopyFromRecordset rs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    相关资源
    最近更新 更多