この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

$ObjectType を使用したスキーマ詳細への動的参照

$ObjectType グローバル変数を使用すると、組織のオブジェクトに関するさまざまなスキーマ情報にアクセスできます。たとえば、オブジェクトの項目の名前、表示ラベル、データ型の参照に使用します。
$ObjectType は、「深い」グローバル変数であり、次のような「二重に動的」な参照に使用することができます。
1$ObjectType[sObjectName].fields[fieldName].Type
次の例では、動的グローバル変数を使用して一般的なオブジェクトビューアを提供します。最初に、DynamicObjectHandler という名前で新しいコントローラ (拡張ではない) を作成します。
1swfobject.registerObject("clippy.codeblock-1", "9");public class DynamicObjectHandler {
2
3    // This class acts as a controller for the DynamicObjectViewer component
4    
5    private String objType;
6    private List<String> accessibleFields;
7
8    public sObject obj { 
9        get; 
10        set {
11	          setObjectType(value);
12	          discoverAccessibleFields(value);
13	          obj = reloadObjectWithAllFieldData();
14        } 
15    }
16    
17    // The sObject type as a string
18    public String getObjectType() {
19    	  return(this.objType);
20    }
21    public String setObjectType(sObject newObj) {
22        this.objType = newObj.getSObjectType().getDescribe().getName();
23        return(this.objType);
24    }
25    
26    // List of accessible fields on the sObject
27    public List<String> getAccessibleFields() {
28     	return(this.accessibleFields);
29    }
30    
31    private void discoverAccessibleFields(sObject newObj) {
32        this.accessibleFields = new List<String>();
33        Map<String, Schema.SobjectField> fields = 
34            newObj.getSObjectType().getDescribe().fields.getMap();
35        for (String s : fields.keySet()) {
36            if ((s != 'Name') && (fields.get(s).getDescribe().isAccessible())) {
37                this.accessibleFields.add(s);
38            }
39        }
40    }
41    
42    private sObject reloadObjectWithAllFieldData() {
43        String qid = ApexPages.currentPage().getParameters().get('id');
44        String theQuery = 'SELECT ' + joinList(getAccessibleFields(), ', ') + 
45                          ' FROM ' + getObjectType() + 
46                          ' WHERE Id = :qid';
47        return(Database.query(theQuery));    	
48    }
49    
50    // Join an Apex List of fields into a SELECT fields list string
51    private static String joinList(List<String> theList, String separator) {
52
53        if (theList == null)   { return null; }
54        if (separator == null) { separator = ''; }
55
56        String joined = '';
57        Boolean firstItem = true;
58        for (String item : theList) {
59            if(null != item) {
60                if(firstItem){ firstItem = false; }
61                else { joined += separator; }
62                joined += item;
63            }
64        }
65        return joined;
66    }
67}
このコントローラでは、次の点に留意してください。
  • Visualforce コンポーネントはコントローラ拡張を使用できません。代わりに、このクラスはコントローラとして記述されます。コンストラクタは定義されないため、このクラスではデフォルトのコンストラクタが使用されます。
  • オブジェクトのメタデータを収集するには、コントローラでオブジェクトを把握している必要があります。Visualforce コンストラクタは引数を取れないため、インスタンス化時に目的のオブジェクトを知る方法がありません。代わりに、公開プロパティ obj を設定することで、メタデータ検出がトリガされます。
  • このクラスでは複数のメソッドが、前の例より若干異なる方法でシステムスキーマ検出メソッドを使用しています。
次の例は、オブジェクトに関するスキーマ情報と、クエリされるレコードの特定の値を表示する Visualforce コンポーネントです。次のコードを使用し、DynamicObjectViewer という名前で新規 Visualforce コンポーネントを作成します。
1swfobject.registerObject("clippy.codeblock-2", "9");<apex:component controller="DynamicObjectHandler">
2    <apex:attribute name="rec" type="sObject" required="true"
3        description="The object to be displayed." assignTo="{!obj}"/>
4
5    <apex:form >
6    <apex:pageBlock title="{!objectType}">
7        <apex:pageBlockSection title="Fields" columns="1">
8            <apex:dataTable value="{!accessibleFields}" var="f">
9                <apex:column >
10                    <apex:facet name="header">Label</apex:facet>
11                    <apex:outputText value="{!$ObjectType[objectType].fields[f].Label}"/>
12                </apex:column>
13                <apex:column >
14                    <apex:facet name="header">API Name</apex:facet>
15                    <apex:outputText value="{!$ObjectType[objectType].fields[f].Name}"/>
16                </apex:column>
17                <apex:column >
18                    <apex:facet name="header">Type</apex:facet>
19                    <apex:outputText value="{!$ObjectType[objectType].fields[f].Type}"/>
20                </apex:column>
21                <apex:column >
22                    <apex:facet name="header">Value</apex:facet>
23                    <apex:outputText value="{!obj[f]}"/>
24                </apex:column>
25            </apex:dataTable>
26        </apex:pageBlockSection>
27        
28        <apex:pageBlockSection columns="4">
29            <apex:commandButton value="View"
30                action="{!URLFOR($Action[objectType].View, obj.Id)}"/>
31            <apex:commandButton value="Edit"
32                action="{!URLFOR($Action[objectType].Edit, obj.Id)}"/>
33            <apex:commandButton value="Clone"
34                action="{!URLFOR($Action[objectType].Clone, obj.Id)}"/>
35            <apex:commandButton value="Delete"
36                action="{!URLFOR($Action[objectType].Delete, obj.Id)}"/>
37        </apex:pageBlockSection>
38    </apex:pageBlock>
39    </apex:form>
40    
41</apex:component>
次の点を確認してください。
  • このコンポーネントを使用するページでは、レコードを検索する必要があります。これを行うには、そのオブジェクトに標準コントローラを使用し、URL でレコードの Id を指定します。たとえば、https://<Salesforce_instance>/apex/DynamicContactPage?id=003D000000Q5GHE です。
  • 選択したレコードはすぐにコンポーネントの obj 属性に渡されます。このパラメータは、すべてのオブジェクトメタデータ検出に使用されます。
  • この 3 つの二重に動的な参照が、$ObjectType[objectType].fields[f] で開始し、各項目のメタデータを表示するのに対し、通常の動的参照は項目の実際の値を表示します。
  • データ値の場合、値は、より自然な {!rec[f]} (コンポーネントへのパラメータ) ではなく {!obj[f]} で、コントローラ内で getter メソッドが使用されます。その理由は単純で、obj 属性はすべての項目のデータを読み込むように更新されていますが、rec は標準コントローラで読み込まれたときと同じ状態のままであり、読み込まれるのが Id 項目のみであるためです。
最後に、新しいコンポーネントを使用して、任意の数の単純な Visualforce ページを作成できます。このページは、コンポーネントを使用して、次の 2 つのページのようなレコード詳細およびスキーマ情報ページを表示します。
1swfobject.registerObject("clippy.codeblock-3", "9");<apex:page standardController="Account"> 
2    <c:DynamicObjectViewer rec="{!account}"/>
3</apex:page>
1swfobject.registerObject("clippy.codeblock-4", "9");<apex:page standardController="Contact">
2    <c:DynamicObjectViewer rec="{!contact}"/>
3</apex:page>