テクテク日記

テクテク=テクノロジー&一歩ずつ(テクテク)

データフロー(Power Query Online)④(おまけ)

以前のブログでデータフローの更新について紹介しました。更新履歴を可視化したpbixについて具体的に解説しませんでしたが、今回はこれについて少し改善された点も含めて簡単に紹介したいと思います。

言語選択後のエラー

上記記事の最後「Q4: データフローの更新履歴をダウンロードして確認したら、文字化けしてました」という部分について、更新用のテンプレートを載せましたが、pbixで他言語を選択すると、テーブルビジュアルが壊れてしまうことを言及しました。これは、Power BIがダイナミックに日本語⇔英語のヘッダー名の切替を行い、ビジュアルに切替後の名前を残すことができない制限によって発生するものとなります。

これに対処するためには、もう一度全ての列をドラッグ&ドロップする必要がありましたが、以下2つの方法で対処が可能となることが分かりました。

カスタムテーブルビジュアル(非推奨)

まずはカスタムテーブルによるタイトルをダイナミックに変更するやり方ですが、具体的には下記Hernanさんのブログを参考にしました(面識はないですが、Hernanさん謝謝)。

medium.com

このやり方のポイントは以下4つ

  • カスタムビジュアルを使用
  • ヘッダーを設定した言語に自由に切り替えることが可能
  • ヘッダーを他言語に切り替えても、コンテンツの言語は変わらない
  • ヘッダー数が多いと、列名がつぶれて出てしまう

最後の2つはマイナス要素となってしまうので、あまり使い勝手が良いとは言えないですが、中身の言語を変更する必要がなく、かつヘッダー数が少ない場合には重宝できるでしょう。

なお、こちらも念のためダウンロードできるようにしておきますが、ポイントは切り替えたい言語のヘッダー名を予め準備しておくことです。詳細はHernanさんのブログを参考して頂きたいのですが、ヘッダーの準備は下図のようになります。

>>ダウンロード

上記ダウンロードリンクのzipファイル内のDataflow_RefreshHistory_dynamic_header.pbixがこちらの相当します。

Power Queryによる調整(推奨)

Power Queryによって簡単に調整することができることを発見しました。ヘッダーが全てテキストになってしまうという副作用がありますが、ないよりはマシなので、多言語でデータフローの更新履歴を確認するニーズがある場合はこちらを使うと良いでしょう。

youtu.be

上記動画の最初のほうで、パラメータをJPからENに切り替えると、テーブルビジュアルが壊れてしまうところ、その後の操作でENやOTHに切り替えてもビジュアルが壊れていないことが分かります。

Power Queryをそこそこ使ったことがある人ならトリックが分かると思いますが、

ピボット解除

を使っているのがトリックとなります。

Dataflow_RefreshHistory_dynamic_header_pq.pbixを下記ダウンロードURLのZipのRefreshStatusフォルダ内より、パラメータを切り替えて確認してみてください。

>>ダウンロード

ラクリは今まで列を1つずつ指定しないとできなかかったため、列名が変化するとエラーが発生していましたが、マトリックスビジュアルを使って、列を1回だけ指定できるようにしてあげるとヘッダー名の言語に左右されず、ビジュアルも壊れることはありません(下図)。

AfterのAttribute列がマトリックスビジュアルの列に指定するためのデータであり、日本語の場合は上記のようになりますが、英語にするとAfterは以下のように変わります。見ての通り、Attributeは名前が変わらなず、中身だけが英語になっているため、マトリックスビジュアルはヘッダーと中身の両方で英語に更新されるようになります。

let
    ソース = Folder.Files(Path),
    CSVファイル選択 = Table.SelectRows(ソース, each Text.Lower([Extension]) = ".csv"),
    抽出 = Table.AddColumn(CSVファイル選択, "カスタム", each Table.PromoteHeaders(Csv.Document([Content], [Encoding = 65001]))),
    抽出2 = Table.AddColumn(抽出, "カスタム2", each Table.AddColumn([カスタム], "FileName", (x)=>[Name])),
    言語環境チェック = Table.AddColumn(
        抽出2,
        "言語",
        each
            if Table.ColumnNames([カスタム]){1} = "データフロー名" then
                "JP"
            else if Table.ColumnNames([カスタム]){1} = "Dataflow name" then
                "EN"
            else
                "OTH"
    ),
    言語環境選択 = Table.SelectRows(言語環境チェック, each [言語] = Language),
    テーブルの展開 = Table.Combine(言語環境選択[カスタム2]),
    重複履歴削除 = Table.Distinct(テーブルの展開),
    selected_columns = List.Select(Table.ColumnNames(重複履歴削除), each _ <> ""),
    列選択 = Table.SelectColumns(重複履歴削除, selected_columns),
    Schema = Table.Schema(列選択),
    変更された型 = Table.TransformColumns(Schema, {"Position", each Number.ToText(_, "00"), type text}),
    結合された列 = Table.CombineColumns(
        Table.TransformColumnTypes(変更された型, {{"Position", type text}}, "ja-JP"),
        {"Position", "Name"},
        Combiner.CombineTextByDelimiter(". ", QuoteStyle.None),
        "Combined"
    ),
    Renamed = List.Zip({selected_columns, 結合された列[Combined]}),
    列名の変更 = Table.RenameColumns(列選択, Renamed),
    ReplaceNA = Table.ReplaceValue(列名の変更, "NA", null, Replacer.ReplaceValue, 結合された列[Combined]),
    データ型の変更 = Table.TransformColumnTypes(
        ReplaceNA,
        List.Transform(
            結合された列[Combined], 
            each if List.AnyTrue(
                {
                    Text.Contains(_, "00"), 
                    Text.Contains(_, "06"), 
                    Text.Contains(_, "07")
                    }) then {_, type datetime}
            else if List.AnyTrue(
                {
                    Text.Contains(_, "08"), 
                    Text.Contains(_, "12"),
                    Text.Contains(_, "13")
                    }) then {_, type time}
            else if List.AnyTrue(
                {
                    Text.Contains(_, "09"), 
                    Text.Contains(_, "10"), 
                    Text.Contains(_, "11")
                    }) then {_, Int64.Type}
            else {_, type text}
        )
        
    ),
    ReplaceErrors = Table.ReplaceErrorValues(データ型の変更,  List.Transform(結合された列[Combined], each {_, null})),
    Unpivot用 = Table.AddIndexColumn(ReplaceErrors, "#", 1, 1, Int64.Type),
    UNpivoted = Table.UnpivotOtherColumns(Unpivot用, {"#"}, "Attribute", "Values")
in
    UNpivoted

まとめ

  • 言語切替が必要ない場合、ダウンロード先のDataflow_RefreshHistory.pbixを使用
  • 他言語で運用する場合、Dataflow_RefreshHistory_dynamic_header_pq.pbixを使用
  • 今回紹介したやり方はワークアラウンド的なやり方ですが、履歴ログを見る分には十分でしょう