1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Power Query でデータ非正規化

Last updated at Posted at 2020-07-15

Power Queryでデータを集計したら
そのまま単独で印刷向けデータまで変換したいと思うのは世の常で
そこで詰まるのが「部署などのグループ間に隙間を作りたい」という操作
そんな時に悩んで考え付いた手順を吐き出してみたい

注意:出てくるデータがテーブルに入るので
   excel内でそのまま使うのは罫線処理のせいではそのままだと結構厳しいです

全体処理

Power Query ステップ名 逆引き(未完成版)
https://qiita.com/olt_yt/items/679605009b6a180b9cda

これの「は行」の処理を抜き出して
下のJSON化と展開手法を使いコード内にデータを含めてます

テーブルをバイナリ(JSON)化したり、テーブルに戻したり
https://qiita.com/tanuki_phoenix/items/5f9991ac2712f91f5fda

詳細は基本的にコードのコメントに着けてるのでそこを見ながら確認ください
コメントのつけ方はPower Query標準のコードの上側に「//」でつけています


let
    ソース = "7ZdJbsMwDEXv4nUWmodepenCmm6QVdG7l6Rn10HtBEGUohtCoL7Jz+chyvtnc74Yy9j5ogVP54tkJkNGOwuZoG3z1lCyNCdaBI8xGooSYwKlc8ZBbLkjvZYRSrmcBQq0xugirQuKVRyqFapguqs8g+JGpkC72gv0IGWL3pjpnXStS+wuxJhDXy3FqWaRpMdew1CTK9ILHWJfk7Hm67SThBVHSBidYXqVk6OCEI1RAlvIMLSwSSmqDMa1YqR0NIQOt3La0xfGtNfJTRWWtO6e6J/0mvSofw3SkFTTKJ0sosBnWHswufXWQxdyrbaoHKaucoE6hrOyjzHuDsrf/a+/D3pEB3fDzDseqFnV3Xgd9o/7Nv9tcnU/nXVw3fJ21/PnDp2SuslM2X7OrLv5N+koDzBJPMq4hd3HMT2HvOalvYtNOMJGlZRwSsaJhx2ogBU8w3lmf7reogWLMGkyu85scVIUCrZM5jtPlpPbJaGl25XyoeTg8s23TLKW8tl3VOpjtnZYC7nOuw0R3lZtiqiP3Fwz+cSMF8/n17crbvR47X/gcymqzALuqjT3WQtFzRXkvROpYn7tPn4f3w==",
    // データ展開部
    X1 = Binary.FromText(ソース),
    X2 = Binary.Decompress(X1,Compression.Deflate),
    X3 = Table.FromRecords(Json.Document(X2,932)),

    //データ読み込み完了以下本体処理
    //テーブルを作るためにグループ化
    グループ化された行 = Table.Group(X3, {"最初の文字"}, {{"Data", each _, type table}}),

    //最初の文字の前後に文字を追加し、後段処理で分割の種にする
    追加されたプレフィックス = Table.TransformColumns(グループ化された行, {{"最初の文字", each "_" & _, type text}}),
    追加されたサフィックス = Table.TransformColumns(追加されたプレフィックス, {{"最初の文字", each _ & "@", type text}}),

    //<主題部>ここでテーブルの先頭に直接入力から生成しているテーブルを追加している
    //今回は横ぬきの逆操作のために、「最初の文字」列の内容を使用
    //★★ここで新旧テーブルを確認する★★
    追加されたカスタム = Table.AddColumn(追加されたサフィックス, "カスタム", each Table.Combine({Table.FromRecords({[ステップ表記 = [最初の文字]]}),[Data]})),
   //不要データを削除
    削除された他の列 = Table.SelectColumns(追加されたカスタム,{"カスタム"}),
    //テーブル展開
    #"展開された カスタム" = Table.ExpandTableColumn(削除された他の列, "カスタム", {"ステップ表記", "タブ", "大区分", "ボタン", "▼"}, {"ステップ表記", "タブ", "大区分", "ボタン", "▼"}),
    //結合してマークダウンの表形式へ
    結合された列 = Table.CombineColumns(#"展開された カスタム",{"ステップ表記", "タブ", "大区分", "ボタン", "▼"},Combiner.CombineTextByDelimiter("|", QuoteStyle.None),"結合済み"),
    //サフィックスで追加した@を置換して、リストヘッダを作成
    置き換えられた値 = Table.ReplaceValue(結合された列,"@||||","__ステップ表記|タブ|大区分|ボタン|▼|_|---|---|---|---|---|",Replacer.ReplaceText,{"結合済み"}),

    //プリフィクス、サフィックスあたりで追加した「_」を種に行方向に分割
    区切り記号による列の分割 = Table.ExpandListColumn(Table.TransformColumns(置き換えられた値, {{"結合済み", Splitter.SplitTextByDelimiter("_", QuoteStyle.Csv), let itemType = (type nullable text) meta [Serialized.Text = true] in type {itemType}}}), "結合済み")
in
    区切り記号による列の分割

重要箇所の詳細解説

「{[ステップ表記 = [最初の文字]]}」ここで1データしか持ってないrecordを作り、それをTable.FromRecordsでテーブルに変換し
Table.Combineを使って元のテーブルにくっつけるという処理をしてる
image.png

Table.FirstN(Table.Combine({Table.FromRecords({[ステップ表記 = [あいうえお]]}),[#"テーブル3 (2)"],Table.Repeat(Table.FromRecords({[ステップ表記 =""]}),10)}))
こんな感じで
Table.FromRecords→空白行直接生成
Table.Repeat→空白行を必要数増やす
Table.FirstN→テーブルの上x行抜き出す
という手順でグループごとに行数をまとめることも可能
image.png

プリフィックス、サフィックスで分割

コード内でプリフィックス、サフィックスで分割記号入れて行増やす方法もしていますが
基本的にどんなところでも実行可能ですが
指定のところを増やすには条件列などの他の作業を経由しないといけない事や
管理が難しいので状況次第で使い分けてください

おまけ

最終的にリスト的なものを吐き出す時に下記図のように
条件づき書式で「;;;↳」のような表示形式にすると
上下が同じ文字なら「↳」二置き換わるようにできたりします
image.png

結果

ステップ表記 タブ 大区分 ボタン
反転された行 変換 テーブル 行の反転  

ステップ表記 タブ 大区分 ボタン
日付と時刻の組み合わせ 変換 日付と時刻の列 日付 日付と時刻の組み合わせ
日付と時刻の組み合わせ 変換 日付と時刻の列 時刻 日付と時刻の組み合わせ
ピボット解除されたほかの列 変換 任意の列 列のピボット解除 その他の列のピボット解除
ピボット解除された列 変換 任意の列 列のピボット解除  
ピボット解除された列 変換 任意の列 列のピボット解除 列のピボット解除
ピボットされた列 変換 任意の列 列ピボット  

ステップ表記 タブ 大区分 ボタン
変更された型 変換 任意の列 データ型の検出  

ステップ表記 タブ 大区分 ボタン
保持した重複データ ホーム 行の削減 行の保持 重複の保持
保存されたエラー ホーム 行の削減 行の保持 エラーの保持
保存された行範囲 ホーム 行の削減 行の保持 行の範囲を保持
保存された最後の行 ホーム 行の削減 行の保持 下位の行を保持
保存された先頭行 ホーム 行の削減 行の保持 上位の行を保持
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?