この記事は Salesforce Platform Advent Calendar 2019 - Qiita 第4日目の投稿です。
はじめに
Apexでよく使うSchema.系のお話
Salesforceでは、データを取得するにはSOQLのクエリなどで取得しますが、
データではなく、オブジェクトや項目の情報を取得する際には、Schemaを使用し取得します。
初歩的なお話ではありますが、よく使う割にいつも書き方を忘れるので、まとめてみました。
使用するケース
・オブジェクトや項目の表示ラベルを取得
・カスタム項目かどうかを判定
・選択リスト値を取得
・レコードタイプIDを取得
などなど
取引先の「種別」の表示ラベルを取得する例
動的な書き方
Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Type').getDescribe().getLabel()
静的な書き方
Schema.SObjectType.Account.fields.Type.getLabel() // パターン1
Account.Type.getDescribe().getLabel() // パターン2
うーん、動的に書くと長い。。
ひとつずつ紐解いていきましょー!!
全オブジェクトを取得
Schema.getGlobalDescribe()
使い方
Map<String, Schema.SObjectType> soMap = Schema.getGlobalDescribe();
全オブジェクトから指定したオブジェクトを取得
Schema.getGlobalDescribe().get('Account')
使い方
Schema.SObjectType st = Schema.getGlobalDescribe().get('Account');
Schema.SObjectType st = Account.getSObjectType(); // SObjectTypeを取得するのでgetSObjectTypeでも取得可
SObjectの情報を取得
Schema.getGlobalDescribe().get('Account').getDescribe() // 動的な記述
Schema.SObjectType.Account // 静的な記述 パターン1
Account.getSObjectType().getDescribe() // 静的な記述 パターン2
使い方
Schema.DescribeSObjectResult dsr = Schema.getGlobalDescribe().get('Account').getDescribe();
Schema.DescribeSObjectResult dsr = Schema.SObjectType.Account;
Schema.DescribeSObjectResult dsr = Account.getSObjectType().getDescribe();
DescribeSObjectResultからオブジェクトの情報を取得できる
例
dsr.getLabel(); // オブジェクトの表示ラベルをStringで取得
dsr.isCustom(); // カスタムオブジェクトならTrue
dsr.getRecordTypeInfosById(); // 取引先に関連するレコードタイプIDをMapで取得
などなど
Apex 開発者ガイド:DescribeSObjectResult クラス
指定したSObjectの全項目を取得
Schema.getGlobalDescribe().get('Account').getDescribe().fields
Schema.SObjectType.Account.fields
使い方
アクセス不可。fieldsの後には項目メンバー変数名またはgetMapメソッドが続きます。
指定したSObjectの全項目を取得
Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap() // 動的な記述
Schema.SObjectType.Account.fields.getMap() // 静的な記述
使い方
Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap();
Map<String, Schema.SObjectField> fMap = Schema.SObjectType.Account.fields.getMap();
全項目から指定した項目の情報を取得
Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Type').getDescribe() // 動的な記述
Schema.SObjectType.Account.fields.Type // 静的な記述 パターン1
Account.Type.getDescribe() // 静的な記述 パターン2
使い方
Schema.DescribeFieldResult dfr = Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Type').getDescribe();
Schema.DescribeFieldResult dfr = Schema.SObjectType.Account.fields.Type;
Schema.DescribeFieldResult dfr = Account.Type.getDescribe();
DescribeFieldResultから項目の情報を取得できる
例
dfr.getLabel(); // 項目の表示ラベルをStringで取得
dfr.getType(); // 項目のデータ型を取得
dfr.getPicklistValues(); // 選択リストの値を取得
などなど
Apex 開発者ガイド:DescribeFieldResult クラス
↓ てことで、はじめのようになる ↓
動的な書き方
Schema.getGlobalDescribe().get('Account').getDescribe().fields.getMap().get('Type').getDescribe().getLabel()
静的な書き方
Schema.SObjectType.Account.fields.Type.getLabel() // パターン1
Account.Type.getDescribe().getLabel() // パターン2
動的な記述にすることで便利な共通メソッドを使用可能
レコードタイプIDを取得する場合
オブジェクト名とレコードタイプ名を文字列で渡すだけでIDを取得できるメソッド
// レコードタイプIDをdeveloperNameで取得
public static Id getRecordtypeId(String objName, String developerName) {
return Schema.getGlobalDescribe().get(objName).getDescribe().getRecordTypeInfosByDeveloperName().get(developerName).getRecordTypeId();
}
使い方
Id recId = getRecordtypeId('Account', 'TestRecordType1');
※レコードタイプIDの取得などは下記のSOQLで取得可能だが、
SELECT回数のガバナ制限にカウントされるため、上記Schemaにて取得するほうが良い
Id recId = [SELECT Id FROM RecordType WHERE SObjectType = 'Account' and DeveloperName = 'TestRecordType1'];
選択リストの値を取得する場合
オブジェクト名と項目名を文字列で渡すだけで選択リストのListを取得できるメソッド
// 選択リスト項目の選択肢の値を取得
public static List<String> getPicklistValues(String objName, String fieldName) {
List<Schema.PicklistEntry> ple = Schema.getGlobalDescribe().get(objName).getDescribe().fields.getMap().get(fieldName).getDescribe().getPicklistValues();
List<String> sList = new List<String>();
for (Schema.PicklistEntry p : ple) {
sList.add(String.valueOf(p.getLabel())); // 表示ラベル
// sList.add(String.valueOf(p.getValue())); // API参照名
}
return sList;
}
使い方
List<String> plvList = getPicklistValues('Account', 'Type');
まとめ
Apexを書いていてSchemaを使ったことがない人はほとんどいないはず。
ただ書き方いっぱいあるから、混乱してる人もいるはず。
こんなもん開発者ガイドを見りゃいいやん、な話だけど、
開発者ガイドって理解し辛いんだもん。。
ってことで今回は、Schema.系の書き方、いつも忘れちゃうので、まとめてみました。