20250829_【VBA】スパとふゆの0からはじめるExcelマクロ(6日目)

【VBA】マクロのリファクタリング術!「置換」機能の”対象範囲”を使いこなせてる?「スパとふゆの0からはじめるExcelマクロ」第6回参加レポ

目次

1. はじめに

Excel VBAの学習を始めたばかりの皆さん、一度書いたコードの修正に思った以上の時間を費やしていませんか?変数名を一つひとつ手作業で直したり、シート名が変わるたびにコードを書き換えたり…。そんな地道でミスの多い作業にうんざりしている方も多いのではないでしょうか。

先日、毎週金曜恒例のLive配信イベント「スパとふゆの0からはじめるExcelマクロ」の第6回(2025/8/29開催)に参加してきました。

今回のテーマは「マクロのリファクタリング(コードの整理)」。その中で解説された、VBE(VBAエディタ)に標準搭載されている「置換」機能の活用法が、まさに目から鱗のゲームチェンジャーでした。この感動を皆さんと共有すべく、早速レポートします!

2. 「スパとふゆの0からはじめるExcelマクロ」とは?

このイベントは、講師の和風スパゲティさんが、生徒役のふゆさんにゼロからVBAを教えるという形式のLive配信です。

「ゆるくてタメになる」をコンセプトに、ふゆさんから初心者目線での「あるある」な疑問が次々と飛び出し、見ている側も一緒に学んでいるようなアットホームな雰囲気が魅力です。

3. 今日のテーマ:マクロの「リファクタリング」

今回のテーマである「リファクタリング」とは、簡単に言うと「すでに動いているコードを、より読みやすく、修正しやすく書き直すこと」です。

マクロを作り始めた頃は、とにかく「動けばOK!」という気持ちでコードを書きますが、数日後に見返すと「なんだっけこれ?」となってしまうことも少なくありません。後々のメンテナンスを楽にするためにも、変数名を分かりやすいものに変えたり、共通の処理をまとめたりする作業は非常に重要です。

しかし、変数名を一つひとつ手作業で直していくのは非常に手間がかかり、修正漏れなどのミスの原因にもなります。そこで大活躍するのが、VBEの「置換」機能なのです。

4. 【目から鱗】VBEの「置換」機能、対象範囲の使い分けが凄かった!

ここからがこの記事のメインコンテンツです。普段なんとなく使っていた「置換」機能の奥深さに、思わず「うわ、マジか!」と声が出ました。

4.1. 基本の呼び出し方:Ctrl + H

VBE(VBAエディタ)の画面で、Excelと同じようにショートカットキー Ctrl + H を押すと、「置換」ダイアログボックスが表示されます。多くの人がこの機能の存在は知っていると思いますが、その真価は「対象」の設定にありました。

4.2. 絶対に知っておくべき4つの「対象」設定

配信中、ふゆさんの「この範囲だけ置換とかもできるんですか?」という鋭い質問をきっかけに、和風スパゲティさんが4つの「対象」設定について詳しく解説してくれました。これが本当に便利なんです!

  1. カレント プロシージャ (P)
    • 範囲: カーソルが現在置かれているSubFunctionの中だけを対象にします。
    • 使い所: 特定の一つのマクロ(プロシージャ)内だけで変数名を変えたい、といった限定的な修正に最適です。
  2. カレント モジュール (M)
    • 範囲: 今開いている(アクティブな)モジュール全体(例:「Module1」や「Sheet1」のコードウィンドウ全体)を対象にします。
    • 使い所: 一つのモジュール内で共通して使っている定数の名前を変更する、といった場合に便利です。
  3. カレント プロジェクト (C)
    • 範囲: ブック全体! すべての標準モジュール、すべてのシートモジュールを含んだ、プロジェクト全体を一気に検索・置換します。
    • 使い所: これが今回の神機能でした!例えば、コード内で "シート1" と書いている部分を、プロジェクト全体で一気に "DataSheet" に変更したい時などに絶大な威力を発揮します。これを知っているだけで、修正時間が劇的に短縮され、初心者から一歩抜け出せる革命的な時短テクニックです。
  4. 選択された文字列 (T)
    • 範囲: マウスでドラッグして選択(ハイライト)した部分だけを対象にします。
    • 使い所: Forループの中だけなど、ごく局所的な修正をしたい場合に役立ちます。

4.3. 【超重要】和風スパさん直伝!事故を防ぐ「完全に一致する単語だけを検索する」

和風スパゲティさんが「鉄則」として教えてくれた、非常に重要な注意点があります。それは、置換を行う際はオプションの「完全に一致する単語だけを検索する」に必ずチェックを入れること!

なぜこれが重要かというと、例えば変数 icnt に置換したい場合、このチェックがないと ListActive といった単語の中に含まれる i まで置換されてしまい、コードが意図せず壊れてしまう危険があるからです。

特に影響範囲の広い「カレント プロジェクト」で置換を行う際は、このチェックがあなたのコードを守る命綱になります。絶対に忘れないようにしましょう。

4.4. やってみて気づいたこと

この機能を教わって、過去の苦労が走馬灯のように蘇りました。以前、複数のモジュールにまたがる大規模なマクロで、参照するシート名を変更する必要があったときのことです。当時はこの機能を知らず、1時間以上かけて全てのモジュールを目で追い、一つひとつ手作業で修正しました。当然、修正漏れがあってデバッグにさらに時間がかかりました…。あの時の苦労が、「カレント プロジェクト」での置換なら文字通り数秒で終わっていたのです。もちろん、プロジェクト全体に影響を与える「すべて置換」ボタンを押す前の一瞬のドキドキ感はありますが、事前にファイルのバックアップを取っておけば、これほど心強い機能はありません。これからは積極的に活用していきます!

5. その他の学び:見やすいコードへの第一歩

今回の配信では、「置換」以外にも見やすいコードを書くためのテクニックが紹介されました。

5.1. 変数名の工夫:ハンガリアン記法 (ws, wbなど)

初心者がよく陥るのが「この変数、何を入れるためだっけ?」と忘れてしまう問題。その解決策として和風スパゲティさんが紹介したのが(和製)ハンガリアン記法です。これは、変数名の接頭辞(頭文字)にその変数のデータ型を示す文字をつける命名規則のことです。

例えば、ワークシートを格納する変数を Dim ws As Worksheet のように宣言します。変数名が ws で始まることで、コードの他の箇所でこの変数を見たときに「ああ、これはワークシートの変数だな」と一目でわかります。これによりコードの可読性が格段に向上するだけでなく、VBEのインテリセンス(入力候補表示機能)が効きやすくなり、タイプミスを防ぎながら爆速でコーディングできるメリットも実演されました。

Sub シート間の値OR書式を比較する_リファクタ前()
    
    Dim 行 As Long
    Dim 列 As Long
    
    Dim 最終行 As Long
    Dim 最終列 As Long
    
    最終行 = Worksheets("シート1").UsedRange.Rows.Count
    最終列 = Worksheets("シート1").UsedRange.Columns.Count
    
    For 行 = 1 To 最終行
    
        For 列 = 1 To 最終列
    
            If Worksheets("シート1").Cells(行, 列).Value <> Worksheets("シート2").Cells(行, 列).Value _
            Or Worksheets("シート1").Cells(行, 列).NumberFormatLocal <> Worksheets("シート2").Cells(行, 列).NumberFormatLocal Then
                Worksheets("シート1").Cells(行, 列).Interior.Color = RGB(255, 0, 0)
                Worksheets("シート2").Cells(行, 列).Interior.Color = RGB(255, 0, 0)
            End If
    
        Next
    
    Next
    
End Sub
Sub シート間の値OR書式を比較する_リファクタ後()
    
    Dim wsシート1 As Worksheet
    Set wsシート1 = Worksheets("シート1")
    Dim wsシート2 As Worksheet
    Set wsシート2 = Worksheets("シート2")
    
    Dim 行 As Long
    Dim 列 As Long
    
    Dim 最終行 As Long
    Dim 最終列 As Long
    
    最終行 = Get最終行(wsシート1)
    最終列 = Get最終列(wsシート1)
    
    For 行 = 1 To 最終行
    
        For 列 = 1 To 最終列
    
            If wsシート1.Cells(行, 列).Value <> wsシート2.Cells(行, 列).Value _
            Or wsシート1.Cells(行, 列).NumberFormatLocal <> wsシート2.Cells(行, 列).NumberFormatLocal Then
                wsシート1.Cells(行, 列).Interior.Color = RGB(255, 0, 0)
                wsシート2.Cells(行, 列).Interior.Color = RGB(255, 0, 0)
            End If
    
        Next
    
    Next
    
End Sub

5.2. 処理の部品化:汎用関数の作成(Get最終行)

【衝撃】Live中に発覚!UsedRangeの落とし穴

リファクタリングの話題は、コードを部品化して再利用しやすくする話へと進みました。最初の目標は単純なものでした。「シートの最終行を取得する」という、よくある処理です。

多くの入門書に載っているコードはこれです: 最終行 = wsシート1.UsedRange.Rows.Count。 しかし、配信中にこのコードでマクロを動かしたとき、事件は起きました。なぜか、データの最終行が比較対象から漏れてしまうのです。

その原因は、UsedRangeがデータが1行目から始まっていない場合に、正しい最終行を返さないという衝撃の事実でした。例えば、データが2行目から54行目まである場合、UsedRange.Rows.Countは行数である「53」を返します。しかし、ループを1から53まで回すと、実際の最終行である54行目が無視されてしまうのです!これは本当に重要な教訓でした。

解決策:バグのない最終行・最終列の取得

このバグの発見から導き出された正しいコードがこちらです。使用範囲の行数(列数)に、その範囲が始まる行番号(列番号)を足し、1を引くことで、絶対的な最終行・最終列を特定できます。

Sub 最終行と最終列の取得_バグなし()
    
    Dim wsシート1 As Worksheet
    Set wsシート1 = Worksheets("シート1")
    Dim wsシート2 As Worksheet
    Set wsシート2 = Worksheets("シート2")
    
    Dim 最終行 As Long
    Dim 最終列 As Long
    
    最終行 = wsシート1.UsedRange.Rows.Count + wsシート1.UsedRange.Row - 1
    最終列 = wsシート1.UsedRange.Columns.Count + wsシート1.UsedRange.Column - 1
    
End Sub

汎用関数へ:自分だけの便利ツールを作ろう

この少し複雑なロジックは、毎回書くのは面倒ですし、ミスの元です。そこで和風スパゲティさんは、これを部品化することを提案しました。そのための仕組みが Function です。

Functionとは、「VBAで使える自分だけのカスタムツールやカスタム関数を作る」ようなもの。インプットとしてシート(シート As Worksheet)を渡すと、中で複雑な計算をやってくれて、アウトプットとして最終行の数値(As Long)を一つだけ返してくれます。

Function Get最終行(シート As Worksheet) As Long
    
    Get最終行 = シート.UsedRange.Rows.Count + シート.UsedRange.Row - 1
    
End Function
Function Get最終列(シート As Worksheet) As Long
    
    Get最終列 = シート.UsedRange.Columns.Count + シート.UsedRange.Column - 1
    
End Function

これは少し発展的な内容とのことでしたが、一度作っておけば色々なプロジェクトにコピーして使える非常に便利な「自作ツール」になります。

6. まとめ

今回の勉強会を通じて、VBEに標準で備わっている機能を正しく知ること、そして簡単なリファクタリングのテクニックを適用するだけで、コーディングのスピードも質も劇的に向上することを実感しました。

特に「置換」機能の対象範囲、中でも「カレント プロジェクト」は、今後のマクロ開発における最強の武器になりそうです。VBAを学ぶ仲間として、皆さんもぜひこの感動を味わってみてください!

7. イベント情報&リンク集

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次