Apexで選択リストの候補値とラベルを取得する方法
Apexから選択リスト項目のDescribe情報を取得し、有効な値と表示ラベルだけを画面へ渡す方法を説明します。値セットの変更にコードを直さず追従できます。
なぜDescribeから選択リストを取るのか
選択リストの選択肢をApexやVisualforceにハードコードすると、管理者が値セットを直すたびにコードも直す必要が出てきます。Schema.DescribeFieldResultからその場で選択肢を取れば、値セットの変更に自動で追従します。
ここで取得できるのは、組織全体の選択リストの値です。レコードタイプごとに絞り込んだ値は取得できません。この制限は後で扱います。
取得の流れ
sObjectの型情報から項目のDescribe情報を取り、そこから選択リストのエントリ一覧を取ります。
| メソッド | 返す値 |
|---|---|
getPicklistValues() | Schema.PicklistEntryのリスト。項目のDescribe情報から呼び出します |
getLabel() | 選択リスト項目の表示ラベル |
getValue() | 選択リスト項目の値(API参照名に相当する内部値) |
isActive() | ユーザー画面のドロップダウンに表示してよい項目ならtrue |
isDefaultValue() | 選択リストの既定値ならtrue |
画面にはラベル、内部処理には値を使う。この使い分けが最初のつまずき所です。
Apexクラスの実装
取引先の選択リスト項目Select__cから、有効な値のラベルだけを取り出してVisualforceへ渡すクラスです。
Picklist.page
<apex:page controller="PicklistController" sidebar="false" tabStyle="Account"> <apex:form> <apex:pageBlock> <apex:pageBlockSection columns="1" title="選択リスト値取得"> <apex:outputPanel> <ul> <apex:repeat value="{!pickListLabels}" var="item"> <li><apex:outputText value="{!item}" /></li> </apex:repeat> </ul> </apex:outputPanel> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
取得したラベルをリスト表示するだけのシンプルなVisualforceページです
PicklistController.cls
public with sharing class PicklistController { public List<String> pickListLabels { get; set; } public PicklistController() { this.pickListLabels = new List<String>(); for (Schema.PicklistEntry entry : getPicklistEntries('Account', 'Select__c')) { if (entry.isActive()) { this.pickListLabels.add(entry.getLabel()); } } } private List<Schema.PicklistEntry> getPicklistEntries(String sObjectName, String fieldName) { Schema.SObjectType sObjType = Schema.getGlobalDescribe().get(sObjectName); if (sObjType == null) { return new List<Schema.PicklistEntry>(); } Schema.SObjectField field = sObjType.getDescribe().fields.getMap().get(fieldName); if (field == null) { return new List<Schema.PicklistEntry>(); } return field.getDescribe().getPicklistValues(); } }
取引先の選択リスト項目Select__cから、有効な値のラベルだけを取り出してVisualforceへ渡します
ユーザーへ見せる文字列はgetValue()ではなくgetLabel()にし、isActive()で無効化済みの選択肢を除外しています。sObject名や項目名が存在しないときは、途中で例外にせず空リストを返すようにもしています。
値セットと制限選択リストの注意
選択リストの選択肢は「値セット」で管理されます。グローバル値セットは、複数のオブジェクトで再利用できるかわりに、常に制限選択リストとして働きます。制限選択リストでは、管理者が定義した値以外をAPI経由で保存しようとするとエラーになります。
ここで間違えやすい
| 間違い | 何が起きるか |
|---|---|
isActive()を見ずに全件を画面へ出す | 無効化した選択肢まで一覧に混ざります |
| レコードタイプ別の選択肢だと思い込む | getPicklistValues()は組織全体の値を返します。レコードタイプで絞り込んだ値は取れません |
Schema.getGlobalDescribe()の戻り値をそのまま使う | 存在しないsObject名を渡すとnullが返るので、事前のチェックが必要です |
| 制限選択リストに、定義していない値を保存できると思い込む | 制限選択リストは、一覧にない値の保存をエラーにします |
レコードタイプ別の選択肢が必要な場合、このSchema.DescribeFieldResultの経路では取得できません。Salesforceの開発者向けブログでも、動的Apexによるこの方式は「レコードタイプごとの選択リスト制限に対応していない」制限が明記されており、必要な場合はUI APIの利用が案内されています。
動作確認の流れ
選択リスト項目を用意する
取引先オブジェクトへ選択リスト項目(例:Select__c)を追加し、選択肢と表示ラベルを設定して保存します。
ApexクラスとVisualforceページをデプロイする
上のPicklistController.clsとPicklist.pageをそのまま配置します。
Visualforceページを開いて確認する
ページへアクセスし、選択リストの有効な値だけがラベルで並んでいることを確認します。
確認した環境
- 2026年9月 / Salesforce Summer '26(APIバージョン67.0)時点の公式リファレンスで、DescribeFieldResultとPicklistEntryのメソッド、制限選択リストの仕様を確認しています
まとめ
- 選択リストの値は
Schema.DescribeFieldResult.getPicklistValues()からSchema.PicklistEntryのリストとして取得できます - 画面にはラベル(
getLabel())、内部処理には値(getValue())を使い分けます isActive()で無効化済みの選択肢を除外できます。フィルタしないと一覧に混ざりますgetPicklistValues()が返すのは組織全体の値です。レコードタイプ別の絞り込みにはUI APIなど別の仕組みが要ります- グローバル値セットは常に制限選択リストとして働き、一覧にない値の保存はエラーになります
Salesforceの導入・運用についてご相談ください
導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。