Help us understand the problem. What is going on with this article?

ApexでgetDescribeをもっと簡単に使いたい。

More than 3 years have passed since last update.

getDescribeってたまに使うのですが、コードが長くなってしまうので短くできないかとまとめてみました。

使うときはこんな感じで

String AccountNameLabel = Describer.getFieldLabel('Account', 'name');

こっちをコピーして

Describer.apxc
public class Describer {

    public class DescriberException extends Exception {}

    // オブジェクトタイプから、そのオブジェクトタイプが有効であるか確認する。
    public static Boolean isValidSObjectType(String objType){ 
        Boolean ret = false;
        if(!isNullOrEmpty(objType)){
            ret = Schema.getGlobalDescribe().containsKey(objType);
        }
        o('Describer.isValidSObjectType: object type \'' + objType + '\' is valid? ' + ret);
        return ret;
    }

    // オブジェクトタイプとフィールド名から、そのフィールドがオブジェクトで有効なフィールドであるか確認する。
    public static Boolean isValidFieldName(String objType, String fieldName){
        Boolean ret = false;
        if(isValidSObjectType(objType) && !isNullOrEmpty(fieldName)){
            ret = Schema.getGlobalDescribe().get(objType).getDescribe().fields.getMap().containsKey(fieldName);
        }   
        o('Describer.isValidFieldName: field \'' + fieldName + '\' for object type \'' + objType + '\' is valid? ' + ret);
        return ret;
    }

    // オブジェクトタイプとフィールド名からラベル名を取得する。
    public static String getFieldLabel(String objType, String fieldName){
        return getDescribeFieldResult(objType, fieldName).getLabel();
    }

    // オブジェクトタイプとフィールド名からフィールドタイプを取得する。
    public static Schema.DisplayType getFieldType(String objType, String fieldName){
        return getDescribeFieldResult(objType, fieldName).getType();
    }

    // オブジェクトタイプとフィールド名から関連名を取得する。
    public static String getRelationshipName(String objType, String fieldName){
        Schema.DescribeFieldResult dfr = getDescribeFieldResult(objType, fieldName);
        if(dfr.getType() != Schema.DisplayType.REFERENCE) throw new DescriberException('\''+fieldName + '\' of \'' + objType + '.\' is not a reference type.');
        return dfr.getRelationshipName();
    }

    // オブジェクトタイプとフィールド名から、フィールドが参照型の際に参照先のオブジェクトタイプ(複数)を取得する。
    public static Set<String> getReferenceTo(String objType, String fieldName){
        Schema.DescribeFieldResult dfr = getDescribeFieldResult(objType, fieldName);
        if(dfr.getType() != Schema.DisplayType.REFERENCE) throw new DescriberException('\''+fieldName + '\' of \'' + objType + '.\' is not a reference type.');

        Set<String> ret = new Set<String>();
        List<Schema.SObjectType> objTypeList = dfr.getReferenceTo();
        for(Schema.SObjectType t : objTypeList){
            ret.add(t.getDescribe().getName());
        }
        return ret;
    }

    // オブジェクトタイプと関連名から、関連先のオブジェクトタイプを取得する。
    public static String getChildObjectType(String objType, String relationshipName){
        if(!isValidSObjectType(objType)) throw new DescriberException('\''+objType + '\' is not a valid sObject type.');
        if(!isValidChildRelationshipName(objType, relationshipName)) throw new DescriberException('\'' + relationshipName + '\' is not a valid child relationship name for sObject \'' + objType + '.\'');

        String ret = null;             
        for(Schema.ChildRelationship childRelName : Schema.getGlobalDescribe().get(objType.trim()).getDescribe().getChildRelationships()){
            if(!isNullOrEmpty(childRelName.getRelationshipName()) && childRelName.getrelationshipname().toLowerCase() == relationshipName.toLowerCase()){ 
                ret = childRelName.getChildSObject().getDescribe().getName();
                break;
            }
        }
        return ret;
    }

    // レコードIdから、オブジェクトタイプを取得する。
    public static String getObjectType(String recordId){
        if(!isValidRecordId(recordId)) throw new DescriberException('\'' + recordId + '\' is not a valid record ID.');
        Id recordIdFromString = recordId;
        return recordIdFromString.getSObjectType().getDescribe().getName();
    }

    // レコードIdが、正しいレコードIdかを確認する
    public static Boolean isValidRecordId(String recordId){
        Boolean ret = false;
        ret = !isNullOrEmpty(recordId) && recordId InstanceOf ID ;
        o('Describer.isValidRecordId: record Id \'' + recordId + '\' is valid? ' + ret);
        return ret;
    }

    // オブジェクトタイプと関連名から、その関連名がオブジェクトで有効であるか確認する。
    public static Boolean isValidChildRelationshipName(String objType, String relationshipName){
        Boolean ret = false;
        if(isValidSObjectType(objType) && !isNullOrEmpty(relationshipName)){    
            for(Schema.ChildRelationship childRelName : Schema.getGlobalDescribe().get(objType).getDescribe().getChildRelationships()){
                if(!isNullOrEmpty(childRelName.getRelationshipName()) && childRelName.getRelationshipName().toLowerCase() == relationshipName.toLowerCase()){ 
                    ret = true;
                    break;
                }
            }
        }
        o('Describer.isValidRelationshipName: relationship name \'' + relationshipName + '\' for object type \'' + objType + '\' is valid? ' + ret);
        return ret;
    }

    // オブジェクト名とフィールド名から sObjectField を取得する。
    @testVisible
    private static Schema.DescribeFieldResult getDescribeFieldResult(String objType, String fieldName){
        if(!isValidSObjectType(objType))          throw new DescriberException('\''+objType + '\' is not a valid sObject type.');
        if(!isValidFieldName(objType, fieldName)) throw new DescriberException('\''+fieldName + '\' is not a valid field name for sObject \'' + objType + '.\'');
        return Schema.getGlobalDescribe().get(objType).getDescribe().fields.getMap().get(fieldName).getDescribe();
    }

    // デバッグ用
    // よくわからない時はとりあえず、コメントを消してログに出してみる。ランタイムコストはヤバイ。
    private static void o(Object o){
        //System.debug(JSON.serializePretty(o));
    }

    @testVisible
    private static Boolean isNullOrEmpty(Object o){
        return o == null || String.valueOf(o) == '';
    }
}
hrk623
Salesforceの中の人です。いつもSalesforceハックを探してます。 発言・投稿はすべて個人的なものです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした