3日がかりのその仕事、3分で終わらせる方法教えます!
パソコンスキルの心技体

For Next、For Each、Do Loop、速いのはどれ? – Excelマクロ・VBA

2012年1月7日
  • このエントリーをはてなブックマークに追加
  • follow us in feedly

エクセルマクロ・VBA達人養成塾 小川です。

キューバ旅行記、その76です。

キューバ屈指の外人向けリゾート地、バラデロにて、自転車でフラフラ移動中です。

エクセルマクロ達人養成塾塾長ブログ-バラデロの柔道場

バラデロの柔道場

エクセルマクロ達人養成塾塾長ブログ-柔道場の中にて

柔道場の中にて

エクセルマクロ達人養成塾塾長ブログ-チェゲバラと嘉納治五郎の肖像写真

チェゲバラと嘉納治五郎の肖像写真

エクセルマクロ達人養成塾塾長ブログ-そして、また海 ヾ(´ー`)ノ

そして、また海 ヾ(´ー`)ノ

エクセルマクロ達人養成塾塾長ブログ-地元の小さな郷土資料館2階から。

地元の小さな郷土資料館2階から。

エクセルマクロ達人養成塾塾長ブログ

エクセルマクロ達人養成塾塾長ブログ
塾長のキューバ旅行記、最初から読みたい方はこちらから


For Next、For Each、Do Loop、速いのはどれ? – Excelマクロ・VBA

今日は、前回のブログ「複数セルでの処理を高速化したい-その2 Unionメソッドを使用する Excelマクロ・VBA」の内容に若干関連したネタを。
複数セルに対して連続処理をするとき。

For Next構文を使うか、For Each構文を使うか、はたまた、Do Loop構文を使うか、ということで選択を迫られることがあります。

…迫られるっていうか、好きに決めていいんですが。
例えば、以下の3つの構文は、どれも、2行目から11行目までのセルに対して、値を記入していきます。

Sub ForNext()

Dim c As Long

For c = 2 To 11

Range(“A” & c).Value = c – 1

Next

End SubSub ForEach()

Dim r As Range

Dim c As Long

c = 1

For Each r In Range(“B2:B11”)

r.Value = c

c = c + 1

Next

End Sub

Sub DoLoop()

Dim c As Long

c = 2

Do Until c > 11

Range(“C” & c).Value = c – 1

c = c + 1

Loop

End Sub

そのとき、では、どの構文が一番高速か、というお話。

まずは、実験。

上記の例では処理するセルの数が10個しかなくて分かりにくいので、100万個にして試してみます。

以下で、サブプロシージャ「main」を実行してみます。

Sub ForNext1000000()

Dim dF As Date

Dim dT As Date

dF = Now

Dim c As Long

For c = 2 To 1000001

Range(“A” & c).Value = c – 1

Next

dT = Now

Debug.Print DateDiff(“s”, dF, dT)

End SubSub ForEach1000000()

Dim dF As Date

Dim dT As Date

dF = Now

Dim r As Range

Dim c As Long

c = 1

For Each r In Range(“B2:B1000001”)

r.Value = c

c = c + 1

Next

dT = Now

Debug.Print DateDiff(“s”, dF, dT)

End Sub

Sub DoLoop1000000()

Dim dF As Date

Dim dT As Date

dF = Now

Dim c As Long

c = 2

Do Until c > 1000001

Range(“C” & c).Value = c – 1

c = c + 1

Loop

dT = Now

Debug.Print DateDiff(“s”, dF, dT)

End Sub

Sub main()

ForNext1000000

ForEach1000000

DoLoop1000000

End Sub

さて、これで、どうなるかとというと…。

手元のマシンで、Excel 2007上で試したところ、イミィディエイトウィンドウには、以下のように出力されました。

For Next構文: 75

For Each構文: 61

Do Loop構文: 75

ということのようです。

For Each構文が一番速いみたいですね。

解説すると。

For Each構文は、ループに入るタイミングで、あらかじめ作業対象のセルの参照の集合を、メモリに読み込みます。

そして、その読み込まれた集合に対して処理をしていきます。

一方、For Next構文、Do Loop構文では、「Range(“C” & c)」といった構文に来る都度、改めて、そこで言われているセルがどこなのか?ということを調べにいきます。

その分のオーバーヘッド(IT用語: 間接的・付加的に必要となる処理とそれにより発生する負荷の大きさ)のせいで、時間がかかってしまうんですね。

てことで、基本は、For Each構文のほうがおすすめです。

あと、For Each構文のほうが、抽象度が高いので、よく分かっていない人に見せたとき、高度なプログラムを書いているように見られがちでもあります。

そういう意味でも、作り込むなら、For Each構文のほうがオススメです(笑

あ、でも、その場限りのちょっとしたデータ分析に使うだけの、使い捨てマクロを書くくらいでしたら、For Next構文のほうがたぶん簡単かも。
まあ、何らかの参考になれば、と思います。

昨日のブログ記事「複数セルでの処理を高速化したい-その2 Unionメソッドを使用する Excelマクロ・VBA」でご紹介したUnionメソッドを使った手法も、それが高速化につながる理由のひとつは、あらかじめ作業対象のセルの参照の集合を、メモリに読み込んでいるからです。

複数セルでの処理を高速化したい-その2 Unionメソッドを使用する Excelマクロ・VBA

前々回のブログ: 「複数セルに値を入れる処理を高速化したい」もあわせてお読みください。

そうそう。あと、お知らせが2つ。
人気のセミナー「エクセルデータ分析7つの上級技」 と、

知る人ぞ知るマイナーだけど高度なタイピングスキル「親指シフト」をマスターできる「親指シフト達人養成塾」を、

久しぶりに開催します。
今日から受講受付開始します。ふるってご参加ください☆
ではでは (^^)/~

キーワード

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

最新の記事

人気記事

最新記事

カテゴリ

最新コメント

タグクラウド