5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PowerQueryで動的に列の分割をしようとしたときの話

5
Last updated at Posted at 2025-12-20

完全に備忘&使いどころは謎ですが、縦に積んだテーブルをPowerQueryで横に積みなおした(この時点で何言ってんだというところですが…)ときのお話です。

背景

アンケートを定期的に実施していて、アンケートテーマによって質問数は様々。
それらをひとつのテーブルに積んでいくために以下のような構成をとっています。

  • アンケートの実施日
  • アンケートのテーマ
  • 回答者の氏名
  • 質問の順番
  • 質問
  • 回答

image.png

データはAIに生成させたサンプルです。実際のアンケートとの関連はありません。

これ👆を…こう👇したい。

image.png

手順

  • 「質問」と「回答」を選択して右クリック「列のマージ」、区切り記号を「タブ」にします。

image.png

image.png

質問と回答がひとつの列にまとまりました。

image.png

  • 「質問の順番」を選択し、「列のピボット」。値列に先ほど作成した「結合済み」、値の集計関数を「集計しない」とします。

image.png

image.png

実施日、テーマ、回答者毎に行がまとまりました。

image.png

  • 以下のステップを追加。「1」の列から順に”質問”と”回答”に分割し、「1_質問」「1_回答」「2_質問」「2_回答」…となるように変形します。
= let
    Source = ピボットされた列,  // 前ステップ
    ExcludeColumns = {"実施日", "テーマ", "回答者"}, // 分割対象にしたくない列を列挙
    ColumnsToSplit = List.RemoveItems(Table.ColumnNames(Source), ExcludeColumns),  // 分割対象外の列を除く

    // 各セルを分割して Record を返す関数(質問/回答)
    SplitCellToRecord = (val as any) as record =>
        let
            txt   = try Text.From(val) otherwise null,
            parts = if txt <> null then Text.Split(txt, "#(tab)") else null,
            cnt   = if parts <> null then List.Count(parts) else 0,
            q     = if cnt > 0 then parts{0} else null,                        // 先頭=質問
            a     = if cnt > 1 then parts{cnt - 1} else null                   // 末尾=回答
        in
            [質問 = q, 回答 = a],

    // すべての分割対象列を同じロジックで処理(Record化→展開)
    Result =
        List.Accumulate(
            ColumnsToSplit,
            Source,
            (state as table, currentColumn as text) =>
                let
                    // 1) 列を Record に変換(質問と回答に分割)
                    Transformed =
                        Table.TransformColumns(
                            state,
                            {
                                { currentColumn, each SplitCellToRecord(_), type record }
                            }
                        ),

                    // 2) Record 列を2列に展開(質問/回答)し、元列名は消える
                    Expanded =
                        Table.ExpandRecordColumn(
                            Transformed,
                            currentColumn,
                            {"質問", "回答"},
                            { currentColumn & "_質問", currentColumn & "_回答" }
                        )
                in
                    Expanded
        )
in
    Result

完成です。

回答者に絞って、各テーマでどのような回答をしているかを並べて見られるようになりました。

image.png

おわりに

列を区切って分割する、それと同時に元の列名を含んだ列名を動的につけ、かつその対象がいくつあるかわからないというところで苦心しましたが、Copilotさんの力を(かなり)借りて、作ることができました。一発で正解は出なくとも、ゼロから作らなくてよいところが本当にありがたい…。できあがったものから関数や使い方を調べることが多くなったこの頃です。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?