Apexでオブジェクトの定義情報を参照する ~Salesforce Schema.系 まとめ~

たまに使うたびに調べ直してるのでメモ

## オブジェクトの情報を取得したい

### sObjectTypeの取得
```java:オブジェクトを固定できるとき
sObjectType sObjType = Account.getSObjectType();
```
```java:オブジェクトを固定でき無いとき
Map<String, sObjectType> sObjTypeMap = Schema.getGlobalDescribe().get(sObjectName);
```
```java:レコードIDから
sObjectType sObjType = recordId.getSObjectType();
```

### sObjectTypeの使い方

#### sObjectをnewする
```java:オプションなし
sObject sObj = sObjType.newSObject();
```
```java:IDあり
sObject sObj = sObjType.newSObject(sObjectID);
```
```java:レコードタイプ指定
sObject sObj = sObjType.newSObject(sObjectType.getDescribe().getRecordTypeInfosByDeveloperName().get(recordTypeName), false);
//最終引数は、trueの場合、デフォルト値あり。
```
### DescribeSObjectResultの取得
```java:オブジェクトを固定できるとき
DescribeSObjectResult sObjectDescribe= Account.getSObjectType().getDescribe();
```
```java:オブジェクトを固定でき無い時
DescribeSObjectResult sObjectDescribe= Schema.getGlobalDescribe().get(sObjectName).getDescribe();
```
### DescribeSObjectResultの使い方
#### オブジェクトの情報を参照
```java:レコードIDのプレフィックス
String objPref = sObjectDescribe.getKeyPrefix();
```
```java:表示ラベル
String objLabel = sObjectDescribe.getLabel();
```
```java:API参照名
String objName = sObjectDescribe.getName();
```
#### 実行ユーザのオブジェクトへのアクセス権を確認
```java:作成
Boolean canRead = sObjectDescribe.isCreateable();
```
```java:参照
Boolean canRead = sObjectDescribe.isAccessible();
```
```java:編集
Boolean canRead = sObjectDescribe.isUpdateable();
```
```java:削除
Boolean canRead = sObjectDescribe.isDeletable();`
```
## レコードタイプの情報を取得したい
### RecordTypeInfoの取得
```java:オブジェクトを固定できるとき
Map<Id, RecordTypeInfo> recTypeMap = Account.getSObjectType().getDescribe().getRecordTypeInfosById();//MapのキーはId
Map<String, RecordTypeInfo> recTypeMap = Account.getSObjectType().getDescribe().getRecordTypeInfosByName();//MapのキーはName(表示ラベル)
Map<String, RecordTypeInfo> recTypeMap = Account.getSObjectType().getDescribe().getRecordTypeInfosByDeveloperName();//MapのキーはDeveloperName(Api参照名)
```
```java:オブジェクトを固定でき無い時
Map<Id, RecordTypeInfo> recTypeMap = Schema.getGlobalDescribe().get(sObjectName).getDescribe().getRecordTypeInfosById();//MapのキーはId
Map<String, RecordTypeInfo> recTypeMap = Schema.getGlobalDescribe().get(sObjectName).getDescribe().getRecordTypeInfosByName();//MapのキーはName(表示ラベル)
Map<String, RecordTypeInfo> recTypeMap = Schema.getGlobalDescribe().get(sObjectName).getDescribe().getRecordTypeInfosByDeveloperName();//MapのキーはDeveloperName(Api参照名)
```

### RecordTypeInfoの使い方
#### レコードタイプ情報を参照
```java:レコードタイプ名
String recTypeName = recTypeInfo.getName();
```
```java:レコードタイプID
Id recTypeId = recTypeInfo.getRecordTypeId();
```
```java:DeveloperName
Id recTypeId = recTypeInfo.getDeveloperName();
```
```java:デフォルトレコードタイプか
Boolean isDefRecType = recTypeInfo.isDefaultRecordTypeMapping();
```
```java:実行ユーザが使用可能か
Boolean isAvailable = recTypeInfo.isAvailable();
```

## 項目の情報を取得したい
### DescribeFieldResultの取得
```java:オブジェクト、項目とも固定できるとき
DescribeFieldResult field = Account.Name.getDescribe();
````
```java:特定オブジェクトの全部の項目を取得したい場合。
Map<String, SObjectField> fields = Account.getSObjectType().getDescribe().fields.getMap();
for(SObjectField f : fields.values()) {
    DescribeFieldResult field  = f.getDescribe();
}
````
```java:オブジェクトは固定できるが、項目は固定できないとき
DescribeFieldResult field = Account.getSObjectType().getDescribe().fields.getMap().get(fieldName).getDescribe();
````
```java:オブジェクトも項目も固定できないとき
DescribeFieldResult field = Schema.getGlobalDescribe().get(sObjectName).getDescribe().fields.getMap().get(fieldName).getDescribe();
````

### DescribeFieldResultの使い方
#### 項目の情報を参照
```java:表示ラベル
String fieldLabel = field.getLabel();
```
```java:データ型
DisplayType dispType = field.getType();
```
補足：DisplayType※数式は、戻り値の型になる。

|DisplayType|項目の型|
|---|---|
|String|テキスト、自動採番|
|TextArea|テキストエリア(ロング、リッチ含む)|
|Double|数値|
|Percent|パーセント|
|Currency|通貨|
|Picklist|選択リスト|
|MultiPicklist|複数選択リスト|
|Date|日付|
|Time|時間|
|DateTime|日付/時間|
|Boolean|チェックボックス|
|Phone|電話|
|Email|メール|
|URL|URL|
|Reference|参照関係、主従関係|
|ID|ID|
|Combobox|コンボボックス|
|address|住所|

```java:自動採番か
Boolean isAutoNumber = field.isAutoNumber();
```
```java:数式か
Boolean isCalculated = field.isCalculated();
```
```java:CascadeDeleteされるか(=主従か)
Boolean isCascadeDelete = field.isCascadeDelete();
```
```java:親オブジェクトのsObjectType
SObjectType　sobjType = field.getReferenceTo();
```
```java:子リレーション名
String relationshipName = field.getRelationshipName();
```
```java:文字数
Integer length = field.getLength();
```
```java:桁数(全体)
Integer length = field.getPrecision();
```
```java:桁数(小数点以下)
Integer length = field.getScale();
```
```java:デフォルト値
Object defaultValue = field.getDefaultValue();
```
```java:ヘルプテキスト
String helpText = field.getInlineHelpText();
```
```java:nullが許可されているか(必須の逆)
Boolean isNilable = field.isNillable();
```
```java:ユニークか
Boolean isUnique = field.isUnique();
```
```java:外部IDか
Boolean isExternalID = field.isExternalID();
```

#### アクセス権を確認
```java:参照
boolean isAccessible = field.isAccessible();
```
```java:編集
boolean isUpdateable = field.isUpdateable();
```
```java:作成
boolean isCreateable = field.isCreateable();
```
## 選択リスト値の情報を取得したい
### PicklistEntryの取得
```java:オブジェクト、項目とも固定できるとき
List<Schema.PicklistEntry> picklistEntries= Account.Type.getDescribe().getPicklistValues();
````
```java:オブジェクトは固定できるが、項目は固定できないとき
List<Schema.PicklistEntry> picklistEntries = Account.getSObjectType().getDescribe().fields.getMap().get(fieldName).getDescribe().getPicklistValues();
````
```java:オブジェクトも項目も固定できないとき
List<Schema.PicklistEntry> picklistEntries = Schema.getGlobalDescribe().get(sObjectName).getDescribe().fields.getMap().get(fieldName).getDescribe().getPicklistValues();
````

### PicklistEntryの使い方
```java:表示ラベル
String Label = picklistEntrie.getLabel();
```
```java:API参照名
String Label = picklistEntrie.getValue();
```
```java:デフォルト値かどうか
Boolean isDefaultValue= picklistEntrie.isDefaultValue()
```
```java:有効or無効
Boolean isActive= picklistEntrie.isActive()://※レコードタイプが関係するかは未検証
```

## Visualforceでの$ObjectType
似たようなものなのでついでに。

### オブジェクト
#### オブジェクト情報
```java:表示ラベル名
{!$ObjectType['Account'].Label}
```
```java:API参照名
{!$ObjectType['Account'].Name}
```
```java:プレフィックスコード
{!$ObjectType['Account'].keyPrefix}
```

#### アクセス権
```java:作成
{!$ObjectType['Account'].createable}
```
```java:参照
{!$ObjectType['Account'].accessible}
```
```java:編集
{!$ObjectType['Account'].updateable}
```
```java:削除
{!$ObjectType['Account'].deletable}
```

### 項目
#### 項目情報
```java:表示ラベル
{!$ObjectType['Account'].fields['Name'].Label}
```
```java:API参照名
{!$ObjectType['Account'].fields['Name'].name}
```
```java:空白にできるか(必須の逆)
{!$ObjectType['Account'].fields['Name'].nillable}
```
#### アクセス権
```java:作成
{!$ObjectType['Account'].fields['Name'].createable}
```
```java:参照
{!$ObjectType['Account'].fields['Name'].accessible}
```
```java:編集
{!$ObjectType['Account'].fields['Name'].updateable}
```


##使用例
####IDからオブジェクト名取得
```java
Id recId = 'XXXXXXXXXXXXXXXXXX';
String objName = recId.getSObjectType().getDescribe().getName();
```

####keyPrefix(レコードIDの上3桁)からオブジェクト名取得
上3桁さえ正しければ良いみたい……

```java
String keyPrefix = '001';
String objName = ID.valueOf(keyPrefix + '000000000000').getSObjectType().getDescribe().getName();
```

####オブジェクト名とレコードタイプ名(Developer Name)から、レコードタイプのIDを取得
```java
String sObjectName = 'Account';
String recordTypeDeveloperName = 'BusinessAccount'

ID recordTypeId =  Schema.getGlobalDescribe().get(sObjectName).getDescribe().getRecordTypeInfosByDeveloperName().get(recordTypeDeveloperName).getRecordTypeId()
```

####SELECT * 的な
```java
String sObjectName = 'Account';
String query = 'SELECT ';

for(String FieldName : Schema.getGlobalDescribe().get(sObjectName).getDescribe().fields.getMap().KeySet()){
	query += FieldName + ',';
}
query = query.removeEnd(',') + ' FROM ' + sObjectName;

List<sObject> records = Database.query(query);
```