- リンクを取得
- ×
- メール
- 他のアプリ
- リンクを取得
- ×
- メール
- 他のアプリ
SalesforceでRecord Typeを動的に取得および利用する方法
Salesforceでは、Record Typeを正確に取得するための戦略が重要です。特にAppExchangeアプリのような強力なアプリケーションを開発する際には、IDやNameを直接参照するのではなく、DeveloperNameを使用してRecord Typeを識別することが推奨されます。以下に、Record Typeを動的に取得し、環境やユーザー設定に依存しない方法を詳しく説明します。
1. なぜDeveloperNameを使用するのか
- Idの問題: Record TypeのIDは環境ごとに異なるため、特定のIDに依存するコードは移植性がありません。
- Nameの問題: Nameはユーザーの言語やローカライズ設定に基づいて変化するため、信頼できる識別子として使用できません。
- DeveloperNameの利点: 変更不可能な一意の識別子であり、どの環境でも同じ値を保持します。
2. 動的なRecord Type取得メソッド
以下は、指定したオブジェクトの利用可能なRecord TypeをDeveloperNameで動的に取得するユーティリティメソッドの例です。このメソッドはキャッシュを活用して効率を向上させています。
public class Utils { // Record types cache private static Map<Schema.SObjectType, Map<String, Id>> rtypesCache; private static List<SObject> results; static { rtypesCache = new Map<Schema.SObjectType, Map<String, Id>>(); results = new List<SObject>(); } /** * 指定されたオブジェクトタイプの利用可能なRecordTypeを取得する * @param token Schema.SObjectType * @return Map<String, Id> DeveloperNameをキーとするRecordType IDのマップ */ public static Map<String, Id> getRecordTypeMapForObjectGeneric(Schema.SObjectType token) { // キャッシュ確認 Map<String, Id> mapRecordTypes = rtypesCache.get(token); if (mapRecordTypes != null) { return mapRecordTypes; } mapRecordTypes = new Map<String, Id>(); rtypesCache.put(token, mapRecordTypes); // Describe情報を取得 Schema.DescribeSObjectResult obj = token.getDescribe(); // RecordTypeをSOQLで取得 if (results.isEmpty()) { String soql = 'SELECT Id, DeveloperName, sObjectType FROM RecordType WHERE IsActive = TRUE'; try { results = Database.query(soql); } catch (Exception ex) { results = new List<SObject>(); } } // RecordTypeInfoを取得し、ユーザーに利用可能なものをフィルタリング Map<Id, Schema.RecordTypeInfo> recordTypeInfos = obj.getRecordTypeInfosByID(); for (SObject rt : results) { if (recordTypeInfos.containsKey(rt.Id) && recordTypeInfos.get(rt.Id).isAvailable()) { mapRecordTypes.put(String.valueOf(rt.get('DeveloperName')), rt.Id); } } return mapRecordTypes; } }
3. 使用例
以下のコードは、`Account`オブジェクトのRecord Typeを動的に割り当てる例です。
// Utilsクラスを使用してAccountのRecordTypeを取得 Map<String, Id> accountTypes = Utils.getRecordTypeMapForObjectGeneric(Account.SObjectType); // 各RecordTypeのDeveloperNameとIdをデバッグ出力 for (String developerName : accountTypes.keySet()) { System.debug('RecordType DeveloperName: ' + developerName + ', Id: ' + accountTypes.get(developerName)); } // 特定の条件に基づいてRecordTypeを利用 if (accountTypes.containsKey('Really_Stinking_Big_Account')) { System.debug('RecordType "Really_Stinking_Big_Account" is available with Id: ' + accountTypes.get('Really_Stinking_Big_Account')); } else { System.debug('RecordType "Really_Stinking_Big_Account" is not available.'); }
4. この方法の利点
- 移植性の高さ: DeveloperNameを使用することで、どの環境でも正確にRecord Typeを特定可能。
- ユーザーや環境に依存しない: `isAvailable`プロパティを活用して、実行中のユーザーに利用可能なRecord Typeのみを使用。
- AppExchange対応: 動的SOQLを利用するため、Record TypeをサポートしないProfessional EditionやGroup Editionにも対応。
- パフォーマンス: キャッシュを利用してクエリ回数を削減。
まとめ
このアプローチにより、Salesforceアプリは柔軟性と堅牢性を備えた設計が可能になります。特に複雑な権限管理や多言語対応が求められる場合に効果的です。
コメント
コメントを投稿