LWP | 記事T254 同じコード・同じデータなのにFindの結果が変わる
図解1|同じ表、同じ検索語でも結果が違う

図1|検索条件も再現条件に含めます。図中のA2・A4は一致候補で、Find単体が複数セルを返す意味ではありません。
解説1|コードとデータのほかに、何が同じか
ストーリー
コイ丸先輩が以前から使っている検索マクロで、同じ商品コード表を調べているのに結果が変わりました。表もコードも変更していません。「直前に手で検索しただけなんだ」。その一言で、シャケモンはコードの外にある条件も確認することにしました。
入力例:比較する表は一つ
新しい検証用ブックに「Find確認」シートを作り、次の文字列を入力します。検索範囲は見出しを除いたA2:A4です。業務中のブックで試すと検索設定にも影響するため、確認用のブックで行います。
セル |
入力する値 |
|---|---|
A1 |
商品コード |
A2 |
A01 |
A3 |
B01 |
A4 |
A01 |
検索語Aと、値A01の関係
部分一致では、A01の一部分であるAも一致します。完全一致では、Aという値そのものが必要です。この表にはAそのものがないため、完全一致で探すと該当なしになります。表の変更がなくても、一致の定義が違えば結果は変わります。 図中のFind(What:="A")は検索範囲に対する呼び出しの省略表記です。LookAtを省略して以前の条件を引き継ぐことを観測する例であり、完成版の実装ではありません。Findが返すのは最初の一致セル1個、またはNothingです。
読むポイント
再現メモには、ブック・範囲・検索語だけでなく、直前の検索条件と期待する一致の意味も残します。部分一致と完全一致を比較するときは、LookAt以外の条件をそろえます。まだ原因を特定していない段階で「データが壊れた」と決めつけないことが大切です。
図解2|手作業の検索とFindは条件を共有する

図2|4引数の保存値と、検索ダイアログとの相互影響を示す模式図です。
解説2|省略した条件は、前回の値から補われる
Range.Findは、ある範囲から指定した値を探してRangeを返すメソッドです。検索文字列Whatだけが入力のすべてではありません。次の4引数は設定が保存され、省略すると前回の値が使われます。
引数 |
決めること |
今回の固定値 |
|---|---|---|
LookIn |
値・数式など、何を調べるか |
xlValues |
LookAt |
完全一致か部分一致か |
xlWhole |
SearchOrder |
行方向か列方向か |
xlByRows |
MatchByte |
全角と半角を区別するか |
False |
共有される状態が、コードの外にある
検索ダイアログでこれらの条件を変えると、次のFindにも影響します。逆に、Findで指定した条件は検索ダイアログ側へ反映されます。図の双方向の矢印は、この相互影響を表しています。ダイアログは模式図で、特定版の画面操作手順ではありません。 手作業を禁止することが解決ではありません。マクロが必要とする条件を呼び出し側で指定すれば、前回の設定へ依存する箇所を減らせます。「前回はたまたま完全一致だった」状態に頼らず、今回の要件をコードへ残します。
4引数の保持と、必要な全指定を区別する
次の完全例では、保存される4引数に加え、After、SearchDirection、MatchCase、SearchFormatも明示します。これらすべてが同じ保存規則を持つという意味ではありません。開始位置、方向、大文字小文字、書式条件まで今回の例として固定するためです。
読むポイント
LookAtを明示することは「何を一致とするか」の対策です。FindNextをどこで終了させるかは、反復処理を終えるための別の条件です。二つを混同せず、どちらも完全例の中で確認します。
図解3|条件を明示した検索を一つの関数にする

図3|検索条件を固定し、見つからない場合と一巡した場合の終了を備えます。
解説3|検索条件を固定して一致するセルを列挙する
サンプルコード FindCellAddresses(全文30行)
01 |
|
|---|---|
02 |
|
03 |
|
04 |
|
05 |
|
06 |
|
07 |
|
08 |
|
09 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
コードの説明
12~17行目で値・完全一致などを指定します。14行目のAfterは範囲最後のセルで、この例はA4の次のA2から検索します。18行目はNothingならAddressを読まず終了します。22~28行目は最初の絶対アドレスを保存し、一巡して戻ったら終了します。途中のNothingも27行目で判定します。
入力・概要
標準モジュールへ全文を置きます。引数は単一連続範囲と検索文字列、戻り値はカンマ区切りのアドレスです。該当なしは空文字列。呼び出しと確認は次の解説へ続きます。
図解4|手作業の履歴を替えても同じ結果か

図4|同じデータで、複数件・1件・該当なしと検索終了を再確認します。
解説4|アドレスと終了まで、同じ条件で再確認する
入力後:イミディエイトで呼び出す
「Find確認」シートを持つ検証ブックの標準モジュールに前頁の関数を置き、VBEのイミディエイト ウィンドウで次の1行を実行します。ThisWorkbookは、そのコードを置いたブックを指します。
サンプルコード イミディエイトの呼び出し
01 |
|
|---|
結果:検索語を一つずつ変える
検索語 |
期待する戻り値 |
確認する場面 |
|---|---|---|
A01 |
A2,A4 |
複数件を一巡して終了 |
B01 |
A3 |
1件を追加して終了 |
Z99 |
空文字列 |
該当なしで終了 |
A |
空文字列 |
完全一致を維持 |
直前の検索を部分一致にした場合と、完全一致にした場合の両方で確かめます。件数だけでなく、返されたセルのアドレス、重複の有無、処理が終了することを確認します。この関数は検索条件を明示しますが、実行後に以前の検索設定へ戻す処理は含みません。
読むポイント:適用できる範囲
この例は一つの連続範囲で文字列の値を検索します。検索中に条件やセル値を変えない前提です。「*」「?」「~」を含む検索語、結合セル、複数領域へそのまま一般化しません。別の要件では、その条件に合う検索と確認例を用意します。 記事制作時はExcel 16.0で、事前のLookAtを変えた省略検索2ケースと、原稿関数8ケースを確認しました。手作業の検索ダイアログ操作と他のExcel版は未実測です。
出典メモ
『デバッキング Excel VBA』V026_261006、5.2.6「Find・FindNextの検索条件と終了条件を確認する」、VDBG-C05-040の30行と入力例を採用。構造・理由・適用条件を保ち、相談場面を加えました。Range.Find公式仕様/Range.FindNext公式仕様。
利用について
Copyright © 2026 LWP 山中 一弘。 本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
