ExcelのマクロVBAが遅くて、実行後に長時間応答しなくなるようなとき、
データ量が多いことや計算が複雑なことが原因の場合もありますが、
たいていの場合はコードの書き方に問題があるようです。
マクロの速度を改善するための対処方法についてメモしました。
目次
意味のないselectをしないようにする
値のコピペの場合には「Copy」や「Paste」を使用しない
マクロの記録機能を使ってコードを作成した場合、
実行する必要のない「select」が入ってしまうことが多いと思います。
たとえば、「セルA1の内容をセルB2にコピー&ペースト」するような場合ですが
Range(“A1”).Select
Selection.Copy
Range(“B2”).Select
ActiveSheet.Paste
Application.CutCopyMode = False
上のコードではコピーをする際にいちいち「select」を使ってセルを選択していますが、
これは省略することができます
(ただし、Pasteする際には、貼り付け先のセルを選択しておく必要があります。)。
Range(“A1”).Copy
Range(“B2”).Select
ActiveSheet.Paste
Application.CutCopyMode = False
これでも、なんだか野暮ったいので、もう少し簡単にしたいですね。
そこで「Copy Destination:=」を用います。
「Copy Destination:=」の後ろにペースト先を書くことによって、
ペーストのほうでも「select」を省略することができます。
Range(“A1”).Copy Destination:= Range(“B2”)
コピー元セル.Copy Destination:= ペースト先セル
さらに「Destination:=」を省略することもできます。
Range(“A1”).Copy Range(“B2”)
*なお、複数のセルをコピペする際には、
コピー元ではRangeなどで複数セルの範囲を指定する必要がありますが、
ペースト先のほうでは先頭のセル1つを指定するだけで構いません。
セルの値だけをコピペしたい場合には
通常「PasteSpecial Paste:=xlPasteValues」を用いると思います。
Range(“A1”).Copy
Range(“A2”).Select
Selection.PasteSpecial Paste:=xlPasteValues
VBAを学び始めたばかりの頃は、上の方法がやや高度に見えて、処理速度も速い方法なのだと思っていました。
しかし、実は(若干稚拙なようにも見える)次に示す方法のほうが処理がかなり早くなるようです。
それは
「コピー元とペースト先のセル(のValueプロパティ)を「=」でつなぐ」方法です。
「=」の後ろのセルの値が「=」の前のセルのほうへ代入されます。
Range(“A2”).Value = Range(“A1”).Value
ペースト先セル.Value = コピー元セル.Value
複数のセルの値のコピペも同様に可能です。
Range(“A11”, “F15”).Value = Range(“A1”, “F5”).Value
ペースト先セル範囲.Value = コピー元セル範囲.Value
ループの繰り返しで値をコピペをしたり、広範囲セルでの多量の値のコピペしたりする際には
処理時間において圧倒的に差が出てきます。
注意
① 「.Value」は省略できない
通常、セルにValueプロパティを書かなければ
Valueは省略されたものとみなされるのですが
(いちいち「.Value」を書かなくてもよい)、
上記の「=でつなぐ値のコピペ」の場合はValueを省略できません。
② 複数のセルの値をコピペする場合は
コピペ前後のそれぞれセル範囲が同じ大きさになるようにする必要がある
たとえば、コピー元の範囲が3行✕4列の場合は、
ペースト先の範囲も3行✕4列で記さなくてはなりません。