我已经在这个网站(以及其他地方)多次阅读过,如果可能的话,最好避免在VBA宏中复制/粘贴.例如,而不是这样做......
For i = 1 To tbl.ListColumns.Count
With tbl.ListColumns(i).DataBodyRange
.FormulaR1C1 = "=2*1"
.Copy
.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End With
Next
Run Code Online (Sandbox Code Playgroud)
......据说这样做更好/更快:
For i = 1 To tbl.ListColumns.Count
With tbl.ListColumns(i)
.DataBodyRange.FormulaR1C1 = "=2*1"
.DataBodyRange = .DataBodyRange.Value
End With
Next
Run Code Online (Sandbox Code Playgroud)
但是在大表(15列,100k行)上测试它,复制/粘贴版本明显更快(1.9秒对2.7秒).即使我首先将tbl.DataBodyRange声明为Range变量,差异仍然存在.
我认为这可能是ListObjects的一些奇怪属性,但如果没有它们,差异实际上更大:
'Runs in 1.1 seconds
With Sheet1.Range("A1:O100000")
.FormulaR1C1 = "=2*1"
.Copy
.PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End With
'Runs in 2.1 seconds
With Sheet1.Range("A1:O100000")
.FormulaR1C1 = "=2*1"
.Value = .Value
End With
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么复制/粘贴方法更快?是否有其他理由避免使用复制/粘贴(假设在宏运行时剪贴板永远不会在Excel之外使用)?
编辑:这是第一组测试结果,比较了Copy/PasteValues与Mat's Mug在接受的答案中描述的数组读/写方法.我测试了1000个细胞到100万个细胞的范围大小,每次增加1000个,并且每个范围大小平均进行10次测试.复制粘贴开始较慢,但很快超过了设定值方法(在图表上很难看到,但收支平衡点是~15k单元格).

我还在该范围的下端进行了10次进一步的测试(范围从100个单元到100000个单元,每次增加100个)以试图确定发生均衡点的位置.这次我使用Charles Williams的"MicroTimer"而不是默认计时器,希望它能够在亚秒级时间内更准确.我还包括"Set Array"版本和原始的".Value …
关于更多理论目的的问题:
在vba/excel-vba中复制粘贴数据的"正确"方法是什么?
现在,至少据我所知,这三种是唯一可用的方法:
Range) .Copy([Destination])方法Worksheet) .Paste([Destination, Link])方法Range) .PasteSpecial([Paste], [Operation], [SkipBlanks], [Transpose])方法现在,我做了我的研究,这些都是利弊的.Copy([Destination]) 和.Paste([Destination, Link])方法,至少那些,我能想到的:
+优点:
- 允许我们将数据粘贴到与复制相同的表达式中(代码可读性我猜...?)
和:
-缺点:
- 细胞参考是完全没有去!
- 你的格式和公式可能搞砸了
- 如果范围重叠,它将显示一个提示,有效地阻止宏死在它的轨道上 (这是一个巨大的无赖,特别是如果你试图自动化的东西)
- 更糟糕的是,如果按下
Cancel提示,它将抛出Error**(除非处理)
在硬币的另一边, .PasteSpecial()
+优点:
PasteSpecial()允许我们粘贴范围的特定部分!- 它允许我们指定我们想要做什么类型的粘贴
- 有一个内置的
skipBlanks和transpose功能- 不是"所以" - 不是
Error!
我努力想出任何一个,但是:
-缺点:
- 要写更多的字符..?
现在,这让我相信,方法的Destination论点.Copy()应该基本上被忽略,而PasteSpecial() …