LWP | M言語のList.Accumulateで累計を作る
M言語のList.Accumulateで累計を作る
図解1|合計は一つ、累計は明細ごと

図1|最後の合計だけでなく、各明細までにいくら積み上がったかを見る。
解説1|合計は一つ、累計は明細ごと
ストーリー
フナさん「合計は14,000円ですね。ただ、受注メモと照合するので、各明細までの累計も欲しいんです。」
シャケモン「では、順番に足すたびに結果を残しましょう。同じ三つの金額でも、欲しい答えの形が違いますね。」
全国規模の中華食材卸・淡水社の、架空の受注明細を使う。一行は一つの受注明細で、下表の順1〜3を今回の計算順とする。金額は数量×単価で求めた受注額。税・送料・値引きは含めず、売上確定額とも区別する。
入力例と期待結果
順 |
明細 |
商品・規格 |
数量×単価 |
金額 |
累計 |
|---|---|---|---|---|---|
1 |
O001-1 |
干ししいたけ500g |
6袋×1,200円 |
7,200円 |
7,200円 |
2 |
O001-2 |
豆板醤1kg |
4本×800円 |
3,200円 |
10,400円 |
3 |
O002-1 |
干ししいたけ500g |
3袋×1,200円 |
3,600円 |
14,000円 |
合計は14,000円という一つの数値。累計は7,200円、10,400円、14,000円という三つの数値になる。袋と本の数量をまとめて足すのではなく、単位が円でそろった金額を足している。
読むポイント
M言語では、この金額列を {7200, 3200, 3600} というListで表せる。この記事では、小さなListを直接書いて、前の結果を次の計算へ渡す仕組みを確かめる。
図解2|前の状態と今回の金額から、次の状態へ

図2|関数が受け取る二つの値と、返す一つの値を追う。
解説2|前の状態と今回の金額から、次の状態へ
ストーリー
シャケモン「List.Accumulateには、金額のList、最初の状態、次の状態を作る関数を渡します。」
フナさん「2件目なら、そこまでの7,200円と、今回の3,200円を受け取るんですね。」
状態とは、次の計算へ持ち越す値のこと。ここでは「ここまでの合計」を数値一つで持つ。関数は、現在の状態と今回の要素を受け取り、次の状態を返す。初回だけは、まだ前の計算結果がないので初期状態の0を使う。
関数の役割
引数 |
この例で渡すもの |
意味 |
|---|---|---|
第1引数 |
{7200, 3200, 3600} |
順に取り出す金額 |
第2引数 |
0 |
計算を始める前の状態 |
第3引数 |
(a_state, a_value) => a_state + a_value |
二つの値から次の状態を返す関数 |
計算結果
回 |
現在の状態 |
今回の金額 |
返す次の状態 |
|---|---|---|---|
1 |
0 |
7,200 |
7,200 |
2 |
7,200 |
3,200 |
10,400 |
3 |
10,400 |
3,600 |
14,000 |
矢印 => の右側が返す値を表す。a_stateとa_valueは、この例で付けた引数名である。Listの各要素を独立に変換するList.Transformと違い、前の計算結果も次の計算の材料になる。
図解3|数値を持ち越すと、戻るのは最後の合計

図3|途中で計算された値が、そのまま出力の一覧になるわけではない。
解説3|数値を持ち越すと、戻るのは最後の合計
ストーリー
フナさん「計算中には10,400円もありますが、出力されるのは最後の14,000円だけなんですね。」
シャケモン「List.Accumulateが返すのは最後の状態です。今は数値一つを次へ渡しているので、答えも14,000だけになります。」
実行するコード
ExcelのPower Queryで空のクエリを作り、詳細エディターの内容を次の式へ置き換える。外部ファイルやテーブルは参照しない。
01 |
|
|---|---|
02 |
|
03 |
|
04 |
|
05 |
|
06 |
|
07 |
|
08 |
|
09 |
|
10 |
|
計算結果
戻り値は数値の14000。7,200と10,400も計算には使われるが、最後の状態の中には残っていない。各明細の累計を欲しい場合は、状態の持ち方を変える必要がある。
読むポイント
合計一つだけなら、List.Sum({7200, 3200, 3600})の方が目的を直接表せる。ここでList.Accumulateを使うのは、「前の状態から次の状態を作る」仕組みを理解し、次の図で途中の結果も残すためである。
図解4|状態をListにして、累計を末尾へ残す

図4|最後の状態の中に、必要な途中結果をすべて含める。
解説4|状態をListにして、累計を末尾へ残す
ストーリー
シャケモン「今度は状態をListにします。末尾の累計へ今回の金額を足して、新しい累計を末尾へ加えましょう。」
フナさん「最後の状態が一覧なら、途中までの金額もまとめて受け取れますね。」
実行するコード
01 |
|
|---|---|
02 |
|
03 |
|
04 |
|
05 |
|
06 |
|
07 |
|
08 |
|
09 |
|
10 |
|
11 |
|
関数の役割と結果
List.Last(a_state)は状態Listの末尾を取り出す。たとえば2回目は、状態が {0, 7200}、今回の金額が3200。末尾の7200へ足して10400を作る。
波括弧で {10400} という一要素のListにし、& で今までのListへ連結すると、次の状態は {0, 7200, 10400} になる。既存のListの要素を書き換える処理ではなく、新しいListを返す式である。
最終状態は {0, 7200, 10400, 14000}。先頭の0は開始用の値なので、List.Skipで一つ除く。戻り値は {7200, 10400, 14000} となり、三つの明細と件数がそろう。
図解5|順序が変われば、途中の累計も変わる

図5|最後の合計の一致と、各行の累計の一致を分けて確認する。
解説5|順序が変われば、途中の累計も変わる
ストーリー
フナさん「最終合計だけ合っていても、並び順が違えば受注メモの途中の金額とは合いません。」
シャケモン「表から金額Listを取り出す前に、何の順で累計を出すか決める必要がありますね。」
入力例と結果
図4のコードでorder_amountsだけを変更すると、次の結果になる。
入力List |
戻る累計List |
最後の値 |
|---|---|---|
{7200, 3200, 3600} |
{7200, 10400, 14000} |
14000 |
{3600, 7200, 3200} |
{3600, 10800, 14000} |
14000 |
{} |
{} |
要素なし |
実際の表を使う場合は、明細順などのキーで必要な順序を確定してから金額列を取り出す。同じキーの行が複数あるなら、その間の順序も決めておく。集計後の表示順だけ変えても、計算時の順序を直したことにはならない。
空Listでは何が起きるか
入力が {} なら、次の状態を作る関数は一度も呼ばれない。List.Accumulateは初期状態の {0} を返し、List.Skipがその一要素を除くため、結果は {} になる。実在しない明細の累計0を出力しない。
読むポイント
この例の入力は数値だけで、nullや数値に変換できない文字列は対象外。実務へ組み込む前に、欠損・エラーの扱いを決める。また、Listを繰り返し連結する小さな教材例であり、大量データでの最速手法を示すものではない。
図解6|ExcelのSCANと、返す値の違いを比べる

図6|同じ累計が得られても、途中結果を返す仕組みは異なる。
解説6|ExcelのSCANと、返す値の違いを比べる
ストーリー
フナさん「Excelの表でも、この三つの累計を並べられますか。」
シャケモン「SCANを使えます。こちらは各回の中間結果を配列で返すので、履歴Listを自分で連結する必要がありません。」
入力例と数式
ExcelのB1を「受注金額」、B2:B4を順に7200、3200、3600とする。C1は「累計」とし、C2:C4を空けて、C2だけに次の式を入れる。
=LET(_amounts,B2:B4,_running_totals,SCAN(0,_amounts,LAMBDA(a_total,a_amount,a_total+a_amount)),_running_totals)LETは入力範囲と計算結果に名前を付けている。SCANの初期値は0。a_totalがここまでの合計、a_amountが今回の金額に当たる。結果はC2:C4へ7,200、10,400、14,000とスピルする。C3やC4へ式をコピーする必要はない。
結果の違い
方法 |
返す値 |
累計を残す方法 |
|---|---|---|
MのList.Accumulate |
最後の状態 |
状態Listへ各回の累計を含める |
ExcelのSCAN |
各回の中間結果の配列 |
関数が中間結果を配列で返す |
SCANはExcel for Microsoft 365・Excel 2024で利用できる。数式の再計算とPower Queryの更新は別の仕組みである。どちらも今回の三明細と各行の累計を照合してから利用する。
出典
Microsoft Learn:List.Accumulate / Microsoft Support:SCAN。2026-11-03確認。会社・取引・価格は説明用の架空例。
