■2-3 変数の有効活用で高速化
この項目では、2次元配列変数とオブジェクト変数を使用した実行速度アップを
確認をしました。




(1)セルデータを2次元配列を使用して一括移動例
比較としてはシート1のA列B列5000行データを、シート2の同じ場所に記入するマクロです。
比較元としては「変数使用1」マクロで1行ずつ記入した例(画面8参照)の時間と比べました。

「変数使用2」マクロはシート1のセルデータを、配列変数「mydat」へ代入し、その代入したデータを
シート2へ一括記入しました。配列のデータ型はバリアント型で本例では2次元配列になります。
一括記入でセルのデータは高速アクセスできますが、配列に代入されるのはデータのみで、
文字サイズやセルの背景色などのセルのプロパティは含まれません。

★本例の場合元マクロ(変数使用1)は「0.55秒」→ 「0.062秒」(変数使用2:画面8参照入)で【約8.8倍アップ】。
 

画面8 比較元マクロの実行例

Sub 変数使用1()
Dim endr As Integer
Dim i As Integer
timck = Timer
    Application.ScreenUpdating = False
ThisWorkbook.Activate
Sheets("Sheet1").Select
    endr = Range("B10000").End(xlUp).Row
For i = 1 To endr
    Sheets("Sheet2").Cells(i, 1) = Sheets("Sheet1").Cells(i, 1)
    Sheets("Sheet2").Cells(i, 2) = Sheets("Sheet1").Cells(i, 2)
Next
Sheets("Sheet1").Select
    Range("A1").Select
    Application.CutCopyMode = False
Application.ScreenUpdating = True
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒"
End Sub
 
 
 
Sub 変数使用2()
Dim endr As Integer
Dim mydat As Variant
    Application.ScreenUpdating = False
ThisWorkbook.Activate
Sheets("Sheet1").Select
 
    endr = Range("B10000").End(xlUp).Row
    mydat = Range(Cells(1, 1), Cells(endr, 2))
 
    Sheets("Sheet2").Select
        Range(Cells(1, 1), Cells(endr, 2)).Value = mydat
Sheets("Sheet1").Select
    Range("A1").Select
End Sub




(2)セルデータをオブジェクト変数を使用して一括移動例
「変数使用3」マクロはシート1のセルデータ範囲を、オブジェクト変数「myrng」へ代入し、その代入した
参照範囲データをシート2へ一括記入しました。

こちらもRangオブジェクト参照で一括記入でき高速アクセスになりますが、データのみの記入で
セルプロパティは含まれない点を注意してください。

★本例の場合元マクロ(変数使用1)は「0.55秒」→ 「0.046秒」(変数使用3:画面9参照)で【約12倍アップ】。

画面9マクロ変数使用3実行例


Sub 変数使用3()
Dim endr As Integer
Dim myrng As Range
    Application.ScreenUpdating = False
ThisWorkbook.Activate
Sheets("Sheet1").Select
    endr = Range("B10000").End(xlUp).Row
    Set myrng = Range(Cells(1, 1), Cells(endr, 2))
 
    Sheets("Sheet2").Select
       Range(Cells(1, 1), Cells(endr, 2)).Value = myrng.Value
 
Sheets("Sheet1").Select
    Range("A1").Select
End Sub




(3)セルデータをコピーしてコピー貼り付けた例
前2項はデータのみの記入でしたが、このコピーペーストではセルのプロパティも反映させて別セルへ記入
できます。データ範囲をコピーして貼り付けは実行速度が遅いと思っていましたが、測定結果は早かった。

★本例の場合元マクロ(変数使用1)は「「0.55秒」→ 「0.015秒」(変数使用4:画面10参照)で【約36倍アップ】。

画面10 マクロ変数使用4実行例


なお本例で見ると、同じデータを別セルへ記入のケースはコピーペーストが
もっとも早い。しかし、配列データの処理や、オブジェクト参照データの処理を
実行した後に別セルへデータ記入の場合は変数へ代入の方が有利です。

Sub 変数使用4()
Dim endr As Integer
    Application.ScreenUpdating = False
ThisWorkbook.Activate
Sheets("Sheet1").Select
    endr = Range("B10000").End(xlUp).Row
 
    Range("A1:B" & endr & "").Select
        Selection.Copy
    Sheets("Sheet2").Select
        Range("A1").Select
    ActiveSheet.Paste
        Range("C1").Select
Sheets("Sheet1").Select
    Range("A1").Select
    Application.CutCopyMode = False
End Sub




(4)変数を少バイトのデータ型を宣言して実行例
バリアント型は数字も文字列も代入できる便利なデータ型ですが、その分メモリーを16バイト使用する
ので、整数型の2バイトに比べメモリ領域を多く消費します。アクセスも2バイトの方が早いはずです。

しかし最近のPCは性能がよくなった関係もあると思いますが、今回比較した下記マクロではデータ型
の相違により実行速度の差は出ませんでした。

★以下の「変数使用5」「変数使用6」の測定結果は同じでした。

Sub 変数使用5()
Dim i As Integer
ThisWorkbook.Sheets("Sheet3").Select
 
For i = 1 To 15000
    Cells(i, 1) = i
Next
Sheets("Sheet1").Select
End Sub
------------------------------------------------------
Sub 変数使用6()
Dim i As Variant
ThisWorkbook.Sheets("Sheet3").Select
 
For i = 1 To 15000
    Cells(i, 1) = i
Next
Sheets("Sheet1").Select
End Sub




■2-4 ワークシート関数使用で高速化
特定の処理を行う場合プロシージャを自分で作成しますが、ワークシート関数で処理できる場合は
「ワークシート関数」使用で高速処理ができます。

★ 比較元データをFor文で作成して実行時間測定
本例は30000行のA列セルに入れたランダム数値から最大値を探すマクロで、Forステートメントで実行
した時間と、ワークシート関数で実行した時間を比較しますが、本項目は比較元時間としてForステート
メントで実行した例です。

画面11 比較元For文マクロの実行例


Sub シート関数1()
Dim i As Integer, mymax(1) As Integer
ThisWorkbook.Sheets("Sheet3").Select
endr = Range("A31000").End(xlUp).Row
 
For i = 2 To endr
    If mymax(1) < Cells(i, 1) Then
        mymax(1) = Cells(i, 1)
        mymax(0) = i
    End If
Next
End Sub




(1)比較元のFor 文と For Each文の速度参考比較例
本項目はFor文を基点に比較するので、For Each文は不用ですが、ついでにFor文と For Each文の
実行速度もチェックしようと思い実行しました。

★For文と For Each文の実行速度のチェック結果は、For文「0.203秒」
       For Each文「0.156秒」(画面12参照)でFor Eachの方が若干【約1.3倍】早かった。

画面12 マクロシート関数2実行例


Sub シート関数2()
Dim i As Integer, mymax(1) As Integer
Dim myrng As Range, chk As Range
ThisWorkbook.Sheets("Sheet3").Select
    endr = Range("A31000").End(xlUp).Row
   Set myrng = Range(Cells(2, 1), Cells(endr, 1))
 
    For Each chk In myrng
        If mymax(1) < chk.Value Then
            mymax(1) = chk.Value
            mymax(0) = chk.Row
        End If
    Next
End Sub




(2)セルデータを変数に入れ最大値抽出例 
前述のFor文で実行とマクロ構成は同じですが、こちらはセルを一度配列に入れ配列データをFor文で
チュックです。本例は最大値の抽出ですが、もしセルデータをチェックや処理する場合は配列に代入後
おこなう方が高速で実行できることの確認です。

★本例の場合元マクロ( シート関数1)は「0.203秒」→
  「0.062秒」(シート関数3:画面13参照)で【約3倍アップ】でした。

画面13 マクロシート関数3実行例


Sub シート関数3()
Dim i As Integer, mymax(1) As Integer
Dim mydat As Variant
ThisWorkbook.Sheets("Sheet3").Select
    endr = Range("A31000").End(xlUp).Row
    mydat = Range(Cells(1, 1), Cells(endr, 1))
 
For i = 1 To endr
    If mymax(1) < mydat(i, 1) Then
        mymax(1) = mydat(i, 1)
        mymax(0) = i
    End If
Next
End Sub




(3)ワークシート関数Maxで最大値抽出例 
この項目が本題のワークシート関数Maxを使用した最大値抽出例で、高速になります。ワークシート
関数で処理できる場合は出来るだけそれを活用した方が、マクロの記述もスッキリし他のどの方法より
高速になります。

★本例の場合元マクロ( シート関数1)は「0.203秒」→ 「0.031秒」(シート関数4:画面14参照)【約6倍アップ】。
 

画面14 マクロシート関数4実行例


Sub シート関数4()
Dim i As Integer, mymax As Integer
Dim myrng As Range
ThisWorkbook.Sheets("Sheet3").Select
    endr = Range("A31000").End(xlUp).Row
    Set myrng = Range(Cells(2, 1), Cells(endr, 1))
 
    mymax = Application.WorksheetFunction.Max(myrng)
End Sub




■2-5 $付き文字型関数を使用で高速化
Excel97の頃は一部の関数にVariant型を返す形式と、Strint型を返す形式の2つの形式をもつものがあ
りました。関数名にドル記号($)を追加するとStrint型の文字列を返す関数となりました。これは使用する
メモリが少なく多少ではあるが、マクロの実行速度向上にも役立っていました。

ただし$付き関数はExcel2003以降のヘルプで検索しても出てこないので、今後も使用可能であるかは
不明でが、Excel2007/2010でも問題なく使用でき速度向上の効果も多少ですがあります。




(1)文字型関数Mid$の使用例
自動記録でチャートを新規に作成するとそのつど新しい名前が付けられるが、それにはブック名も含ま
れています。その後自動記録したマクロを実行する場合のチャート指定は、ブック名の無いチャート名が
必要です。本例はMid$関数でチャート名を取り出したケースです。

30万回実行で約0.1秒のアップであり大きな効果ではないが、「チリも積もれば山となる」であり、
よく使用する関数があれば$付きを使ってみてください。

★本例の場合元マクロ( 文字型関数1)は「0.203秒」→「0.048秒」(文字型関数2:画面15参照)【約4倍アップ】。

画面15 文字型関数Mid$を使用した結果


Sub 文字型関数1()
Dim i As Long
For i = 1 To 300000
    dd = Mid("VWAPチャート グラフ 65", 10)
Next
End Sub
---------------------------------------------------------
Sub 文字型関数2()
Dim i As Long
For i = 1 To 300000
    dd = Mid$("VWAPチャート グラフ 65", 10)
Next
End Sub


(2)$付き(文字型)にできる関数
主な$付き(文字型)にできる関数を表1に示します。
なお、Excel97時代は問題ありませんでしたが、Excel2010でも全て問題なく使用できるかは未確認です。
【表1$付き(文字型)にできる関数 】
Chr$ ChrB$ CurDir$
Date$ Dir$ Error$
Format$ Hex$ Input$
LCase$ Left$ LeftB$
LTrim$ Mid$ Oct$
Right$ RightB$ RTrim$
Space$ Str$ String$
Time$ Trim$ UCase$



【戻る】    【Top画面】   【HPへ】