Excel VBA記録したマクロの修正方法1(初心者向け解説3)

くるみこ
くるみこ

どうですか? 前回は「マクロの記録」を色々なパターンでテストしたけどどんなことがわからなかったか教えてよ!

色々見すぎてどんなことがわからなかったのかもわからなくなっちゃった!
でも動かしたとおりにマクロが書かれていくことはわかりました(^^;

前回記事のおさらいはこの下の記事を見て確認くださいね(^^)/

くるみこ
くるみこ

前回記事でわかったことは
・「マクロの記録」で作ったマクロの実行は「ボタン」を使えば簡単
・「マクロ」を使うための「開発」タブは必ず必要となります
・「マクロの記録」でテストした操作のコードを確認できました

今回は「マクロの記録」で記録したコードの修正にチャレンジしてみましょう!

【この記事でわかること】
・「マクロの記録」で記録したコードの修正はVBA活用の基礎になることがわかります

・VBA上級者でも「マクロの記録」を使って勉強していることがわかります
・自分で考えていろいろやってみることが大事だということがわかります

くるみこ
くるみこ

ただ、1記事で終わらせるにはボリュームがあまりにも大きいので2回に分けて解説していきたいと思いますm(_ _)m
それでは前半部分の解説をスタートします!

「マクロの記録」で記録したコードを修正してみよう

前回記事のテストで記録されたマクロ(VBA)は忠実に動作を記録しているがゆえに、無駄な部分がたくさん記録されています。では、さっそく見て行きましょう

さっそく無駄な部分を修正(編集)してみよう

「セルを選択」「セルに入力」「ショートカットで移動」のコード

Sub Macro1()
    Range("A1").Select              'セルを選択
    ActiveCell.FormulaR1C1 = "ID"   'セルに入力
    Range("B1").Select              'セルを選択
    ActiveCell.FormulaR1C1 = "名称" 'セル漢字入力
    ActiveCell.Characters(1, 2).PhoneticCharacters = "メイショウ"
    Selection.End(xlUp).Select  'ショートカットで上へ移動
End Sub

・修正(編集)したVBAコード

Sub Macro1_改()
    Range("A1") = "ID"   'セルに入力
    Range("B1") = "名称" 'セル漢字入力
End Sub

・修正した結果、6行あったコードが2行(1/3)になっています
・「Range(“A1”).Select」のセルを選択するSelect」というコードは、本当に選択する必要がある場合を除いて、基本的には必要のないコードです。そのあとに続くコード(ActiveCell.FormulaR1C1)の右辺がその答えです
・「ActiveCell.FormulaR1C1」が「Select」してアクティブになったセルという意味です
・ですからここに、「Range(“A1”).」を当てはめて、「Range(“A1”) = “ID”」となります
・「Range(“B2”).」も全く同じです
・「PhoneticCharacters」は漢字変換の元(いわゆるフリガナ)で必要ないのでカットできます
・「Selection.End(xlUp).Select」 も「Select」でセルの移動を表しているだけなのでここでは必要ないコードです

「シート」の処理に関する操作コード

Sub Macro2()
'
' Macro2 Macro
'

'
    Sheets.Add After:=ActiveSheet   '新規シート作成
    Sheets("Sheet1").Select 'Sheet1選択
    Range("A1:E11").Select  '範囲選択
    Selection.Copy          '選択範囲をコピー
    Sheets("Sheet9").Select '新規シートを選択
    ActiveSheet.Paste       'コピーしたデータを貼り付け
    Sheets.Add After:=ActiveSheet
    Sheets("Sheet1").Select
    Selection.End(xlUp).Select
    Range("A1:E1").Select
    '選択した範囲から最下部まで選択(ショートカット)
    Range(Selection, Selection.End(xlDown)).Select
    '前に操作した(セルのコピー、または切り取り)を無効にしている
    Application.CutCopyMode = False
    Selection.Copy
    Sheets("Sheet10").Select
    '選択したセルに値貼付け
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    '複数シート選択
    Sheets(Array("Sheet1", "Sheet9", "Sheet10")).Select
    Sheets("Sheet10").Activate
    Application.CutCopyMode = False
    '選択した複数シートをまとめてコピー
    Sheets(Array("Sheet1", "Sheet9", "Sheet10")).Copy Before:=Sheets(4)
End Sub

・修正(編集)したVBAコード

Sub Macro2_改()
    Sheets.Add After:=ActiveSheet   '新規シート作成
    Sheets("Sheet1").Range("A1:E11").Copy '範囲をコピー
    Sheets("Sheet9").Paste       'コピーしたデータを貼り付け
    Sheets.Add After:=ActiveSheet
    Sheets("Sheet1").Range("A1:E1").End(xlDown).Copy
    Sheets("Sheet10").PasteSpecial Paste:=xlPasteValues
    '選択した複数シートをまとめてコピー
    Sheets(Array("Sheet1", "Sheet9", "Sheet10")).Copy Before:=Sheets(4)
End Sub

・修正(編集)した結果20行あったコードが7行(約1/3)になっています
・基本的に「Select」の部分は修正が可能な部分です
「Select」してアクティブになった部分に「何か」をするという場合は、「Select」するそのセルのアドレス(番地)に直接「何か」を書き込めばよいということです
・それ以外の「Sheets.Add After:=ActiveSheet」は変更なしです。ただ「ActiveSheet」の部分は状況によって特定のシート名に変更されるものです
・「PasteSpecial」については、「Operation:=xlNone, SkipBlanks:=False, Transpose:=False」の部分は規定で省略可能となっているのでカットしても支障がない部分です
・「Sheets(Array(“Sheet1”, “Sheet9”, “Sheet10”))」の部分は、配列としてまとめて処理しているのがわかります

「オートフィルタ」「ソート」処理のコード

Sub Macro3()
'
' Macro3 Macro
' マクロの説明を記録実行前に記入しておくとここにコメントが入ります

'
    'オートフィルタテスト
    Selection.AutoFilter    'オートフィルタを設定
    'AからE列の2番目のフィールド=B列で「a」を抽出
    ActiveSheet.Range("$A$1:$E$11").AutoFilter Field:=2, Criteria1:=Array("aaa" _
        , "aab", "aad", "abc", "cba"), Operator:=xlFilterValues
    '1番目のフィールド=A列で「1」を抽出
    ActiveSheet.Range("$A$1:$E$11").AutoFilter Field:=1, Criteria1:="1"
    Selection.AutoFilter    'オートフィルタを解除
    'ここからソートテスト
    'B列で昇順ソート
    'ソートの条件をクリア
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    'ソートの条件を指定「Key=B列」「Order=昇順xlAscending」
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range("B2:B11") _
        , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    'ソート実行
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")   'ソートの範囲
        .Header = xlYes             '先頭行は見出し
        .MatchCase = False          '大文字小文字は区別しない
        .Orientation = xlTopToBottom '上下方向に
        .SortMethod = xlPinYin      'フリガナを使う
        .Apply                      'ここでソート実行
    End With
    'B列で降順ソート「Key=B列」「Order=降順xlDescending」
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range("B2:B11") _
        , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    'A列を昇順。B列を降順でソート
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range("A2:A11") _
        , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 Key:=Range("B2:B11") _
        , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

・修正(編集)したVBAコード

Sub Macro3_改()
' マクロの説明を記録実行前に記入しておくとここにコメントが入ります
    'オートフィルタテスト
    'AからE列の2番目のフィールド=B列で「a」を抽出
    Range("A1").AutoFilter Field:=2, Criteria1:="a"
    '1番目のフィールド=A列で「1」を抽出
    Range("A1").AutoFilter Field:=1, Criteria1:="1"
    'ここからソートテスト
    'B列で昇順ソート
    'ソートの条件をクリア
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    'ソートの条件を指定「Key=B列」「Order=昇順xlAscending」
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 _
        Key:=Range("B2:B11") , _
        Order:=xlAscending
    'ソート実行
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")   'ソートの範囲
        .Header = xlYes             '先頭行は見出し
        .MatchCase = False          '大文字小文字は区別しない
        .SortMethod = xlPinYin      'フリガナを使う
        .Apply                      'ここでソート実行
    End With
    'B列で降順ソート「Key=B列」「Order=降順xlDescending」
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 _
        Key:=Range("B2:B11"), _
        Order:=xlDescending
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")
        .Header = xlYes
        .MatchCase = False
        .SortMethod = xlPinYin
        .Apply
    End With
    'A列を昇順。B列を降順でソート
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 _
        Key:=Range("A2:A11"), _
        Order:=xlAscending
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add2 _
        Key:=Range("B2:B11"), _
        Order:=xlDescending
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:E11")
        .Header = xlYes
        .MatchCase = False
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub


【オートフィルター部分】
・[8行目]はじめに「Selection.AutoFilter」が記録されています。これは表のタイトル行にオートフィルタボタン(▼ボタン)を表示するという命令です。だからマクロでは不要です
・ただし、マクロ開始前にオートフィルタが設定されている場合は「Selection.AutoFilter」でオートフィルタを解除する必要があります(設定も解除も同じ「Selection.AutoFilter」を使います
・[10,13行目]「ActiveSheet.Range(“$A$1:$E$11”).AutoFilter」の「ActiveSheet.」は不要です
・そして「Range(“$A$1:$E$11”)」のように絶対参照で表全体を指定していますが、表がセルA1から始まっているのなら「Range(“A1”)」とすればOKです
・引数は「Field:=2」と「Criteria1:=”a”」は絶対に必要ですがそれ以降は不要でしょう
・記録では「Criteria1:=Array(“aaa” , “aab”, “aad”, “abc”, “cba”)」となっていますがもともと指定したのは「”a”」でした。「”a”」の指定で抽出された該当文字列が配列で記録されているようです

【ソート処理部分】
・ソートはあまり不要な部分は無さそうですが、次の部分は無くても支障がないでしょう
・[20,33,45,47行目]SortFields.Addメソッドの引数「SortOn:=xlSortOnValues」と
 「DataOption:=xlSortNormal」は無くても支障ないでしょう
・[27,39,53行目]Sortオブジェクトの「Orientation= xlTopToBottom」も削除しました
・[44~47行目]AB列を一緒にソートしている部分は、途中で「SortFields.Clear」せずに
 連続で次の条件を入力しているのがわかるでしょうか

くるみこ
くるみこ

前半部分の解説はここでおわりにします!
後半の解説にご期待ください(^^)/

それにしても、どうやってコードのいらない部分とかがわかるんですか?
全然わかんないよ~!

くるみこ
くるみこ

そうだよね!でも全部覚えようとしなくても、少しずつでいいんだよ!
ああ、こんなことがあるんだって思うだけでいいんです!そういえばあの時見た気がする!って知らないうちに頭のどこかに記憶されればいいんです(^^ゞ
コードにコメントを入れておいたのであとで確認してくださいね(^^)

・今回はここまでで終了です!
・この続きは次回記事まで少しだけお待ちください・・・・ご期待くださいね~(^^)/

スポンサーリンク

まとめ(おわりに)

まとめと感想など

・「セルを選択」「セルに入力」「ショートカットで移動」「シート」「オートフィルタ」「ソート」処理コードの記録状況が確認できました
・「Select」は本当に選択する必要がある場合を除いて基本的には省略可能なコードです
・「Select」されてアクティブになったセルに操作を行っていますので
・これを連結してしまえば「Select」と次の「ActiveCell.FormulaR1C1」が省略できる部分です
・「Selection.AutoFilter」は表のタイトル(見出し)行にオートフィルタボタン(▼ボタン)を表示するという命令です(設定と解除の両方に使用します)がマクロ(VBA)を使う場合は解除しておく必要があります
マクロを編集する場合は、実際に動作させながら確認していくことが大事です

マクロ(VBA)を実行する際は必ずバックアップを取ってから行ってください
・マクロ(VBA)は実行後にファイルを保存すると元に戻すことはできません!
・実行後にファイルを保存せず終了すれば、実行前に戻すことができます!

★★★ ランキング参加中! クリックしてね(^^)/ ★★★

今後の記事について

今回の記事はいかがだったでしょうか。皆さまのお役に立てたなら幸いです(^^;
是非!サンプルファイルをダウンロード出来ますのでそのまま使ってみてください(^^)/
当面は今回の記事に続き「初心者向けマクロ」の記事を継続して書いていきます

【検討中の今後の記事内容は・・・・・】
・実務に役立つものを提供できるよう現在検討中です
・その他雑記的に「小ネタなどいろいろ」・・・・・
・今後の記事にご期待ください(^^)/

サンプルファイルをダウンロードできます(下記リンク先へ)

記事で使用したサンプルファイルがダウンロードできるページを設置しています
こちら(このリンク先)からご利用ください