🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →

The ExcelMaster.ai Blog

Excel VBA で WorksheetFunction を使う — Excel 自身の関数をコードから呼ぶ(そして 2 通りの失敗の仕方)

Excel VBA で WorksheetFunction を使う — Excel 自身の関数をコードから呼ぶ(そして 2 通りの失敗の仕方)

Application.WorksheetFunction を使えば、SUM や VLOOKUP、COUNTIF をループで書き直す代わりに、VBA から Excel の 450 を超える組み込み関数を借りられます。落とし穴は呼び出し方が 2 通りあり、失敗の仕方が違うことです。WorksheetFunction.X は一致がないと実行時エラーを発生させ、Application.X は IsError でテストできるエラー値を返します。どちらの呼び出し方を使うか、なぜ結果を Variant で受けなければならないか、この方法で呼んではいけない関数はどれか、そして 1 セルずつループする代わりに範囲全体を渡すのはいつかを解説します。

Henry
Excel VBA で Remove Duplicates を使う — 1 行で重複を削除(そしてなぜ元に戻せないのか)

Excel VBA で Remove Duplicates を使う — 1 行で重複を削除(そしてなぜ元に戻せないのか)

Range.RemoveDuplicates はコード 1 行で Excel の重複の削除ボタンを実行しますが、ループにはない形で破壊的です。行をその場で削除し、最初の出現を残し、マクロが動いたあとは元に戻せません。誰もがつまずく引数が Columns で、その数値はシートの列文字ではなく範囲内のオフセットです。範囲オフセットの罠、Header xlYes が大事な理由、最初ではなく最後の行を残す方法、そして代わりに Advanced Filter や Dictionary に手を伸ばすのはいつかを解説します。

Henry
Excel VBA で Advanced Filter を使う — 一意な値を抽出し、新しい範囲へフィルターする(ループなしで)

Excel VBA で Advanced Filter を使う — 一意な値を抽出し、新しい範囲へフィルターする(ループなしで)

Range.AdvancedFilter は、ビューではなくデータを出力する唯一のフィルターです。一意なリストや条件に一致した行の集合を、ループなしで、何も削除せずに、1 回の呼び出しで別の場所へ引き出せます。異質に感じる部分は、その WHERE 句がセルの中に置かれること、つまり見出しがデータと正確に一致しなければならない条件範囲です。xlFilterInPlace と xlFilterCopy の違い、条件範囲の仕組み、Unique True が非破壊的に重複を除く方法、空の出力を返す見出し不一致の罠、そして AutoFilter や Remove Duplicates とどう違うかを解説します。

Henry
Excel VBA で Find を使う — セルを正しく検索する(返すのは位置ではなく Range)

Excel VBA で Find を使う — セルを正しく検索する(返すのは位置ではなく Range)

VBA の Range.Find はコードから使う Excel の Ctrl+F で、位置を表す数値ではなく Range オブジェクト(一致がなければ Nothing)を返すため多くの人がつまずきます。error 91 のクラッシュを防ぐたった 1 つのチェック、実行のたびに Find の挙動が変わる「引数を記憶する」罠、LookAt xlWhole と xlPart が完全一致と部分一致をどう決めるか、そして無限ループにせず FindNext で全一致を取得する方法を解説します。

Henry
Excel VBA で AutoFilter を使う — コードで行をフィルターする(非表示は削除ではない)

Excel VBA で AutoFilter を使う — コードで行をフィルターする(非表示は削除ではない)

VBA の AutoFilter はコードから表をフィルターしますが、隠された行は消えていません — SUM にはやはり数えられ、コピーにも付いてきて、範囲の中にそのまま残ります。定番のバグを防ぐ考え方、可視行だけに触れるにはなぜ SpecialCells xlCellTypeVisible を通す必要があるか、条件と演算子の仕組み、2 回目の実行でフィルターがオフになるトグルの罠、そして大量の行を高速に消す「フィルターしてから削除」パターンを解説します。

Henry
Excel VBA で Sort を使う — Range.Sort と Sort オブジェクト(元の並び順を取り戻す方法)

Excel VBA で Sort を使う — Range.Sort と Sort オブジェクト(元の並び順を取り戻す方法)

VBA のソートは Ctrl+Z の効かない恒久的な並べ替えなので、最初のルールは手をつける前に元の並び順を守ることです。ビューとミューテーションを分ける考え方、Header xlYes が大事な理由(さもないと見出しがデータに紛れ込む)、手軽な Range.Sort と無制限の Sort オブジェクトの違い、古いソートキーを引き継ぐ SortFields.Clear の罠、そして文字列として保存された数値が誤った順序で並ぶ理由を解説します。

Henry
Excel VBA で行を削除する — 行・空白行・条件による削除(ループは逆順で!)

Excel VBA で行を削除する — 行・空白行・条件による削除(ループは逆順で!)

VBA で行を削除するのは、値の消去ではなく構造の変更です。削除した行の下はすべて 1 行ずつ上へ詰まるため、順方向ループは行を飛ばします。直す唯一のルール(下から上へループする、または Union でまとめて削除する)、EntireRow.Delete がセルの消去とどう違うか、空白行を高速に取り除く方法、そして参照数式やデータを壊さずに条件で行を削除する方法を解説します。

Henry
Excel VBA で行・列を挿入する — グリッドを正しくずらす(ループ挿入で崩さないコツ)

Excel VBA で行・列を挿入する — グリッドを正しくずらす(ループ挿入で崩さないコツ)

挿入は削除の鏡像です。既存の行を下へ(列なら右へ)押しやって場所を空けるので、削除ループを壊すのと同じずれが挿入ループも壊します。EntireRow.Insert と Shift 引数を使った部分範囲の挿入の違い、CopyOrigin が新しい行にどの隣の書式を継承させるか、ループ内で安全に挿入する向き、そして多数の行を 1 回の呼び出しでまとめて追加する方法を解説します。

Henry
Excel VBA で列・行を非表示にする — 非表示は削除ではない(なぜ合計が変わらないのか)

Excel VBA で列・行を非表示にする — 非表示は削除ではない(なぜ合計が変わらないのか)

VBA で列を非表示にするのは、削除でもフィルターでもありません。データはそのまま残り、すべての SUM に含まれ、範囲コピーでも一緒にコピーされ、ただ表示幅がゼロになるだけです。なぜ .Hidden が EntireColumn と EntireRow に属するのか、なぜ非表示のセルも数式で数えられるのか、動かなくなったシートを救う「すべて再表示」の 1 行、そして手動で隠した行が AutoFilter で隠れた行とループ時にどう違うのかを解説します。

Henry
Excel VBA の Worksheet_BeforeDoubleClick — ダブルクリックをアクションに変える(そして編集モードを抑制する)

Excel VBA の Worksheet_BeforeDoubleClick — ダブルクリックをアクションに変える(そして編集モードを抑制する)

Worksheet_BeforeDoubleClick は、セルをダブルクリックした瞬間に — 編集モードに入る前に — Excel が発火させるイベントで、Target セルと Cancel フラグを手渡してくれます。Cancel を True にすれば編集モードを抑制し、代わりに自分のアクションを走らせられます — チェックマークを切り替える、行を完了にする、明細へドリルダウンする。Intersect で 1 列に絞る方法、Cancel を忘れるとセルが編集モードに落ちる理由、そしてコードを置くべき場所を解説します。

Henry
Excel VBA の Worksheet_BeforeRightClick — 右クリックメニューを置き換える(そして無効化がセキュリティでない理由)

Excel VBA の Worksheet_BeforeRightClick — 右クリックメニューを置き換える(そして無効化がセキュリティでない理由)

Worksheet_BeforeRightClick は、セルを右クリックした瞬間に — コンテキストメニューが現れる前に — Excel が発火させるイベントで、Target セルと Cancel フラグを手渡してくれます。Cancel を True にすれば組み込みメニューを抑制し、代わりに自分のアクションを走らせたり独自のメニューを出したりできます。Copy や Paste を潰さないよう Intersect でスコープを絞る方法、右クリックの無効化が保護ではなく UX の選択である理由、そしてコードを置くべき場所を解説します。

Henry
Excel VBA の Workbook_BeforePrint — 印刷をブロックし、ヘッダーを刻み、印刷プレビューの落とし穴

Excel VBA の Workbook_BeforePrint — 印刷をブロックし、ヘッダーを刻み、印刷プレビューの落とし穴

Workbook_BeforePrint は、ブック内の何かが印刷される前に Excel が発火させるイベントで、Cancel フラグを手渡してくれます。Cancel を True にすれば印刷はブロックされます — 印刷前に検証する、あるいは草案が出ていくのを止める。印刷プレビューでもこのイベントが発火する理由(だから重い処理はプレビューを遅くする)、シートごとではなくブック全体で一度だけ走る理由、無言の Cancel がバグである理由、そしてコードを置くべき場所を解説します。

Henry
Excel VBA の Workbook_BeforeClose — 閉じる操作を取り消し、保存を促し、コードを置くべき場所

Excel VBA の Workbook_BeforeClose — 閉じる操作を取り消し、保存を促し、コードを置くべき場所

Workbook_BeforeClose は、誰かがファイルを閉じようとした瞬間に — 何も破棄される前に — Excel が発火させるイベントで、Cancel フラグを手渡してくれます。Cancel を True にすれば、閉じる操作は取り消されます。閉じる際の後始末を走らせる方法、Saved プロパティで Excel が二重に保存を尋ねるのを止める方法、クラッシュ時には決して発火しない理由、そしてコードを置くべき場所を解説します。

Henry
Excel VBA の Workbook_BeforeSave — 保存を検証・ブロックし、SaveAsUI が本当に伝えていること

Excel VBA の Workbook_BeforeSave — 保存を検証・ブロックし、SaveAsUI が本当に伝えていること

Workbook_BeforeSave は、保存が要求された瞬間に — ディスクに何かが書き込まれる前に — Excel が発火させるイベントで、SaveAsUI と Cancel という 2 つのフラグを手渡します。必須セルが空のときに保存をブロックする方法、誰がいつ保存したかを自動で刻む方法、ハンドラーの中で Save を呼ぶと永遠にループする理由、そして SaveAsUI でファイル名を強制する方法を解説します。

Henry
Excel VBA の Worksheet_Activate と Deactivate — シートを切り替えたときにコードを走らせる(そして離脱を取り消せない理由)

Excel VBA の Worksheet_Activate と Deactivate — シートを切り替えたときにコードを走らせる(そして離脱を取り消せない理由)

Worksheet_Activate はシートがアクティブになったときに発火し、Worksheet_Deactivate はそのシートを離れる直前に発火します — シートの到着と出発のイベントです。両者を定義づける勘所は — BeforeClose や BeforeSave と違い、どちらも Cancel を渡さないので、シートの切り替えを見ることはできても、それをブロックすることはできません。表示時にリフレッシュするパターン、押し戻しの回避策、そしてシートレベルとブックレベルのハンドラーを解説します。

Henry
Excel VBA のクラスモジュール — 自分だけのオブジェクトを作る(設計図 vs インスタンス、そして As New の罠)

Excel VBA のクラスモジュール — 自分だけのオブジェクトを作る(設計図 vs インスタンス、そして As New の罠)

VBA のクラスモジュールを使うと、データと振る舞いをまとめた設計図として自分だけのオブジェクト型を定義でき、New で独立したインスタンスをいくつでも作り出せます。誰もがつまずく落とし穴は、オブジェクトが参照型であること。Set b = a は両方の名前を同じインスタンスに向け、Dim x As New は遅延インスタンス化の罠を隠します。モジュール名がそのまま型名になる仕組み、Type よりクラスが勝る場面、そして New にまつわる典型的な落とし穴の避け方を解説します。

Henry
Excel VBA の Type — 関連するフィールドを 1 つの変数にまとめる(ユーザー定義型 vs クラス)

Excel VBA の Type — 関連するフィールドを 1 つの変数にまとめる(ユーザー定義型 vs クラス)

VBA の Type は Type ... End Type で宣言するユーザー定義型で、関連する複数のフィールドを 1 つの変数にまとめます。Name、Age、Salary を 3 本の平行配列ではなく 1 つの変数として一緒に運べます。Type は値型なので、ある Type 変数を別の変数に代入するとすべてのフィールドがコピーされ、共有されるオブジェクトとは対照的です。宣言をどこに書くべきか、コピーと共有の違いがなぜ重要か、そしてクラスモジュールに切り替えるべき正確な境目を解説します。

Henry
Excel VBA の Property — Get・Let・Set(クラスのフィールドへのアクセスを制御する)

Excel VBA の Property — Get・Let・Set(クラスのフィールドへのアクセスを制御する)

Property Get・Let・Set は、クラスのフィールドをゲートに変えます。外部が読み書きするたびにあなたのコードが走る小さなプロシージャなので、入力を検証したり、値をその場で計算したり、フィールドを読み取り専用にしたりできます。誰もがつまずく区別が Let と Set です。Let は値を代入し、Set はオブジェクトを代入します。取り違えるとコンパイルエラーか実行時エラーになります。バッキングフィールドのパターン、素の Public 変数こそが正直な選択になる場面、そして読み取り専用プロパティの作り方を解説します。

Henry
Excel VBA の ActiveCell — カーソルのある唯一のセル(ActiveCell と Selection の違い、そして壊れるとき)

Excel VBA の ActiveCell — カーソルのある唯一のセル(ActiveCell と Selection の違い、そして壊れるとき)

ActiveCell は、いまカーソルがある1つのセルを指すライブなポインターです — つねにちょうど1つのセル、アクティブシート上、そして現在の Selection の内側にあります。Selection との違い、.Value と .Offset での読み書き、そして壊れる一番の理由 — ユーザーが残したシートとカーソルにそのまま従うので、ユーザーの現在地に関係しないコードには不向きだということ — を解説します。

Henry
Excel VBA の Selection — ハイライトされたものを扱う(そして、なぜつねに Range とは限らないのか)

Excel VBA の Selection — ハイライトされたものを扱う(そして、なぜつねに Range とは限らないのか)

Selection は、いまハイライトされているものを指すライブなポインターです — ふつうはセルの範囲ですが、グラフやシェイプ、あるいは何もない場合もあります。だからこそ Selection を範囲だと決めてかかるコードは、グラフが選択された瞬間にクラッシュします。選択セルのループ、.Areas による複数エリア選択の扱い、TypeName によるガード、そして Selection を完全に避けて範囲を名指しすべきときを解説します。

Henry
Excel VBA の Select と Activate — マクロ記録の .Select 癖を断ち切る

Excel VBA の Select と Activate — マクロ記録の .Select 癖を断ち切る

マクロ記録は、あなたのマウスがすることをそのまま書きます — シートを Select し、セルを Select し、Selection に作用する — それが人の働き方であって、コードのあるべき姿ではないからです。Select(1つまたは複数のセルをハイライト)と Activate(唯一のアクティブセルを設定)の本当の違い、ほぼすべての .Select が削除できる遅く脆い回り道である理由、本当に選択が必要になるまれな場面、そして記録されたコードを、修飾された範囲参照へ直接作用するようリファクタリングする方法を解説します。

Henry
Excel VBA の Workbook_Open — ファイルを開いた瞬間にマクロを自動実行する(そしてコードを置くべき場所)

Excel VBA の Workbook_Open — ファイルを開いた瞬間にマクロを自動実行する(そしてコードを置くべき場所)

Workbook_Open は、ファイルが開き終わった瞬間に Excel が発火させるイベントです — ボタン不要で、自分から走るコード。ただし発火するのは、コードが ThisWorkbook オブジェクト(標準の Module ではなく)に置かれ、かつユーザーがマクロを有効にしている場合だけ。コードをどこに置くべきか、なぜ無言で走らないのか、Workbook_Open と Auto_Open の違い、そして速く落ちにくく保つ方法を解説します。

Henry
Excel VBA の Worksheet_Change — セルが編集されたときにコードを走らせる(そして避けるべき無限ループ)

Excel VBA の Worksheet_Change — セルが編集されたときにコードを走らせる(そして避けるべき無限ループ)

Worksheet_Change は、シート上でユーザーがセルを編集するたびに Excel が発火させるイベントで、変更されたセルを Target として手渡してくれます。誰もがはまる罠 — ハンドラーがセルに書き込むと、その書き込みがまたイベントを発火させ、Excel は永遠にループします。Application.EnableEvents による解決策、Intersect で対象を絞る方法、なぜ数式の再計算を無視するのか、そしてコードを置くべき場所を解説します。

Henry
Excel VBA の Worksheet_SelectionChange — カーソルが動いたときにコードを走らせる(もたつきなしでアクティブ行をハイライト)

Excel VBA の Worksheet_SelectionChange — カーソルが動いたときにコードを走らせる(もたつきなしでアクティブ行をハイライト)

Worksheet_SelectionChange は、カーソルが動くたび — クリック、矢印キー、Enter — に Excel が発火させるイベントです。新しい選択範囲を Target として手渡すので、アクティブ行のハイライトのような、カーソルを追う小技が可能になります。ただし絶えず発火するため、重いコードはシート全体をもたつかせます。正しいアクティブ行ハイライトのパターン、なぜループしうるのか、そして羽のように軽く保つ方法を解説します。

Henry
Excel VBA の For Each — インデックスに触れずコレクションをループする(そして隠れた罠)

Excel VBA の For Each — インデックスに触れずコレクションをループする(そして隠れた罠)

For Each は「すべての要素にこれをせよ」と伝えるだけで、順序と境界の面倒は VBA が引き受けます — カウンターも、1 つずれるバグもありません。しかしその手軽さは 3 つの手強いルールを隠しています:ループ変数はオブジェクトか Variant でなければならず、配列のループは読み取り専用で、走査中のコレクションから要素を削除してはいけません。For Each が For…Next に勝る場面と、静かに裏切る場面を解説します。

Henry
Excel VBA の Collection — 順序を保ち、伸びるリスト(そしてなぜ Dictionary ではないのか)

Excel VBA の Collection — 順序を保ち、伸びるリスト(そしてなぜ Dictionary ではないのか)

VBA の Collection は、Add するたびに伸びる順序付きのリストです — ReDim も、サイズの当て推量も要りません。しかし初心者が毎回ぶつかる 4 つの鋭い角があります:0 始まりではなく 1 始まり、要素を上書きできない(Add/Remove だけ)、重複キーはエラー 457 を投げ、組み込みの Exists チェックがない。Collection が Array や Dictionary に勝る場面と、静かに代償を求める場面を解説します。

Henry
Excel VBA の With ステートメント — オブジェクトを一度だけ書く(そして成否を分ける先頭のドット)

Excel VBA の With ステートメント — オブジェクトを一度だけ書く(そして成否を分ける先頭のドット)

With ステートメントは、オブジェクトに一度だけ名前を付け、そのメンバーに先頭のドットだけで触れさせてくれます — 打つ量が減り、コードは速く、ブロックはすっきり。しかしその先頭のドットこそがすべてです:忘れると .Font は Font になり、あなたのオブジェクトではなくアクティブシートに無言でバインドされます。With が実際に最適化するもの、ドット抜けの罠、そして With が For Each とどう組むのかを解説します。

Henry
Excel VBA の Dim — 変数の宣言、Option Explicit、そしてタイプミスが生む「空の箱」

Excel VBA の Dim — 変数の宣言、Option Explicit、そしてタイプミスが生む「空の箱」

Dim は使う前に名前付きの箱を確保します。しかし変数を宣言する本当の理由は、名前を打ち間違えた瞬間に VBA が新しい空の Variant を無言で作ってしまうことにあります。Option Explicit がなぜ VBA で最も価値ある 1 行なのか、Dim a, b As Long の罠、そして Set が必要になる場面を解説します。

Henry
Excel VBA のデータ型 — String、Long、Double、Variant(値ごとに正しい箱を選ぶ)

Excel VBA のデータ型 — String、Long、Double、Variant(値ごとに正しい箱を選ぶ)

VBA のデータ型とは、変数の箱の形と大きさのこと — そしてそれを選ぶことは、実は何が壊れうるかを選ぶことです。なぜ Integer は 32,767 でオーバーフローするのか(Long を使う)、なぜ Variant はバグを隠す怠惰な既定なのか、なぜお金には Double でなく Currency が要るのか、そして型が一致しませんとオーバーフローのエラーの読み方を解説します。

Henry
Excel VBA の Const — マジックナンバーに名前を付ける(そして値がずれない理由)

Excel VBA の Const — マジックナンバーに名前を付ける(そして値がずれない理由)

VBA の定数とは、コンパイル時に値へ固定された名前 — コードじゅうに散らばったマジックナンバーの処方箋です。なぜ Const は値のずれを止めるのか、なぜ定数への代入がコンパイルエラーになるのか(それが機能なのです)、なぜ Const はコンパイル時のリテラルでなければならないのか、そしていつ Enum に手を伸ばすべきかを解説します。

Henry
Excel VBA の Offset — セルからの相対移動(Offset と Resize、そして 1 つずれる罠)

Excel VBA の Offset — セルからの相対移動(Offset と Resize、そして 1 つずれる罠)

Range.Offset は (行, 列) だけずらした新しい範囲を返します — 移動するだけでサイズは変えず、Offset(1,0) は 1 行目ではなく 1 行下を意味します。考え方の軸、見出しを飛ばす定番イディオム Offset(1).Resize(n-1)、そして VBA のメソッドが OFFSET ワークシート関数とどう違うかを解説します。

Henry
Excel VBA の UsedRange と CurrentRegion — データブロック全体を取得する(どちらを信じるべきか)

Excel VBA の UsedRange と CurrentRegion — データブロック全体を取得する(どちらを信じるべきか)

UsedRange と CurrentRegion はどちらも「ブロック全体」を取得しますが、答えている問いが違います。UsedRange は Excel がキャッシュした外接矩形で、過大に報告し縮まりません。CurrentRegion はセルの周囲でその場で計算され、空白行で止まります。どちらをいつ信じるべきかを解説します。

Henry
Excel VBA の Trim — 空白が消えない理由と Chr(160) の対処法

Excel VBA の Trim — 空白が消えない理由と Chr(160) の対処法

VBA の Trim は両端だけを削り、内側の空白には触れません。さらに、Web や PDF からの貼り付けで紛れ込む非改行スペース Chr(160) も無視します。考え方の軸、使うべき正規化関数 1 つ、そしてどの関数がどの場面で勝つか。Excel 365 / 2021 / 2019 で検証済み。

Henry
VBA InputBox — 2つの InputBox と使い分け

VBA InputBox — 2つの InputBox と使い分け

VBA の InputBox は1つではなく2つあります。単純な InputBox で足りる場面、Type を付けた Application.InputBox が勝つ場面、そして両方を静かに壊す「キャンセルの落とし穴」まで。コピペで動く例、Excel 365 / 2021 / 2019 で動作確認済み。

Henry
VBA UserForm — 本格的な入力フォームを作る

VBA UserForm — 本格的な入力フォームを作る

VBA UserForm を正しく作る方法。イベント駆動の考え方、.Show のあとコードが「消える」理由、そして入力した値を読めるかどうかを決める Unload と Hide のルールまで。コピペで動くイベントコード、Excel 365 / 2021 / 2019 で動作確認済み。

Henry
Excel VBA Whileループ — Excelを固めずにループする方法

Excel VBA Whileループ — Excelを固めずにループする方法

VBAのWhileループは「必ず終わる」という約束であり、それを守るのはあなた。すべてのWhileループに必要な3つの部分、なぜDo WhileがWhile...Wendより良いのか、そして二度とExcelを固めない方法を、コピペ実例とともに。Excel 365 / 2021 / 2019で動作確認済み。

Henry