ExcelのLAMBDAに配列(スピルする範囲や配列定数)を渡したとき、「ORだけが要素ごとに判定されず、配列全体を見てしまう」現象に悩む人は少なくありません。原因はLAMBDAではなく、OR/ANDが“集約(配列→1つの結果)”として設計されていることです。要素ごとのORに直す実務的な書き方を、再現例と一緒に整理します。
起きている現象:ORが“各要素”ではなく“配列全体”を評価してしまう
次のように、LAMBDAの引数に配列(例:{"aaa";"bbb"} や {"ccc";123})を渡し、ISNUMBER() の判定結果を確認している状況を想定します。
=LET(
txtA, {"aaa";"bbb"},
txtB, {"ccc";123},
f, LAMBDA(a,b,
HSTACK(
a,
b,
ISNUMBER(a),
ISNUMBER(b),
OR(ISNUMBER(a), ISNUMBER(b))
)
),
f(txtA, txtB)
)
感覚としては「1行目(aaa/ccc)はどちらも数値ではないからORはFALSE、2行目(bbb/123)はどちらかが数値だからTRUE」になってほしいはずです。ところが、実際にはOR列が両方TRUEになったり、逆に両方FALSEになったりします。
| 行 | a(txtA) | b(txtB) | ISNUMBER(a) | ISNUMBER(b) | OR(ISNUMBER(a),ISNUMBER(b)) | 期待するOR |
|---|---|---|---|---|---|---|
| 1 | aaa | ccc | FALSE | FALSE | TRUE(配列全体に123があるため) | FALSE |
| 2 | bbb | 123 | FALSE | TRUE | TRUE | TRUE |
さらに厄介なのが、txtB の2行目だけを 123 から "ddd" に変えると、1行目のORまで巻き添えで変わることです。これは「ORが各行のペアを見ている」のではなく、「配列全体のどこかにTRUEがあるか」を一度だけ判定しているために起きます。
原因:OR/ANDは“配列を受けると1つの結果に集約する”関数
ポイントは、OR/ANDは配列に対して要素ごとにスピルする関数ではなく、配列全体をまとめて1つの真偽値に潰す(集約する)という性質を持つことです。
Excelでは昔から、OR(A1:A10) のように範囲を渡すと「範囲のどこかがTRUEならTRUE」という集計をしてきました。動的配列(スピル)やLAMBDAを使っても、この“集計としてのOR”は変わりません。
今回の例では、ISNUMBER(a) と ISNUMBER(b) は配列(2行分)を返します。ところが、そこへ OR(...) をかけると、ORは配列を横断して1回だけ評価し、単一のTRUE/FALSEを返します。さらに HSTACK のように配列同士を結合する場面では、スカラー(1つの値)は配列サイズに合わせて自動的に拡張(ブロードキャスト)されるため、同じTRUE/FALSEが“各行に横流し”されて見えてしまいます。
| 式 | 結果の形 | 意味合い |
|---|---|---|
ISNUMBER({"aaa";123}) | {FALSE;TRUE}(配列) | 要素ごとの判定 |
OR(ISNUMBER({"aaa";123})) | TRUE(1値) | 配列全体を集約して判定 |
HSTACK({"a";"b"}, TRUE) | 2行×2列(TRUEが各行に複製) | スカラーが配列に拡張される |
つまり「LAMBDAが突然“配列全体の文脈”に切り替わった」のではなく、ORが最初から“配列→1値”の関数であり、結果が結合時に拡張されて見えているだけ、という整理になります。
解決策A:ORを使わず、真偽値の加算で“要素ごとのOR”を作る
実務で最も手堅く、式も短いのがこの方法です。OR相当は「TRUE/FALSEを1/0として足し算し、合計が1以上ならTRUE」と考えます。
(ISNUMBER(a)+ISNUMBER(b))>0
これを先ほどの式に差し替えると、期待どおりに要素ごとの結果が返ります。
=LET(
txtA, {"aaa";"bbb"},
txtB, {"ccc";123},
f, LAMBDA(a,b,
HSTACK(
a,
b,
ISNUMBER(a),
ISNUMBER(b),
(ISNUMBER(a)+ISNUMBER(b))>0
)
),
f(txtA, txtB)
)
| 行 | a | b | (ISNUMBER(a)+ISNUMBER(b))>0 |
|---|---|---|---|
| 1 | aaa | ccc | FALSE |
| 2 | bbb | 123 | TRUE |
加算方式の良いところは、配列同士の演算(+)は基本的に要素ごとに計算されるため、ORのように“全体集約”が起きにくい点です。スピル範囲にそのまま使えるので、データ検証・抽出条件・判定列の生成に向きます。
加算ORの定番テンプレート
| やりたいこと | テンプレート | メモ |
|---|---|---|
| 2条件のOR | (cond1+cond2)>0 | 最も基本 |
| 3条件以上のOR | (cond1+cond2+cond3)>0 | 条件を足していくだけ |
| AND(全て満たす) | (cond1*cond2*cond3)>0 | 掛け算は“全てTRUEなら1” |
| ORの結果を明示的にTRUE/FALSEにする | IF((cond1+cond2)>0, TRUE, FALSE) | 表示を揃えたい時 |
注意点:エラー値が混ざる可能性がある場合
ISNUMBER() 自体は通常エラーを返しにくいですが、実務では「途中に#N/Aが入る」「別の判定式がエラーになる」ことがあります。足し算・掛け算はエラーを伝播しやすいので、必要ならエラーを0(FALSE扱い)に落とす一工夫を入れると安定します。
=LET(
c1, IFERROR(--ISNUMBER(a),0),
c2, IFERROR(--ISNUMBER(b),0),
(c1+c2)>0
)
--(ダブルマイナス)はTRUE/FALSEを1/0に強制変換する定番テクニックです。IFERRORで包めば、エラーを0として扱えます。
解決策B:MAPで“要素ごと”にORを呼ぶ(ORを残したい人向け)
「どうしてもORという関数名のまま書きたい」「条件が複雑で加算より読みやすい」場合は、MAPで1要素ずつスカラーにしてからORを実行するのが正攻法です。
=LET(
txtA, {"aaa";"bbb"},
txtB, {"ccc";123},
MAP(txtA, txtB, LAMBDA(a,b, OR(ISNUMBER(a), ISNUMBER(b))))
)
MAPは、対応する要素同士を1件ずつLAMBDAに渡していくため、LAMBDA内のaとbはスカラー(単一値)になり、ORが集約を起こしません。その結果、出力は要素ごとのTRUE/FALSEになります。
MAPで“デバッグ表示”も一緒に作る
判定の途中経過を文字列化して確認したい場合も、MAPは便利です。
=LET(
txtA, {"aaa";"bbb"},
txtB, {"ccc";123},
MAP(txtA, txtB,
LAMBDA(a,b,
"A="&a
&" / B="&b
&" / ISNUMBER(A)="&ISNUMBER(a)
&" / ISNUMBER(B)="&ISNUMBER(b)
&" / OR="&OR(ISNUMBER(a),ISNUMBER(b))
)
)
)
「どの行で何がTRUEになっているか」を可視化しやすく、判定式が長い場合の切り分けにも使えます。
MAPを使うときの実務メモ
- 配列の形(行数・列数)は揃える:MAPは基本的に対応する要素同士を処理します。片方だけ縦2行、もう片方が縦3行のようにサイズが違うと意図しない結果やエラーになります。
- スピル範囲にもそのまま使える:
MAP(A2:A100, B2:B100, ...)のように範囲を渡せば、結果が縦にスピルします。 - Microsoft 365の新しめのExcelで利用できる:環境によってはMAPが未提供の場合があります。その場合は次のBYROW/BYCOLや、加算方式が現実的です。
解決策C:行単位・列単位の判定ならBYROW/BYCOLが分かりやすい
「要素ごと」ではなく「行ごと(1行の中でどれかがTRUEならTRUE)」のような要件なら、ORはむしろ得意です。集約が起きる性質を意図してスコープを狭めるのがコツです。
例えば、A~C列のどこかに数値がある行だけTRUEにしたい場合は、次のように書けます。
=BYROW(A2:C10, LAMBDA(r, OR(ISNUMBER(r))))
BYROWが1行ずつ r(1×3の配列)を渡し、ORがその行の中だけを集約して1つの結果を返します。これなら「ORが配列全体を見てしまう」問題にはなりません。逆に、列ごとに判定したいならBYCOLです。
=BYCOL(A2:C10, LAMBDA(c, OR(ISNUMBER(c))))
| 関数 | 向いている判定単位 | ORの“集約”は? |
|---|---|---|
| MAP | 要素(セル)ごと | 起きない(スカラーで実行できる) |
| BYROW | 行ごと | その行の中だけで集約(意図通り) |
| BYCOL | 列ごと | その列の中だけで集約(意図通り) |
「LAMBDAが配列全体の文脈に切り替わらないようにする」ことはできる?
結論から言うと、OR/AND自体の挙動を“要素ごとにする設定”はありません。LAMBDAは“自動でループする関数”ではなく、引数に配列が来たときは、Excel全体の配列計算ルールに従って各関数が動くだけです。
そのため、対処は次のどちらかになります。
- ORの代替を、配列演算(+や*)で書く(解決策A)
- MAP/BYROW/BYCOLなどで「1回に扱う単位」を強制的に小さくする(解決策B/C)
「突然の文脈切り替えを止める」というより、“集約される場所”をコントロールすると考えると整理しやすくなります。
ORの代替:実務で使える“安定する書き方”まとめ
要素ごとのORを作りたいときに、最終的に迷わないための実務向けチートシートです。
| シーン | おすすめ | 例 |
|---|---|---|
| LAMBDAに配列を渡して、要素ごとにOR | 加算式(最短・高速) | (ISNUMBER(a)+ISNUMBER(b))>0 |
| ORという関数名で読みやすく保ちたい | MAPでスカラー化 | MAP(a,b,LAMBDA(x,y,OR(ISNUMBER(x),ISNUMBER(y)))) |
| 行の中に1つでも該当があればTRUEにしたい | BYROW + OR | BYROW(A2:D10,LAMBDA(r,OR(r="OK"))) |
| FILTERの条件でOR | 加算式(定番) | FILTER(data,(cond1+cond2)>0) |
「危険な関数」を見分けるコツ:配列を渡して“1つに潰れるか”で判断する
今回の混乱は「関数によって配列の扱いが違う」ことが根本原因です。そこで、判断基準をシンプルにします。
配列を渡したときに結果が1つに潰れる関数は“集約系”であり、要素ごとに使いたい場合はそのまま当てると事故りやすい、という覚え方です。
=OR({FALSE,TRUE,FALSE}) → TRUE(1つに潰れる)
=SUM({1,2,3}) → 6(1つに潰れる)
=ISNUMBER({1,"a",3}) → {TRUE,FALSE,TRUE}(要素ごと)
| タイプ | 代表例 | 配列を渡すと… | 要素ごとにしたい時の対処 |
|---|---|---|---|
| 集約・集計系 | OR, AND, SUM, MAX, MIN, COUNT, AVERAGE, TEXTJOIN など | 1つの値になりやすい | MAP/BYROW/BYCOLで単位を区切る、または演算子(+/*)で置き換える |
| 要素ごとに返す系 | ISNUMBER, LEN, UPPER, SUBSTITUTE, IF(条件次第)など | 同じ形の配列で返りやすい | そのまま使えることが多い |
| 配列を作る/整形する系 | MAP, BYROW, BYCOL, FILTER, TAKE, DROP, HSTACK, VSTACK など | スピルを前提に組める | 集約系の“安全装置”として包む |
迷ったら、{"a";1} のような小さな配列定数を直接渡してみて、結果が1つなら集約系・複数なら要素系、というテストが一番速いです。
よくある落とし穴:ORが原因の“巻き添え”を作らない設計
今回の相談で特に怖いのは、「別要素を変えただけで、関係ない行の結果まで変わる」ことです。これは、判定の最小単位が“行”ではなく“配列全体”になっているサインです。実務では、次のような場所で起きやすいので注意してください。
- 検証列をスピルで一気に作る:HSTACKで判定列を並べると、スカラーのブロードキャストが目立つ
- FILTER条件の中でOR/ANDを直接使う:範囲を渡した瞬間に全体集約になり、条件が1つに潰れることがある
- LAMBDAで“汎用化”した瞬間に配列が引数に入る:セル参照ではなく配列参照になり、関数の配列対応差が表面化する
設計のコツは、「どの単位で判定したいか」を先に決め、その単位に合わせてMAP/BYROWを選ぶことです。要素ごとならMAP、行ごとならBYROW、列ごとならBYCOL。ここが決まると、ORが“危ない”のではなく“使いどころがある”と理解できます。
実務例:入力チェック関数をLAMBDAで作る(巻き添えを防ぐ書き方)
最後に、実務でよくある「A列は数値、B列は任意。どちらかが数値ならOK、両方非数値ならNG」といったチェックを、LAMBDAで関数化する例を示します。
パターン1:加算ORで作る(軽量・安定)
=LAMBDA(a,b,
(ISNUMBER(a)+ISNUMBER(b))>0
)
これを名前の定義で ISNUM_OR のように登録しておけば、次のように使えます。
=ISNUM_OR(A2:A100, B2:B100)
パターン2:MAPで作る(ORを読みやすく残す)
=LAMBDA(a,b,
MAP(a,b, LAMBDA(x,y, OR(ISNUMBER(x), ISNUMBER(y))))
)
判定を追加したい場合も、MAP内のORに条件を足すだけで済みます。
=LAMBDA(a,b,
MAP(a,b, LAMBDA(x,y,
OR(
ISNUMBER(x),
ISNUMBER(y),
x="",
y=""
)
))
)
「空白ならOK」など、業務ルールをそのまま書けるので、保守性を優先する現場ではこちらが好まれます。
まとめ:ORが“悪い”のではなく、配列の単位を合わせるのがコツ
- OR/ANDは配列を受け取ると配列全体を1つに集約する性質がある
- LAMBDAが原因に見えても、実態はORの設計 + スカラーのブロードキャストで説明できる
- 要素ごとのORが欲しいなら、加算式(
(cond1+cond2)>0)が最短で安定 - ORを残したいなら、MAPでスカラー化してからORを実行する
- 行/列単位なら、BYROW/BYCOLで“集約の範囲”を意図通りにする

コメント