■2-6 不要行を高速で削除する方法
本例では不要行として空白行があった場合の高速削除例ですが、WebページからデータをExcelシート
へ貼り付けた場合、空白以外にも不要な行があり、削除に時間が掛かることがあります
(画面16は空白の5行6行を削除例です)

AutoFilter メソッドを使用して不要行を削除する例
高速化の方法は、準備として未使用の列に同じ数字(本例は1)を記入し、フィルタでキーワードを指定し
(本例は空白ですがキーワードは何でもよい)不要列を表示します。表示された行のみ準備で記入した
数字を含む全データを削除します。その後準備で記入した数字列を基準に並べ替えを実行すれば
空白行は最後尾に集まり不要行削除の完了です。

 画面2-16 不要行削除例


★本例の場合元マクロ(空白行削除1)は「3.9秒」→「2.77秒」(空白行削除2:画面17参照)で【約1.4倍アップ】。
  

画面17 マクロ空白行削除1実行例

Sub 空白行削除1()
Dim i As Integer, endr As Integer
Application.ScreenUpdating = False
ThisWorkbook.Sheets("Sheet3").Select
endr = Range("A31000").End(xlUp).Row + 1
 
For i = endr To 3 Step -1
    If Cells(i, 1) = "" Then
       Rows(i).Delete Shift:=xlUp
    End If
Next
End Sub

Sub 空白行削除2()
Dim myRange As Range, myRange1 As Range
Application.ScreenUpdating = False
endr = Range("A31000").End(xlUp).Row + 1
 
Set myRange = Range(Cells(1, 1), Cells(endr, 2))
    myRange.Columns(2) = 1
Set myRange1 = Range(Cells(2, 1), Cells(endr, 2))
 
myRange.AutoFilter
    myRange1.AutoFilter Field:=1, Criteria1:=""
    myRange1.SpecialCells(xlCellTypeVisible).ClearContents
Selection.AutoFilter
 
Cells.Select
    Selection.Sort Key1:=Range("B1"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom
Range("A1").Select
   Columns("B:B").ClearContents
End Sub

【補足】下記のマクロ例は、SpecialCells(xlCellTypeBlanks)で、指定した範囲の空白セルを一気に取得
して、その空白セルを一括削除方式です。かなりの高速を期待したが、「1.15秒」→「0.95秒」で殆んど
高速になりません。

Sub 空白行削除3()
Dim myRange As Range
    timck = Timer
Application.ScreenUpdating = False
endr = Range("A31000").End(xlUp).Row + 1
    Set myRange = Range(Cells(1, 1), Cells(endr, 1))
    myRange.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub




■2-6a 行追加の高速化
本例はWebから取得した時系列株価データに、最初の1行を空け、別データ追加を高速で行う方法です。
(例題データは"AAAA"・・ですが、実際は本日の株価を追加です)。
(「空白行」は33行を1行空けその行に別データ追加、「行明け高速」はコピーを34にペーストで33行へ別記入)

 画面2-16a 1行開けて別データ挿入例


★本例の場合元マクロ(行明け)は「0.031秒」→「0.015秒」(行明け高速:画面17a参照)で【約2倍アップ】。
  

画面17a 1行開けて別データ挿入例


Sub 行空け()
timck = Timer  '◆測定スタート
行空け
    Rows("33").Select
            Selection.Insert Shift:=xlDown
データ記入
   Cells(33, 2) = "AAAA": Cells(33, 3) = "BBBB": Cells(33, 4) = "CCCC"
   Cells(33, 5) = "DDDD": Cells(33, 6) = "EEEE"
   Cells(33, 1) = Date
 
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒", Title:="行空け"
End Sub

Sub 行空け高速()
timck = Timer  '◆測定スタート
 
行空け
 endr2 = Cells(10000, 1).End(xlUp).Row
   Range(Cells(33, 1), Cells(endr2, 6)).Copy Range("A34")
 
データ記入
   Cells(33, 2) = "AAAA": Cells(33, 3) = "BBBB": Cells(33, 4) = "CCCC"
   Cells(33, 5) = "DDDD": Cells(33, 6) = "EEEE"
   Cells(33, 1) = Date
 
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒", Title:="行空け高速"
End Sub




■2-6b 列移動の高速化
本例はWebから取得した時系列株価データを、Excelチャートのフォーマットに変更を高速で行う方法です。
 B列を空け、後ろにズラシ(B→C、C→D・・・)、空いたB列へG列を記入例です。


画面17b 列移動の高速化例


Sub 列削除1()
 
timck = Timer  '◆測定スタート
データ整理
    Columns("G").Delete Shift:=xlToLeft    '調整後終値*カット
    Columns("B").Insert Shift:=xlToRight   'B列を空ける
 
    Columns("G:G").Select            'G列をB列へ
    Selection.Copy
    Range("B1").Select
    ActiveSheet.Paste
    Columns("G:G").Select
    Application.CutCopyMode = False
    Selection.ClearContents
    Range("A1").Select
 
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒", Title:="列削除1"
End Sub

Sub 列削除2()
 
timck = Timer  '◆測定スタート
    endr2 = Cells(10000, 1).End(xlUp).Row
 
Range(Cells(32, 2), Cells(endr2, 6)).Copy Range("C32")     'B列以降をC列へ貼り付け
Range(Cells(32, 7), Cells(endr2, 7)).Copy Range("B32")     'G列をB列へ
Range(Cells(32, 7), Cells(endr2, 7)).ClearContents
    Application.CutCopyMode = False
 
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒", Title:="列削除2"
End Sub





■2-7 CSVファイルを高速で取り込む方法
ブックを開かずに高速でCSVファイルを取り込む方式
古い話で恐縮ですが、今回時間測定に使用した東京都の郵便番号のCSVファイルは、Excel95では
1秒以下でExcelに取り込め問題ありませんでした。
しかし同じファイルで、同じマクロ(テキスト取込1)で、Excel97/2000/2002では約30秒掛かるようになり
かなりイライラしました。(実行例は画面18参照)
(そのころ、この「テキスト取込2」マクロで約200倍高速にすることができた)

しかし、その後Excel2003ではExcel95レベルの約1秒に戻ったので、ここに紹介のブックを開かずに高速
でテキストファイルを取り込む方式は、最近では大きく取り上げるほど有効なマクロではないが、拡張子
TXTのデータベースファイルにも使用できるので活用してください。

★本例の場合元マクロ(テキスト取込1)は「0.45秒」→
   「0.20秒」(テキスト取込2:画面19、画面20参照)で【約2倍アップ】でした。

画面18 CSVファイルの高速取り込み例(Excel2002)


画面19 CSVファイルの高速取り込み例(Excel2010)


画面20 CSVファイルの高速取り込み例(Excel2002)


Sub テキスト取込1()
 
    Workbooks.Open Filename:=ThisWorkbook.Path & "\" & "13TOKYO.CSV"
End Sub


Option Base 1
Sub テキスト取込2()
Dim dat(5000, 15) As String
Dim txtpas As String, i As Integer
 
txtpas = ThisWorkbook.Path & "\" & "13TOKYO.CSV"
    i = 1
    Open txtpas For Input As #1
Do Until EOF(1)
    Input #1, dat(i, 1), dat(i, 2), dat(i, 3), dat(i, 4), dat(i, 5), _
             dat(i, 6), dat(i, 7), dat(i, 8), dat(i, 9), dat(i, 10), _
        dat(i, 11), dat(i, 12), dat(i, 13), dat(i, 14), dat(i, 15)
     i = i + 1
Loop
Close #1
 
    Range(Cells(1, 1), Cells(i - 1, 15)).Value = dat
End Sub




■2-7a  セルデータを高速txtファイル保存
以下は、セルデータを配列に代入し、それをtxtファイルに保存例。

Sub ダイアログ銘柄を保存()
Application.ScreenUpdating = False
Sheets("リアルタイム解析").Select
ReDim dbd(39, 6)
 
dbd = Range(Cells(43, 1), Cells(81, 6)).Value
 
 filretu = 31
 Call 保存場所指定 ’詳細省略
 
ファイル名
fmei = "優先G@-Cリスト"
    Open phn & "\" & fmei & ".txt" For Output As #1
    For i = 1 To 39
        For j = 1 To 6
            Print #1, dbd(i, j)
        Next j
    Next i
    Close #1
 
 MsgBox "「" & fmei & "」を " & phn & "へ保存ました。"
 
End Sub




■2-7b  txtファイルを取込みセルデータを高速書き込み
以下は、txtファイルを取込み、それを高速でセルへ書き込む例。

Sub ダイアログ銘柄取り込み()
Dim txtpas As String           'サンプルtxtファイル保存場所
Dim dat(39, 6) As String     '2次配列宣言
Dim i As Integer               'カウンター
 
Sheets("リアルタイム解析").Select
Application.ScreenUpdating = False
 
ダイアログ表示
         flt$ = "(*.txt),*.txt"
     fff = Application.GetOpenFilename(flt$, 2, "ダイアログへ表示の銘柄を取り込み")
     If fff = "False" Then
        MsgBox "ファイルを1個指定して下さい"
        End
     End If
 
txtファイル取込
    i = 1
    Open fff For Input As #1
        For i = 1 To 39
            For j = 1 To 6
                Input #1, dat(i, j)
            Next j
        Next i
    Close #1
 
セルへ書き込み
        For i = 1 To 39
            For j = 1 To 6
                Cells(i + 42, j) = dat(i, j)
            Next j
        Next i
 
End Sub





■2-8 コピー貼り付けと一括書込みの速度比較
(1)セルへ計算式を書き込み例
コピー操作は通常のExcel操作でもかなり早く、マクロ化しても高速の効果はほとんど期待できないが、
ソースが見やすくなるので保守性はよくなります。

★本例の場合元マクロ(コピー1)は「0.17秒」→「0.078秒」(コピー2:画面21参照)で【約2倍アップ】でした。
  

上記は20000行の処理(実行例は画面21参照)でこの程度であり、行数が少ない場合は高速の効果は
期待できない。なお、ダイレクトに数式を書き込む方式の「コピー4」マクロは早いと思い込んでいましたが、
実際は「コピー2」「コピー3」より若干は早い程度でした。

画面21 セルへ計算式を書き込み例





[1]一般的なマニュアル操作の自動記録
自動作成する手順としては、"A2"へ変換式を入れ、次に式を入れたそのセルをコピーし、"A3"〜"A列最
終"を選択し貼り付けた例です。なお、選択したセルはアクティブ(黒)になっているので、通常は他の1セル

(本例はA1)を選択しアクティブ(選択)を解除します。

Sub コピー1()
timck = Timer
endr = Range("E30000").End(xlUp).Row
        Range("A2").Select
        ActiveCell.FormulaR1C1 = "=MID(RC[4],6,5)"
    Range("A2").Select
        Selection.Copy
    Range(Cells(3, 1), Cells(endr, 1)).Select
    ActiveSheet.Paste
        Range("A2").Select
        Application.CutCopyMode = False
End Sub


[2]FillDownメソッドで実行例
このマクロはマニュアル操作の、メニューの「編集」「フィル」「下方向にコピー」の自動記録版で、指定した

Sub コピー2()
endr = Range("E30000").End(xlUp).Row
    Range("A2").Formula = "=MID(E2,6,5)"
    Range(Cells(2, 1), Cells(endr, 1)).FillDown
End Sub


[3]AutoFillメソッドで実行例
このマクロはマニュアル操作の「Ctru」+ 「↓」の自動記録版で、指定したセル範囲へ対象オブジェクト

Sub コピー3()
endr = Range("E30000").End(xlUp).Row
    Cells(2, 1).Formula = "=MID(E2,6,5)"
End Sub



[4]ダイレクトに数式をセルへ記入例
指定したセル範囲へダイレクトに数式を記入する。なお、前述例も同様ですが各行対応へはExcelの機能
で自動的に変換されています。

Sub コピー4()
endr = Range("E30000").End(xlUp).Row
    Range(Cells(2, 1), Cells(endr, 1)).Formula = "=MID(E2,6,5)"
End Sub


(2)セルの計算式を数値化例
マクロと、コピーを形式を選択して貼り付け(値)で実行のマクロを比較しました(実行例は画面22参照)。

本例の場合「数値値化1」「数値値化2」とも計算式から値(データ)になりますが、元が文字列の関係で


画面22セルの計算式を数値化例

Sub 数値値化1()
Dim i As Integer
    For i = 2 To endr
        Cells(i, 1).Value = Cells(i, 1).Value
    Next
Range("a2").Select
End Sub

Sub 数値値化2()
Dim myrang As Range
Set myrang = Range(Cells(2, 1), Cells(endr, 1))
    myrang.Copy
   myrang.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone
    Range("a1").Select
    Application.CutCopyMode = False
End Sub




■2-9 フォルダ内のファイル名を高速で取得する方法
Dir関数使用と、FileSystemObject使用の実行時間を比較しました。
1個のフォルダ内のファイル名取得では、約600件のファイルが入っているフォルダで確認した結果は、
Dir関数の方が約6倍早かった(画面23参照)。ただしこれは一個のフォルダの話であり、サブフォルダ
も対象にその中のファイル名を取得する場合は、Dir関数でのマクロ作成は難しく実現は困難ですが、


画面23 ファイル名取得の高速化例


Dim pth1 As String, su As Integer
 
Sub システム1()
Dim myobj As Object, objFsy As Object, myfile As Object
su = 0: pth1 = ""
 Columns("B:B").Clear
 
    Set myobj = CreateObject("Shell.Application") _
        .BrowseForFolder(0, "フォルダを選択してください", &H1)
    If myobj Is Nothing Then
        Exit Sub
    End If
        pth1 = myobj.Self.Path
    Set myobj = Nothing
 
timck = Timer
    Set objFsy = CreateObject("Scripting.FileSystemObject")
        For Each myfile In objFsy.GetFolder(pth1).Files
            If "db" <> Right(myfile, 2) Then
                su = su + 1
                Cells(su, 2).Value = myfile
            End If
    Next
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒", Title:="システム1"
MsgBox su & "個のファイル名を取得しました。"
 

Sub システム0()
Dim myobj As Object, pth As String, moz As String
su = 0: pth1 = ""
 Columns("B:B").Clear
 
    Set myobj = CreateObject("Shell.Application") _
        .BrowseForFolder(0, "フォルダを選択してください", &H1)
    If myobj Is Nothing Then
        Exit Sub
    End If
        pth1 = myobj.Self.Path
    Set myobj = Nothing
 
timck = Timer
       pth = pth1 & "\"
       moz = Dir(pth & "*" & "*")
                Name pth & moz As pth & LCase(moz)
            su = su + 1
       Cells(su, 2).Value = pth & moz
    Do Until moz = ""
        moz = Dir()
        If moz = "" Then Exit Do
       Cells(su, 2).Value = pth & moz
    Loop
MsgBox "マクロ処理時間⇒ " & Timer - timck & "秒", Title:="システム0"
MsgBox su & "個のファイル名を取得しました。"
 
 

■2-10 その他の高速化マクロ作成例 以上が主なマクロ高速化のアイテムですが、以降に紹介のマクロについては速度の測定とアップ率の 記述はありませんが、マクロ作成時に注意して折り込めば見やすいマクロになると共にスピードアップ
(1)Withステ−トメントの使用 1つのオブジェクトに対して複数の処理を行う場合は、Withステ−トメントを使って記述すると、入力が 楽になり読みやすくなります。また、オブジェクトの指定も1回で済むので実行効率がよくなりスピ−ド アップとなります。
Sub with例1()
    UserForm1.Caption = "マクロ実行中:しばらくお待ち下さい"
    UserForm1.Label1.BackColor = RGB(0, 153, 255)
    UserForm1.Label1.TextAlign = fmTextAlignCenter
    UserForm1.Label1.Font.Size = 14
        UserForm1.Show 0
 End Sub
---------------------------------------------------------
Sub with例2()
    With UserForm1
        .Caption = "マクロ実行中:しばらくお待ち下さい"
        .Label1.BackColor = RGB(0, 153, 255)
        .Label1.TextAlign = fmTextAlignCenter
        .Label1.Font.Size = 14
    End With
        UserForm1.Show 0
 End Sub
---------------------------------------------------------
Sub with例3()
    With UserForm1
        .Caption = "マクロ実行中:しばらくお待ち下さい"
        With .Label1
            .TextAlign = fmTextAlignCenter
            .Font.Size = 14
        End With
    End With
        UserForm1.Show 0
 

(2)文字の入替を高速で行なうには 過去に文字内容を変換するマクロを作ったとき、Replaceメソッドの引数を大文字小文字及び、半角全角 は区別しない(False)に指定で作成しました(文字替え例2参照)。しかし、時間が掛かったので調べまし たら、原因は大文字小文字及び、半角全角は区別しないの設定が大きく影響しており、 このことから、もし大きなデータの変換が必要な場合、事前に面倒でも大文字小文字および半角全角 はどちらかに統一し引数を区別する(True)に指定で実行した方がよい。
Sub 文字替え例1()
   Cells(1, 1).Replace What:="-", Replacement:="ー", LookAt:=xlPart, _
        SearchOrder:=xlByColumns, MatchCase:=True, MatchByte:=True
 
End Sub
----------------------------------------------------------
Sub 文字替え例2()
   Cells(1, 1).Replace What:="-", Replacement:="ー", LookAt:=xlPart, _
        SearchOrder:=xlByColumns, MatchCase:=False, MatchByte:=False
End Sub




(3)変数への代入回数を減らす
1つのデータを取得るのに変数を多く使用すれば、マクロのステップ数が多くなり、また一度データを変数

今回サンプル記述の「変数削減1」は悪いマクロの見本と言われます。それでは、変数を使わないで
目的のExcelのバージョンを取得した「変数削減2」良いマクロは走行時間的にも早いか確認しましたが、
30万回実行して結果は同じでした。むしろ数十回確認すると「変数削減2」の方が遅くなることがあり

結論としては、走行時間としては殆んど変わらないので、マクロ作成を始めたばかりで、変数を使った方
が判りやすく作成がスムーズにいく方は適度に変数を使い練れてきたら、良いプログラムと言われるよう

Sub 変数削減1()
Dim evra As String, evrbas As String, evrc As Integer
For i = 1 To 300000
     evra = Application.Version
     evrb = Left(evra, 2)
     evrc = Val(evrb)
Next
End Sub
------------------------------------------------------------
Sub 変数削減2()
Dim evrc As Integer
For i = 1 To 300000
    evrc = Val(Left(Application.Version, 2))
Next
 
(4)余分な再計算をおこなわない 例として、A1〜A100セルの合計計算をおこなう計算式がA101セルに入っている場合(実行例は画面24 数式の参照元セルの100セル全部の値が変われば100回再計算が実行されます。マクロが見に行った ときだけ合計値が欲しいのであればこの再計算は無駄な動作であり再計算を止めればマクロの実行 画面24 A1〜A100セルの合計計算例 下記マクロで100セルの数値を100回変更して、毎回再計算の「再計算」と再計算ストップの「再計算a」を 比較した結果は、約1.4倍の速度アップでした。
Sub 再計算()
Range("A101").Formula = "=SUM(A1:A100)"
For i = 1 To 100
    For j = 1 To 100
        Cells(j, 1) = Int((10000 - 1 + 1) * Rnd + 1)
    Next
Next
End Sub
-------------------------------------------------------------
Sub 再計算a()
Range("A101").Formula = "=SUM(A1:A100)"
    Application.Calculation = xlManual
For i = 1 To 100
    For j = 1 To 100
        Cells(j, 1) = Int((10000 - 1 + 1) * Rnd + 1)
    Next
Next
 
以上はマクロで再計算方法を設定でしたが、 画面25計算方法のマニュアル設定例
【戻る】    【Top画面】   【HPへ】