こんにちは!VBAの基礎をマスターし、次のステージへ進もうとしているあなたへ。
今日は、多くのVBAエンジニアが最初に直面する「マクロ記録の壁」を華麗に突破し、プロのコードへと昇華させるための極意をお伝えします。
「マクロ記録を使えば、やりたい操作のコードが自動で手に入る。最高じゃないか!」
最初は誰もがそう感動します。しかし、実際にそのコードを覗いてみると、`Select`や`Activate`の嵐……。データを少し処理するだけなのに、画面がバチバチと切り替わり、実行速度も遅い。
――ここをクリアすれば、あなたのVBAスキルは一気にプロフェッショナル領域へ到達します。
今日は、マクロ記録の「おもちゃのコード」を、実務で耐えうる「高速かつ堅牢なプロのコード」へ生まれ変わらせるリファクタリング術を、優しく、そして徹底的に解説していきましょう。
—
1. なぜ「マクロ記録のコード」は実務で使えないのか?
まずは、敵を知ることから始めましょう。
例えば、「Sheet1のセルA1に『売上』と入力し、太字にする」という操作をマクロ記録したとします。生成されるコードはおおむね以下のようになります。
Sub Macro1()
‘ 【マクロ記録が生成するコード】
Sheets(“Sheet1”).Select
Range(“A1”).Select
ActiveCell.FormulaR1C1 = “売上”
Selection.Font.Bold = True
End Sub
一見すると動くように思えますが、ここにはVBAのパフォーマンスを殺す「3つの大罪」が隠されています。
1. 画面のチラつき(UIの描き直し)
`Select`や`Activate`を実行するたびに、Excelはわざわざ画面の表示を切り替えます。これが実行速度を極限まで遅くする原因です。
2. 不安定さ(コンテキストへの依存)
「今どのシートがアクティブか」「どのセルが選択されているか」という、目に見えない状態(コンテキスト)に依存するため、予期せぬエラーを引き起こします。
3. 冗長性
オブジェクトを「選んでから操作する(Select + Selection)」という2段階踏んでいるため、コードが無駄に長くなります。
現実の業務で扱うデータ量は、何万行にも及びます。そんな巨大なデータを扱うとき、画面をペタペタと選択している暇はありません。
—
2. プロの合言葉:「Selectするな、直接叩け」
プロのVBAエンジニアが持っている絶対的な鉄則、それは「セルを選択(Select)せずに操作する」ことです。
Excel VBAの本質は、オブジェクト(シートやセル)を直接変数やコードで指定し、そのプロパティ(属性)やメソッド(動作)を背後で操作することにあります。
先ほどのマクロ記録のコードを、プロの書き方に書き換えてみましょう。
Sub ProCode()
‘ 【プロのコード】Selectを完全に排除
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets(“Sheet1”)
‘ セルを選択することなく、直接値を代入し、太字にする
With ws.Range(“A1”)
.Value = “売上”
.Font.Bold = True
End With
End Sub
どうですか? `Select`も `ActiveCell`も `Selection`も一切登場しません。
画面は一切切り替わらず、バックグラウンドで一瞬にして処理が完了します。これが「Rangeオブジェクトを直接操作する」ということです。
—
3. 実践!マクロ記録を「実務レベル」に昇華させる3ステップ
では、実際にあなたが日常の業務で行うような操作を例に、リファクタリングの手順をマスターしていきましょう。
お題:特定のセル範囲をコピーして、別のシートに値だけを貼り付ける
ステップ1:まずはマクロ記録で「骨組み」を手に入れる
まずは手探りでも構いません。「開発」タブから「マクロの記録」を開始し、手作業でコピー&ペーストを行って停止します。
Sub RecordingSample()
Range(“A1:C10”).Select
Selection.Copy
Sheets(“Sheet2”).Select
Range(“A1”).Select
ActiveSheet.Paste
Application.CutCopyMode = False
End Sub
うーん、相変わらずごちゃごちゃしていますね。これをリファクタリングしていきましょう。
ステップ2:不要なSelectとActivateを削ぎ落とす
「選ぶ」という動作をすべて消去し、どこからどこへデータを動かすのかを直結させます。
Sub RefactoringStep2()
‘ Sheet1のA1:C10を、Sheet2のA1に直接コピーする
Sheets(“Sheet1”).Range(“A1:C10”).Copy Destination:=Sheets(“Sheet2”).Range(“A1”)
Application.CutCopyMode = False
End Sub
これだけでもかなりスッキリしました!`A.Copy Destination:=B` という書き方は、コピー&ペーストの定番イディオムです。
ステップ3:さらに実務レベルへ!「値のみ」を高速転送する
実務では、セルの「書式(色や罫線)」までコピーしたくないケースがほとんどです。「値(Value)」だけを高速に渡したい場合は、`Copy`メソッドすら使わず、値の直渡しを行います。
Sub MasterpieceCode()
‘ 【実務レベルの極み】オブジェクト変数の活用と値の直接転送
Dim wsSource As Worksheet
Dim wsDest As Worksheet
‘ ワークシートを変数に格納(コードの可読性と保守性を爆上げします)
Set wsSource = ThisWorkbook.Sheets(“Sheet1”)
Set wsDest = ThisWorkbook.Sheets(“Sheet2”)
‘ 値を一括で転送(圧倒的な爆速処理)
wsDest.Range(“A1:C10”).Value = wsSource.Range(“A1:C10”).Value
‘ 後片付け
Set wsSource = Nothing
Set wsDest = Nothing
End Sub
この「`転送先.Value = 転送元.Value`」という手法は、VBAにおけるデータ処理の最速パターンの一つです。メモリ上で一瞬にして値がコピーされるため、クリップボードを汚さず、エラーも起きにくい最強の書き方です。
—
4. 陥りやすい罠:「アクティブシート」の呪縛
マクロ記録のコードを直すときによくあるエラーが、「親オブジェクトの省略による意図しないシートへの書き込み」です。
例えば、以下のようなコードを書いたとします。
‘ 危険な例
Range(“A1”).Value = “テスト”
このコード、今どのシートが表示されているかによって、書き込まれる場所が変わってしまいますよね。運悪く別のシートを開いているときに実行すると、全く関係ないデータを上書きしてしまう大惨事になりかねません。
対策:
必ず「どのブックの、どのシートの、どのセルか」を明示する癖をつけましょう。
‘ 安全な例
ThisWorkbook.Sheets(“集計シート”).Range(“A1”).Value = “テスト”
`ThisWorkbook`(このマクロが書かれているファイル)とシート名を必ずセットで指定する。これがプログラマの基本作法です。
—
まとめ:マクロ記録は「優秀な設計図」である
ここまで「マクロ記録のコードはダメだ」とお伝えしてきましたが、決してマクロ記録を否定しているわけではありません。
プロのエンジニアであっても、「複雑なグラフの設定方法」や「新しいExcelの機能のプロパティ名」が分からないときは、まずマクロ記録を取ってコードの断片(ヒント)を確認します。
つまり、マクロ記録は「答えそのもの」ではなく、「コードを組み立てるための優秀な設計図(パーツ集)」なのです。
- 記録機能でパーツの書き方(メソッドやプロパティ名)を調べる。
- それを `Select` や `Activate` を排除したスマートな構文に組み替える。
このステップを踏めるようになった瞬間から、あなたのVBAスキルは「初心者」を卒業し、確かなエンジニアの領域へと足を踏み入れています。
ここをクリアしたあなたなら、もう怖くありません。ぜひ、今日からあなたの過去のマクロコードをリファクタリングしてみてください。その圧倒的な動作の軽さに、きっと感動するはずです。
それでは、次回の極知見でお会いしましょう!
