[Power Query] １列に積み重なったデータを表形式にするベストプラクティスは？ (2) Table.Split → Table.Transpose → Table.Combine

※この記事は 2023/7/22 に作成しました。
※オプションで、「地域の設定」の「クエリステップ」は、「常に英語」に設定されています。日本語で使用している場合は、各自環境で作成されるコードに読み替えてください。

以下のように、複数の項目が1列になっているデータをテーブルにする方法の2番目です。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e87b3164-4a5b-f0dc-49fe-af959488dddc.png"/>

# Index
- [(1) Table.AddIndexColumn → Table.Pivot](https://qiita.com/spumoni/items/f949f370aea5a831aeea)
- [(2) Table.Split → Table.Transpose → Table.Combine](https://qiita.com/spumoni/items/0de5b66f3d71b69572bd)
- [(3) List.Split → Table.FromRows](https://qiita.com/spumoni/items/0bcf50c7720f93804fcb)
- [(4) Table.AlternateRows → Table.FromColumns](https://qiita.com/spumoni/items/679150a28de7a9a30f1d)
- [(5) List.Alternate → Table.FromColumns](https://qiita.com/spumoni/items/4aac2d40984ba4c244ce)
- [(6) まとめ](https://qiita.com/spumoni/items/3503970baa038e349a79)


# 解法２: 3行ごとにテーブルを作成して縦横変換
　データを3行ごとにテーブルに変換し、Table.Transposeで縦横入替してつなげます。
　GUIが使用できないので少々面倒に思えますが、内容は比較的簡単です。

## Table.Split
　この関数はGUIから操作できないため、以下のように数式バーの左の「fx」を押してステップを追加し、Table.Split関数を入力します。（詳細エディタを使用してもよい）
　Table.Splitの第二引数は、項目数の3を入れます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/fffc4b77-537e-d5a6-b7b4-e6ec4f8fad34.png"/>
　3項目ずつがテーブルになったリストが出来上がります。
<img width="100" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/368c5352-0e50-f889-6c70-cd4f95f152eb.png"/>

## Table.Transpose
　テーブルの縦横入替するには、「変換」タブの「テーブル」グループから「入れ替え」を使用します。その時使われる関数が Table.Transpose です。しかし、今回はリストの項目それぞれに処理を適用しなければならないので、 **List.Transoform** 関数を利用し、その中で Table.Transpose を使用することになります。
　先と同様に「fx」でステップを追加し、関数を入力します。List.Transformの第2引数は、関数になります。１つ１つに関数を適用する「each」を最初に書き、「_」はそれぞれのリストにあるテーブルを示します。(see. [Mから始めよう #6](https://qiita.com/spumoni/items/6841aec922c02ee92a2f#7-each-%E3%81%A8-_%E3%82%A2%E3%83%B3%E3%83%80%E3%83%BC%E3%82%B9%E3%82%B3%E3%82%A2%E3%83%BC))
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7f8e9b35-7604-aeed-f1d0-5034da013435.png"/>

## Table.Combine
　最後に、全てのテーブルを結合するのですが、これもGUIからできないので、「fx」でステップを追加し、以下の関数を入力します。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/7313a1f3-1336-b1d9-2012-123f0c2da6d5.png"/>

　Table.TransformとTable.Combineは、以下のような処理イメージです。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/dd537aa9-2399-75ee-dd7d-342ef1abbe6e.png"/>


　最後に、列の型と列名を設定して完成です。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/420242d2-4b75-63cb-ba8f-ee7ddfe3180c.png"/>

## Table.Split関数

```text:構文
Table.Split(
    table as table, 
    pageSize as number
) as list
```

　Table.Splitは、テーブルの行を、指定された行数で区切って複数のテーブルを作成し、リスト形式で返す関数です。戻り値がリスト型であることに注意してください。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/a310f9b1-80d8-91af-5dd5-104eb6185b5a.png"/>


https://learn.microsoft.com/ja-jp/powerquery-m/table-split

## ソースコード

```text
let
    // ファイルの読み込み
    Source = Table.FromColumns(
        {
            Lines.FromBinary(
                File.Contents( "** File Name **" ),
                null,
                null,
                932  // シフトJIS
            )
        }
    ),
    // ** Table.Split **
    Custom1 = Table.Split(Source, 3),
    ListTransform = List.Transform(
        Custom1,
        each Table.Transpose(_)
    ),
    // テーブルの結合
    Custom2 = Table.Combine(ListTransform),
    // 列の型を設定
    ChangedType = 
        Table.TransformColumnTypes(
            Custom2,
            {
                {"Column1", type text}, 
                {"Column2", type text}, 
                {"Column3", type date}
            }
        ),
    // 列名の変更
    RenamedColumns = 
        Table.RenameColumns(
            ChangedType,
            {
                {"Column1", "書名"}, 
                {"Column2", "著者名"}, 
                {"Column3", "出版日"}
            }
        )
in
    RenamedColumns
```