VBA性能向上委員会

VBAプログラミングの実行速度に関して、より速い性能を求めて徹底検証をします。


HOME > VBA性能徹底検証 > セルのコピー

セルのコピー

[A1]の値が条件に合致したら[B1]にコピーする。これを[Ax]まで繰り返す。

VBAプログラムでは、ごく一般的なロジックです。


一般的なロジックだからこそ、性能を見直すべき大きなポイントでもあります。

今回はセルの値をコピーする性能について、検証します。


  • For文で、Valueを代入
  • アドレス指定して、Valueを代入
  • アドレス指定して、Copyメソッド
  • アドレス指定して、PasteSpecialメソッド

[A:A]の値を[B:B]にコピーするロジックを、以上4つのパターンに分けて検証します。



For文で、Valueを代入 サンプルプログラム

Dim c As Range
For Each c In Range("A:A")
c.Offset(, 1).Value = c.Value
Next c

範囲[A:A]までをループさせ、Offset(, 1)で隣のセルに値を代入しています。

代入の前に、条件式を入れると、どこにでもある一般的なロジックですね。



アドレス指定して、Valueを代入 サンプルプログラム

Range("B:B").Value = Range("A:A").Value

ごく単純な値の代入です。

特に条件がなくコピー元セル範囲とコピー先セル範囲が決まっている場合や、条件で絞った後に一括でコピーする場合等で、この様な書き方になると思われます。



アドレス指定して、Copyメソッド サンプルプログラム

Range("A:A").Copy Range("B:B")

値の代入ではなく、セルのコピー&ペーストをする方法です。

RangeオブジェクトのCopyメソッドを使用し、引数にコピー先セルを指定しています。

EXCELで操作する際は、セルをコピーして、ペースト先セルを選択してEnterキーを押したときと同じ動きをします。



アドレス指定して、PasteSpecialメソッド サンプルプログラム

Range("A:A").Copy
' 値の貼り付け
Range("B:B").PasteSpecial xlPasteValues
' 書式の貼り付け
Range("B:B").PasteSpecial xlPasteFormats
Application.CutCopyMode = False

形式を選択して貼り付けをする方法です。

コピー元のセルのRangeオブジェクトのCopyメソッドを実行した後に、コピー先のセルのRangeオブジェクトのPasteSpecialメソッドを実行する流れとなります。

また、PasteSpecialメソッドは、セルをコピーして、ペースト先セルを選択してCtrl + Vキーを押したときと同じ動きをしますので、Application.CutCopyMode = Falseにてコピー状態を解除する必要があります。


ここでは、よく使用するであろう、値の貼り付けと書式の貼り付けの両方を実行し、検証をします。



検証

上記4つのパターンについての実行結果は以下の通りです。

回数ForValueCopyPasteSpecial
1回目2.0630.0470.0160.016
2回目2.8130.0470.0160.031
3回目2.7810.0320.0160.032
4回目2.8280.0310.0000.032
5回目2.7970.0460.0000.063
6回目2.8130.0470.0160.032
7回目2.8280.0320.0160.016
8回目2.7970.0940.0160.047
9回目2.8130.0310.0000.063
10回目2.9060.0470.0160.016
平均2.7440.0450.0110.035

※単位は全て『秒』


今回の検証によりわかることは、ループさせて一つ一つコピーするより、一括でコピーするほうが速いということです。


最速はCopyメソッドで、For文と比べて0.4%も速くなっています。

5分かかっていたマクロが、1秒で終わります。この差は脅威ですね。


絶対に対応すべき点の一つでもあります。