【上級編】【PowerQuery】ループ処理を直接書く方法!

M言語で再帰処理を書いてみよう!

かじむー

では再帰処理を組み込んで関数を作ってみよう!

では10以降の連番を作る関数を作ってみます。

いきなり作りこまずですね
まずは11だけを自動で作る中身を書いてみます。

再帰処理のベースを作る

テーブルをリストに変換

最初に扱いやすいリストに変換します。
先程の繰り返し処理の時と同様です!

リストの最後を取得

そしてリストの一番最後を取得するために
List.Lat関数を使います!

リストの最後を取得
// 最終番号を取得 = 10
last_num = List.Last(list_no)

そうすると自動的に最終番号を取得できますね!

次の番号を生成

先程の最終番号に1をプラスすれば
11」が求められますね!

次の番号
// 次の番号(最終番号に1を足す) = 11
next_num = last_num + 1

次の番号をリストに追加

ではこの「11」を「1~10リスト加えてあげましょう!

リストに追加

// 次の番号をリストに加える {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
list_new_no =list_no & {next_num}

リストに加える際は
{ } で囲んでリスト化して「&で繋げばOKです!

リストを整理

最後にこれをテーブルに変換します!
ここでは#tableを使って直接テーブルを作りたいのですが…

これを使うにはリストの形を少し変える必要があります

・・・こんな感じですね!

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
 ↓
{{1}, {2}, {3}, {4} {5}, {6}, {7}, {8}, {9}, {10}, {11}}

リストの中でさらにリストとして格納します!

ここでList.Transform関数を使います。

リストを整理
// リストを整理 {{1}, {2}, {3}, {4} {5}, {6}, {7}, {8}, {9}, {10}, {11}}
list_trans = List.Transform(list_new_no, each {_})

この様に書く事で出来ます!
この「_」はリストから1つずつ渡される値になります。
繰り返し処理で書いた「x」に当たりますね!

テーブルを作成

リストを整理
// テーブルを作成
tbl_new =  #table(
            type table [No = number],
            list_trans
        )

ではこの結果を見てみると・・・!

はい!これで自動で11までつくれましたね!

自動で11まで生成する全コード
let
    // No列をリスト化
    list_no = table_number[No],
    // 最終番号を取得
    last_num = List.Last(list_no),
    // 次の番号(最終番号に1を足す)
    next_num = last_num + 1,
    // 次の番号をリストに加える {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
    list_new_no =list_no & {next_num},
    // リストを整理 {{1}, {2}, {3}, {4} {5}, {6}, {7}, {8}, {9}, {10}, {11}}
    list_trans = List.Transform(list_new_no, each {_}),
    // テーブルを作成
    tbl_new =  #table(
                type table [No = number],
                list_trans
            )
in
    tbl_new

ベースを元に再帰処理を実装していく

かじむー

ではこれをベースに再帰処理に書き換えてこう!

続きの処理に渡したいデータを整理

まずこの後の処理に渡したいものは何か?を考えます。

連番11まで追加したテーブルに
続きの12,13をつけ足して欲しいので
この11まで生成されたテーブル
続きの処理に渡したいですよね!

そしてこのままいくと
永遠に連番が増えていくので
何番まで連番を増やすのか?制限をかける数も渡したいです!

という事で
この2つをパラメータとして記述します!

パラメータ
(tbl as table, limit_num as number) =>

こうする事でこれが関数としてみなされましたね。

ループを抜ける処理を追加

そして最後1つ付け加えます!

永遠に数が増えていかない様に
制限の数を超えないなら再帰処理(自分自身を呼び出す)
制限の数を超えた結果を返す
という処理です!

ループを抜ける処理
result = if next_num < limit_num then @連番生成(tbl_new, limit_num) else tbl_new

自分自身を呼び出す場合は
@関数名()で呼び出すことができます。

では実際にこの関数を使って
連番を生成したいと思います!

ではテーブルに table_number を選んで
制限として20を与えて生成すると…

はい!20まで番号が自動生成されましたね!

再帰処理を実際に書いてみたという内容でした~!

連番生成関数
(tbl as table, limit_num as number) =>
let
    // No列をリスト化
    list_no = tbl[No],
    // 最終番号を取得
    last_num = List.Last(list_no),
    // 次の番号(最終番号に1を足す)
    next_num = last_num + 1,
    // 次の番号をリストに加える {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
    list_new_no =list_no & {next_num},
    // リストを整理 {{1}, {2}, {3}, {4} {5}, {6}, {7}, {8}, {9}, {10}, {11}}
    list_trans = List.Transform(list_new_no, each {_}),
    // テーブルを作成
    tbl_new =  #table(
                type table [No = number],
                list_trans
            )
    ,
    // 結果
    result = if next_num < limit_num then @連番生成(tbl_new, limit_num) else tbl_new
in
    result

今回のまとめ

▼繰り返し処理を書く方法

 List.TransformMany関数を使う

▼再帰処理を書く方法

 @関数名を書いて自身を呼び出す

いかがだったでしょうか?

今回はM言語を直接書く内容だったので
ハードルが少し高かったかもしれません。

でも自由に記述できるようになれば
自由自在に加工することができます!

皆さんもPowerQuery上級者になって
職場の業務改善をしていきましょう!

かじむー

業務改善のご相談いつでもお待ちしております♪
1 2