「累積合計を一覧で表示したい」と思うことはありますよね。SUM関数で合計は出せますが、途中経過は表示できません。
SCAN関数を使えば、各ステップの中間値を配列で返せます。累積売上や残高推移が数式1つで完成しますよ。
この記事では、SCAN関数の基本からREDUCE関数との違いまでわかりやすく解説します。
SCAN関数とは?
SCAN関数(読み方: スキャン関数)は、配列の全要素を順番に処理して、各ステップの中間値を配列で返す関数です。「scan(走査する)」が名前の由来ですね。
先頭からデータをたどりながら結果を記録するイメージです。
REDUCE関数が「最終値だけ」を返すのに対し、SCAN関数は「途中経過もすべて」返します。これが最大の特長です。
SCAN関数にできることをまとめると、次のとおりです。
- 配列の全要素を順番に処理して中間値を配列で返す
- LAMBDA関数で処理内容を自由にカスタマイズできる
- 「前回の結果を次の計算に使う」累積処理の途中経過が見える
NOTE
SCAN関数はGoogleスプレッドシート独自の関数です。Excelには対応する関数がありません。同様の処理は、SUM関数と$記号を組み合わせた累積合計で対応してください。
SCAN関数の基本構文
=SCAN(初期値, 配列, LAMBDA(累積値, 現在値, 処理))
カッコの中に、初期値・処理対象の配列・各要素に適用するLAMBDA関数を指定します。構文はREDUCE関数と同じです。
| 引数 | 必須/任意 | 説明 |
|---|---|---|
| 初期値 | 必須 | 累積処理の開始値。合計なら0、積なら1、文字列結合なら”” |
| 配列 | 必須 | 処理対象のセル範囲または配列 |
| LAMBDA(累積値, 現在値, 処理) | 必須 | 各要素に適用する関数。仮引数は必ず2つ |
LAMBDA関数の仮引数は必ず2つ必要です。1つ目が「累積値」、2つ目が「現在値」を受け取ります。
初期値・累積値とは?
SCAN関数を理解するカギは「初期値」と「累積値」です。
初期値は「最初に手元に何を持って始めるか」を決める値です。合計を求めるなら0、積を求めるなら1を指定します。
累積値は「ここまでの処理結果」が入る変数です。最初の要素を処理するときは初期値が入ります。2番目以降は前回の処理結果が入ります。
次の数式を例に動きを見てみましょう。
=SCAN(0, {10,20,30}, LAMBDA(acc, val, acc+val))
- acc=0, val=10 → 0+10=10 → 配列に 10 を記録
- acc=10, val=20 → 10+20=30 → 配列に 30 を記録
- acc=30, val=30 → 30+30=60 → 配列に 60 を記録
結果は {10, 30, 60} です。REDUCE関数なら最終値の60だけが返ります。SCAN関数は各ステップの値をすべて返すのが違いです。
LAMBDA関数のおさらい
SCAN関数を理解するには、LAMBDA関数の基本を知っておく必要があります。
LAMBDA関数は「自分だけの関数を作れる」関数です。引数と処理内容を自分で定義できます。
=LAMBDA(引数, 処理)(値)
たとえば =LAMBDA(x, x*2)(5) と書くと、xに5が入って10が返ります。SCAN関数の中では、累積値と現在値が自動的に渡されます。
SCAN関数の基本的な使い方
ここでは、シンプルな数値データを使ってSCAN関数の動きを確認していきます。
サンプルデータ
A1:A5に以下のデータが入っているとします。
| A | |
|---|---|
| 1 | 売上 |
| 2 | 100 |
| 3 | 200 |
| 4 | 150 |
| 5 | 250 |
累積合計を求める
A2:A5の累積合計を求めます。出力先のセル(たとえばB2)に以下の数式を入力してください。
=SCAN(0, A2:A5, LAMBDA(acc, val, acc + val))
結果は {100, 300, 450, 700} です。B2:B5に各ステップの累積合計が展開されます。
| A | B | |
|---|---|---|
| 1 | 売上 | 累積合計 |
| 2 | 100 | 100 |
| 3 | 200 | 300 |
| 4 | 150 | 450 |
| 5 | 250 | 700 |
SUM関数では最終合計の700しか出せません。途中経過も見たいときはSCAN関数の出番です。
累積積を求める
各数値を順番に掛け合わせた途中経過を表示するには、初期値を1にして掛け算します。
=SCAN(1, A2:A5, LAMBDA(acc, val, acc * val))
結果は {100, 20000, 3000000, 750000000} です。初期値を1にするのがポイントですね。0だと何を掛けても0になります。
文字列を逐次結合する
B1:B4に「東京」「大阪」「名古屋」「福岡」が入っている場合、1つずつ追加していく過程を表示できます。
=SCAN("", B1:B4, LAMBDA(acc, val, IF(acc="", val, acc & "→" & val)))
各ステップで文字列が増えていく様子が一覧で確認できますよ。結果は次のとおりです。
{"東京", "東京→大阪", "東京→大阪→名古屋", "東京→大阪→名古屋→福岡"}
SCAN関数の実務活用パターン
パターン1: 月次の累積売上を表示する
月ごとの売上データから、累積売上の推移を自動で表示する例です。A列に月名、B列に売上が入っているとします。
| A | B | |
|---|---|---|
| 1 | 月 | 売上 |
| 2 | 1月 | 500,000 |
| 3 | 2月 | 620,000 |
| 4 | 3月 | 480,000 |
| 5 | 4月 | 710,000 |
C2に以下の数式を入力してください。
=SCAN(0, B2:B5, LAMBDA(acc, val, acc + val))
結果は {500000, 1120000, 1600000, 2310000} です。
| A | B | C | |
|---|---|---|---|
| 1 | 月 | 売上 | 累積売上 |
| 2 | 1月 | 500,000 | 500,000 |
| 3 | 2月 | 620,000 | 1,120,000 |
| 4 | 3月 | 480,000 | 1,600,000 |
| 5 | 4月 | 710,000 | 2,310,000 |
売上レポートで「年初からの累計」を並べたい場面にぴったりです。行を追加しても数式を修正する必要がありません。
パターン2: 在庫数の推移を計算する
入荷と出荷のデータから、在庫数の推移を追跡する例です。初期在庫100個からスタートします。
| A | B | |
|---|---|---|
| 1 | 日付 | 入出荷 |
| 2 | 3/1 | +50 |
| 3 | 3/5 | -30 |
| 4 | 3/10 | +80 |
| 5 | 3/15 | -60 |
C2に以下の数式を入力してください。
=SCAN(100, B2:B5, LAMBDA(acc, val, acc + val))
結果は {150, 120, 200, 140} です。初期値に100(期首在庫)を指定しています。
| A | B | C | |
|---|---|---|---|
| 1 | 日付 | 入出荷 | 在庫数 |
| 2 | 3/1 | +50 | 150 |
| 3 | 3/5 | -30 | 120 |
| 4 | 3/10 | +80 | 200 |
| 5 | 3/15 | -60 | 140 |
初期値を変えるだけで「期首在庫が違う場合」もすぐに対応できます。累積処理はSCAN関数が最も得意とするパターンです。
パターン3: 口座残高の推移を表示する
入出金データから口座残高の推移を計算する例です。初期残高を1,000,000円とします。
| A | B | |
|---|---|---|
| 1 | 摘要 | 金額 |
| 2 | 給与 | 250,000 |
| 3 | 家賃 | -80,000 |
| 4 | 食費 | -35,000 |
| 5 | 副業 | 50,000 |
C2に以下の数式を入力してください。
=SCAN(1000000, B2:B5, LAMBDA(acc, val, acc + val))
結果は {1250000, 1170000, 1135000, 1185000} です。
残高の推移が一覧で見えます。どの時点で残高が最も少なかったかもひと目でわかりますよ。
REDUCE関数との違い・使い分け
SCAN関数と最も混同しやすいのがREDUCE関数です。構文はまったく同じですが、返す結果が異なります。
| 比較項目 | SCAN関数 | REDUCE関数 |
|---|---|---|
| 戻り値 | 中間値を含む配列 | 最終値のみ(1つの値) |
| 結果の形 | 元の配列と同じサイズ | スカラー値 |
| 構文 | 同じ | 同じ |
| 典型的な用途 | 累積合計・残高推移を表示したいとき | 合計・積など最終結果だけ欲しいとき |
たとえば {10, 20, 30} に対して累積合計を求めた場合、結果はこうなります。
- SCAN: {10, 30, 60}(途中経過も含む配列)
- REDUCE: 60(最終値のみ)
SCAN関数が向いている場面
「途中経過も見たい」ときはSCAN関数です。累積売上推移・口座残高の推移・在庫数の変動など、一覧表示に向いています。
REDUCE関数が向いている場面
「最終的な1つの値だけ欲しい」ときはREDUCE関数です。合計金額や累積割引後の最終価格など、答えが1つに定まる処理に向いています。
選び方の判断基準
迷ったときは次のように考えてください。
- 結果をセル1つに出したい → REDUCE関数
- 結果を一覧(複数セル)で見たい → SCAN関数
構文が同じなので、まずSCAN関数で途中経過を確認してからREDUCE関数に切り替える、という使い方もおすすめですよ。
LAMBDA系関数の全体像
LAMBDA関数と組み合わせて使う関数は複数あります。全体像を把握しておくと、使い分けの判断がしやすくなりますよ。
| 関数 | 処理単位 | 結果の形 | 主な用途 |
|---|---|---|---|
| MAP | セルごと | 元と同じ形 | セルごとの変換・加工 |
| BYCOL | 列ごと | 横1行 | 列ごとの集計 |
| BYROW | 行ごと | 縦1列 | 行ごとの集計 |
| REDUCE | 配列全体 | 1つの値 | 全体を1つに集約 |
| SCAN | 累積 | 元と同じサイズ | 累積計算の中間結果 |
| MAKEARRAY | 行×列 | 新しい配列 | 計算で配列を生成 |
SCAN関数はREDUCE関数の対です。最終値だけならREDUCE、途中経過も必要ならSCANと覚えておきましょう。
よくあるエラーと対処法
SCAN関数はLAMBDA関数と組み合わせるため、構文のミスが起こりやすいです。
| エラー | 原因 | 対処法 |
|---|---|---|
#NAME? | 関数名のスペルミス | 「SCAN」のスペルを確認してください |
#NAME? | Excelで使用しようとした | SCAN関数はGoogleスプレッドシート専用です |
#NAME? | LAMBDA関数の仮引数名が不正 | 仮引数名にセル参照(A1等)やスペースは使えません |
#N/A | LAMBDAの引数が2つでない | LAMBDAの仮引数は必ず2つ(累積値と現在値)にしてください |
#VALUE! | 初期値の型が処理と合わない | 合計なら0、文字列結合なら””を初期値にしてください |
#ERROR! | LAMBDAの構文ミス | カッコの閉じ忘れ、カンマの過不足を確認してください |
#REF! | 展開先のセルにデータがある | SCAN関数は配列を返すため、展開先のセルを空にしてください |
特に多いのが「LAMBDAの引数が2つでない」エラーです。仮引数は必ず2つにしてください。1つや3つだと#N/Aエラーになります。
SCAN関数は配列を返すため、展開先に既存データがあると#REF!エラーになります。出力先のセル範囲を事前に空にしておきましょう。
TIP
LAMBDA関数の仮引数名で迷ったら、
acc(accumulator の略)とval(value の略)を使うのがおすすめです。累積値と現在値の役割が一目でわかります。なお、SCAN関数は1つの配列に対して最大約39,998回まで繰り返し処理ができます。
まとめ
SCAN関数は、各ステップの中間値を配列で返す関数です。途中経過を一覧で表示したい場面で活躍します。
この記事のポイントをおさらいしておきましょう。
- SCAN関数は
=SCAN(初期値, 配列, LAMBDA(acc, val, 処理))で、中間値を含む配列を返す - 初期値は「最初に手元に何を持って始めるか」を決める値(合計なら0、積なら1)
- 累積売上・在庫推移・残高推移など、途中経過を見たい場面に最適
- REDUCE関数は最終値のみ。途中経過も欲しいならSCAN関数を選ぶ
- 構文はREDUCE関数とまったく同じ。切り替えも簡単
- Googleスプレッドシート独自の関数で、Excelでは使えない
まずはシンプルな累積合計から試してみてください。
=SCAN(0, A2:A5, LAMBDA(acc, val, acc + val))
途中経過が配列で返ってくる動作を体感すれば、さまざまな累積処理に応用できますよ。
