8
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?

Dataverseの選択肢列をPower Queryで読み出す

Last updated at Posted at 2025-12-21

この記事はMicrosoft Power BI Advent Calendar 2025に参加しています。
使用しているPower BIは2025/12/21時点の最新バージョンです。

Power PlatformやDynamics365を触ったことのある方はMicrosoft Dataverseも同時に触っていると思います。
今回の記事ではMicrosoft DataverseをPower BIで可視化する際のハードルの一つである選択肢列(Picklist, MultiSelectPicklist)をPower Queryで読み出す方法について書いていきます。

選択肢列について

選択肢列の作成

選択肢列は定義した選択肢のリストに基づく一つ、または複数の値を選択して入力することができます。
これらの選択肢列は環境全体で共有するグローバル選択肢と、個別のテーブルに属するローカル選択肢のどちらかを設定できます。

また、各選択肢にはラベル、値、色が設定できます。
image.png

ここから先は一つの値を選択する選択肢列を単一選択肢列、複数の値を選択する選択肢列を複数選択肢列と呼称します。
また、グローバルとローカルを区別する必要がある場合はグローバル単一選択肢列のように呼称します。
選択肢列に定義された選択肢のグループはPicklistと呼称します。

選択肢列の詳しい説明はMicrosoft Learnの選択肢の作成をご覧ください。
image.png

Dataverseで入力済みの選択肢列が含まれたテーブルがどう表示されるか

Dataverseでは単一選択肢列なら選んだラベルが一つ、複数選択肢列なら選んだラベルが,区切りで表示されます。
この表示はグローバルな列とローカルな列でも差はありません。
image.png

Power Queryで入力済みの選択肢列が含まれたテーブルがどう表示されるか

同じテーブルをPower Queryで読み込んでみました。
image.png
Power Queryではラベルは表示されず、が単一選択肢列なら一つ、複数選択肢列なら,区切りで表示されます。

つまり、選択肢列で定義されたPicklistを別途Power Queryで読み出さない限り、本来表示したいラベルの入力内容をPower BI上で復元することは出来ません。

Power QueryでPicklistを読み出す

Picklistを読み出す方法

Picklistを読み出すにはWeb.Contents関数とDataverseのWebAPIを使用します。
方法としては三つあります。

  1. GlobalOptionSetDefinitionsからグローバル変数を見つける
  2. 特定のテーブルに使われているPicklistを取得する
  3. 特定のテーブルに使われているMultiSelectPicklistを取得する

グローバルとローカル、単一選択肢列と複数選択肢列で使える読み出し方法が異なります。
表にすると以下のようになります。

列の種類/定義する場所 グローバル ローカル
単一選択肢列 1, 2 2
複数選択肢列 1, 3 3

グローバル変数はGlobalOptionSetDefinitionsから単一選択肢列と複数選択肢列をまとめて取得できます。
しかしローカル変数はWebAPIからテーブルを直接指定することでしか取得できず、しかも単一選択肢列と複数選択肢列で取得する方法が異なります。

細かい理屈は専門外なので実際の方法については式と結果だけを書いていきます。

GlobalOptionSetDefinitionsからグローバル変数を見つける

式は以下の通りです。

GlobalOptionSetDefinitions
let
    ソース = Json.Document(Web.Contents("https://" & [DataverseURL] & "/api/data/v9.0/GlobalOptionSetDefinitions")),
    テーブルに変換済み = Table.FromRecords({ソース}),
    #"展開された value" = Table.ExpandListColumn(テーブルに変換済み, "value"),
    #"展開された value1" = Table.ExpandRecordColumn(#"展開された value", "value", {"@odata.type", "ParentOptionSetName", "IsCustomOptionSet", "IsGlobal", "IsManaged", "Name", "ExternalTypeName", "OptionSetType", "IntroducedVersion", "MetadataId", "HasChanged", "Options", "TrueOption", "FalseOption", "Description", "DisplayName", "IsCustomizable"}, {"value.@odata.type", "value.ParentOptionSetName", "value.IsCustomOptionSet", "value.IsGlobal", "value.IsManaged", "value.Name", "value.ExternalTypeName", "value.OptionSetType", "value.IntroducedVersion", "value.MetadataId", "value.HasChanged", "value.Options", "value.TrueOption", "value.FalseOption", "value.Description", "value.DisplayName", "value.IsCustomizable"}),
    フィルターされた行 = Table.SelectRows(#"展開された value1", each ([value.Name] = [選択肢列の名前])),
    #"value Options" = フィルターされた行{0}[value.Options],
    テーブルに変換済み1 = Table.FromList(#"value Options", Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column1" = Table.ExpandRecordColumn(テーブルに変換済み1, "Column1", {"Value", "Color", "IsManaged", "ExternalValue", "ParentValues", "Tag", "IsHidden", "MetadataId", "HasChanged", "Label", "Description"}, {"Value", "Color", "IsManaged", "ExternalValue", "ParentValues", "Tag", "IsHidden", "MetadataId", "HasChanged", "Label", "Description"}),
    削除された他の列 = Table.SelectColumns(#"展開された Column1",{"Value", "Color", "IsHidden", "Label"}),
    #"展開された Label" = Table.ExpandRecordColumn(削除された他の列, "Label", {"UserLocalizedLabel"}, {"UserLocalizedLabel"}),
    #"展開された UserLocalizedLabel" = Table.ExpandRecordColumn(#"展開された Label", "UserLocalizedLabel", {"Label", "LanguageCode"}, {"Label", "LanguageCode"}),
    変更された型 = Table.TransformColumnTypes(#"展開された UserLocalizedLabel",{{"Value", Int64.Type}, {"Color", type text}, {"IsHidden", type logical}, {"Label", type text}, {"LanguageCode", Int64.Type}})
in
    変更された型

[DataverseのURL]と[選択肢列の名前]をそれぞれ置き換えれば読み出せます。

式の結果はこのようになります。
image.png
Valueをキーにマージするなりリレーションシップを組めば選択肢列のラベルを表示することができます。

特定のテーブルに使われているPicklistを取得する

式は以下の通りです。

Local_single_picklist
let
    ソース = Json.Document(Web.Contents("https://" & [DataverseURL] , [RelativePath="/api/data/v9.1/EntityDefinitions(LogicalName='[ローカル選択肢列が格納されているテーブル名]')/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet($select=Options)"])),
    value = ソース[value],
    テーブルに変換済み = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column1" = Table.ExpandRecordColumn(テーブルに変換済み, "Column1", {"LogicalName", "MetadataId", "OptionSet"}, {"LogicalName", "MetadataId", "OptionSet"}),
    フィルターされた行 = Table.SelectRows(#"展開された Column1", each ([LogicalName] = "[読み出したい単一選択肢列名]")),
    OptionSet = フィルターされた行{0}[OptionSet],
    Options = OptionSet[Options],
    テーブルに変換済み1 = Table.FromList(Options, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column2" = Table.ExpandRecordColumn(テーブルに変換済み1, "Column1", {"Value", "Color", "IsManaged", "ExternalValue", "ParentValues", "Tag", "IsHidden", "MetadataId", "HasChanged", "Label", "Description"}, {"Value", "Color", "IsManaged", "ExternalValue", "ParentValues", "Tag", "IsHidden", "MetadataId", "HasChanged", "Label", "Description"}),
    削除された他の列 = Table.SelectColumns(#"展開された Column2",{"Value", "Color", "Label", "IsHidden"}),
    #"展開された Label" = Table.ExpandRecordColumn(削除された他の列, "Label", {"UserLocalizedLabel"}, {"UserLocalizedLabel"}),
    #"展開された UserLocalizedLabel" = Table.ExpandRecordColumn(#"展開された Label", "UserLocalizedLabel", {"Label", "LanguageCode", "IsManaged", "HasChanged"}, {"Label", "LanguageCode", "IsManaged", "HasChanged"}),
    変更された型 = Table.TransformColumnTypes(#"展開された UserLocalizedLabel",{{"Value", Int64.Type}, {"LanguageCode", Int64.Type}, {"Color", type text}, {"Label", type text}, {"IsManaged", type logical}, {"IsHidden", type logical}})
in
    変更された型

[DataverseのURL]と[ローカル選択肢列が格納されているテーブル名]をそれぞれ置き換えれば、展開された Column1ステップでそのテーブルに使われているグローバルとローカルの単一選択肢列が表示されます。
image.png

読み出したい単一選択肢列だけになるようにフィルターをかけます。
image.png

式の結果はこのようになります。
image.png

特定のテーブルに使われているMultiSelectPicklistを取得する

式は以下の通りです。

Local_multiple_picklist
let
    ソース = Json.Document(Web.Contents("https://" & [DataverseURL] , [RelativePath="/api/data/v9.1/EntityDefinitions(LogicalName='[ローカル選択肢列が格納されているテーブル名]')/Attributes/Microsoft.Dynamics.CRM.MultiSelectPicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet($select=Options)"])),
    value = ソース[value],
    テーブルに変換済み = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column1" = Table.ExpandRecordColumn(テーブルに変換済み, "Column1", {"LogicalName", "MetadataId", "OptionSet"}, {"LogicalName", "MetadataId", "OptionSet"}),
    フィルターされた行 = Table.SelectRows(#"展開された Column1", each ([LogicalName] = "[読み出したい複数選択肢列名]")),
    OptionSet = フィルターされた行{0}[OptionSet],
    Options = OptionSet[Options],
    テーブルに変換済み1 = Table.FromList(Options, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column2" = Table.ExpandRecordColumn(テーブルに変換済み1, "Column1", {"Value", "Color", "IsManaged", "ExternalValue", "ParentValues", "Tag", "IsHidden", "MetadataId", "HasChanged", "Label", "Description"}, {"Value", "Color", "IsManaged", "ExternalValue", "ParentValues", "Tag", "IsHidden", "MetadataId", "HasChanged", "Label", "Description"}),
    削除された他の列 = Table.SelectColumns(#"展開された Column2",{"Value", "Color", "Label", "IsHidden"}),
    #"展開された Label" = Table.ExpandRecordColumn(削除された他の列, "Label", {"UserLocalizedLabel"}, {"UserLocalizedLabel"}),
    #"展開された UserLocalizedLabel" = Table.ExpandRecordColumn(#"展開された Label", "UserLocalizedLabel", {"Label", "LanguageCode", "IsManaged", "HasChanged"}, {"Label", "LanguageCode", "IsManaged", "HasChanged"}),
    変更された型 = Table.TransformColumnTypes(#"展開された UserLocalizedLabel",{{"Value", Int64.Type}, {"LanguageCode", Int64.Type}, {"Color", type text}, {"Label", type text}, {"IsManaged", type logical}, {"IsHidden", type logical}})
in
    変更された型

単一選択肢列を読み出す時と同じように、[DataverseのURL]と[ローカル選択肢列が格納されているテーブル名]をそれぞれ置き換えれば、展開された Column1ステップでそのテーブルに使われているグローバルとローカルの複数選択肢列が表示されます。

後の手順も一緒です。

単一選択肢列と複数選択肢列を読み出す時の違い

違いはAPIで読み出すAttributesだけです。

単一選択肢列
Microsoft.Dynamics.CRM.PicklistAttributeMetadata

複数選択肢
Microsoft.Dynamics.CRM.MultiSelectPicklistAttributeMetadata

まとめ

とても面倒

選択肢列はDataverseでよく使われる要素でありながら、なんとPower Queryで読み出す方法の書かれたリファレンスがLearnにありません。

Dataverseを推すならもっと簡単に読み出せるようにして欲しいですね。

すごく面倒

後述の参考にした情報などを探さず独力で出来た人はすごいと思います。

参考にした情報

https://hatfullofdata.blog/power-bi-dataverse-choices-and-choice-column/
https://community.fabric.microsoft.com/t5/Power-Query/Getting-Local-Choice-column-labels-Multi-select/td-p/3595704
https://gist.github.com/expiscornovus/55439b541ed0dc97a597ff16ba3d8ea0

8
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
8
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?