なんでもエクセル(Nandemo Excel)

何でもエクセルでやってしまう そこのあなた。ようこそ

Power Query:縦に並んだデータをグループごとに横に並べる

縦並びのデータを区分を指定して横方向に組み替えしたいという質問は、度々目にするんだけど、グループ化したテーブルに連番列を追加する操作が必要なので、マウスを使った操作だけでは難しい。マウス操作中心でやる方法は、以前に書いたので割愛。

ということで、他の方法はないかと考えてみた。

ひとまず「テーブル1」は既に用意されているものとして、2つの方法を比較してみる。

その1:グループ化でテーブルを作る方法
let     ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],     型の変更 = Table.TransformColumnTypes(ソース, {         {"番号", Int64.Type}, {"商品コード", type text}     }),     行のグループ化 = Table.Group(         型の変更, {"番号"}, {             "テーブル",             each Table.AddIndexColumn(_, "連番", 1, 1),             type table [商品コード=text, 連番=Int64.Type]         }     ),     列の展開 = Table.ExpandTableColumn(行のグループ化, "テーブル", {"商品コード", "連番"}),     列の編集 = Table.TransformColumns(列の展開, {"連番", each Number.ToText(_, "商品コード0"), type text}),     列のピボット = Table.Pivot(列の編集, List.Distinct(列の編集[連番]), "連番", "商品コード") in     列のピボット

こっちは以前に書いた方法と一緒。インデックス列の追加以外はマウス操作で対応できる。

2つ目。テーブルではなくレコードに変換してから展開する。

その2:グループ化でレコードを作る方法
let     ソース = Excel.CurrentWorkbook(){[Name="テーブル1"]}[Content],     型の変更1 = Table.TransformColumnTypes(         ソース, {         {"番号", Int64.Type}, {"商品コード", type text}     }),     行のグループ化 = Table.Group(型の変更1, {"番号"}, {         "レコード", each Table.Transpose(_){1}, type record     }),     見出し = (t)=> List.Transform(         {1..Record.FieldCount(Record.Combine(行のグループ化[レコード]))},         each Number.ToText(_, t)     ),     レコード列の展開 = Table.ExpandRecordColumn(         行のグループ化, "レコード", 見出し("Column0"), 見出し("商品コード0")     ),     型の変更2 = Table.TransformColumnTypes(         レコード列の展開,         List.Transform(見出し("商品コード0"), each {_, type text})     ) in     型の変更2

列を展開するだけでいいから便利。ただ見出しや型の設定が若干面倒かもしれない。

やっぱりテーブルに連番作って「展開」→「見だし編集」→「列のピボット」が一番なのかな。

因みに数式(Microsoft365)でやるなら下記の通り。

その1:数式をオートフィルでコピーでする場合
D2:=UNIQUE(テーブル1[番号]) E2:=TRANSPOSE(FILTER(テーブル1[商品コード],テーブル1[番号]=D2,"")) E2を下方向にオートフィルコピー

ただこれだと「量が増えたら下に数式をコピーし直さないダメじゃん」とか「見出しも欲しいってば」とかいわれそうなので、全部スピルで表示させてみる。

その2:スピルで全部表示させる場合
D2:=LET(     x,UNIQUE(テーブル1[番号]),     y,TEXTJOIN(";",,BYROW(x,LAMBDA(a,         TEXTJOIN(",",,FILTER(テーブル1[商品コード],テーブル1[番号]=a))     ))),     z,IFERROR(TEXTSPLIT(y,",",";"),""),     hd,HSTACK("番号",TEXT(SEQUENCE(,COLUMNS(z)),"商品コード0")),     bd,HSTACK(x,z),     VSTACK(hd,bd) )

文字列として結合してから分割。もうちょっとまともな方法はないものか……