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

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

以下のように、複数の項目が1列になっているデータをテーブルにする方法の5番目です。
<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)


# 解法5: List.Alternateを使う
　解法4で使ったTable.AlternateRowsをList.Alternateに置き換えてみます。ただし、パラメータの使い方が異なっていますので注意します。

## List.Alternate

```text:構文
List.Alternate(
    list as list, 
    count as number, 
    optional repeatInterval as nullable number, 
    optional offset as nullable number
) as list
```
リスト内でオフセットが奇数であるすべての要素によって構成されたリストを返します。 パラメーターに応じて、リスト list の値の取得とスキップを交互に行います。
- count:毎回スキップされる値の数を指定します。
- repeatInterval:スキップされた値の間に追加される値の数を示す、省略可能な繰り返し間隔。
- offset:初期オフセットで値のスキップを開始する、オプション オフセット パラメーター。

https://learn.microsoft.com/ja-jp/powerquery-m/list-alternate

　Table.AlternateRowsとパラメータの使い方が異なっています。第1、第2引数は必須で、あとは省略できます。

```text:例1
= List.Alternate( {1..10}, 2 ) 
```
　例1は、1～10のリストを作成し、2つの項目をスキップします。帰ってくる値は `{3,4,5,6,7,8,9,10}` です。

```text:例2
= List.Alternate( {1..10}, 2, 3 )
```
　例2は、1～10のリストを作成し、2つの項目をスキップした後、3つの項目を残す処理を繰り返します。帰ってくる値は `{3,4,5,8,9,10}` になります。

```text:例3
= List.Alternate( {1..10}, 2, 3, 1 )
```
　第4引数は、処理を開始する位置を指定します。例3では1が入力されているので、1項目飛ばした後、例2と同様の処理が行われます。帰ってくる値は `{1,4,5,6,9,10}` になります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/c3d23c7d-6b57-e412-912b-9c3f17af60ed.png"/>

　リストに対して、項目名を右クリックして「代替アイテムの削除」を選択すると、GUIからList.Alternateを生成することができます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/f760c204-a41a-6611-e13e-e8a27196ac1a.png"/>

```
RemovedAlternateItems = 
    List.Alternate(
        Column1,
        2,  // 削除するアイテムの数
        1,  // 保持するアイテムの数
        1   // 削除する最初のアイテム -1
)
```
## List.Transform & Table.FromColumns

```
TableFromColumns = 
    Table.FromColumns(
        List.Transform(
            {0..2},
            each List.Alternate(
                List.Skip(Source[Column1],_),2,1,1)
        )
    )
```
　List.Transformで0から2までの値を `_` に入れて List.Skipで項目をスキップさせます。

## ソースコード
　全体の処理は以下のようになります。

```
let
    // ファイルの読み込み
    Source = Table.FromColumns(
        {
            Lines.FromBinary(
                File.Contents( "** File Name **" ),
                null,
                null,
                932  // シフトJIS
            )
        }
    ),
    // 変換処理
    TableFromColumns = 
        Table.FromColumns(
            List.Transform(
                {0..2},
                each List.Alternate(
                    List.Skip(Source[Column1],_),2,1,1)
            )
        )
        
in
    TableFromColumns
```