一括処理(MAP / BYROW / BYCOL / SCAN)
“1行ずつIFを書く”を卒業。配列に対して一括で処理すると、シートが軽くて壊れにくくなります。
現場のExcelでよくある状況:
行が増えるたびに式を下までコピー
どこかの行だけ式がズレる(地味に怖い)
判定列(フラグ列)が増殖する
重くなって固まる
最近のExcelは、配列(スピル)に対して
一括で処理できる関数が揃ってきました。
MAP:配列を1要素ずつ処理して結果を返す(複数配列にも対応)
BYROW:行単位で処理(行ごとの判定や整形)
BYCOL:列単位で処理(列ごとの集計や検査)
SCAN:逐次処理(累積・ランニング計算)
この章では、これらを使って
行ごとの判定・アラート列を自動生成する実務テンプレを作ります。
この章のゴール(今日できること)
MAP / BYROW / BYCOL の使い分けができる
“行単位の判定列”をコピー無しで作れる
SCANで「累積」「逐次集計」を関数で返せる
実務演習:問い合わせ表のアラート列(優先対応/期限切れ/要確認)を自動生成できる
1) まずは役割整理(どれを使うべきか)
MAP:要素ごと(セルごと)に処理したい
文字列整形、1件ずつ計算、複数列を同時参照して判定、など
BYROW:1行を“ひとかたまり”として扱いたい
「1行の情報を使って判定ラベルを返す」
“行単位の品質チェック”に強い
BYCOL:1列を“ひとかたまり”として扱いたい
列ごとの合計・平均・空欄数
列の品質検査(空欄率、NG率)
SCAN:前の結果を引き継ぐ(累積・逐次)
累積売上、累積件数、残高推移
“途中経過を見たい”時の武器
2) 基本構文(最小だけ)
MAP
=MAP(配列1, [配列2...], LAMBDA(x, [y...], 計算))
BYROW
=BYROW(配列, LAMBDA(r, 計算))
BYCOL
=BYCOL(配列, LAMBDA(c, 計算))
SCAN
=SCAN(初期値, 配列, LAMBDA(acc, x, 更新式))
3) 行単位・列単位の処理パターン(現場で使う形)
3-1. MAP:2列を見て“アラート文”を作る(コピー不要)
例:期限(A列)とステータス(B列)からアラートを作る。
=MAP(A2:A1000, B2:B1000,
LAMBDA(due, st,
IF(st="完了","",
IF(due<TODAY(),"期限切れ",
IF(due<=TODAY()+2,"要対応(期限近い)","")
)
)
)
)
3-2. BYROW:1行まるごとで判定(列が多い表に強い)
例:1行の中に「メール」「電話」があり、どちらか欠けたら要確認。
=BYROW(A2:F1000,
LAMBDA(r,
LET(
mail, INDEX(r,1,4),
phone, INDEX(r,1,5),
IF(OR(mail="", phone=""), "要確認", "OK")
)
)
)
BYROWは「行の中の列番号」をINDEXで取るのが定番です。
3-3. BYCOL:列ごとの空欄数を出す(品質監視)
=BYCOL(A2:F1000,
LAMBDA(c, COUNTBLANK(c))
)
3-4. SCAN:累積を作る(途中経過が必要なとき)
日別売上(A2:A31)から累積売上を作る。
=SCAN(0, A2:A31, LAMBDA(acc, x, acc + x))
4) 実務演習:行ごとの判定・アラート列の自動生成(完成まで)
ここからは、問い合わせ表の“アラート列”を関数で自動生成します。
目的:担当者が見るべき行を自動で浮かび上がらせる。
演習の前提(問い合わせテーブル)
テーブル tblInq(Ctrl+Tでテーブル化推奨)
列例:
受付日
顧客
件名
優先度(高/中/低)
期限(日付)
ステータス(未対応/対応中/完了)
担当(任意)
メール(任意)
電話(任意)
Step1:ルール定義(現場で効く最小セット)
アラートの優先順位を次で作ります。
期限切れ(未対応/対応中で、期限<今日) → 最優先
期限が近い(期限≦今日+2) → 要対応
優先度が高(ただし完了は除外) → 高優先
連絡先不足(メールor電話が空) → 要確認
それ以外 → 空欄
Step2:MAPで“アラート列”を一撃生成(推奨)
Reportシート(またはtblInqの外側のCalc列)に貼り付けます。
(テーブルの列内にスピルは置けないことがあるため、外に置くのが安定です)
=LET(
pr, tblInq[優先度],
due, tblInq[期限],
st, tblInq[ステータス],
mail,tblInq[メール],
tel, tblInq[電話],
MAP(pr, due, st, mail, tel,
LAMBDA(p, d, s, m, t,
IF(s="完了","",
IF(d<TODAY(),"🚨期限切れ",
IF(d<=TODAY()+2,"⚠期限近い",
IF(p="高","優先度:高",
IF(OR(m="", t=""),"要確認(連絡先不足)","")
)
)
)
)
)
)
)
記号(🚨⚠)が不要なら削除してください。
“短いラベル”の方が現場の運用には向きます。
Step3:アラート対象だけ抽出して「優先対応リスト」を作る(FILTER連携)
上のアラート結果がA2からスピルしているとして(A2#)、
アラートが空でない行だけを抜きます。
=LET(
alert, A2#,
src, tblInq,
FILTER(src, alert<>"")
)
Step4:期限順に並べ替えて、今日見る順番にする(SORT連携)
=LET(
alert, A2#,
x, FILTER(tblInq, alert<>""),
SORT(x, XMATCH("期限", tblInq[#Headers]), 1)
)
Step5:SCANで“累積件数”を作る(担当者の作業見積り)
優先対応リストがB2からスピルしていて、そこに「金額」ではなく「件数」を累積したい場合、
1行=1件として累積件数を作れます。
例:優先対応リストの行数分だけ 1 を並べて累積:
=LET(
n, ROWS(B2#)-1,
SCAN(0, SEQUENCE(n,1,1,1), LAMBDA(acc, x, acc+x))
)
これで「上から何件処理すると何件目まで終わるか」の目安を出せます。
5) 追加の便利レシピ(現場で効く)
5-1. BYCOLで“列の品質ダッシュ”を作る(空欄率)
列ごとの空欄数:
=BYCOL(tblInq,
LAMBDA(c, COUNTBLANK(c))
)
列ごとの空欄率(行数で割る):
=LET(
n, ROWS(tblInq),
BYCOL(tblInq, LAMBDA(c, COUNTBLANK(c)/n))
)
5-2. BYROWで“要確認理由”をまとめて返す(監査向け)
1行の中で欠損をまとめる例:
=BYROW(tblInq,
LAMBDA(r,
LET(
mail, INDEX(r,1, XMATCH("メール", tblInq[#Headers])),
tel, INDEX(r,1, XMATCH("電話", tblInq[#Headers])),
due, INDEX(r,1, XMATCH("期限", tblInq[#Headers])),
st, INDEX(r,1, XMATCH("ステータス", tblInq[#Headers])),
TEXTJOIN(" / ", TRUE,
IF(AND(st<>"完了", due<TODAY()), "期限切れ", ""),
IF(OR(mail="", tel=""), "連絡先不足", "")
)
)
)
)
6) よくあるつまずき(現場で止まらないために)
6-1. テーブル列内にスピルを置いて #SPILL ! / 入らない
→ スピルはテーブル外(Calc/Report)に置くのが安定です。
6-2. MAPの引数の配列サイズが合わない
→ 参照範囲(行数)が揃っているか確認してください。
テーブル列(tblInq[列名])で揃えるのが安全です。
6-3. 逐次(SCAN)が分かりにくい
→ “累積”が必要な場面だけで使うと良いです。
(累積売上、累積件数、残高推移)
まとめ:一括処理で「コピー文化」を終わらせる
MAP:複数列を見て、判定や整形を一括生成
BYROW:行単位の品質チェックや判定に強い
BYCOL:列単位の監視(空欄率など)に強い
SCAN:累積や逐次計算で“途中経過”を出せる
この型を入れるだけで、
「式のコピー」「ズレ」「行だけ壊れる」事故が大幅に減ります。
