【问题标题】:Delphi - Excel - How to speed up operationDelphi - Excel - 如何加快运算速度
【发布时间】:2014-10-15 21:03:38
【问题描述】:

我正在为 Delphi XE6 中的 Excel 编写插件。我不得不将行从一张纸“复制”到另一张纸。挑战在于我的手术花费的时间比我认为的要长得多。例如,将 500 行(23 列)从一张纸复制到另一张纸需要 28 秒左右...

部分挑战是我必须逐行处理。我有一个 INT 数组,每行一个 INT。 INT 值告诉我是否需要复制该行...

...for loop i ... through entire array....
...if row I am interested in...

      // Set the Original Sheet Active
      MasterOrigSheet.Select;

      // Build my row numbers
      SourceRangeCell := 'A' + IntToStr(i);
      DestRangeCell := 'A' + IntToStr(DestRowNumber);

      // Copy the row from source to destination
      MasterOrigSheet.Range[SourceRangeCell, SourceRangeCell].EntireRow.Copy
        (NewSheet.Range[DestRangeCell, DestRangeCell].EntireRow);
      Inc(DestRowNumber);

有没有更快的方法来做到这一点?我正在复制整行。我没有使用 COPY/PASTE 缓冲区...感谢任何帮助或想法。

【问题讨论】:

  • 最快的方法是只调用一次Copy。在单个范围内指定整个源并在其上调用Copy
  • @@David,在 600 行中,我可能想要第 1,2,4,5,7,8,9,13,14,17 行...基本上我会做大部分,但我肯定会跳过一些/很多......也就是我的行不连续。我无论如何都找不到定义这样的范围...这是我只能调用一次 COPY 的唯一方法,对吗?
  • 不能选择多行吗?如果在 Excel 中其自身,保持控制并选择第二个范围,则效果相同。
  • 或者只复制所有行,然后删除你不想要的行
  • @Zibelas,我怀疑这会带来很大的改进。我强烈怀疑此操作中的主要时间消耗不是将数据从一张纸实际复制到另一张纸,而是正在进行的 COM 调用次数。如果我是对的,那么您的建议只会在复制超过 50% 的行时有所改善。

标签: excel performance delphi


【解决方案1】:

目标是限制您需要调用 Excel 的次数。

为此,利用Worksheet.Range 属性在单个字符串中接受多个单元格这一事实。使用联合运算符(逗号)一次描述多个单元格。也就是说,在您的循环中,建立一个以逗号分隔的要复制的单元格列表。然后调用Range 获取范围引用,并在该单个范围上使用EntireRow.Copy

另外,避免重复不需要完成的工作。例如,原始表应在整个循环中保持选中状态,因此您无需继续告诉 Excel 在每次迭代中选择它。即使该操作没有实际效果,您的程序仍需要完成打包 COM 调用并将其传递到 Excel 的工作。

【讨论】:

  • Rob,我喜欢这个主意,但我找不到任何允许这样做的语法。我试过 MyRange := sheet.range[A5..H5 A6..H6]; MyRange := sheet.range[A5:H5 A6:H6]; MyRange := sheet.range[A5 H5 A6 H6];和 MyRange := sheet.range.cells[A5 H5 A6 H6];我知道我可以使用 UNION 命令,但似乎无法使联合运算符(空格)起作用。
  • 我说要构建一个字符串sheet.range['A5 A7 A9'].EntireRow 来创建一个由三个不相邻的行组成的范围。
  • 但这仍然行不通。 sheet.range['A5,A6'].EntireRow 有效。运行良好。如果我将其更改为 ... sheet.range['A5 A6'].EntireRow;它会编译,但会在运行时引发 COM 错误。在行列表之间使用 SPACE 不是有效的语法(据我所知)。顺便说一句,我正在运行 Excel 2013。
  • 对不起。我一定是看错了什么。空间运算符用于交集。 comma 运算符用于联合。使用逗号。
  • 那行得通... sheet.range['A5,A7,A9'].EntireRow;谢谢你。我查看了 Excel 的开发人员文档,但找不到任何对此语法的引用。你在哪里找到的?
猜你喜欢
  • 1970-01-01
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多