在 VBA 中复制粘贴数据的 "correct" 方法是什么?

What is the "correct" way to copy-paste data in VBA?

将VBA中的数据复制粘贴到Excel中的"correct"方法是什么?

现在,至少据我所知,这三个是唯一可用的方法:

  1. (Range).Copy([Destination])方法
  2. (Worksheet).Paste([Destination, Link])方法
  3. (Range) .PasteSpecial([Paste], [Operation], [SkipBlanks], [Transpose])方法

现在,我做了研究,这些是 .Copy([Destination]) 优点和缺点 ].Paste([Destination, Link]) 方法,至少我能想到的那些:

优点:

  • 允许我们将数据粘贴到与复制相同的表达式中 (我猜代码可读性..?)

缺点:

  • 单元格引用绝对不行!
  • 您的格式和公式可能会搞砸
  • 如果范围重叠,它会显示一个提示,有效地阻止宏死在它的轨道上(这是一个巨大的失败,特别是如果你试图自动化一些东西)
  • 更糟糕的是,如果您在提示符下按 Cancel,它会抛出一个 Error**(除非已处理)

在硬币的另一面,.PasteSpecial()

优点:

  • PasteSpecial() 允许我们粘贴范围的特定部分!
  • 它允许我们指定要执行的粘贴类型
  • 具有内置的 skipBlankstranspose 功能
  • 不是"so"Error-容易!

我努力想出任何一个,但是:

缺点:

  • 要写更多的字符?

现在,这让我相信,.Copy() 方法的 Destination 参数基本上应该被忽略,应该始终使用 PasteSpecial() 代替。

是否存在使用它比 .PasteSpecial() 更可取的场合?还是应该 PasteSpecial() 成为每个复制粘贴操作的标准?

这与可读性或您输入的字符数无关。这是关于你需要达到的目标

换句话说,它绝对不是主观的或基于意见的,就像编程中的几乎所有其他东西一样...

#ItDepends.

如果您正在使用 Excel 和复制粘贴单元格,您是否 Ctrl+CCtrl+V 或使用 选择性粘贴?

取决于您需要做什么。

  • 如果您要复制一个单元格,它的值、格式、数据验证、边框等;那么 .Paste [Destination] 就是你最好的朋友。这是 Ctrl+C/Ctrl+V[=76 的编程等价物=]... 等同于 PasteSpecial/All,这太过分了,因为 .Paste [Destination] 在这种情况下已经做了您需要它做的所有事情。

    Cell references are a complete no go!

    当然可以。硬编码的单元格引用是不好的。 .Paste [Destination] 无论如何都不会强迫你这样做,所以这一点没有实际意义。

    If the range overlaps it will display a prompt, effectively stopping macro dead in its tracks

    复制和粘贴范围不能重叠,句号。您也会通过 .PasteSpecial 获得该提示。

  • 如果您要复制单元格的Value而不是其格式、数据验证、边框等;那么 .PasteSpecial 绝对是一个更好的主意,因为这在编程上等同于 特殊粘贴/值 - 除了将单元格的 Value 分配给你想要什么(不需要往返 to/from 剪贴板); OTOH 如果你 的意思是粘贴格式、数据验证或诸如此类的东西,那么这可能是最简单的方法。

Paste 没有 "mess up" 格式。它完全按照它的意思去做。 PastePasteSpecial 而不是 等价物。使用正确的工具来完成工作。它们实际上分别是 "paste" 和 "paste special" 的程序等效项 - 如果您处于 Excel 并系统地进行 "paste special",您将完成您的工作。但每次你对 "paste all" 这样做时,你都比需要的更加努力。

PasteSpecial 看起来像一把漂亮的锤子,但并非所有东西都是钉子。当您可以避免写入剪贴板时,避免它通常是个好主意……但是话又说回来,(想想 100K+ 个单元格),它可能比仅仅分配值表现得更好。

也就是说:

@ScottCraner I did think about it, but that's not really copy-pasting, but more of a typical pointer referencing, hence I decided not to include it in my question. I didn't want to open a book to the "what counts as copy-pasting" discussion.

这是错误的。 .Range(foo).Value = .Range(bar).Value 不是 "typical pointer referencing"。它实际上是将 foo 的值放入二维变体数组,并将该二维变体数组转储到 bar,覆盖先前保存的值。因此,它绝对是点击剪贴板的完全有效替代方案 - 但您需要测试并与 Copy+PasteSpecial 进行比较,看看这是否是您的最佳(/最有效)解决方案情况:

Testing with 1500000 cells (100000 rows)
Pasting from clipboard, single operation: 324.21875ms
Setting cell values, single operation:    1496.09375ms


Testing with 150 cells (10 rows)
Pasting from clipboard, single operation: 11.71875ms
Setting cell values, single operation:    3.90625ms
Pasting from clipboard, iterative:        1773.4375ms
Setting cell values, iterative:           105.46875ms