bull 条件ロジックの場合 (3 項演算子など)コードロジックの各ブランチを実行しますbull 有効な入力および無効な入力を使用してメソッドへのコールを行いますbull エラーが予期されずtryhellipcatchブロックで取得されない限り例外を投げずに正常に完了しますbull 例外を取得するのではなく取得されたすべての例外を必ず処理しますbull Systemassertメソッドを使用してコードが適切に動作することを明らかにしますbull runAsメソッドを使用してさまざまなユーザーコンテキストでアプリケーションをテストしますbull isTestアノテーションを使用しますisTestで指定したクラスは1 MB という Apex スクリプトの組織内
の上限には含まれませんbull 一括トリガ機能を実行しますテスト内で最低 20 件のレコードを使用しますbull ORDER BYキーワードを使用しレコードが予期された順序で返されるようにしますbull レコード ID が順番に並んでいることを想定しません
複数のレコードを同じ要求で挿入しない限りレコード ID は昇順で作成されませんたとえば取引先 Aを作成しID 001D000000IEEmTを受信し取引先 B を作成すると取引先 B の ID は順序が上位になる場合とならない場合があります
bull Apex テスト結果ページにはコードカバー率のセクションがありますこのセクションでは組織のすべてのクラスおよびトリガおよびテストの対象となる各クラスおよびとリガのコードの行の割合を一覧表示しますカバー率の数値をクリックするとページが表示されテストの対象となるクラスまたはトリガのコードの行がすべて青でまたテストの対象外であるコードのすべての行が赤で強調表示されますまたクラスまたはトリガの特定の行がテストで実行された回数も表示されます
- テストクラスで必要なデータを作成しますテストは特定の組織のデータに依存する必要がありません- starttestメソッドをコールする前にすべてのテストデータを作成します- テストがコミットしていないためデータを削除する必要はありません
bull Forcecom IDE ではApex プロジェクトの Read timeout値を増加する必要があります詳細はhttpswikiapexdevnetcomindexphpApex_Toolkit_for_Eclipse を参照してください
bull Salesforcecom ユーザーインターフェースで[すべてのテストを実行] ボタンを使用してすべてのテストを同時に実行する代わりに組織内のクラスを個別にテストする必要があります
bull その他のユーザによるテスト (ページ 132)
テストは1 つのマイル追跡アプリケーションで使用されますアプリケーションの既存のコードは500 未満のマイルが 1 日に入力されることを確認しますプライマリオブジェクトは Mileage__c というカスタムオブジェクトですここに全体のテストクラスを示します次のセクションはコードの特定の部分を行います
isTest private class MileageTrackerTestSuite
static testMethod void runPositiveTestCases()
Double totalMiles = 0 final Double maxtotalMiles = 500 final Double singletotalMiles =300 final Double u2Miles = 100
Setup User User u1 = [select id from User where alias=auser]
Run As U1 SystemRunAs(u1)
Systemdebug(Inserting 300 miles(single record validation))
Mileage__c testMiles1 = new Mileage__c(Miles__c = 300 Date__c = Systemtoday()) inserttestMiles1
validate single insert for(Mileage__c m[SELECT miles__c FROM Mileage__c WHERE createdDate= TODAY and createdById = u1id and miles__c = null]) totalMiles += mmiles__c
SystemassertEquals(singletotalMiles totalMiles)
validate bulk totalMiles = 0 Systemdebug(Inserting 200 mileage records(bulkvalidation))
ListltMileage__cgt testMiles2 = new ListltMileage__cgt() for(integer i=0 ilt200 i++) testMiles2add( new Mileage__c(Miles__c = 1 Date__c = Systemtoday()) )
insert testMiles2
for(Mileage__c m[SELECT miles__c FROM Mileage__c WHERE createdDate = TODAY and createdById= u1id and miles__c = null]) totalMiles += mmiles__c
SystemassertEquals(maxtotalMiles totalMiles)
end RunAs(u1)
validate additional user totalMiles = 0 setup RunAs User u2 = [select id from Userwhere alias=tuser] SystemRunAs(u2)
Mileage__c testMiles3 = new Mileage__c(Miles__c = 100 Date__c = Systemtoday()) inserttestMiles3
for(Mileage__c m[SELECT miles__c FROM Mileage__c WHERE createdDate = TODAY and createdById= u2id and miles__c = null]) totalMiles += mmiles__c validateSystemassertEquals(u2Miles totalMiles)
SystemRunAs(u2)
runPositiveTestCases()
static testMethod void runNegativeTestCases()
User u3 = [select id from User where alias=tuser] SystemRunAs(u3)
Apex のテスト Version 180 | テストの例 | 130
Systemdebug(Inserting a record with 501 miles(negative test case))
Mileage__c testMiles3 = new Mileage__c( Miles__c = 501 Date__c = Systemtoday() )
try insert testMiles3 catch (DmlException e) Assert Error Message Systemassert(egetMessage()contains(Insert failedFirst exception on + row 0 first errorFIELD_CUSTOM_VALIDATION_EXCEPTION + Mileage request exceeds daily limit(500)[Miles__c]) egetMessage() )
Assert field SystemassertEquals(Mileage__cMiles__c egetDmlFields(0)[0])
Assert Status Code SystemassertEquals(FIELD_CUSTOM_VALIDATION_EXCEPTION egetDmlStatusCode(0) ) catch RunAs(u3) runNegativeTestCases()
class MileageTrackerTestSuite
正のテストケース
次では上記のコード特に単一レコードおよび複数レコードの正のテストケースを行います
1 スクリプトの次のステップを示すデバッグログにテキストを追加します
Systemdebug(Inserting 300 more milessingle record validation)
2 Mileage__c オブジェクトを作成しデータベースに挿入します
Mileage__c testMiles1 = new Mileage__c(Miles__c = 300 Date__c = Systemtoday() ) inserttestMiles1
3 挿入されたレコードを返してコードを検証します
for(Mileage__c m[SELECT miles__c FROM Mileage__c WHERE createdDate = TODAY and createdById= createdbyId and miles__c = null]) totalMiles += mmiles__c
4 systemassertEqualsメソッドを使用して期待された結果が返されることを確認します
SystemassertEquals(singletotalMiles totalMiles)
5 次のテストに移る前に合計マイル数を 0 に戻します
totalMiles = 0
6 200 件のレコードの一括挿入を作成してコードを検証します
まずスクリプトの次のステップを示すデバッグログにテキストを追加します
Systemdebug(Inserting 200 Mileage recordsbulk validation)
7 次に 200 件の Mileage__c レコードを挿入します
ListltMileage__cgt testMiles2 = new ListltMileage__cgt() for(integer i=0 ilt200 i++)testMiles2add( new Mileage__c(Miles__c = 1 Date__c = Systemtoday()) ) inserttestMiles2
Apex のテスト Version 180 | テストの例 | 131
8 SystemassertEqualsを使用して期待された結果が返されることを確認します
for(Mileage__c m[SELECT miles__c FROM Mileage__c WHERE createdDate = TODAY and createdById= createdbyId and miles__c = null]) totalMiles += mmiles__c SystemassertEquals(maxtotalMiles totalMiles)
負のテストケース
次は上記のコード特に負のテストケースを行います
1 runNegativeTestCasesという静的テストメソッドを作成します
static testMethod void runNegativeTestCases()
2 スクリプトの次のステップを示すデバッグログにテキストを追加します
Systemdebug(Inserting 501 miles negative test case)
3 501 マイルの Mileage__c record レコードを作成します
Mileage__c testMiles3 = new Mileage__c( Miles__c = 501 Date__c = Systemtoday() )
4 insertステートメントをtrycatchブロック内に配置します検証の例外を取得して生成されたエラーメッセージを確認します
try insert testMiles3 catch (DmlException e)
5 Systemassertおよび SystemassertEqualsを使用してテストを実行します次のコードを以前作成した catchブロックに追加します
Assert Error Message Systemassert(egetMessage()contains(Insert failedFirst exception+ on row 0 first error FIELD_CUSTOM_VALIDATION_EXCEPTION + Mileage request exceedsdaily limit(500) [Miles__c]) egetMessage())
Assert Field SystemassertEquals(Mileage__cMiles__c egetDmlFields(0)[0])
Assert Status Code SystemassertEquals(FIELD_CUSTOM_VALIDATION_EXCEPTION egetDmlStatusCode(0))
セカンドユーザとしてのテスト
次は上記のコード特にセカンドユーザとして実行します
1 次のテストに移る前に合計マイル数を 0 に戻します
totalMiles = 0
2 次のユーザを設定します
User u2 = [select id from User where alias=tuser] SystemRunAs(u2)
Apex のテスト Version 180 | テストの例 | 132
3 スクリプトの次のステップを示すデバッグログにテキストを追加します
Systemdebug(Setting up testing - deleting any mileage records for +UserInfogetUserName() + from today)
4 次に 1 件の Mileage__c レコードを挿入します
Mileage__c testMiles3 = new Mileage__c(Miles__c = 100 Date__c = Systemtoday()) inserttestMiles3
5 挿入されたレコードを返してコードを検証します
for(Mileage__c m[SELECT miles__c FROM Mileage__c WHERE createdDate = TODAY and createdById= u2Id and miles__c = null]) totalMiles += mmiles__c
6 systemassertEqualsメソッドを使用して期待された結果が返されることを確認します
SystemassertEquals(u2Miles totalMiles)
Apex のテスト Version 180 | テストの例 | 133
第 7 章
ダイナミック Apex
ダイナミック Apexによって開発者は以下の能力を供給することによってより柔軟なアプリケーションの作成が可能になります
トピック
bull Apex 定義情報についてbull sObjectとフィールドの定義情報へのアクセス
定義情報 はS オブジェクトと項目プロパティに関する情報を提供しますたとえばS オブジェクトの定義情報であればS オブジェ
bull 動的 SOQLbull 動的 SOSLbull ダイナミック DML
クトの種別が作成や復元などの操作S オブジェクトの名前と表示ラベルS オブジェクトの項目や子オブジェクトなどをサポートするかどうかといった情報です項目の定義情報であればその項目がデフォルト値を持っているか合計数を示す項目か項目の種別は何かといった情報です
定義情報は個別のレコードではなく組織内のobjectsについての情報を提供します
bull ダイナミックSOQLクエリを書く ダイナミックSOSLクエリとダイナミックDML
ダイナミック SOQL および SOSL クエリによりSOQL または SOSLを実行時に文字列として実行できます一方ダイナミック DMLによりレコードを動的に作成しDML を使用してデータベースに挿入できますダイナミック SOQLSOSLおよび DML を使用してユーザ権限をカスタマイズできるだけでなくアプリケーションを組織に合わせて的確にカスタマイズすることもできますこの特性はForcecom AppExchange からインストールされたアプリケーションに便利です
Apex 定義情報について
ApexはsObjectとフィールド定義情報に関して以下の2つのデータ構造を提供します
bull トークン-軽量直列化可能なsObjectへの参照またはコンパイル時に検証されるフィールド可能の参照bull 定義結果-sObjectまたはフィールドに関するすべての定義プロパティを含むオブジェクト定義結果オブジェ
クトは直列化不可能でランタイムで有効です
トークンからその定義結果まで移動するのはまたその逆は簡単ですsObjectとトークンは両方ともトークン用の定義結果を返すメソッドgetDescribeを持っています定義結果においてはgetSObjectTypeとgetSObjectFieldメソッドはsObjectとフィールド用にそれぞれトークンを返します
トークンは軽量なのでそれを使うことによってより速くて効率のよいコードの作成が可能です例えばスクリプトで使用する必要のあるsObjectまたはフィールドのタイプを決定する際にはsObjectまたはフィールドのトークンバージョンを使用してくださいsObjectがContactオブジェクトかどうか決定するためには例えばフィールドがNameフィールドまたはカスタム計算されたフィールドかは等価演算子(==)を使ってトークンを比較することができます
以下のコードはsObjectとフィールドプロパティについての情報にアクセスするためのトークンと定義結果の使い方の一般例を示しています
Create a new account as the generic type sObject sObject s = new Account()
Verify that the generic sObject is an Account sObject Systemassert(sgetsObjectType()== AccountsObjectType)
Get the sObject describe result for the Account object SchemaDescribeSObjectResult r =AccountsObjectTypegetDescribe()
Get the field describe result for the Name field on the Account objectSchemaDescribeFieldResult f = SchemasObjectTypeAccountfieldsName
Verify that the field token is the token for the Name field on an Account objectSystemassert(fgetSObjectField() == AccountName)
Get the field describe result from the token f = fgetSObjectField()getDescribe()
以下のアルゴリズムはApexスクリプト内で定義情報を使って作業可能な方法を示しています
1 組織内のsObject用のトークンのリストとマップを作成します Accessing All sObjects (ページ 138)参照 2 アクセスが必要なObjectを決定します3 sObject用の定義結果を作成します4 必要に応じてsObject用のフィールドトークンのマップを作成します Accessing All Field Describe Results for an
sObject (ページ 138)参照 5 アクセスが必要なスクリプトのフィールドのための定義結果を作成します
定義情報権限を理解する
Apexは通常システムモードで実行されますパッケージに含まれるすべてのクラスとトリガすなわち元々組織にあるものは動的に調べることのできるsObject上に制限を持っていませんこれは元々のスクリプトでは現在のユーザ権限に関わらず組織用のすべてのsObjectのマップを作成可能です
ダイナミック Apex Version 180 | Apex 定義情報について | 135
認定された Apex パートナーによって作成されたマージされたパッケージ内に含まれるForcecom AppExchangeからインストールされるダイナミックApexスクリプトは管理されたパッケージの外の sObject に対して制限されたアクセス権はありませんパートナーは管理されたパッケージの一部として含まれない標準sObjectへのアクセスを許可するためにパッケージ内でAPI Access値を設定可能ですパートナーは標準オブジェクトへのアクセスが要求可能な一方でカスタムオブジェクトは管理されたパッケージの一部として含まれず決してパッケージされたダイナミック Apex スクリプトによって参照されたりアクセスされたりできません
詳細はSalesforcecom オンラインヘルプの「パッケージの API とダイナミック Apex アクセスについて」を参照してください
sObjectトークンを使う
AccountとMyCustomObject__cなどのSObjectはトークンと定義結果情報にアクセスする特殊静的メソッドとメンバー変数を持った静的クラスとして機能します定義結果へのアクセスを得るためにコンパイルタイムにおいてsObjectとフィールド名を明示的に参照する必要があります
sObjectのトークンにアクセスするには以下のメソッドの1つを使ってください
bull AccountなどのsObjectタイプ上のsObjectTypeメンバー変数にアクセスしてくださいbull sObject定義結果sObject変数リストまたはマップ上のgetSObjectTypeメソッドを呼び出してください
SchemaSObjectTypeはsObjectトークン用のデータタイプです
以下の例ではAccount sObject用のトークンが返されます
SchemasObjectType t = AccountsObjectType
以下の例でもAccount sObject用のトークンが返されます
Account A = new Account() SchemasObjectType T = AgetSObjectType()
この例はsObjectまたはsObjectのリストが特定のタイプかどうか決定するために使われます
public class sObjectTest Create a generic sObject variable s SObject s =Databasequery(select id from account limit 1)
Verify if that sObject variable is an Account token SystemassertEquals(sgetSObjectType()AccountsObjectType)
一般的な sObjects のリストを作成 ListltsObjectgt l = new Account[]
Verify if the list of sObjects contains Account tokensSystemassertEquals(lgetSObjectType() AccountsObjectType)
いくつかの標準sObjectはsObjectTypeと呼ばれるフィールドを持っています例えばAssignmentRuleQueueSObjectおよびRecordTypeこれらのタイプのsObjectはトークンの取得に常にgetSObjectTypeメソッドを使いますプロパティを使う場合例えばRecordTypesObjectTypeフィールドが返されます
sObject定義結果を使う
sObjectの定義結果にアクセスするには以下のメソッドの1つを使ってください
bull sObjectトークン上のgetDescribeメソッドを呼び出してくださいbull sObjectの名前と一緒にスキーマsObjectType静的変数を使います例えばSchemasObjectTypeLead
ダイナミック Apex Version 180 | Apex 定義情報について | 136
SchemaDescribeSObjectResultはsObjectトークン用のデータタイプです
以下の例ではsObjectトークン上でgetDescribeを使います
SchemaDescribeSObjectResult D = AccountsObjectTypegetDescribe()
以下の例ではスキーマsObjectType静的メンバー変数を使います
SchemaDescribeSObjectResult D = SchemaSObjectTypeAccount
sObject定義結果に利用可能なメソッドについての詳細はsObject Describe Result Methods (ページ 245)を参照してください
フィールドトークンを使う
項目のトークンにアクセスするには以下のメソッドの1つを使ってください
bull sObject静的タイプの静的メンバー変数名例えばAccountNameにアクセスしてくださいbull 項目定義結果上のgetSObjectFieldメソッドを呼び出します
項目トークンはデータタイプSchemaSObjectFieldを使います
以下の例では項目トークンはAccountオブジェクトのAccountNumber項目用に返されます
SchemaSObjectField F = AccountAccountNumber
以下の例では項目トークンは項目定義結果から返されます
Get the describe result for the Name field on the Account object SchemaDescribeFieldResultf = SchemasObjectTypeAccountfieldsName
Verify that the field token is the token for the Name field on an Account objectSystemassert(fgetSObjectField() == AccountName)
Get the describe result from the token f = fgetSObjectField()getDescribe()
項目定義結果を使う
項目の定義結果にアクセスするには以下のメソッドの1つを使ってください
bull 項目トークン上のgetDescribeメソッドを呼び出してくださいbull sObjectトークンのfieldsメンバー変数に項目メンバー変数 NameBillingCityなど を使ってアクセスし
てください
項目定義結果はデータタイプSchemaDescribeFieldResultを使います
以下の例ではgetDescribeメソッドを使っています
SchemaDescribeFieldResult F = AccountAccountNumbergetDescribe()
この例では以下のfieldsメンバー変数メソッドを使います
SchemaDescribeFieldResult F = SchemaSObjectTypeAccountfieldsName
ダイナミック Apex Version 180 | Apex 定義情報について | 137
上記の例ではシステムは最終メンバー変数 (Name)がコンパイルタイムにおいて指定のsObjectに有効だと認証する特別解析を使いますパーサーがfieldsメンバー変数を見つけると後ろに戻ってsObject (Account)名を見つけfieldsメンバー変数に続く項目名が正当だと認証しますfieldsメンバー変数はこの方式で使われた時のみ機能します
1つのApexスクリプト内にたった10のfieldsメンバー変数ステートメントしか持つことができません
メモ 項目メンバー変数名またはgetMapメソッドのいづれかを使わずにfieldsメンバー変数を使うべきではありませんgetMapについての詳細はAccessing All Field Describe Results for an sObject (ページ138)を参照してください
項目定義結果に利用可能なメソッドについての詳細は「項目定義結果メソッド (ページ 249)」を参照してください
すべてのObjectにアクセスする
スキーマgetGlobalDescribeメソッドを使ってsObjectトークン 値 に対するすべてのsObject名 キー 間の関係を表すマップを返してください例
MapltString SchemaSObjectTypegt gd = SchemagetGlobalDescribe()
マップには以下の特徴があります
bull 権限に基づいて動的すなわち現在組織に利用可能なsObject上でランタイムで生成されますbull sObject名はケースインセンシティブですbull キーは必要に応じて名前空間を使いますbull キーはsObjectがカスタムオブジェクトかどうかを反映します
例えばマップを生成するコードブロックが名前空間N1にありまたsObjectもN1にある場合マップ内のキーはMyObject__cとして表されますしかしながらコードブロックが名前空間N1にありsObjectは名前空間N2にある場合キーはN2__MyObject__cです
さらに標準sObjectは名前空間プレフィックスを持っていません
sObject用のすべての項目定義結果にアクセスする
項目定義結果のgetMapメソッドを使ってsObject用のすべての項目名 キー と項目トークン 値 の間の関係を表すマップを返してください
以下の例では名前で項目にアクセスするのに使用可能なマップを生成します
MapltString SchemaSObjectFieldgt M = SchemaSObjectTypeAccountfieldsgetMap()
メモ このマップの値タイプは項目定義結果ではありません定義結果を使用するととても多くのシステムリソースを使いますそれは適切な項目を探すのに利用可能なトークンのマップです項目を決定したらその定義結果を作成してください
マップには以下の特徴があります
bull 動的でそのsObjectの項目上でランタイムにおいて作成されますbull すべての項目名はケースインセンシティブですbull キーは必要に応じて名前空間を使います
ダイナミック Apex Version 180 | Apex 定義情報について | 138
bull キーは項目がカスタムオブジェクトかどうかを反映します
例えばマップを生成するコードブロックが名前空間N1にありまた項目もN1にある場合マップ内のキーはMyField__cとして表されますしかしながらコードブロックが名前空間N1にあり項目は名前空間N2にある場合キーはN2__MyField__cです
さらに標準項目は名前空間プレフィックスを持っていません
sObject に関連するすべてのカテゴリのアクセス
describeDataCategoryGroupsおよび describeDataCategoryGroupStructuresメソッドを使用して特定のオブジェクトに関連するカテゴリを返します
1 選択したオブジェクトに関連するすべてのカテゴリグループを返します (describeDataCategoryGroups (ページ240) を参照)
2 返されたマップから詳細に検索するカテゴリグループ名と sObject 名を取得します ( SchemaDescribeDataCategoryGroupResult (ページ 240) を参照)
3 カテゴリグループおよび関連するオブジェクトを指定しこのオブジェクトに使用できるカテゴリを取得します ( describeDataCategoryGroupStructures (ページ 241) を参照)
describeDataCategoryGroupStructuresメソッドは指定したカテゴリグループのオブジェクトに使用できるカテゴリを返しますデータカテゴリの詳細はSalesforcecomオンラインヘルプの「データカテゴリとは」を参照してください
次の例ではdescribeDataCategoryGroupSampleメソッドは記事オブジェクトおよび質問オブジェクトに関連するすべてのカテゴリグループを返しますdescribeDataCategoryGroupStructuresメソッドはリージョンカテゴリグループの記事および質問に使用できるすべてのカテゴリを返します記事および質問に関する詳細はSalesforcecom オンラインヘルプ「記事の管理」「Answers の概要」を参照してください
次の例を使用するには下記の手順を実行する必要があります
bull Salesforce Knowledge を有効化するbull Answers 機能を有効化するbull リージョンというデータカテゴリグループを作成するbull リージョンを Answers で使用するデータカテゴリグループとして割り当てるbull リージョンデータカテゴリグループが Salesforce Knowledge に割り当てられていることを確認する
データカテゴリグループの作成についての詳細はSalesforcecomオンラインヘルプの「カテゴリグループの作成と変更」を参照してくださいAnswers の詳細はSalesforcecomオンラインヘルプの「回答の概要」を参照してください
public class DescribeDataCategoryGroupSample private void describeDataCategoryGroupSample()try Creating the list of sobjects to use for the describe call ListltStringgt objType= new ListltStringgt()
objTypeadd(KnowledgeArticleVersion) objTypeadd(Question)
Describe Call ListltSchemaDescribeDataCategoryGroupResultgt describeCategoryResult =SchemadescribeDataCategoryGroups(objType)
Using the results and retrieving the information for(SchemaDescribeDataCategoryGroupResultsingleResult describeCategoryResult) Getting the name of the categorysingleResultgetName()
Getting the name of label singleResultgetLabel()
ダイナミック Apex Version 180 | Apex 定義情報について | 139
Getting description singleResultgetDescription()
Getting the sobject singleResultgetSobject() catch(Exception e)
public class DescribeDataCategoryGroupStructures private voidgetDescribeDataCategoryGroupStructureResults() try Making the call to thedescribeDataCategoryGroups ListltStringgt objType = new ListltStringgt()objTypeadd(KnowledgeArticleVersion) objTypeadd(Question)ListltSchemaDescribeDataCategoryGroupResultgt describeCategoryResult =SchemadescribeDataCategoryGroups(objType)
Creating a list of pair objects to use as a parameter for the describe callListltDataCategoryGroupSobjectTypePairgt pairs = new ListltDataCategoryGroupSobjectTypePairgt()
Looping throught the first describe result to create the list of pairs for the seconddescribe call for(SchemaDescribeDataCategoryGroupResult singleResult describeCategoryResult) DataCategoryGroupSobjectTypePair p = newDataCategoryGroupSobjectTypePair() psetSobject(singleResultgetSobject())psetDataCategoryGroupName(singleResultgetName()) pairsadd(p)
describeDataCategoryGroupStructures() ListltSchemaDescribeDataCategoryGroupStructureResultgtresults = SchemadescribeDataCategoryGroupStructures(pairs false)
Getting data from the result for(SchemaDescribeDataCategoryGroupStructureResultsingleResult results) Get name of the associated Sobject singleResultgetSobject()
Get the name of the data category group singleResultgetName()
Get the name of the label singleResultgetLabel()
Get the description of the data category group singleResultgetDescription()
Get the top level categories DataCategory [] toplevelCategories =singleResultgetTopCategories()
Recursively get all the categories ListltDataCategorygt allCategories =getAllCategories(toplevelCategories) for(DataCategory category allCategories) Getthe name of the category categorygetName()
Get the label of the category categorygetName()
Get the list of sub categories in the category DataCategory [] childCategories =categorygetChildCategories() catch (Exception e)
private DataCategory[] getAllCategories(DataCategory [] categories) if(categoriesisEmpty())return new DataCategory[] else DataCategory category = categories[0] DataCategory[]temp = new DataCategory[]category categoriesremove(0)categoriesaddAll(categorygetChildCategories()) tempaddAll(getAllCategories(categories))return temp
動的 SOQL
動的ク SOQLはApexスクリプトを使ってランタイムにおいて SOQL 文字列の作成を参照します動的 SOQLによってさらに柔軟なアプリケーションの作成が可能になりますたとえばエンドユーザの入力をベースにした検索の作成または幅広い項目名を使ったレコードの更新が可能です
ダイナミック Apex Version 180 | 動的 SOQL | 140
ランタイムにおける動的 SOQLクエリの作成には次の方法の1つでデータベースqueryメソッドを使ってください
bull クエリが1つのレコードを返す時1つのsObjectが返します
sObject S = Databasequery(string_limit_1)
bull クエリが複数のレコードを返す時sObjectsのリストを返します
ListltsObjectgt L = Databasequery(string)
通常の割り当てステートメントと forループにおいてなどインライン SOQL クエリが使用可能な場合はいつでもデータベースqueryメソッドは利用可能です動的 SOQL クエリの処理とほぼ同様に結果は処理されます
動的 SOQL 結果は具体的な sObject として指定可能ですAccount または MyCustomObject__c などまたは一般的な sObject データ型として指定できますランタイムにおいてシステムはクエリのタイプが変数の宣言タイプとマッチしているか認証しますクエリが正しい sObject タイプを返さない場合はランタイムエラーが発生しますこれは一般的な sObject から具体的な sObject をキャストする必要がないことを意味します
動的 SOQLクエリは静的クエリと同じガバナー制限を持っていますガバナー制限の詳細は「実行ガバナーと制限の理解」を参照してください
SOQL クエリ構文の詳細は『Forcecom Web Services API Developers Guide』のwwwsalesforcecomusdeveloperdocsapiindex_CSHhtmsforce_api_calls_soqlhtm を参照してください
SOQL インジェクション
SOQL インジェクションとはSOQL ステートメントをスクリプトに送ることによって意図していなかったユーザがアプリケーションにデータベースメソッドを実行することですこれはアプリケーションが動的 SOQLを構築するためのエンドユーザ入力に依存し入力を適切に処理しない場合はいつでもApexスクリプト内で発生可能です
SOQL注入を防ぐためにはescapeSingleQuotesメソッドを使ってくださいこのメソッドはエスケープキャラクター()を文字列内のユーザからパスされるすべてのシングルクォーテーションマークに追加しますメソッドはすべてのシングルクォーテーションマークがデータベースメソッドの代わりに文字列の囲みとして使われることを確実にします
動的 SOSL
動的 SOSLはApexスクリプトを使ってランタイムにおいてSOSL文字列の作成を参照します動的 SOSLによってさらに柔軟なアプリケーションの作成が可能になりますたとえばエンドユーザの入力をベースにした検索の作成または幅広い項目名を使ったレコードの更新が可能です
動的 SOSLクエリをランタイムにおいて作成するには検索queryメソッドを使ってください例
ListltList ltsObjectgtgt myQuery = searchquery(SOSL_search_string)
ダイナミック Apex Version 180 | 動的 SOSL | 141
以下の例ではシンプルSOSLクエリ文字列を実行しています
String searchquery=FINDEdgeIN ALL FIELDS RETURNING Account(idname)Contact LeadListltListltSObjectgtgtsearchList=searchquery(searchquery)
各リストが特定のsObjectタイプの検索結果を含む場合sObjectのリストに対する動的 SOSLステートメント評価結果リストは常に動的 SOSLクエリにて指定されたのと同じ順番で返されます上記の例よりAccountからの結果が最初次がContactでその次がLeadです
通常の割り当てステートメントとforループにおいてなどインラインSOSLクエリが使用可能な場合はいつでも検索queryメソッドは利用可能です静的SOSLクエリの処理とほぼ同様に結果は処理されます
SOSL クエリはApexクラスおよび特定ブロックでのみサポートされますトリガで SOSL を使用することはできません
動的 SOSLクエリは静的クエリと同じガバナー制限を持っていますガバナー制限の詳細は「実行ガバナーと制限の理解」を参照してください
SOSLクエリ構文の詳細はForcecom Web Services API Developers Guide内のwwwsalesforcecomusdeveloperdocsapiindex_CSHhtmsforce_api_calls_soslhtmを参照してください
SOSL インジェクション
SOSL インジェクションとはSOSL ステートメントをスクリプトに送ることによって意図していなかったユーザがアプリケーションにデータベースメソッドを実行することですこれはアプリケーションが動的 SOSLを構築するためのエンドユーザ入力に依存し入力を適切に処理しない場合はいつでもApexスクリプト内で発生可能です
SOSL注入を防ぐためにはescapeSingleQuotesメソッドを使ってくださいこのメソッドはエスケープキャラクター()を文字列内のユーザからパスされるすべてのシングルクォーテーションマークに追加しますメソッドはすべてのシングルクォーテーションマークがデータベースメソッドの代わりに文字列の囲みとして使われることを確実にします
ダイナミック DML
ランタイムにおける定義情報の問い合わせとSOQLクエリの構築に加えて動的にsObjectを作成しそれをDMLを使ってデータベースに挿入可能です
指定されたタイプの新規sObjectを作成するにはsObjectトークン上でnewSObjectメソッドを使ってくださいトークンには具体的なsObjectタイプ Accountなど を与える必要がある点に注意してください例
Get a new account Account A = new Account() Get the token for the accountSchemasObjectType tokenA = AgetSObjectType() The following produces an error becausethe token is a generic sObject not an Account Account B = tokenAnewSObject() Thefollowing works because the token is cast back into an Account Account B =(Account)tokenAnewSObject()
sObjectトークンtokenAはAccountのトークンですが別にアクセスされるのでsObjectと考えられますnewSObjectメソッドを使うには具体的なsObjectタイプAccountに入れられる必要がありますキャストの詳細についてはクラスとキャスト (ページ 110)を参照してください
ダイナミック Apex Version 180 | ダイナミック DML | 142
newSObjectを使ってIDの指定も可能です例
SObject s = Databasequery(Select Id from account limit 1)[0]getSObjectType()newSObject([SELECT Id FROM Account LIMIT 1][0]id)
項目値を設定する取得する
Stringとして表現されるAPI名または項目のトークンのいづれかを使っている項目の値を設定または取得するためにオブジェクト上のgetとputメソッドを使ってください以下の例では項目AccountNumberのAPI名が使用されます
SObject s = [SELECT accountNumber FROM account LIMIT 1] Object o = sget(AccountNumber)sput(AccountNumber abc)
以下の例では代わりにAccountNumber項目のトークンを使います
SchemaDescribeFieldResult f = SchemasObjectTypeAccountfieldsAccountNumber Sobject s= Databasequery(SELECT AccountNumber FROM Account LIMIT 1) sput(fgetsObjectField()12345)
ObjectスカラデータタイプはsObject上の項目値を設定または取得するために総称データタイプとして使用可能ですこれはanyType項目タイプと同等ですObjectデータタイプはsObjectの総称的タイプとして使用可能なsObjectデータタイプとは違う点に注意してください
メモ 項目に割り当てた文字列値が長すぎる場合API バージョン 150 以上を使用して保存 (コンパイル)した Apex クラスにはランタイムエラーが発生します
外部キーを設定する取得する
ApexはAPIと同じ方法で名前 または外部ID による外部キーの投入をサポートします外部キーのスカラID値を設定または取得するにはgetまたはputメソッドを使ってください
外部キーに関連付けられたrecordを設定または取得するにはgetSObjectおよびputSObjectメソッドを使ってくださいこれらのメソッドはObjectではなくsObjectデータタイプで使用されなければならないことに注意してください例
SObject c = Databasequery(SELECT Id FirstName AccountId AccountName FROM Contact LIMIT1) SObject a = cgetSObject(Account)
子sObjectで作業中に親sObject値用の外部IDを指定する必要はありません親sObjectにIDを与えた場合はDML操作によって無視されますApexは外部キーが常に投入されたIDとともに親オブジェクトを返す関係SOQLクエリを通じて投入されると仮定していますIDがない場合は子オブジェクトとともに使ってください
例えばカスタムオブジェクトC1が子カスタムオブジェクトC2にリンクする外部キーc2__cを持っているとしますC1オブジェクトを作成し 値c2__rに割り当てられた 「xxx」と名づけられたC2レコードに関連付けたいとします親から子への関係を通じて投入されるので「xxx」レコードのIDは不要です例
insert new C1__c(name = x c2__r = new C2(name = xxx))
c2__rのIDに値を割り当てた場合それは無視されますIDがない場合それをレコードではなくオブジェクト (c2__c)に割り当ててください
ダイナミック Apex Version 180 | ダイナミック DML | 143
ダイナミックApexを使用して外部キーにアクセスすることもできます次の例はダイナミックApexを使用して親子関係のサブクエリから値を取得する方法について示しています
String queryString = SELECT Id Name (SELECT FirstName LastName from Contacts LIMIT 1)from Account SObject[] queryParentObject = Databasequery(queryString)
for (SObject parentRecord queryParentObject) Object ParentFieldValue =parentRecordget(Name) Prevent a null relationship from being accessed SObject[]childRecordsFromParent = parentRecordgetSObjects(Contacts) if (childRecordsFromParent= null) for (SObject childRecord childRecordsFromParent) Object ChildFieldValue1 =childRecordget(FirstName) Object ChildFieldValue2 = childRecordget(LastName)Systemdebug(Account Name + ParentFieldValue + Contact Name + ChildFieldValue1 + + ChildFieldValue2)
ダイナミック Apex Version 180 | ダイナミック DML | 144
第 8 章
Apex の一括処理
開発者はApexの一括処理を使用しForcecomプラットフォームで長時間にわたり実行される複雑なプロセスを構築できますたとえば特定
トピック
bull Apex の一括処理の使用 の日付を越えたレコードを検索してアーカイブに追加する夜間に実行bull Apex による共有管理について されるアーカイブソリューションを構築できますまたは毎晩すべて
の取引先と商談を探索しカスタム条件に基づき必要に応じて再割り当てをするデータの整理処理を構築できます
Apex の一括処理はインターフェースとして公開され開発者によって実行される必要があります一括処理ジョブはApex を使用して実行時に起動できます
キュー内または有効な一括処理ジョブを 5 件作成できますSalesforcecomの [スケジュール済みジョブ] を表示してまたはプログラムでForcecomWeb サービス API を使用して AsyncapexJob オブジェクトを問い合わせて現在のカウントを評価できます
警告 一括ジョブをトリガから開始する場合は細心の注意を払ってくださいトリガは 5 件を超える一括ジョブを追加しないようにする必要があります具体的にはAPIの一括更新インポートウィザードユーザインターフェースを使用した一括レコードの変更および複数のレコードを一度に更新できるすべてのケースなどです
一括ジョブはApex スケジューラを使用して特定の時刻に実行されるようプログラム的にスケジュールしたりまたは Salesforcecom ユーザインターフェースを使用して [Apex をスケジュール] ページを使用してスケジュールすることもできます[Apex をスケジュール] の詳細はSalesforcecom オンラインヘルプの「Apex のスケジュール」を参照してください
Apex の一括インターフェースはApex による共有管理の再適用にも使用されます
一括ジョブの詳細は「Apexの一括処理の使用 (ページ 146)」を参照してください
Apex による共有管理についての詳細は「Apex による共有管理について (ページ 153)」を参照してください
Apex の一括処理の使用
Apexの一括処理を使用するにはSalesforcecom提供のインターフェースDatabaseBatchableを実装するApexクラスを記述しプログラムに基づいてクラスを開始する必要があります
Apex の一括ジョブの実行を監視または停止するには[設定] [監視] [Apex] [ジョブ] をクリックします詳細はSalesforcecom オンラインヘルプの「Apex ジョブキュー」を参照してください
DatabaseBatchableインターフェースの実装
DatabaseBatchableインターフェースには実装しなければならない 3 つのメソッドが含まれています
bull startメソッド
global (DatabaseQueryLocator | IterableltsObjectgt) start(DatabaseBatchableContext bc)
startメソッドはApexの一括処理ジョブの開始時に呼び出されます startメソッドはインターフェースメソッド executeに渡すレコードまたはオブジェクトを収集するために使用します このメソッドはDatabaseQueryLocator オブジェクトまたはジョブに渡されるレコードまたはオブジェクトを含む反復可能オブジェクトを返します
DatabaseQueryLocator オブジェクトは一括処理ジョブで使用するオブジェクトの範囲を作成する単純なクエリ (SELECT) を使用する場合に使用します QueryLocator オブジェクトを使用する場合SOQL クエリによって取得されるレコード合計数に対するガバナ制限は無視されます たとえばAccount オブジェクトのApex の一括処理ジョブは組織内のすべての取引先レコード (最大 5000 万件のレコード) の QueryLocator を返すことができますもう 1 つの例としては組織内のすべての取引先レコードの QueryLocator を返す Contactオブジェクトの共有再適用があります
反復可能オブジェクトは一括処理ジョブの複雑な範囲を作成する必要がある場合に使用します またリスト全体を反復する独自のカスタムプロセスを作成するために反復可能オブジェクトを使用することもできます
重要 反復可能オブジェクトを使用する場合SOQL クエリによって取得されるレコード合計数に対するガバナ制限はそのまま適用されます
bull executeメソッド
global void execute(DatabaseBatchableContext BC listltPgt)
executeメソッドはメソッドに渡されるレコードの各一括処理に対して呼び出されますデータのそれぞれの塊に必要な処理をすべて実行する場合にこのメソッドを使用します
このメソッドは次を取ります
- DatabaseBatchableContext オブジェクトへの参照- ListltsObjectgtなどの sObjects のリストまたはパラメータ化された型のリスト DatabaseQueryLocator
を使用する場合は返されたリストを使用する必要があります
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 146
bull finishメソッド
global void finish(DatabaseBatchableContext BC)
finishメソッドはすべてのバッチが処理された後にコールされます確認の電子メールの送信や処理完了後の操作を実行するのにこのメソッドを使用します
Apexの一括処理ジョブの各実行は個別のトランザクションと見なされますたとえば1000 件のレコードを含む Apex の一括処理ジョブがDatabaseexecuteBatchから任意の scopeパラメータを指定せずに実行されるとこのジョブはそれぞれ 200 件のレコードを含む 5 つのトランザクションと見なされます Apex のガバナ制限は各トランザクションでリセットされます最初のトランザクションが成功し2 番目が失敗した場合最初のトランザクションで行われたデータベースの更新はロールバックされません
DatabaseBatchableContext の使用
DatabaseBatchableインターフェースのすべてのメソッドは DatabaseBatchableContext オブジェクトへの参照を必要とします このオブジェクトは一括ジョブの進行状況を追跡するために使用します
次に DatabaseBatchableContext オブジェクトを含むインスタンスメソッドを示します
説明戻り値引数名前
この一括ジョブに関連するAsyncApexJobオブジェクトの ID を文字列として返します このメソッ
IDgetJobId
ドは一括処理ジョブのレコードの進行状況を追跡するために使用します
次の例ではDatabaseBatchableContext を使用して一括処理ジョブに関連する AsyncApexJob を問い合わせます
global void finish(DatabaseBatchableContext BC) DatabaseBatchableContext の一括処理ジョブを示す AsyncApexJob の ID を取得します AsyncApexJob オブジェクトを問い合わせて現在のジョブの情報を取得します AsyncApexJob a = [Select Id Status NumberOfErrors JobItemsProcessedTotalJobItems CreatedByEmail from AsyncApexJob where Id = BCgetJobId()] ジョブの完了を通知する電子メールを Apex ジョブの登録者に送信します MessagingSingleEmailMessage mail = newMessagingSingleEmailMessage() String[] toAddresses = new String[] aCreatedByEmailmailsetToAddresses(toAddresses) mailsetSubject(Apex Sharing Recalculation + aStatus)mailsetPlainTextBody (The batch Apex job processed + aTotalJobItems + batches with+ aNumberOfErrors + failures) MessagingsendEmail(new MessagingSingleEmailMessage[] mail )
DatabaseQueryLocator を使用した範囲の定義
startメソッドは一括処理ジョブまたは反復ジョブで使用するレコードを含む DatabaseQueryLocator オブジェクトを返すことができます
次に DatabaseQueryLocator の使用例を示します
global class SearchAndReplace implements DatabaseBatchableltsObjectgt
global final String Query global final String Entity global final String Field globalfinal String Value
global SearchAndReplace(String q String e String f String v)
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 147
Query=q Entity=e Field=fValue=v
global DatabaseQueryLocator start(DatabaseBatchableContext BC) returnDatabasegetQueryLocator(query)
global void execute(DatabaseBatchableContext BC ListltsObjectgt scope) for(sobject s scope) sput(FieldValue) update scope
global void finish(DatabaseBatchableContext BC)
Apex の一括処理の反復を使用した範囲の定義
startメソッドは一括処理ジョブまたは反復ジョブで使用するレコードを含む DatabaseQueryLocator オブジェクトを返すことができます 反復ジョブを使用して返された項目をより簡単に行うことができます
global class batchClass implements Databasebatchable global Iterablestart(DatabaseBatchableContext info) return new CustomAccountIterable() global voidexecute(DatabaseBatchableContext info ListltAccountgt scope) ListltAccountgt accsToUpdate =new ListltAccountgt() for(Account a scope) aname = true anumberOfEmployees = 70accsToUpdateadd(a) update accsToUpdate global void finish(DatabaseBatchableContextinfo)
DatabaseexecuteBatchメソッドの使用
DatabaseexecuteBatchメソッドを使用して一括処理ジョブをプログラムに基づいて開始できます
重要 DatabaseexecuteBatchを呼び出すとSalesforcecom ではスケジュールされた時間のキューにのみプロセスを追加します 実際の実行はサービスの使用可能状態に応じて遅れる場合があります
DatabaseexecuteBatchメソッドは次の2 つのパラメータを採用します
bull DatabaseBatchableを実装するクラスbull DatabaseexecuteBatchメソッドはオプションのパラメータ scopeを採用します このパラメータは
executeメソッドに渡す必要があるレコードの数を指定します この値は 0 より大きくする必要があります上限はありませんが非常に大きい値を使用すると他に制限される場合がありますこれは渡される各レコードに対し多数の処理がありガバナ制限に達する場合に使用します レコード数を制限することによってトランザクションあたりの処理が制限されます
DatabaseexecuteBatchメソッドはジョブの進捗状況の追跡に使用できる AsyncApexJob オブジェクトの IDを返します 例
ID batchprocessid = DatabaseexecuteBatch(reassign)
AsyncApexJob aaj = [SELECT Id Status JobItemsProcessed TotalJobItems NumberOfErrorsFROM AsyncApexJob WHERE ID = batchprocessid ]
AsyncApexJob オブジェクトについての詳細は『Forcecom Web Services API Developers Guide』のAsyncApexJobを参照してください
Apex の一括処理の例
次に DatabaseQueryLocator の使用例を示します
global class UpdateAccountFields implements DatabaseBatchableltsObjectgt global final StringQuery global final String Entity global final String Field global final String Value
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 148
global UpdateAccountFields(String q String e String f String v) Query=q Entity=eField=fValue=v
global DatabaseQueryLocator start(DatabaseBatchableContext BC) returnDatabasegetQueryLocator(query)
global void execute(DatabaseBatchableContext BC ListltsObjectgt scope) for(Sobject s scope)sput(FieldValue) update scope
global void finish(DatabaseBatchableContext BC)
次のコードを使用して上記のクラスを呼び出すことができます
id batchinstanceid = databaseexecuteBatch(new UpdateAccountFields(qefv) 5)
次のクラスはApex の一括処理を使用して特定のユーザが所有するすべての取引先を異なるユーザに割り当てることができます
global class OwnerReassignment implements DatabaseBatchableltsObjectgt String query Stringemail Id toUserId Id fromUserId
global databasequerylocator start(DatabaseBatchableContext BC) returnDatabasegetQueryLocator(query)
global void execute(DatabaseBatchableContext BC ListltsObjectgt scope) ListltAccountgt accns= new ListltAccountgt()
for(sObject s scope)Account a = (Account)s if(aOwnerid==fromUserId)aOwnerid=toUserId accnsadd(a)
update accns
global void finish(DatabaseBatchableContext BC) MessagingSingleEmailMessage mail = newMessagingSingleEmailMessage()
mailsetToAddresses(new String[] email) mailsetReplyTo(batchacmecom)mailsetSenderDisplayName(Batch Processing) mailsetSubject(Batch Process Completed)mailsetPlainTextBody(Batch Process has completed)
MessagingsendEmail(new MessagingSingleEmailMessage[] mail )
次のコードを使用して前述の例の OwnerReassignment クラスを実行できます
OwnerReassignment reassign = new OwnerReassignment() reassignquery=SELECT Id NameOwnerid FROM Account WHERE ownerid= + uid + reassignemail=adminacmecomreassignfromUserId = u reassigntoUserId = u2 ID batchprocessid =DatabaseexecuteBatch(reassign)
Apex の一括処理のコールアウトの使用
Apex の一括処理でコールアウトを使用するにはこのクラス定義で DatabaseAllowsCalloutsを使用する必要があります 例
global class SearchAndReplace implements DatabaseBatchableltsObjectgt DatabaseAllowsCallouts
コールアウトにはHTTP 要求および webServiceキーワードで定義されたメソッドが含まれています
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 149
Apex の一括処理の状況の使用
Apexの一括処理ジョブの各実行は個別のトランザクションと見なされますたとえば1000 件のレコードを含む Apex の一括処理ジョブが任意の scopeパラメータを指定せずに実行されるとこのジョブはそれぞれ200 件のレコードを含む 5 つのトランザクションと見なされます
クラス定義でDatabaseStatefulを指定するとこれらのトランザクションで状況を保持できます処理されているレコードをカウントまたは集計する場合に役立ちますたとえばジョブで商談レコードが処理されたとします executeでメソッドを定義し処理された商談数の合計を集計できます
DatabaseStatefulを指定しない場合インターフェースメソッドのすべてのメンバー変数が元の値に戻されます
次の例ではレコードが処理されるとカスタム項目 total__cを集計します
global class SummarizeAccountTotal implements DatabaseBatchableltsObjectgt DatabaseStateful
global final String Query global integer Summary
global SummarizeAccountTotal(String q)Query=q Summary = 0
global DatabaseQueryLocator start(DatabaseBatchableContext BC) returnDatabasegetQueryLocator(query)
global void execute(DatabaseBatchableContext BC ListltsObjectgt scope) for(sObject s scope)Summary = IntegervalueOf(sget(total__c))+Summary
global void finish(DatabaseBatchableContext BC)
また変数を指定してクラスの最初の状況にアクセスします この変数を使用してDatabaseBatchableメソッドのすべてのインスタンスと最初の状況を共有します 例
取引先の sObject のリストを使用してインターフェースを実装します initialState 変数は最終として宣言されます
global class MyBatchable implements DatabaseBatchableltsObjectgt private final StringinitialState String query
global MyBatchable(String intialState) thisinitialState = initialState
global DatabaseQueryLocator start(DatabaseBatchableContext BC) Access initialStatehere
return DatabasegetQueryLocator(query)
global void execute(DatabaseBatchableContext BC ListltsObjectgt batch) AccessinitialState here
global void finish(DatabaseBatchableContext BC) Access initialState here
initialStateはクラスの「最初の」状況ですこれを使用して一括処理ジョブの実行時にクラスのインスタンス間で情報を受け渡すことはできません たとえばexecuteで initialStateの値を変更した場合処理されたレコードの 2 番目の塊は新しい値にアクセスできません最初の値だけがアクセス可能です
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 150
Apex の一括処理のテスト
DatabaseBatchableインターフェースを実装する Apex をテストするにはインターフェースにより実装された各メソッドを直接コールし一括処理ジョブのシミュレーションを実行しなければなりません
一括処理 Apex をテストする場合executeメソッドの 1 つの実行だけをテストできます executeBatchメソッドの scopeパラメータを使用してexecuteメソッドに渡されるレコード数を制限しガバナ制限に達しないようにすることができます
executeBatchメソッドは匿名プロセスを開始します 一括処理 Apex をテストする場合結果に対してテストする前に一括処理ジョブを終了する必要があります executeBatchメソッドの周囲でテストメソッドstartTestおよび stopTestを使用してテストを続行する前に終了するようにします startTestメソッド後に作成されたすべての非同期コールはシステムによって収集されます stopTestを実行する場合すべての非同期プロセスが同期して実行されます
メモ startTestブロックおよび stopTestブロックで呼び出された futureまたは executeBatchなどの非同期コールはキュー内ジョブ数の制限に対してカウントされません
下記の例は OwnerReassignment クラスをテストします
public static testMethod void testBatch() user u = [SELECT ID username FROM User WHEREusername=testuser1acmecom] user u2 = [SELECT ID username FROM User WHEREusername=testuser2acmecom] String u2id = u2id 200 件のテスト アカウントを作成 - 1 つの実行をシミュレーションします 重要 - Salesforcecom テスト フレームで可能なのは 1 つの実行のテストだけです
List ltAccountgt accns = new ListltAccountgt() for(integer i = 0 ilt200 i++) Account a =new Account(name=testAccount+i Ownerid = uID) accnsadd(a)
insert accns
TestStartTest() OwnerReassignment reassign = new OwnerReassignment()reassignquery=SELECT ID Name Ownerid FROM Account WHERE ownerid= + uid + LIMIT=200 reassignemail=adminacmecom reassignfromUserId = uId reassigntoUserId= u2Id ID batchprocessid = DatabaseexecuteBatch(reassign) TestStopTest()
SystemAssertEquals(databasecountquery(SELECT count() + FROM Account WHEREownerid=u2ID) 200)
Apex の一括処理のガバナ制限
Apex の一括処理について次のガバナ制限に注意してください
bull 最大 5 件のキュー内またはアクティブ一括処理ジョブを Apex で行うことができますVisualforce でも 5 件の一括処理ジョブを行うことができます
bull ユーザは 1 度に最大 5 個のクエリカーソルを開くことができます たとえば5 個のカーソルが開き新しいカーソルを同じユーザが開こうとする場合にクライアント アプリケーションがログインしている場合5個のカーソルのうち最も古いカーソルが解放されます
メモ 異なる Forcecom 機能のカーソル制限は個別に追跡されます たとえば5 個の Apex クエリーカーソル5 個のバッチカーソル5 個の Visualforce 個を同時に開くことができます
bull DatabaseQueryLocatorオブジェクトでは最大 5000 万件のレコードが返されます 5000 万件以上のレコードが返された場合一括処理ジョブは即座に終了し「失敗」とマークされます
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 151
bull オプションの scopeパラメータでサイズが指定されていない場合Salesforcecom はQueryLocator が 200 件のバッチに返したレコードを一括処理し各バッチを executeメソッドに渡します Apex ガバナ制限はexecuteの各実行でリセットされます
bull 組織で 24 時間当たり最大 250000 件の executeメソッドを呼び出すことができますbull startexecuteおよび finishメソッドはメソッドごとに 1 回のコールアウトだけ実行できます
Apex の一括処理のベストプラクティス
bull 一括ジョブをトリガから開始する場合は細心の注意を払ってください トリガは 5 件を超える一括ジョブを追加しないようにする必要があります 具体的にはAPI の一括更新インポートウィザードユーザインターフェースを使用した一括レコードの変更および複数のレコードを一度に更新できるすべてのケースなどです
bull DatabaseexecuteBatchを呼び出すとSalesforcecom ではスケジュールされた時間のキューにのみジョブを配置します 実際の実行はサービスの使用可能状態に応じて遅れる場合があります
bull 一括処理 Apex をテストする場合executeメソッドの 1 つの実行だけをテストできます executeBatch
メソッドの scopeパラメータを使用してexecuteメソッドに渡されるレコード数を制限しガバナ制限に達しないようにすることができます
bull executeBatchメソッドは匿名プロセスを開始します一括処理Apexをテストする場合結果に対してテストする前に一括処理ジョブを終了する必要があります executeBatchメソッドの周囲でテストメソッドstartTestおよび stopTestを使用してテストを続行する前に終了するようにします
bull ジョブトランザクション全体で変数またはデータを共有する場合はクラス定義で DatabaseStatefulを使用します これを使用しない場合各トランザクションの開始時にすべてのインスタンス変数が初期状態にリセットされます
bull futureとして宣言されたメソッドはDatabaseBatchableインターフェースを実装したクラスでは許可されません
bull futureとして宣言されたメソッドはApex の一括処理クラスからは呼び出せませんbull Apex の一括処理メソッドから DatabaseexecuteBatchメソッドを呼び出すことはできませんbull サービスの機能停止などの重大な障害が発生した場合進行中の処理は「失敗」とマークされます エラー
を修正するために一括処理ジョブをもう一度実行する必要がありますbull Apex の一括処理ジョブが実行されると一括処理ジョブを送信したユーザーに電子メール通知が送信されま
すまたは管理パッケージにコードが含まれ登録組織が一括処理ジョブを実行している場合[Apex例外通知受信者] 項目に表示された受信者に電子メールが送信されます
bull 各メソッドの実行では標準のガバナ制限非同期ブロックである Visualforce コントローラまたはWSDL メソッドが使用されます
bull Apex の一括処理が呼び出されるたびに AsyncApexJob レコードが作成されますこのレコードの ID を使用してジョブの状況エラーの数進行状況申請者を取得する SOQL クエリを構成します AsyncApexJob オブジェクトについての詳細は『Forcecom Web Services API Developers Guide』のAsyncApexJobを参照してください
bull クラス内のすべてのメソッドは globalとして定義する必要があります
Apex の一括処理 Version 180 | Apex の一括処理の使用 | 152
bull 共有再適用の場合Salesforcecom では一括処理内のレコードに対する Apex による共有管理をすべてexecuteメソッドで削除してから再作成することをお勧めしますこれにより共有が正確で完全であることを保証します
関連リンク例外ステートメント共有の理解
Apex による共有管理について
共有とはレコードに対してアクションを実行する許可をユーザまたはユーザグループに付与する行為のことです共有アクセス権はSalesforcecom ユーザインターフェースおよび Forcecom を使用して付与することもApex を使用してプログラムで付与することもできます
この項ではApex を使用した共有の概要について説明します
bull 共有の理解 (ページ 153)bull Apex を使用したレコードの共有 (ページ 156)bull Apex による共有管理の再適用 (ページ 160)
共有に関する詳細はSalesforcecom オンラインヘルプの「組織のデフォルト共有モデルの設定」 を参照してください
共有の理解共有 はカスタムオブジェクトとAccountContactOpportunityCase などの多くの標準オブジェクトのレコードレベルのアクセス制御を実現します管理者は最初にオブジェクトの組織の共有アクセスレベルを設定しレコード所有者ロール階層共有ルール共有の直接設定などに基づいてその他のアクセス権を付与します開発者は Apex 共有管理を使用できるようになりApex を使用したプログラムからのアクセス権の付与が可能になりますレコードに対するほとんどの共有は関連する共有オブジェクトで保持されますこれは他のプラットフォームのアクセス制御リスト (ACL) と似た機能です
共有タイプ
Salesforcecom には次の共有タイプがあります
Forcecom による共有管理Forcecom による共有管理ではレコードの所有者ロール階層および共有ルールに基づいて Forcecomによって付与される共有アクセス権を使用します
レコードの所有者各レコードはユーザ (場合によりカスタムオブジェクトケースおよびリードのキュー) が所有しますレコードの所有者にはフルアクセスが自動的に付与されレコードを参照編集移行共有および削除できます
Apex の一括処理 Version 180 | Apex による共有管理について | 153
ロール階層ロール階層によりその階層内の別のユーザよりも上位のユーザが下位ユーザの所有レコードまたは下位ユーザに共有されておりレコードに対して同じレベルのアクセス権を持つことができますそのためロール階層内のレコード所有者より上位のユーザにもそのレコードに対するフルアクセスが暗黙的に付与されますただしカスタムオブジェクトでは設定によりこの動作が無効になる場合がありますロール階層は共有レコードとして維持されるのではなくロール階層アクセス権が実行時に取得されます詳細はSalesforcecom オンラインヘルプの「階層を使用したアクセス権の制御」を参照してください
共有ルール共有ルールはシステム管理者が特定のユーザグループが所有するレコードへのアクセス権を特定のグループまたはロール内のユーザに自動的に付与する場合に使用します共有ルールはForcecomAppExchange からインストールしたアプリケーションのパッケージに追加したり共有ロジックをサポートする目的で使用したりすることはできません
Forcecomによる共有管理によって追加されたすべての暗黙的共有をSalesforcecomユーザインターフェースForcecom Web サービス APIまたは Apex を使用して直接変更することはできません
ユーザによる共有管理 (共有の直接設定)
ユーザによる共有管理によりレコードの所有者やレコードに対するフルアクセスを持つユーザはユーザまたはユーザグループとレコードを共有できます一般にこの処理はエンドユーザが単一レコードに対して実行しますレコードの所有者とロール階層内でその所有者の上位にあるユーザにのみレコードに対するフルアクセスが付与されます他のユーザにフルアクセスを付与することはできません特定のオブジェクトに対するオブジェクトレベルの「すべての編集」権限を持つユーザはレコードを手動で共有することもできますレコードの所有者が変わったり共有で付与されたアクセス権がオブジェクトの組織の共有デフォルトアクセスレベルより低くなった場合にユーザによる共有管理が削除されます
Apex による共有管理Apex による共有管理により開発者はアプリケーションの特定の共有要件を Apex を使用したプログラムでサポートできるようになりますこの共有タイプはForcecom による共有管理と似ていますがアプリケーション開発者のみが Apex を使用してこの共有を管理します「すべてのデータの編集」権限を持つユーザのみがレコードへの Apex による共有管理を追加または変更できますApex による共有管理はレコード所有者が変更しても維持されます
メモ Apex による共有管理はカスタムオブジェクトでのみ有効です
共有の理由項目
Salesforcecomユーザインターフェースにおけるカスタムオブジェクトの Reason項目はレコードで使用される共有の型を指定しますこの項目はApex または Forcecom API では rowCauseとなります
次のリスト項目のそれぞれはレコードに使用される共有の種類です[理由]項目値の下のテーブルおよび関連する rowCause値です
bull Forcecom による共有管理
Apex の一括処理 Version 180 | 共有の理解 | 154
rowCause値 (Apex または Forcecom API で使用)Reason Field値
ImplicitChild取引先の共有ImplicitParent関連するレコードの所有者または共有
所有者所有者
Team営業チームRule共有ルールTerritoryRuleテリトリー割り当てルール
bull ユーザによる共有管理
rowCause値 (Apex または Forcecom API で使用)Reason Field値
Manual共有の直接設定TerritoryManualテリトリー直接設定
bull Apex による共有管理
rowCause値 (Apex または Forcecom API で使用)Reason Field値
開発者による定義開発者による定義
Apex による共有管理の表示理由は開発者が定義します
アクセスレベル
レコードへのユーザのアクセス権を決定する際アクセスの最も権限の高いレベルを使用しますほとんどの共有オブジェクトは次のアクセス権をサポートしています
説明API 名アクセスレベル
レコードの所有者とロール階層内でその所有者の上位にあるユーザにのみレコードを参照または編集できますこのアクセスレベルは AccountShare オブジェクトにのみ適用されます
None非公開
指定されたユーザまたはグループがレコードを参照のみを実行できます
Read参照のみ
指定されたユーザまたはグループがレコードを参照および編集できます
Edit参照更新
Apex の一括処理 Version 180 | 共有の理解 | 155
説明API 名アクセスレベル
指定されたユーザまたはグループがレコードを参照編集移行共有削除できます
Allフルアクセス
メモ このアクセスレベルはForcecom 共有管理でのみ付与できます
Apex を使用したレコードの共有プログラムから共有にアクセスするには共有したい標準オブジェクトまたはカスタムオブジェクトに関連付けられている共有オブジェクトを使用する必要がありますたとえばAccountShare は Account オブジェクトの共有オブジェクトContactShare は Contact オブジェクトの共有オブジェクトとなります他のオブジェクトについても同様ですさらにすべてのカスタムオブジェクトの共有オブジェクトには次のように名前が付けられていますMyCustomObjectはカスタムオブジェクトの名前ですMyCustomObject__Share
主従関係の従側にあるオブジェクトには関連付けられた共有オブジェクトはありません従レコードへのアクセスは主の共有オブジェクトと関係の共有設定により定義されます詳細はSalesforcecomオンラインヘルプの「カスタム オブジェクトのセキュリティ」を参照してください
共有オブジェクトにはForcecom 共有管理ユーザ共有管理Apex 共有管理の 3 種類の共有すべてをサポートするレコードが含まれています組織のデフォルトロール階層「すべてのデータの表示」や「すべてのデータの編集」などのプロファイル権限により暗黙的にユーザに付与された共有はこのオブジェクトでは追跡されません
各共有オブジェクトには次のプロパティがあります
説明プロパティ名
共有 sObject に対し指定されたユーザまたはグループが権限を与えられたアクセスレベルプロパティ名はオブジェクト名に AccessLevelが追加されたものと
objectNameAccessLevel
なりますたとえばLeadShare オブジェクトのプロパティ名はLeadShareAccessLevelとなります有効な値は次のとおりですbull Edit
bull Read
bull All
メモ AllアクセスレベルはForcecom 共有管理でのみ使用できます
この項目にはその親オブジェクトに割り当てられた組織のデフォルトアクセスレベルよりも高いアクセスレベルが割り当てられていなければなりません詳細は「アクセスレベル」 (ページ 155)を参照してください
オブジェクトの IDこの項目は更新できませんParentID
Apex の一括処理 Version 180 | Apex を使用したレコードの共有 | 156
説明プロパティ名
ユーザまたはグループにアクセス権が付与される理由この理由によって共有のタイプが決まります共有のタイプは共有レコードの変更権限を制御しますこの項目は更新できません
RowCause
アクセス権を付与するユーザまたはグループの IDグループにはパブリックグループロールテリトリーを指定できますこの項目は更新できません
UserOrGroupId
詳細は『Forcecom Web Services API』の個別の共有オブジェクトを参照してください
Apex を使用したユーザ共有管理の作成
Apex を使用しユーザまたはグループに対してレコードの共有を直接設定することができますレコード所有者が変更になると共有は自動的に削除されます次にクラスの例を示します
public class JobSharing
static boolean manualShareRead(Id recordId Id userOrGroupId) カスタムオブジェクト Job の新しい共有オブジェクトを作成Job__Share jobShr = new Job__Share()
共有されるレコードの ID を設定jobShrParentId = recordId
アクセス権を付与するユーザまたはグループの ID を設定jobShrUserOrGroupId = userOrGroupId
アクセスレベルを設定jobShrAccessLevel = Read
共有の直接設定の場合rowCause を「manual」に設定 オブジェクト共有のデフォルト値が「manual」であるためこの行は省略できますjobShrRowCause = SchemaJob__ShareRowCauseManual
共有するレコードを挿入しsave result を取得 false パラメータは処理するレコードを複数渡された場合 部分処理を許可しますDatabaseSaveResult sr = Databaseinsert(jobShrfalse)
save result を処理if(srisSuccess()) 成功を表しますreturn true else 最初のsave result エラーを取得DatabaseError err = srgetErrors()[0]
エラーが 3 つのアクセスレベルに関連しているかどうかを確認 オブジェクトのデフォルト値と同等かより権限の大きいアクセスレベルは 許可されません これらの共有レコードは不要であるため挿入例外が許可されますif(errgetStatusCode() == StatusCodeFIELD_INTEGRITY_EXCEPTION ampamperrgetMessage()contains(AccessLevel)) 成功を表しますreturn true else 失敗を表しますreturn false
manualShareRead メソッドのテストstatic testMethod void testManualShareRead() テストのためのユーザを選択ListltUsergt users = [select id from user where isActive = true limit 2] Iduser1Id = users[0]Id Id user2Id = users[1]Id
新規ジョブの作成Job__c j = new Job__c() jName = Test Job jOwnerId = user1Id insertj
レコード所有者ではないユーザに共有の直接設定を挿入SystemassertEquals(manualShareRead(jIduser2Id) true)
ジョブ共有レコードのクエリを実行ListltJob__Sharegt jShrs = [select id userOrGroupIdaccessLevel rowCause from job__share where parentId = jId and userOrGroupId= user2Id]
ジョブに対する 1 つの共有の直接設定をテストSystemassertEquals(jShrssize() 1 Set the
Apex の一括処理 Version 180 | Apex を使用したレコードの共有 | 157
objects sharing model to Private)
共有の直接設定の属性をテストSystemassertEquals(jShrs[0]accessLevel Read)SystemassertEquals(jShrs[0]rowCause Manual) SystemassertEquals(jShrs[0]userOrGroupIduser2Id)
不正なジョブ ID をテストdelete j
削除されたジョブ ID に対する共有の直接設定を挿入SystemassertEquals(manualShareRead(jIduser2Id) false)
重要 組織のデフォルトアクセスレベルは最も権限の大きいアクセスレベルに設定することはできませんカスタムオブジェクトの場合は Public ReadWrite となります詳細は「アクセスレベル」 (ページ155)を参照してください
Apex による共有管理の作成
Apex による共有管理を使用し開発者はアプリケーションの動作をサポートする共有をプログラムで操作できるようになりますこの共有タイプはForcecom による共有管理と似ていますがアプリケーション開発者のみが Apex を使用してこの共有を管理します「すべてのデータの編集」権限を持つユーザのみがレコードへの Apex による共有管理を追加または変更できますApex による共有管理はレコード所有者が変更しても維持されます
メモ Apex による共有管理はカスタムオブジェクトでのみ有効です
Apex による共有管理にはApex 共有の理由を使用する必要がありますApex 共有の理由は開発者がユーザやユーザグループに対してレコードを共有した理由を追跡するための 1 つの方法です複数の Apex 共有理由を使用することで共有レコードの更新や削除に必要なコーディングを簡略化することができますまた開発者は別の理由を使用して同じユーザやグループに何度も共有することができるようになります
Apex 共有の理由はオブジェクトの詳細ページとして定義されますApex 共有の理由にはそれぞれラベルと名前が付けられます
bull ユーザインターフェースでレコードの共有を参照すると[理由]列に表示ラベルが表示されますこれによりユーザとシステム管理者が共有の目的を理解できます表示ラベルはトランスレーションワークベンチ使用した翻訳でも有効化されます
bull この名前はAPI および Apex で理由を参照するときに使用します
Apex 共有の理由名の形式は次のとおりです
MyReasonName__c
Apex 共有の理由は次のようにプログラムから参照できます
SchemaCustomObject__SharerowCauseSharingReason__c
たとえばJob というオブジェクトの Apex 共有の理由である Recruiter は次のように参照できます
SchemaJob__SharerowCauseRequester__c
Apex の一括処理 Version 180 | Apex を使用したレコードの共有 | 158
詳細は「スキーマメソッド」 (ページ 238)を参照してください
Apex 共有の理由を作成する手順は次のとおりです
1 [設定] [作成] [オブジェクト] をクリックします2 カスタムオブジェクトを選択します3 [Apex 共有の理由] 関連リストで [新規] をクリックします4 Apex 共有の理由の表示ラベルを入力しますユーザインターフェースでレコードの共有を参照すると[理
由]列に表示ラベルが表示されます表示ラベルはトランスレーションワークベンチ使用した翻訳でも有効化されます
5 Apex 共有の理由の名前を入力しますこの名前はForcecom API および Apex で理由を参照するときに使用しますこの名前はアンダースコアと英数字のみを含み組織内で一意の名前にする必要があります最初は文字であることスペースは使用しない最後にアンダースコアを使用しない2 つ続けてアンダースコアを使用しないという制約があります
6 [保存] をクリックします
Apex による共有管理例
次の例では人事採用アプリケーションの構築中でJob というカスタムオブジェクトが存在すると仮定していますこのジョブにリストされた採用担当者および採用担当マネージャにレコード所有者とほぼ同様にレコードへのフルアクセス権を付与したいと考えています次のトリガはジョブ作成時に採用担当者および採用担当マネージャにアクセス権を付与します
trigger JobApexSharing on Job__c (after insert)
if(triggerisInsert) Job に共有オブジェクトの新しいリストを作成ListltJob__Sharegt jobShrs =new ListltJob__Sharegt()
採用担当者および採用担当マネージャの共有のための変数を宣言Job__Share recruiterShr Job__SharehmShr
for(Job__c job triggernew) 新規共有オブジェクトのインスタンス化recruiterShr = newJob__Share() hmShr = new Job__Share()
共有されるレコードの ID を設定recruiterShrParentId = jobId hmShrParentId = jobId
アクセス権を付与するユーザまたはグループの ID を設定recruiterShrUserOrGroupId =jobRecruiter__c hmShrUserOrGroupId = jobHiring_Manager__c
アクセスレベルを設定recruiterShrAccessLevel = edit hmShrAccessLevel = read
採用担当者と採用担当マネージャの Apex 共有の理由を設定recruiterShrRowCause =SchemaJob__ShareRowCauseRecruiter__c hmShrRowCause =SchemaJob__ShareRowCauseHiring_Manager__c
挿入するためにリストにオブジェクトを追加jobShrsadd(recruiterShr) jobShrsadd(hmShr)
共有レコードを挿入しsave result を取得 処理するレコードを複数渡された場合 部分処理を許可しますDatabaseSaveResult[] lsr = Databaseinsert(jobShrsfalse)
カウンタを作成Integer i=0
save results を処理for(DatabaseSaveResult sr lsr) if(srisSuccess()) 最初の saveresult エラーを取得error DatabaseError err = srgetErrors()[0]
エラーが 3 つのアクセスレベルに関連しているかどうかを確認 オブジェクトのデフォルト値と同等かより
Apex の一括処理 Version 180 | Apex を使用したレコードの共有 | 159
権限の大きいアクセスレベルは 許可されません これらの共有レコードは不要であるため 挿入例外が許可されますif((errgetStatusCode() == StatusCodeFIELD_INTEGRITY_EXCEPTION ampamperrgetMessage()contains(AccessLevel))) エラーが 3 つのアクセスレベルに関連していない場合エラーを発生triggernewMapget(jobShrs[i]ParentId) addError(Unable to grant sharing accessdue to following exception + errgetMessage()) i++
重要 組織のデフォルトアクセスレベルは最も権限の大きいアクセスレベルに設定することはできませんカスタムオブジェクトの場合は Public ReadWrite となります詳細は「アクセスレベル」 (ページ155)を参照してください
Apex による共有管理の再適用組織のデフォルトアクセスレベルが変更されるとSalesforcecomはオブジェクトの全レコードの共有を自動的に再適用します再適用により適切な場合は Forcecom 共有管理が追加されますまた付与されたアクセス権が冗長である場合はすべての共有タイプが削除されますたとえばオブジェクトの共有モデルが「非公開」から「公開参照のみ」に変更されるとユーザに「参照のみ」アクセス権を付与する共有の直接設定が削除されます
Apex 共有管理を再適用するにはSalesforcecom が提供する再適用を行うインターフェースを実装するApex クラスを記述する必要がありますその後Apex 共有管理の再適用リストのカスタムオブジェクトの詳細ページにおいてクラスとカスタムオブジェクトを関連付ける必要があります
メモ Apex 共有管理の再適用は現在限定リリースプログラムで使用できます組織での Apex 共有管理の再適用の詳細についてはsalesforcecom までお問い合わせください
その後Apex共有の理由を指定するカスタムオブジェクト詳細ページからこのクラスを実行しますアプリケーションのロジックに定義されたユーザへのアクセス権限の付与においてオブジェクトへのロックにより Apexスクリプトが実行されない場合管理者はそのオブジェクトの Apex 共有管理を再適用しなければならないことがありますDatabaseexecuteBatchメソッドをApex共有管理の再適用をプログラムに基づいて開始することもできます
メモ カスタムオブジェクトの組織のデフォルト共有アクセスレベルが更新される度にそのカスタムオブジェクトに関連付けられた Apex 最適用クラスもまた実行されます
Apexの再適用の実行を監視または停止するには[設定] [監視] [Apex] [ジョブ]をクリックします詳細はSalesforcecom オンラインヘルプの「Apex ジョブキュー」を参照してください
共有の再適用のための Apex クラスの作成
Apex 共有管理を再適用するには再適用を行う Apex クラスを記述する必要がありますこのクラスはSalesforcecom が提供する DatabaseBatchableインターフェースを実装している必要があります
DatabaseBatchableインターフェースはApex共有管理の再適用などすべてのApexの一括処理プロセスに使用されますこのインターフェースは組織で複数回実装できます実装しなければならないメソッドの詳細は「Apex の一括処理の使用 (ページ 146)」を参照してください
Apex 共有管理の再適用を作成する前にベストプラクティスについても検討してください
Apex の一括処理 Version 180 | Apex による共有管理の再適用 | 160
Apex による共有管理の再適用例
この例では人事採用アプリケーションの構築中でJob というオブジェクトが存在すると仮定していますジョブにリストされた採用担当者および採用担当マネージャにレコードへのアクセス権が付与されていることを確認したいと考えています次の Apex クラスがその確認を行います
global class JobSharingRecalc implements DatabaseBatchableltsObjectgt
start メソッドは共有の再適用の最初にコールされます このメソッドは再適用する必要のあるレコードを含む SOQL クエリロケータを返します このメソッドは global でなければなりませんglobalDatabaseQueryLocator start(DatabaseBatchableContext BC) returnDatabasegetQueryLocator([SELECT Id Hiring_Manager__c Recruiter__c FROM Job__c])
executeBatch メソッドはstart から返されたレコードのチャンクによって実行されます このメソッドはglobal でなければなりません global void execute(DatabaseBatchableContext ListltsObjectgtscope) メソッドに渡されたレコードの塊のマップを作成しますMapltID Job__cgt jobMap = new MapltIDJob__cgt((ListltJob__cgt)scope)
挿入する Job__Share オブジェクトのリストを作成ListltJob__Sharegt newJobShrs = newListltJob__Sharegt()
Job レコードのすべての既存の共有レコードをバッチから検索 このアプリケーションの Apex 共有の理由を使用しているレコードのみが返されますListltJob__Sharegt oldJobShrs = [select id from Job__Sharewhere Id In jobMapkeySet() and (rowCause = SchemaJob__SharerowCauseRecruiter__c orrowCause = SchemaJob__SharerowCauseHiring_Manager__c)]
各 Job レコードに対し採用担当者と採用担当マネージャの新しい共有レコードを 作成for(Job__c job jobMapvalues()) Job__Share jobHMShr = new Job__Share() Job__Share jobRecShr = newJob__Share()
Job のアクセス権を付与するユーザ (採用担当マネージャ) の ID を設定jobHMShrUserOrGroupId =jobHiring_Manager__c
ジョブの採用担当マネージャには常に「参照のみ」アクセス権が付与されていなければなりませんjobHMShrAccessLevel = Read
共有されるレコードの IDjobHMShrParentId = jobId
採用担当マネージャの Apex 共有の利用に rowCause を設定 これにより共有レコードを Apex 共有管理として確立しますjobHMShrRowCause = SchemaJob__ShareRowCauseHiring_Manager__c
挿入するために共有レコードをリストに追加newJobShrsadd(jobHMShr)
Job のアクセス権を付与するユーザ (採用担当者) の ID を設定jobRecShrUserOrGroupId =jobRecruiter__c
ジョブの採用担当マネージャには常に「参照更新」アクセス権が付与されていなければなりませんjobRecShrAccessLevel = Edit
共有されるレコードの IDjobRecShrParentId = jobId
採用担当者の Apex 共有の利用に rowCause を設定 これにより共有レコードを Apex 共有管理として確立しますjobRecShrRowCause = SchemaJob__ShareRowCauseRecruiter__c
挿入するために共有レコードをリストに追加newJobShrsadd(jobRecShr)
try 既存の共有レコードを削除 これにより新しい共有レコードを最初から記述できますDeleteoldJobShrs
新しい共有レコードを挿入しsave result を取得 false パラメータは処理するレコードを複数渡された
Apex の一括処理 Version 180 | Apex による共有管理の再適用 | 161
場合 部分処理を許可しますDatabaseSaveResult[] lsr = Databaseinsert(newJobShrsfalse)
save results を挿入のために処理for(DatabaseSaveResult sr lsr) if(srisSuccess()) 最初の save result エラーを取得DatabaseError err = srgetErrors()[0]
エラーが明白なアクセスレベルに関連しているかどうかを確認 オブジェクトのデフォルト値と同等かより権限の大きいアクセスレベルは 許可されません これらの共有レコードは不要であるため 挿入例外が許可されますif((errgetStatusCode() == StatusCodeFIELD_INTEGRITY_EXCEPTION ampamperrgetMessage()contains(AccessLevel))) エラーは明白なアクセスレベルとは無関係です Apexジョブの送信者に電子メールを送信MessagingSingleEmailMessage mail = newMessagingSingleEmailMessage() String[] toAddresses = new String[] adminyourcompanycommailsetToAddresses(toAddresses) mailsetSubject(Apex Sharing Recalculation Exception)mailsetPlainTextBody (The Apex sharing recalculation threw the following exception +errgetMessage()) MessagingsendEmail(new MessagingSingleEmailMessage[] mail ) catch(DmlException e) 処理が失敗した場合はApex ジョブの送信者に電子メールを送信MessagingSingleEmailMessage mail = new MessagingSingleEmailMessage() String[] toAddresses= new String[] adminyourcompanycom mailsetToAddresses(toAddresses)mailsetSubject(Apex Sharing Recalculation Exception) mailsetPlainTextBody (The Apexsharing recalculation threw the following exception + egetMessage())MessagingsendEmail(new MessagingSingleEmailMessage[] mail )
finish メソッドは共有の再適用の最後にコールされます このメソッドは global でなければなりませんglobal void finish(DatbaseBatchableContext BC) Apex ジョブの送信者にジョブが完了したこと
を通知する電子メールを送信MessagingSingleEmailMessage mail = new MessagingSingleEmailMessage()String[] toAddresses = new String[] adminyourcompanycommailsetToAddresses(toAddresses) mailsetSubject(Apex Sharing Recalculation Completed)mailsetPlainTextBody (The Apex sharing recalculation finished processing)MessagingsendEmail(new MessagingSingleEmailMessage[] mail )
Apex による共有管理の再適用のテスト
DatabaseBatchableインターフェースを実装する Apex をテストするにはインターフェースにより実装された各メソッドを個別にコールし共有の再適用のシミュレーションを実行しなければなりません
DatabaseBatchableインターフェースを実装するクラスがメソッドに渡されるDatabaseBatchInput引数で getAsyncApexJobIdメソッドを使用している場合テストメソッド setupAsyncApexJobを使用したテストで使用するために AsyncApexJob レコードを準備する必要があります詳細は「テストメソッド」 (ページ 293)を参照してください
startから返された QueryLocator オブジェクトをテストするにはDatabaseQueryLocator の getQueryメソッドを使用する必要があります詳細は「データベースのApexの一括処理オブジェクトとメソッド」 (ページ273)を参照してください
下記の例では前の項のクラスでテストを行いテストメソッド setupAsyncApexJobの使い方について説明しますまたstartから返された QueryLocator オブジェクトのテスト方法も示します
public class JobSharingTester
JobSharingRecalc クラスのテストstatic testMethod void testApexSharing() DatabaseBatchable インターフェースを実装するクラスをインスタンス化JobSharingRecalc recalc = newJobSharingRecalc()
AsyncApexJob オブジェクトの準備に必要な変数を宣言Integer totalItems Integer itemsProcessedInteger errs
テストで使用する新規 Job を作成 少なくとも 1 つの Job が存在していなければなりませんJob__c j= new Job__c() jName = Test Job jRecruiter__c = UserInfogetUserId()
Apex の一括処理 Version 180 | Apex による共有管理の再適用 | 162
jHiring_Manager__c = UserInfogetUserId() insert j
TeststartTest()
バッチ処理可能なクラスから start メソッドをコールDatabaseQueryLocator ql = recalcstart()
バッチ処理可能なクラスからの start メソッドのコールで 正しいクエリロケータが返されることをテストクエリの結果を文字列で表したものを取得するには QueryLocatorgetQuery メソッドを使用する 必要がありますSystemassertEquals(qlgetQuery() SELECT Id Hiring_Manager__c Recruiter__c fromJob__c)
バッチ処理可能なクラスから executeBatch メソッドをコールするための変数を設定 バッチ処理全体に含まれるチャンク数excution totalItems = 1 バッチ処理全体で処理されたチャンク数itemsProcessed =0 バッチ処理全体のエラー数チャンク 1 個あたりのエラーは 1 つerrs = 0
クエリロケータのチャンクの start メソッドから返される クエリのレコード 返されるレコードの最大数は 200 レコードMapltID Job__cgt jobMap = new MapltID JOB__cgt( [SELECT Id Hiring_Manager__cRecruiter__c FROM Job__c limit 200])
バッチ可能なクラスから execute メソッドをコールrecalcexecute(jobMapvalues())
クエリジョブは executeBatch メソッドの引数として渡されます クエリはexecute メソッドで挿入されたジョブと関連する共有レコードを 返しますListltJob__cgt jobs = [SELECT Id Hiring_Manager__cRecruiter__c (Select Id ParentId UserOrGroupId AccessLevel RowCause FROM Shares where(rowCause = SchemaJob__SharerowCauseRecruiter__c or rowCause =SchemaJob__SharerowCauseHiring_Manager__c)) from Job__c WHERE Id In jobMapkeySet()]
ジョブに Apex 共有管理が存在することを確認for(Job__c job jobs) 各ジョブには最大 2 つのApex 共有管理レコードが存在しますSystemassert(jobSharessize() lt= 2)
for(Job__Share jobShr jobShares) Job に対し採用担当マネージャの共有レコードをテストif(jobShrRowCause == SchemaJob__ShareRowCauseHiring_Manager__c)SystemassertEquals(jobShrUserOrGroupIdjobHiring_Manager__c)SystemassertEquals(jobShrAccessLevelRead) Job に対し採用担当者の共有レコードをテストelse if(jobShrRowCause == SchemaJob__ShareRowCauseRecruiter__c)SystemassertEquals(jobShrUserOrGroupIdjobRecruiter__c)SystemassertEquals(jobShrAccessLevelEdit)
バッチ処理可能なクラスから finish メソッドをコールするための変数を設定 バッチ処理全体に含まれるチャンク数excution totalItems = 1 バッチ処理全体で処理されたチャンク数itemsProcessed = 1 バッチ処理全体のエラー数チャンク 1 個あたりのエラーは 1 つerrs = 0
バッチ可能なクラスから finish メソッドをコールrecalcfinish()
TeststopTest()
再適用に使用される Apex クラスの関連付け
再適用に使用される Apex クラスはカスタムオブジェクトと関連付けられていなければなりません
Apex による共有管理の再適用クラスをカスタムオブジェクトと関連付ける手順は次のとおりです
1 [設定] [作成] [オブジェクト] をクリックします2 カスタムオブジェクトを選択します3 [Apex 共有の再適用] 関連リストで [新規] をクリックします
Apex の一括処理 Version 180 | Apex による共有管理の再適用 | 163
4 このオブジェクトの Apex 共有を再適用する Apex クラスを選択します選択するクラスはDatabaseBatchableインターフェースを実装している必要があります同じApexクラスを同じカスタムオブジェクトと複数関連付けることはできません
5 [保存] をクリックします
Apex の一括処理 Version 180 | Apex による共有管理の再適用 | 164
第 9 章
管理パッケージでの Apex の開発
パッケージとは個々のコンポーネントなどの小さいものや関連アプリケーションのセットなどの大きいものを格納するコンテナですパッ
トピック
bull パッケージバージョン ケージの作成後他のSalesforcecomユーザおよび組織 (社外のユーザbull Apex の廃止 組織も含む) にそのパッケージを配布できます組織は他の多くの組
織でダウンロードおよびインストールできる単一の管理パッケージを作bull パッケージバージョンの動作成できます管理パッケージは未管理パッケージとは異なりコンポーネントの一部がロックされていて後でアップグレードできます未管理パッケージにはロックされたコンポーネントは含まれておらずアップグレードはできません
ここでは管理パッケージの Apex の開発に関連する次のトピックについて説明します
bull パッケージバージョンbull Apex の廃止bull パッケージバージョンの動作
パッケージバージョン
パッケージでアップロードされる一連のコンポーネント示す番号ですバージョン番号の形式はmajorNumberminorNumberpatchNumber (例 213) となりますメジャー番号およびマイナー番号はメジャーリリースごとに選択された値に増えますpatchNumberはパッチリリース時のみ生成されますpatchNumber
がない場合0 であるものとしますパッチバージョンは現在パイロットプログラムで使用できます組織のパッチバージョンの有効化に関する詳細はsalesforcecomまでお問い合わせください未管理パッケージはアップグレードできないため各パッケージバージョンは単に配布用コンポーネントのセットですパッケージバージョンは管理パッケージでより大きな意味を持ちますパッケージは異なるバージョンで異なる動作をします公開者はパッケージバージョンを使用してパッケージを使用する既存の連携に影響を与えることなく後続のパッケージバージョンをリリースすることにより管理パッケージのコンポーネントを発展させることができます
既存の登録ユーザが新しいパッケージをインストールした場合パッケージ内の各コンポーネントのインスタンスは 1 つだけですがコンポーネントは古いバージョンをエミュレートできますたとえば登録ユーザはApexクラスを含む管理パッケージを使用するとします公開者が Apex クラスのメソッドを廃止し新しいパッケージをリリースする場合でも新しいバージョンをインストールした後登録ユーザは Apex クラスのインスタンスを 1 つだけ使用できますただしこのApexクラスは古いバージョンの廃止されたメソッドを参照するコードの以前のバージョンをエミュレートできます
管理パッケージで Apex を開発する場合次の点に注意してください
bull 管理パッケージは固有の名前空間を持ちますこの名前空間はインストール先の組織において名前の重複を防ぐため自動的にクラスメソッド変数などの前に追加されます
bull 管理パッケージの一部であるApexコードは自動的に隠されインストール先の組織内では見ることができません唯一の例外としてグローバルとして宣言されているメソッドですそのようなメソッドの署名はインストールを行う組織でも参照できます
bull パッケージ管理者はdeprecatedアノテーションを使用して今後のリリースの管理パッケージでは参照できないメソッドクラス例外列挙インタフェース変数を指定することができます管理パッケージのコードをリファクタリングする場合に役立ちます
bull システムメソッドを runAsを使用してパッケージバージョンコンテキストを異なるパッケージバージョンに変更するテストメソッドを作成できます
bull クラスが「管理-リリース済み」パッケージバージョンでアップロードされた後にインストールまたは抽象クラスまたは仮想クラスにメソッドを追加することはできません
bull 明示的に名前空間を参照する非管理パッケージに含まれる Apex スクリプトはアップロードできません
Apex の廃止
パッケージ管理者はdeprecatedアノテーションを使用して今後のリリースの管理パッケージでは参照できないメソッドクラス例外列挙インタフェース変数を指定することができます管理パッケージのコードをリファクタリングする場合に役立ちます別のパッケージを「管理 - リリース済み」でアップロードすると最新のパッケージバージョンをインストールする新しい登録ユーザは非推奨の要素を確認できませんがその要素は既存の登録ユーザおよび API 連携で機能し続けますメソッドまたはクラスなど破棄された項目は最初はパッケージ開発者によって参照できます
管理パッケージでの Apex の開発 Version 180 | パッケージバージョン | 166
メモ 非管理パッケージの Apex クラスまたはトリガの deprecatedアノテーションは使用できません
パッケージ開発者は異なる Salesforcecom 組織のユーザのパイロットユーザによる評価およびフィードバックのために管理-ベータパッケージバージョンを使用できます開発者がApex識別子を廃止しあるバージョンのパッケージを「管理 - ベータ」としてアップロードしてもパッケージバージョンをインストールした登録ユーザはパッケージバージョンの廃止された識別子を参照できますパッケージ開発者がその後「管理-リリース済み」パッケージバージョンをアップロードした場合インストールした後登録ユーザにはパッケージバージョンの廃止された識別子は表示されません
パッケージバージョンの動作
パッケージコンポーネントは異なるパッケージバージョンで異なる動作をします動作のバージョニングにより新しいコンポーネントをパッケージに追加し既存のコンポーネントを調整することができますコードは既存の登録者にもシームレスに機能しますパッケージ開発者が新しいコンポーネントをパッケージに追加し新しいパッケージバージョンをアップロードした場合新しいパッケージバージョンをインストールした登録者は新しいコンポーネントを使用できるようになります
Apex コードの動作のバージョニングApex には特殊構文がありパッケージ開発者はクラスおよびトリガで異なるバージョンに異なる動作をさせる条件付きロジックを使用できますこれによりパッケージ開発者はコードをアップグレードしても以前のパッケージバージョンのクラスおよびトリガの既存の動作を継続してサポートできます
登録者が複数のバージョンのパッケージをインストールしパッケージ内の Apex クラスまたはトリガを参照するコードを記述する場合参照しているバージョンを選択する必要がありますパッケージ内で参照しているApex コード内で参照を作成する呼び出し Apex コードのバージョン設定に基づき異なるコードパスを条件付きで実行できます呼び出しコードのパッケージバージョン設定はPackageVersionRequestオブジェクトを使用してパッケージコード内で決定できますパッケージ開発者はこのオブジェクトおよび付随するメソッドを使用して要求コンテキストを決定しさまざまなバージョンのパッケージの異なる動作を示すことができます
次の例は異なるパッケージバージョンのトリガの動作を示します
trigger oppValidation on Opportunity (before insert before update)
for(Opportunity o Triggernew)
New validation added in package version 15 Applies to all version of the managedpackage except 10 If(PackageVersionRequestisGreaterThan(PackageVersion10))If(oProbability gt= 50 ampamp oDescription == NULL) oaddError(All deals over 50 require adescription)
Validation applies to all versions of the managed package If(oIsWon == true ampampoLeadSource == NULL) oaddError(A lead source must be provided for all Closed Won deals)
パッケージバージョンを処理するメソッドの詳細は「Package メソッド (ページ 284)」を参照してください
管理パッケージでの Apex の開発 Version 180 | パッケージバージョンの動作 | 167
メモ 非管理パッケージではPackageVersionRequestオブジェクトは使用できません
インストールパッケージのあるクラスがパッケージの別のクラスのメソッドを呼び出す場合要求コンテキストは保持されますたとえば登録者は CountryUtil クラスおよび ContinentUtil Apex クラスを含む GeoReports パッケージをインストールしたとします登録者は GeoReportsEx クラスを新規作成しバージョン設定を使用してバージョン 23 の GeoReports パッケージにバインドしますGeoReportsEx が CountryUtil のメソッドを内部的に呼び出す ContinentUtil のメソッドを呼び出すと 要求コンテキストは ContinentUtil から CountryUtil に反映されCountryUtil PackageVersionRequestの変数はバージョン 23 の GeoReports パッケージを参照します
バージョニングされていない Apex コードの項目パッケージバージョンでいくつかのApex項目の動作を変更できますたとえば新しい登録者が後続のバージョンのパッケージを参照できないようメソッドを廃止できます
ただし次のリストの修飾子キーワードアノテーションについてはバージョニングできませんパッケージ開発者が次の修飾子キーワードまたはアノテーションのいずれかを変更すると変更はすべてのパッケージバージョンに反映されます
管理パッケージの Apex コードで使用される場合これらの項目のいくつかに行うことができる変更には制限事項があります
パッケージ開発者は次の項目を追加または削除できます
bull future
bull isTest
bull with sharing
bull without sharing
bull transient
パッケージ開発者は次の項目に制限付きで変更を行うことができます
bull private globalに変更できますbull public globalに変更できますbull protected globalに変更できますbull abstract virtualに変更できますが削除できませんbull final 削除できますが追加はできません
パッケージ開発者は次の項目の追加または変更することはできません
bull global
bull virtual
パッケージ開発者は webServiceキーワードを追加できますがいったん追加すると削除することはできません
メモ 管理パッケージコードの webServiceメソッドまたは変数を廃止することはできません
管理パッケージでの Apex の開発 Version 180 | バージョニングされていない Apex コードの項目 | 168
パッケージバージョンの動作のテスト異なるパッケージバージョンの Apex クラスまたはトリガの動作を変更する場合異なるパッケージバージョンで期待されているようにコードをテストすることが重要ですシステムメソッドをrunAsを使用してパッケージバージョンコンテキストを異なるパッケージバージョンに変更するテストメソッドを作成できますrunAs
はテストメソッドでのみ使用できますこのメソッドはテストメソッドのPackageVersionRequestオブジェクトとして効果的に設定します
次の例は異なるパッケージバージョンの異なる動作のトリガを示します
trigger oppValidation on Opportunity (before insert before update)
for(Opportunity o Triggernew)
Add a new validation to the package Applies to versions of the managed package greaterthan 10 If(PackageVersionRequestisGreaterThan(PackageVersion10)) If(oProbabilitygt= 50 ampamp oDescription == NULL) oaddError(All deals over 50 require a description)
Add a new validation to the package This validation applies to all versions of themanaged packageIf(oIsWon == true ampamp oLeadSource == NULL) oaddError(A lead source mustbe provided for all Closed Won deals)
次のテストクラスはトリガの動作を確認します
isTest public class OppTriggerTests
static testMethod void testOppValidation()
Set up 50 opportunity with no description Opportunity o = new Opportunity() oName =Test Job oProbability = 50 oStageName = Prospect oCloseDate = Systemtoday()
Test running as latest package version try insert o catch(SystemDMLException e)Systemassert( egetMessage()contains( All deals over 50 require a description)egetMessage())
Run test as managed package version 10 SystemrunAs(PackageVersion10) try inserto catch(SystemDMLException e) Systemassert(false egetMessage())
Set up a closed won opportunity with no lead source o = new Opportunity() oName = TestJob oProbability = 50 oStageName = Prospect oCloseDate = Systemtoday() oStageName= Closed Won
Test running as latest package version try insert o catch(SystemDMLException e)Systemassert( egetMessage()contains( A lead source must be provided for all Closed Wondeals) egetMessage())
Run test as managed package version 10 SystemrunAs(PackageVersion10) try inserto catch(SystemDMLException e) Systemassert( egetMessage()contains( A lead sourcemust be provided for all Closed Won deals) egetMessage())
管理パッケージでの Apex の開発 Version 180 | パッケージバージョンの動作のテスト | 169
第 10 章
Apex メソッドの Web サービスとしての公開
外部アプリケーションがコードおよびアプリケーションにアクセスできるようApex メソッドを公開できますApex メソッドを公開するにはWebService メソッドを使用します
トピック
bull WebService メソッド
ヒント Apex Web サービスを使用すると外部アプリケーションは Web サービスを使用して Apex メソッドを呼び出すことができますApex コールアウトを使用するとApex は外部 Webまたは HTTP サービスを呼び出すことができます
WebService メソッド
ApexクラスメソッドはカスタムのForcecom Web サービスAPIコールとしての表示が可能ですこれにより外部アプリケーションが Apex Web サービスを実行しSalesforcecom でアクションを実行できるようになりますこれらのメソッドの定義には webServiceキーワードを使用します例
global class MyWebService webService static Id makeContact(String lastName Account a) Contact c = new Contact(lastName = Weissman AccountId = aId) insert c return cid
外部アプリケーションの開発者はクラスの WSDL を生成してwebServiceメソッドを含む Apex クラスと統合できますApex クラス詳細ページから WSDL を生成する手順は次のとおりです
1 アプリケーションで[設定] [開発] [Apex クラス] をクリックします2 webServiceメソッドを含むクラス名をクリックします3 [WSDL の生成] をクリックします
WebService メソッドによるデータの公開カスタム webServiceメソッドの呼び出しには必ず System コンテキストを使用しますその結果現在のユーザーの証明書は使用されずこれらのメソッドにアクセスできるユーザーが権限項目レベルのセキュリティ共有ルールに関係なく全機能を使用できますwebServiceキーワードでメソッドを公開する開発者は機密情報データを不注意に公開しないよう注意する必要があります
警告 with sharingキーワードを使用して定義されたクラスにメソッドが含まれていない場合webServiceキーワードにより API を介して公開する Apex クラスメソッドではレコードのオブジェクト権限項目レベルのセキュリティ共有ルールを参照しません with sharingを使用して定義されたクラスだけが現在のユーザの共有ルールに関係します
WebServiceキーワード使用に関する考慮事項webServiceキーワードを使用する場合次の考慮事項について注意してください
bull クラスの定義には webServiceキーワードを使用できませんただし最上位の外部クラスメソッドと内部クラスメソッドを定義するために使用できます
bull webServiceキーワードを使用してインターフェースを定義またはインターフェースのメソッドおよび変数を定義することはできません
bull システム定義の enum は Web サービスメソッドで使用することはできませんbull トリガのメソッドを定義できないためトリガに webServiceキーワードを使用できませんbull webServiceキーワードと共に定義されているメソッドを含むすべてのクラスは globalとして宣言する必要
がありますメソッドまたは内部クラスを globalとして宣言した場合外部のトップレベルクラスもglobalとして宣言する必要があります
bull webServiceキーワードで定義されるメソッドは本質的にグローバルですこれらのメソッドをクラスにアクセスできる Apex スクリプトで使用できますwebServiceキーワードをglobalより多くのアクセスを可能にするアクセス変更子の種類として検討することができます
bull webServiceキーワードを使用するメソッドを staticとして定義する必要があります
Apex メソッドの Web サービスとしての公開 Version 180 | WebService メソッド | 171
bull 管理パッケージコードの webServiceメソッドまたは変数を廃止することはできませんbull 特定の Apex 要素に SOAP アナログがないためwebServiceキーワードで定義されたメソッドは次の要素
をパラメータとして使用することはできませんこれらの要素はメソッド内で使用できますが戻り値としてマークすることはできません
- Map- Sets- Pattern オブジェクト- Matcher オブジェクト- 例外オブジェクト
bull webServiceキーワードはWeb サービスの一部として公開するメンバー変数で使用する必要がありますこれらのメンバー変数を staticとマークすることはできません
bull Salesforcecom はアクセスが Restrictedになっている AppExchange パッケージからの Web サービスへのアクセスと executeanonymous要求を拒否します
bull 項目に割り当てた文字列値が長すぎる場合APIバージョン 150 以上を使用して保存 (コンパイル) したApexクラスにはランタイムエラーが発生します
次の例はWeb サービス変数と Web サービスメソッドを持つクラスを示しています
global class SpecialAccounts
global class AccountInfo WebService String AcctName WebService Integer AcctNumber
WebService static Account createAccount(AccountInfo info) Account acct = new Account()acctName = infoAcctName acctAccountNumber = StringvalueOf(infoAcctNumber) insertacct return acct
WebService static Id [] createAccounts(Account parent Account child Account grandChild)
insert parent childparentId = parentId insert child grandChildparentId = childIdinsert grandChild
Id [] results = new Id[3] results[0] = parentId results[1] = childId results[2] =grandChildId return results
TestMethod static void testAccountCreate() AccountInfo info = new AccountInfo()infoAcctName = Manoj Cheenath infoAcctNumber = 12345 Account acct =SpecialAccountscreateAccount(info) Systemassert(acct = null)
AJAX を使用してこの Web サービスを呼び出すことができます詳細は「AJAX のApex」 (ページ 82)を参照してください
Web サービスメソッドのオーバーロードSOAP およびWSDL ではメソッドをオーバーロードできませんその結果ApexではwebServiceキーワードでマークされた 2 つのメソッドに同じ名前を付けることはできません同じクラスで同じ名前を持つWeb サービスメソッドを使用するとコンパイル時エラーが発生します
Apex メソッドの Web サービスとしての公開 Version 180 | Web サービスメソッドのオーバーロード | 172
第 11 章
Apex を使用したコールアウトの呼び出し
Apex コールアウトを使用して外部 Web サービスへのコールを作成またはApexスクリプトから HTTP 要求を送信して応答を受信すること
トピック
bull リモート サイト設定の追加 によってApex を外部サービスとを密接に統合することができますbull SOAP サービス WSDL ドキュメ
ントからのクラスの定義Apex はSOAP および WSDLまたは HTTP サービス (RESTful サービス) を使用する Web サービスと統合できます
bull HTTP コールアウトの呼び出し メモ Apex コールアウトが外部サイトを呼び出す前にそのサイトを [リモートサイトの設定] ページで登録する必要がありまbull 証明書の使用
bull コールアウトの制限 す登録しない場合コールアウトが失敗しますSalesforcecomでは認証されていないネットワーク アドレスへのコールが行われないようにします
2 種類のコールアウトの詳細は次の項目を参照してください
bull SOAP サービス WSDL ドキュメントからのクラスの定義 (ページ174)
bull HTTP コールアウトの呼び出し (ページ 181)
ヒント コールアウトによってApex は外部 Web または HTTPサービスを呼び出すことができますApex Web サービスを使用すると外部アプリケーションはWeb サービスを使用して Apexメソッドを呼び出すことができます
リモートサイト設定の追加
Apex コールアウトが外部サイトを呼び出す前にそのサイトを [リモートサイトの設定] ページで登録する必要があります登録しない場合コールアウトが失敗しますSalesforcecomでは認証されていないネットワークアドレスへのコールが行われないようにします
リモートサイト設定を追加する手順は次のとおりです
1 [設定] [セキュリティのコントロール] [リモートサイト設定] をクリックします2 [新規リモートサイト] をクリックします3 [リモートサイト名]には分かりやすい名前を入力してください4 リモートサイトの URL を入力します5 必要に応じてサイトの説明を入力します6 [保存] をクリックします
SOAP サービス WSDL ドキュメントからのクラスの定義
クラスはローカルハードドライブやネットワークに保管されている WSDL ドキュメントから自動的に生成されます WSDL ドキュメントを使ってクラスを作成すると開発者は Apex スクリプトの中で外部 Web サービスを呼び出すことができます
メモ 可能な場合にはアウトバウンドメッセージを使用して統合ソリューションを処理します必要な場合に限りサードパーティの Web サービスの呼び出しを使用します
WSDL から Apex クラスを作成する手順は次のとおりです
1 アプリケーションで[設定] [開発] [Apex クラス] をクリックします2 [WSDL からの生成] をクリックします3 [参照] をクリックしてローカルハードドライブまたはネットワーク上の WSDL ドキュメントを選択する
かフルパスを入力しますこの WSDL ドキュメントが作成する Apex クラスの基礎となりますが1 MB以下である必要があります
メモ
指定した WSDL ドキュメントに送信ポートを参照する SOAP エンドポイントの場所が記載されている場合があります
セキュリティ上の理由からSalesforcecom では指定できる送信ポートを次の 1 つに制限します
bull 80 このポートはHTTP 接続のみを受け付けますbull 443 このポートはHTTPS 接続のみを受け付けますbull 7000-10000 (7000 と 10000 も含む) これらのポートはHTTP 接続または HTTPS 接続を受け付け
ます
4 [WSDL を解析] をクリックしてWSDL ドキュメントの内容を確認しますアプリケーションがWSDLドキュメント内の名前空間それぞれのデフォルトクラス名を生成しエラーがあれば報告しますWSDL に
Apex を使用したコールアウトの呼び出し Version 180 | リモート サイト設定の追加 | 174
Apex クラスがサポートしていないスキーマタイプまたはスキーマ構造が含まれているか結果生成されるクラス名が100000文字というApexクラスの制限を超える場合には解析は失敗しますたとえばSalesforcecomSOAP API WSDL は解析できません
5 必要に応じてそのクラス名を変更しますそれぞれの名前空間に対して同じクラス名を使用することにより1 つのクラスに複数の WSDL 名前空間を保存できますがApex クラスは合計 100000 文字以内にしてください
6 [Apex の生成] をクリックしますウィザードの最終ページにはどのクラスが正常に生成されたか他のクラスからのエラーがあればそれも含めて表示されます生成が成功した場合には生成されたコードを表示するためのリンクも示されます
正常に生成された Apex クラスにはWSDL ドキュメントで示されていたサードパーティ Web サービスを呼び出すスタブとタイプクラスが含まれていますこれらのクラスによりApex から外部の Web サービスを呼び出すことができますWeb サービスコールの SOAP 要求および応答は 1 MB 以下に制限されています
生成された Apex については次の点にご注意ください
bull WSDL ドキュメントに Apex の予約語が含まれている場合はApex クラスが生成されるときにその語の後ろに「_x」が付きますたとえばWSDL ドキュメントに「limit」があると生成されるApexクラスでは「limit_x」になります「予約キーワード (ページ397)」を参照してくださいApex変数名でサポートされていない WSDL の要素名の文字の処理の詳細については「WSDL 使用についての考慮事項 (ページ 180)」を参照してください
bull WSDL の操作に複数の要素がある出力メッセージがある場合生成された Apex は内部クラスの要素をラップしますWSDL 操作を示す Apex メソッドは各要素の代わりに内部クラスを返します
WSDL からクラスを生成したあとWSDL で参照される外部サービスを呼び出すことができます
メモ このトピックの残りのサンプルを使用する前に「生成されるコードについて」から Apex クラスdocSampleClassをコピーして組織に追加する必要があります
外部サービスの呼び出しWSDL ドキュメントを使用して Apex クラスを生成した後外部サービスを呼び出すにはApex スクリプトにstub のインスタンスを作成してそれにメソッドをコールしますたとえばApexから StrikeIron IP アドレス検索サービスを呼び出すために次のようなスクリプトを作成することができます
stub を作成 strikeironIplookupDNSSoap dns = new strikeironIplookupDNSSoap()
ライセンスのヘッダーを設定 dnsLicenseInfo = new strikeironLicenseInfo()dnsLicenseInfoRegisteredUser = new strikeironRegisteredUser()dnsLicenseInfoRegisteredUserUserID = youcompanycomdnsLicenseInfoRegisteredUserPassword = your-password
Web サービスコールを作成 strikeironIplookupDNSInfo info = dnsDNSLookup(wwwmynamecom)
HTTP ヘッダーのサポートWeb サービスコールアウトに HTTP ヘッダーを設定できるようになりましたたとえばこの機能を使用して認可ヘッダーに Cookie の値を設定できますHTTP ヘッダーを設定するにはinputHttpHeaders_xおよびoutputHttpHeaders_xをスタブに追加します
Apex を使用したコールアウトの呼び出し Version 180 | 外部サービスの呼び出し | 175
メモ API バージョン 160 より前ではコールアウト HTTP 応答はコンテンツタイプのヘッダーに関係なく UTF-8 を使用してデコードされますAPI バージョン 170 移行ではHTTP 応答はコンテンツタイプのヘッダーで指定されたエンコードを使用してデコードされます
次のサンプルでは「生成されるコードについて」 (ページ178)のサンプルWSDL ファイルを使用しています
Web サービスコールアウトの HTTP ヘッダーの送信
docSampleDocSamplePort stub = new docSampleDocSamplePort() stubinputHttpHeaders_x = newMapltString Stringgt()
基本認証ヘッダーの設定
stubinputHttpHeaders_xput(Authorization Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==)
クッキーヘッダーの設定 stubinputHttpHeaders_xput(Cookie name=value)
カスタム HTTP ヘッダーの設定 stubinputHttpHeaders_xput(myHeader myValue)
String input = This is the input string String output = stubEchoString(input)
inputHttpHeaders_xの値を指定すると標準ヘッダーセットを上書きします
Web サービスコールアウトレスポンスからの HTTP レスポンスヘッダーのアクセス
docSampleDocSamplePort stub = new docSampleDocSamplePort() stuboutputHttpHeaders_x =new MapltString Stringgt() String input = This is the input string String output =stubEchoString(input)
クッキーヘッダーの取得 String cookie = stuboutputHttpHeaders_xget(Set-Cookie)
カスタムヘッダーの取得 String myHeader = stuboutputHttpHeaders_xget(My-Header)
outputHttpHeaders_xのデフォルト値は null ですoutputHttpHeaders_xを設定してからレスポンスのヘッダーの内容にアクセスできます
サポートされた WSDL 機能Apex ではドキュメントリテラルでラップした WSDL スタイルと組み込みデータ型のみをサポートしています
Apex タイプスキーマタイプStringxsdanyURI
Booleanxsdboolean
Datexsddate
DatetimexsddateTime
Doublexsddouble
Doublexsdfloat
Integerxsdint
Apex を使用したコールアウトの呼び出し Version 180 | サポートされた WSDL 機能 | 176
Apex タイプスキーマタイプIntegerxsdinteger
Stringxsdlanguage
Longxsdlong
StringxsdName
StringxsdNCName
IntegerxsdnonNegativeInteger
StringxsdNMTOKEN
StringxsdNMTOKENS
StringxsdnormalizedString
StringxsdNOTATION
IntegerxsdpositiveInteger
StringxsdQName
Integerxsdshort
Stringxsdstring
Datetimexsdtime
Stringxsdtoken
IntegerxsdunsignedInt
LongxsdunsignedLong
IntegerxsdunsignedShort
メモ Salesforcecom データ型 anyType はAPI バージョン 150 以降を使用して保存される Apex コードを生成するときに使用する WSDL ではサポートされませんAPI バージョン 140 以前を使用して保存されるコードではanyType は String にマッピングされます
Apex では次のスキーマ構造をサポートしています
bull API バージョン 150 以上を使用して保存した Apex コードの xsdall
bull API バージョン 150 以上を使用して保存した Apex コードの xsdannotation
bull API バージョン 150 以上を使用して保存した Apex コードの xsdattribute
bull API バージョン 150 以上を使用して保存した Apex コードの xsdchoice
bull xsdelementAPI バージョン 150 以上を使用して保存した Apex コードではref属性が次の制限付きでサポートされます
- 名前空間を指定して異なる名前空間で refをコールできます- グローバル要素は refを使用できません- 要素に refが含まれている場合nameも typeを含むことはできません
bull xsdsequence
Apex を使用したコールアウトの呼び出し Version 180 | サポートされた WSDL 機能 | 177
次のデータ型はコールインとして使用されている場合つまり外部Web サービスがApex Web サービスメソッドをコールする場合にのみサポートされていますこれらのデータ型はコールアウトとして使用されている場合つまり Apex Web サービスメソッドが外部 Web サービスをコールする場合はサポートされていません
bull blobbull decimalbull enum
Apex は次のようなその他の WSDL コンストラクタデータ型サービスをサポートしていません
bull RPCエンコード化サービスbull 複数の portTypes複数のサービスまたは複数のバインドを含む WSDL サービスbull 外部スキーマをインポートする WSDL ファイルたとえば次の WSDL フラグメントはサポートされてい
ない外部スキーマをインポートします
ltwsdltypesgt ltxsdschema elementFormDefault=qualifiedtargetNamespace=https3amazonawscomdoc2006-03-01gt ltxsdincludeschemaLocation=AmazonS3xsdgt ltxsdschemagt ltwsdltypesgt
ただし同じスキーマ内のインポートはサポートされています次の例では外部 WSDL は変換しているWSDL に貼り付けられます
ltwsdltypesgt ltxsdschema xmlnstns=https3amazonawscomdoc2006-03-01xmlnsxsd=httpwwww3org2001XMLSchema elementFormDefault=qualifiedtargetNamespace=https3amazonawscomdoc2006-03-01gt
ltxsdelement name=CreateBucketgt ltxsdcomplexTypegt ltxsdsequencegt [] ltxsdschemagtltwsdltypesgt
bull 前の表に記載されていないスキーマタイプbull Salesforcecom WSDL などサイズ制限をこえた WSDL
生成されるコードについて次の例ではWSDL ドキュメントから Apex クラスがどのように作成されるかを示します次のコードではサンプル WSDL ドキュメントを示します
ltwsdldefinitions xmlnshttp=httpschemasxmlsoaporgwsdlhttpxmlnssoap=httpschemasxmlsoaporgwsdlsoap xmlnss=httpwwww3org2001XMLSchemaxmlnssoapenc=httpschemasxmlsoaporgsoapencodingxmlnstns=httpdocsamplecomdocSample targetNamespace=httpdocsamplecomdocSamplexmlnswsdl=httpschemasxmlsoaporgwsdlgt
lt-- Above the schema targetNamespace maps to the Apex class name --gt
lt-- Below the type definitions for the parameters are listedEach complexType and simpleTypeparameteris mapped to an Apex class inside the parent class for the WSDLThen each elementin the complexType is mapped to a public field inside the class --gt
ltwsdltypesgt ltsschema elementFormDefault=qualifiedtargetNamespace=httpdocsamplecomdocSamplegt ltselement name=EchoStringgtltscomplexTypegt ltssequencegt ltselement minOccurs=0 maxOccurs=1 name=inputtype=sstring gt ltssequencegt ltscomplexTypegt ltselementgt ltselementname=EchoStringResponsegt ltscomplexTypegt ltssequencegt ltselement minOccurs=0 maxOccurs=1name=EchoStringResult type=sstring gt ltssequencegt ltscomplexTypegt ltselementgtltsschemagt ltwsdltypesgt
Apex を使用したコールアウトの呼び出し Version 180 | 生成されるコードについて | 178
lt--The stub below defines operations --gt
ltwsdlmessage name=EchoStringSoapIngt ltwsdlpart name=parameters element=tnsEchoStringgt ltwsdlmessagegt ltwsdlmessage name=EchoStringSoapOutgt ltwsdlpart name=parameterselement=tnsEchoStringResponse gt ltwsdlmessagegt ltwsdlportType name=DocSamplePortTypegtltwsdloperation name=EchoStringgt ltwsdlinput message=tnsEchoStringSoapIn gt ltwsdloutputmessage=tnsEchoStringSoapOut gt ltwsdloperationgt ltwsdlportTypegt
lt--The code below defines how the types map to SOAP --gt
ltwsdlbinding name=DocSampleBinding type=tnsDocSamplePortTypegt ltwsdloperationname=EchoStringgt ltsoapoperationsoapAction=urndotnetcallouttestsoapsforcecomEchoString style=document gtltwsdlinputgt ltsoapbody use=literal gt ltwsdlinputgt ltwsdloutputgt ltsoapbody use=literalgt ltwsdloutputgt ltwsdloperationgt ltwsdlbindinggt
lt-- Finally the code below defines the endpoint which maps to the endpoint in the class--gt
ltwsdlservice name=DocSamplegt ltwsdlport name=DocSamplePortbinding=tnsDocSampleBindinggt ltsoapaddresslocation=httpwwwqaresponderinfoWebServicesDocSampleasmx gt ltwsdlportgtltwsdlservicegt ltwsdldefinitionsgt
この WSDL ドキュメントから次の Apex クラスを生成することができます
Generated by wsdl2apex
public class docSample
public class EchoStringResponse_element
public String EchoStringResult
private String[] EchoStringResult_type_info = new String[] EchoStringResulthttpwwww3org2001XMLSchema string01false
private String[] apex_schema_type_info = new String[] httpdocsamplecomdocSampletrue
private String[] field_order_type_info = new String[] EchoStringResult
public class DocSamplePort
public String endpoint_x = httpwwwqaresponderinfoWebServicesDocSampleasmx
private String[] ns_map_type_info = new String[] httpdocsamplecomdocSampledocSample
public String EchoString(String input) docSampleEchoString_element request_x = newdocSampleEchoString_element() docSampleEchoStringResponse_element response_xrequest_xinput = input MapltString docSampleEchoStringResponse_elementgt response_map_x= new MapltString docSampleEchoStringResponse_elementgt() response_map_xput(response_xresponse_x) WebServiceCalloutinvoke( this request_x response_map_x newString[]endpoint_x urndotnetcallouttestsoapsforcecomEchoStringhttpdocsamplecomdocSample EchoString httpdocsamplecomdocSampleEchoStringResponse docSampleEchoStringResponse_element ) response_x =response_map_xget(response_x) return response_xEchoStringResult
public class EchoString_element
public String input private String[] input_type_info = new String[] inputhttpwwww3org2001XMLSchema string01false private String[]
Apex を使用したコールアウトの呼び出し Version 180 | 生成されるコードについて | 179
apex_schema_type_info = new String[] httpdocsamplecomdocSample true privateString[] field_order_type_info = new String[]input
元の WSDL ドキュメントからの次のマッピングに注意してください
bull WSDL ターゲット名前空間は Apex クラス名にマップしますbull 複雑なデータ型はクラスになりますデータ型の各要素はクラスの公開項目ですbull WSDL ポート名は stub クラスにマップしますbull WSDL の各処理は公開メソッドにマップします
上記で生成されたクラスを使用して外部 Web サービスを呼び出すことができます次のコードは外部サーバーで echoStringメソッドをどのようにコールするかを示しています
docSampleDocSamplePort stub = new docSampleDocSamplePort() String input = 入力文字列ですString output = stubEchoString(input)
WSDL 使用についての考慮事項WSDL から Apex クラスを生成する場合次の点に注意してください
ヘッダーのマッピング
WSDL ドキュメントで定義されているヘッダーは生成されたクラスの stub の公開項目となりますこれはAJAX Toolkit および Net と同様です
ランタイムイベントについて
Apex スクリプトが外部サービスへのコールアウトを作成している場合次のことがチェックされます
bull 要求サイズが 1 MB 未満であることbull 応答サイズが 1 MB 未満であることbull HTTP 要求またはWeb サービスコールを作成する場合のタイムアウト制限の詳細は「コールアウトの制限
(ページ 184)」を参照してくださいbull Apex クラスでは循環参照が無効であることbull Salesforcecom ドメインへの複数のループバック接続が無効であることbull エンドポイントにアクセスする場合[設定] [セキュリティ] [リモートサイト設定] で登録することbull データベース接続が停止しないようトランザクションが開かれないこと
変数名でサポートされていない文字について
WSDL ファイルにはApex変数名で使用できない要素名を使用することができますWSDL ファイルからApex変数名を生成する場合次のルールが適用されます
bull 要素名の最初の文字がアルファベットでない場合x文字が生成された Apex 変数名の先頭に追加されますbull 要素名の最後の文字が Apex 変数名で使用できない場合x文字が生成された Apex 変数名に追加されますbull 要素名に Apex 変数名で使用できない文字が含まれている場合その文字は (_) 文字に置き換えられますbull 要素名に Apex 変数名で使用できない文字が 1 行に 2 文字含まれている場合最初の文字はアンダースコア
(_) 文字に置き換えられ2 番目の文字は x文字に置き換えられますこれによりApex では使用できない 2つの連続したアンダースコアで変数名が生成されないようにします
Apex を使用したコールアウトの呼び出し Version 180 | WSDL 使用についての考慮事項 | 180
bull 2 つのパラメータa_および a_xを使用する処理があるとします生成されたApexには 2 つの変数がありいずれもa_xという名前ですクラスはコンパイルしません手動でApexを編集しいずれかの変数名を変更する必要があります
WSDL ファイルから生成したクラスのデバッグ
Forcecom Web サービスNetおよび Axis を使用してコードをテストします他のツールを使用する場合問題が発生する場合があります
デバッグヘッダーを使用して要求の XML を返しSOAP メッセージに応答して問題の検出を行います詳細は「Apex の Web サービス API コールと SOAP ヘッダー」 (ページ 406)を参照してください
HTTP コールアウトの呼び出し
Apex ではHTTP サービスを使用しGETPOSTPUTおよび DELETE のような HTTP 要求を作成する組み込みクラスをいくつか提供します
これらの HTTP クラスを使用してREST ベースのサービスに統合できますWSDL からApexスクリプトを生成する別のオプションとしてSOAP ベースの Web サービスに登場することもできますWSDL で開始する代わりに HTTP クラスを使用して要求および応答の SOAP メッセージの構造をより高度に処理します
詳細およびサンプルは「HTTP (RESTful) サービスクラス」 (ページ349)を参照してくださいまたForcecomToolkit for Google Data APIs を HTTP コールアウトの使用を拡張します
証明書の使用
コールアウトによって Salesforcecomで生成されたまたは認証機関 (CA) が署名した証明書を送信して双方向の SSL 認証を使用できますコールアウトの対象が証明書を受け取るとセキュリティが拡張され証明書を使用して要求をキーストアに対して認証できます
コールアウトの双方向 SSL 認証を有効にする手順は次のとおりです
1 証明書を生成します2 証明書をコードと統合します「SOAP サービスでの証明書の使用」および「HTTP 要求での証明書の使用」
を参照してください3 サードパーティに接続し自己署名の証明書を使用している場合Salesforcecom 証明書を共有し証明書を
キーストアに追加できるようにします組織内で使用される別のアプリケーションに接続している場合クライアント証明書を要求するようWeb またはアプリケーションサーバーを設定しますこのプロセスは使用する Web サーバーまたはアプリケーション サーバーの種類によって異なりますJava の Tomcat を使用して両方向 SSL を設定する方法についてその例がhttpwwwvorburgerchblog1200608setting-up-two-way-mutual-ssl-withhtml のブログに投稿されています
4 コールアウトのリモートサイト設定を設定しますApexコールアウトが外部サイトを呼び出す前にそのサイトを [リモートサイトの設定] ページで登録する必要があります登録しない場合コールアウトが失敗します
Apex を使用したコールアウトの呼び出し Version 180 | HTTP コールアウトの呼び出し | 181
証明書の生成Salesforcecom で生成された自己署名証明書または認証機関 (CA) で署名された証明書を使用できますコールアウトの証明書を生成する手順は次のとおりです
1 外部 Web サイトが自己署名の証明書を承認するかどうかまたは CA の署名が必要かどうかに基づいて作成する証明書の種類を決定します証明書を作成した後に証明書の種類を変更することはできません
2 [設定] [セキュリティコントロール] [証明書およびキーの管理] をクリックし[自己署名証明書の作成]または [CA 署名の証明書を作成] をクリックします証明書の種類を選択します後で変更することはできません
3 Salesforcecom 証明書の説明ラベルを入力しますこの名前は証明書を参照する場合主に管理者によって使用されます
4 一意名を入力します入力した証明書ラベルに従って名前が自動的に入力されますこの名前はアンダースコアと英数字のみを含み組織内で一意の名前にする必要があります最初は文字であることスペースは使用しない最後にアンダースコアを使用しない2 つ続けてアンダースコアを使用しないという制約がありますForcecom Web サービス API または Apex を使用して証明書を参照する場合一意名を使用します
5 生成した証明書およびキーのキーサイズを選択します1024を選択すると1024 ビットのキーを使用する証明書を生成し1 年間有効です2048を選択すると2048 ビットのキーを使用する証明書を生成し2 年間有効ですセキュリティ上の理由により2048を指定することをお勧めします
メモ Salesforcecom 証明書を保存するとキーサイズは変更できません
6 CA 署名証明書を作成している場合次の情報も入力する必要がありますこれらの項目を結合して一意の証明書を生成します
説明項目
署名付き証明書を要求する会社の完全修飾名形式は通常httpwwwmycompanycomとなります
Common Name
証明書に関連する電子メールアドレスEmail Address
会社の法律上の名前Company
マーケティング会計など証明書を使用する会社の部署
Department
会社がある都市City
会社がある州State
会社がある国を示す 2 文字のコードアメリカ合衆国の場合値は USです
Country Code
7 [保存] をクリックします
正常に Salesforcecom 証明書を保存した後証明書および対応するキーが自動的に生成されます
CA 署名証明書を作成した後使用する前に署名付き証明書をアップロードする必要がありますSalesforcecomオンラインヘルプの「CA 署名証明書のアップロード」を参照してください
Apex を使用したコールアウトの呼び出し Version 180 | 証明書の生成 | 182
SOAP サービスでの証明書の使用Salesforcecomで証明書を生成した後SOAP Web サービスへのコールアウトの双方向認証をサポートできます
証明書を Apex を統合する手順は次のとおりです
1 他社から Web サービスから WSDL を受け取るか接続するアプリケーションから生成します2 Web サービスの WSDL から Apex クラスを生成します「SOAP サービス WSDL ドキュメントからのクラ
スの定義 (ページ 174)」を参照してください3 生成された Apex クラスにはWSDL ドキュメントで示されていた他社の Web サービスを呼び出すスタブが
含まれていますApexクラスを編集し値をスタブクラスのインスタンスのclientCertName_x変数に割り当てます値は [設定] [セキュリティコントロール] [証明書とキーの管理] を使用して生成した証明書の一意名と一致する必要があります
次の例では前の手順の最後のステップを説明し「生成されるコードについて」 (ページ178)のサンプルWSDLファイルを使用していますこの例ではDocSampleCertの一意名で証明書を生成したと想定します
docSampleDocSamplePort stub = new docSampleDocSamplePort() stubclientCertName_x =DocSampleCert String input = これは入力文字列です String output = stubEchoString(input)
組織のサードパーティから取得した証明書を使用する従来のプロセスがありますbase64 でクライアント証明書のキーをエンコードしstub のclientCert_x変数に割り当てますプライベートキーを保護するセキュリティのベストプラクティスに従っていないためSalesforcecom 証明書を使用するより安全性が低くなりますSalesforcecom 証明書を使用する場合プライベートキーは Salesforcecom の外部に保存されません
メモ [設定] [開発] [API] [クライアント証明書の生成]で生成したクライアント証明書は使用しないでください従来のプロセスを使用する場合組織のサードパーティから取得された証明書を使用する必要があります
次の例では従来のプロセスを説明し「生成されるコードについて」 (ページ178)のサンプルWSDL ファイルを使用しています
docSampleDocSamplePort stub = new docSampleDocSamplePort() stubclientCert_x =MIIGlgIBAzCCBlAGCSqGSIb3DQEHAaCCBkEEggY9MIIGOTCCAe4GCSqGSIb3DQEHAaCCAd8EggHb+MIIB1zCCAdMGCyqGSIb3DQEMCgECoIIBgjCCAX4wKAYKKoZIhvcNAQwBAzAaBBSaUMlXnxjzpfdu+6YFwZgJFMklDWFyvCnQeuZpN2E+Rb4rf9MkJ6FsmPDA9MCEwCQYFKw4DAhoFAAQU4ZKBfaXcN45w+9hYm215CcA4n4d0EFJL8jr68wwKwFsVckbjyBzzYHO6AgIEAA==
キーストアのパスワード stubclientCertPasswd_x = passwd
String input = This is the input string String output = stubEchoString(input)
HTTP 要求での証明書の使用Salesforcecom で証明書を生成した後HTTP 要求へのコールアウトの双方向認証をサポートできます
証明書を Apex を統合する手順は次のとおりです
1 証明書を生成します証明書の一意名を入力します2 Apex でHttpRequestクラスの setClientCertificateNameメソッドを使用しますこのメソッドの引数
に使用される値は前のステップで生成された証明書の一意名に一致しなければなりません
Apex を使用したコールアウトの呼び出し Version 180 | SOAP サービスでの証明書の使用 | 183
次の例は前述の手順の最後のステップを示しますこの例ではDocSampleCertの一意名で証明書を生成したと想定します
HttpRequest req = new HttpRequest() reqsetClientCertificateName(DocSampleCert)
コールアウトの制限
Apex スクリプトでHTTP 要求または Web サービスコールに対するコールアウトを実行する場合に次の制限が適用されますWeb サービスは Forcecom Web サービス API コールの場合または外部 Web サービスコールの場合があります
bull 1 つの Apex トランザクションでHTTP 要求または API コールに対するコールアウトを最大 10 回実行できます
bull HTTP サービスまたは Web サービスのコールアウトの要求または応答の最大サイズは 1 MB ですbull デフォルトのタイムアウトが 10 秒であることカスタムタイムアウトはコールアウトごとに定義できます
最小値は 1 ミリ秒最大値は 60 秒ですWeb サービスまたは HTTP コールアウトのカスタムタイムアウトの設定方法については次の例を参照してください
bull 1 つの Apex トランザクションによる各コールアウトのタイムアウトの累積値は最大 120 秒です累積値とは特定のApexトランザクションによって呼び出されたすべてのコールアウトのタイムアウトを合計した値です
次にWeb サービスコールアウトのカスタムタイムアウトの設定についての例を示します
docSampleDocSamplePort stub = new docSampleDocSamplePort() stubtimeout_x = 2000 タイムアウト (ミリ秒)
次にHTTP コールアウトのカスタムタイムアウトの設定についての例を示します
HttpRequest req = new HttpRequest() reqsetTimeout(2000) タイムアウト (ミリ秒)
Apex を使用したコールアウトの呼び出し Version 180 | コールアウトの制限 | 184
第 12 章
参照
Apex リファレンスにはApex 言語についての情報が含まれていますトピック
bull データ操作言語 (DML) の操作 データベース内のデータの操作に使用されます
bull Apex のデータ操作言語 (DML) 操作
bull 標準クラスおよびメソッドプリミティブデータ型コレクションsObjectsApex のほかの部分に使用できます
bull Apex 標準クラスおよび標準メソッド
bull Apex クラス 使用可能な組み込みクラスbull Apex クラス
Apex のデータ操作言語 (DML) 操作
データベース内のデータを取得挿入削除更新するためにデータ操作言語 (DML)操作を使います
以下の2つの異なる形式を使ってDML操作を実行可能です
bull Apex DMLステートメントは例えば以下のものです
insert SObject[]
bull Apex DMLデータベースメソッドは例えば以下のものです
DatabaseSaveResult[] result = DatabaseInsert(SObject[])
ほとんどのDML操作がどちらの方式でも利用可能な一方でいくつかはどちらか片方にしか存在しません
異なるDML操作形式は異なるタイプの例外処理を可能にします
bull try catchブロックを使うことによって 大量のDML処理中に発生するエラーをコントロールフローを即時に遮るApex例外として出したい場合DMLを使ってくださいこの機能はほとんどのデータベースの手続き型言語における例外の処理方法に似ています
bull 大量のDML操作の部分的成功を可能にしたいならばデータベースメソッドを使ってください記録が失敗した場合もDML操作の残りは成功可能ですアプリケーションは次に記録を拒否し操作を再試行しますこの方式を使っている場合DML例外エラーを決して出さないコードを書くことができます代わりにコードは成功と失敗を判断する適切な結果列を使用可能ですDMLデータベースメソッドはDMLステートメントのように出された例外構文を含むことも可能です
以下のApex DML操作が利用可能です
bull convertLead1
bull delete
bull insert
bull merge2
bull undelete
bull update
bull upsert
システムコンテキストと共有ルール
ほとんどのDML操作はシステムコンテキストにて実行され現在のユーザのプロファイル許可フィールドレベルセキュリティ組織全体のデフォルト役割階層のポジションおよび共有ルールを無視しますしかしながらDML操作がwith sharingキーワードによって定義されたクラス内で呼び出された場合現在のユーザの共有ルールが考慮されます詳細はwith sharingまたはwithout sharingキーワードを使う (ページ 105)を参照してください
1convertLeadだけがデータベースメソッドとして利用可能です
2mergeだけがApex DMLステートメントとして利用可能です
参照 Version 180 | Apex のデータ操作言語 (DML) 操作 | 186
文字列項目の切り捨てと API バージョン
項目に割り当てた文字列値が長すぎる場合API バージョン 150 以上を使用して保存 (コンパイル) した Apex クラスにはランタイムエラーが発生します
ConvertLead 操作convertLead DML操作は 任意に 商談と同様にリードを取引先と取引先担当者に変換します
メモ convertLeadconvertLeadだけがデータベースメソッドとして利用可能です
データベースメソッド構文
bull LeadConvertResult DatabaseconvertLead(LeadConvert leadToConvert Boolean opt_allOrNone)bull LeadConvertResult[] DatabaseconvertLead(LeadConvert[] leadsToConvert Boolean opt_allOrNone)
オプションの opt_allOrNoneパラメータは一部のみの成功を許可するかどうかを指定しますこのパラメータを偽に設定した場合レコードが失敗しても残りの DML 操作を成功させることができますこのメソッドは成功したレコード失敗したレコードおよびその理由の確認に使用できる結果オブジェクトを返します
ルールとガイドライン
リードを変換する際は次のルールやガイドラインを考慮する必要があります
bull 項目マッピングシステムは標準リード項目を標準取引先取引先担当者商談項目に自動的に対応付けますカスタムリードのフィールドに関してはSalesforcecomの管理者がカスタムアカウントコンタクト商談フィールドのマッピング方法を指定することができます項目マッピングの詳細はSalesforcecom オンラインヘルプを参照してください
bull 差し込み項目 データが既存のアカウントとコンタクトオブジェクトにマージされた場合ターゲットオブジェクト内の空白のフィールドは上書きされます既存データ IDを含む は上書きされません唯一の例外はターゲットコンタクトオブジェクト内のLeadSourceフィールドがソースLeadConvertオブジェクト内のLeadSourceフィールドの内容によって上書きされる場合においてLeadConvertオブジェクトのsetOverwriteLeadSourceにTrueを指定した場合です
bull レコードタイプ組織でレコードタイプを使用している場合新しい所有者のデフォルトのレコードタイプはリード変換時に作成されたレコードに割り当てられますリードを変換するユーザのデフォルトのレコードタイプによって変換時に使用できるリードのソース値が決まります必要なリードのソース値が使用できない場合リードを変換するユーザのデフォルトのレコードタイプに値を追加しますレコードタイプの詳細はSalesforcecom オンラインヘルプを参照してください
bull 選択リスト値システムは空の標準リード選択リスト項目を対応付けるときに取引先取引先担当者商談のデフォルトの選択リストを割り当てます組織でレコードタイプを使用している場合空の値は新しいレコード所有者のデフォルトの選択リストの値で置き換えられます
bull 自動フィード登録リードを取引先取引先担当者および (オプションで) 商談に変換すると生成されたレコードの所有者が自動的に登録されリード所有者はリードレコードから登録解除されますリードに登録されたユーザは生成されたレコードに登録されリードからは登録解除されますリードに登録されたリード所有者およびその他のユーザは新規フィードで取引先取引先担当者商談のレコードの変更を確認できます[設定] [個人情報] [個人情報] の [フィードの自動登録を無効化]項目がオフであれば登録できますレコードへの変更をユーザのホームページのニュースフィードに表示できるようレコードに登録できます登録するとSalesforcecom のレコードの最新状況を確認するのに役立ちます
参照 Version 180 | ConvertLead 操作 | 187
リードの変換の基本ステップ
リードの変換は次の基本ステップに従います
1 アプリケーションがコンバートされるリードのIDを決定します2 状況に応じてアプリケーションはリードがマージされるアカウントのIDを決定しますアプリケーショ
ンはリード名にマッチするアカウントを探すためにSOQLを以下の例のように使用することができます
select id name from account where name=CompanyNameOfLeadBeingMerged
3 状況に応じてアプリケーションはそのコンタクトまたはリードがマージされるアカウントのIDを決定しますアプリケーションはリード名にマッチするコンタクトを探すためにSOQLを以下の例のように使用することができます
select id name from contact where firstName=FirstName and lastName=LastName andaccountId = 001
4 状況に応じてアプリケーションは商談がリードから作成されるかどうかを決定可能です5 すべての可能なコンバートされた状況オプションを取得するためにアプリケーションはLeadSourceテーブル
に問い合わせます(SELECT FROM LeadStatus WHERE IsConverted=1)それからコンバートされた状況の値を選択します
6 アプリケーションはconvertLeadを呼び出します7 アプリケーションは返された結果を通して繰り返され各リードにどのコンバージョンが成功したか決定
するためにに各LeadConvertResultオブジェクトを検査します8 オプションでキューが所有するリードを変換する場合は所有者を指定する必要がありますこれはキュー
が取引先と取引先担当者を所有することができないからです既存の取引先または取引先担当者を指定する場合も所有者を指定する必要があります
LeadConvertオブジェクトメソッド
convertLeadデータベースメソッドは最高で100のLeadConvertオブジェクトをを受け付けますLeadConvertオブジェクトは以下のメソッドをサポートします
説明戻り値の型引数名前
リードのマージ先アカウントのIDを設定しますIDgetAccountId
リードのマージ先取引先担当者のIDを設定しますIDgetContactId
コンバートされたリードのリードステータス値を取得します
StringgetConvertedStatus
変換するリードのIDを取得しますIDgetLeadID
作成する商談名を取得しますStringgetOpportunityName
新しく作成する取引先取引先担当者商談の所有者となるユーザの ID を取得します
IDgetOwnerID
リード変換時に商談を作成するかどうかを指定 (デフォルトの falseで商談を作成しtrueでは作成しない)します
BooleanisDoNotCreateOpportunity
参照 Version 180 | ConvertLead 操作 | 188
説明戻り値の型引数名前
ターゲットの取引先担当者オブジェクトの LeadSource
項目にソースのリードオブジェクトのLeadSource項BooleanisOverWriteLeadSource
目の値を上書きするかどうかを指定します (上書きする場合は true上書きしない場合は falseでデフォルトでは上書きしません)
setOwnerIdで指定された所有者に電子メールの通知を送るかどうかを指定 (送る場合はtrue送らない場合はfalseでデフォルトでは送らない) します
BooleanisSendNotificationEmail
リードのマージ先アカウントのIDを設定します既存アカウント 個人取引先を含む が更新される時のみこの値
VoidID IDsetAccountId
は要求されます該当しない場合はsetAccountIDが指定された場合新しいアカウントが作成されます
リードのマージ先コンタクトのIDを設定します このコンタクトはsetAccountIdで指定されたアカウントに
VoidID IDsetContactId
関連づれられている必要がありますsetAccountIdは指定される必要があります 既存コンタクトを更新する場合のみこの値が必要です
重要 リードをパーソナルアカウントにコンバートする場合setContactIdを指定しないでください指定するとエラーが発生します個人取引先のsetAccountIdのみ指定してください
setContactIDが指定された場合アプリケーションはアカウントに暗黙的に関連付けられた新しいコンタクトを作成しますコンタクト名とその他の既存データは上書きされません LeadSourceフィールドのみが上書きされる設定であるsetOverwriteLeadSourceがTrueに設定されていない限り
コンバートされたリードのリードステータス値を設定しますこのフィールドは必要です
VoidString StatussetConvertedStatus
リードコンバージョン中に商談を作成するかどうか指定しますデフォルト値はfalseですデフォルトで商談
VoidBooleanCreateOpportunity
setDoNotCreateOpportunity
は作成されますリードの商談を作成したくない場合のみこのフラグを trueに設定します
コンバートするリードのIDを設定してくださいこのフィールドは必要です
VoidID IDsetLeadId
作成する商談名を設定してください名前が指定されない場合この値の規定値はリードの会社名になりま
VoidString OppNamesetOpportunityName
すこの項目の文字数は 80 文字までですsetDoNotCreateOpportunityがTrueの場合商談は作成されずこのフィールドは空白のまま残されますそうでない場合はエラーが返されます
参照 Version 180 | ConvertLead 操作 | 189
説明戻り値の型引数名前
ターゲットコンタクトオブジェクト上のLeadSource
フィールドをソースリードオブジェクト内のLeadSource
VoidBooleanOverwriteLeadSource
setOverwriteLeadSource
フィールドの内容で上書きするかどうかを指定する規定値はFalseでそのフィールドを上書きしませんTrueとして指定した場合はターゲットコンタクト用のsetContactIdも指定する必要があります
新しく作成する取引先取引先担当者商談の所有者となるユーザの ID を指定アプリケーションがこの値を
VoidID IDsetOwnerId
指定しない場合は新規オブジェクトのオーナーはリードのオーナーになりますこのメソッドは既存オブジェクトをマージするのには適用不可ですsetOwnerIdが指定された場合ownerIdフィールドは既存アカウントまたはコンタクト内で上書きされません
setOwnerIdによって指定されたオーナーに通知電子メールを送信するか指定します規定値はFalseで送信しません
VoidBooleanSendEmail
setSendNotificationEmail
LeadConvertResultオブジェクト
LeadConvertResultオブジェクトの列はconvertLeadデータベースメソッドで返されますSObject列に関連したLeadConvertResult列内の各エレメントはconvertLeadデータベースメソッド内の SObject[]パラメータとして通過しますつまりLeadConvertResult列内の最初のエレメントはSObject列内の最初のエレメントにマッチしますまた二番目のエレメントは2 番目のエレメントに対応し3 番目以降も同じです1つしかsObjectが渡されない場合LeadConvertResults 列は1つのエレメントしか含みません
LeadConvertResultオブジェクトは以下のメソッドを持っています
説明型名前
新規アカウントのID(新規アカウントが指定されている場合)またはconvertLeadが呼び出された時に指定されたアカウントのID
IDgetAccountId
新規コンタクトのID(新規コンタクトが指定されている場合)またはconvertLeadが呼び出された時に指定されたコンタクトのID
IDgetContactId
エラーが発生した場合エラーコードと説明を提供している1つ以上のデータベースエラーオブジェクト詳細
DatabaseError[]DatabaseError []
getErrors
は「データベースエラーオブジェクトメソッド」(ページ 277)を参照してください
コンバートされたリードのIDIDgetLeadId
新規商談のIDconvertLead呼び起こされた際に作成された場合
IDgetOpportunityId
参照 Version 180 | ConvertLead 操作 | 190
説明型名前
DML操作がこのオブジェクトに対して成功した場合TrueのBoolean値となるそうでない場合Falseとなる
BooleanisSuccess
データベースメソッド例
Lead myLead = new Lead(lastname = Fry company=Fry And Sons) insert myLead
DatabaseLeadConvert lc = new databaseLeadConvert() lcsetLeadId(myLeadid)
LeadStatus convertStatus = [Select Id MasterLabel from LeadStatus where IsConverted=truelimit 1] lcsetConvertedStatus(convertStatusMasterLabel)
DatabaseLeadConvertResult lcr = DatabaseconvertLead(lc) Systemassert(lcrisSuccess())
Delete 操作delete DML 操作は1つ以上の既存の sObject レコード個別アカウントまたはコンタクトなどをあなたの組織のデータベースから削除します deleteはForcecom Web サービス API 内の delete()ステートメントに似ています
DMLステートメント構文delete sObject | RecordID
データベースメソッド構文
bull DeleteResult DatabaseDelete((sObject recordToDelete | RecordID ID) Boolean opt_allOrNone)bull DeleteResult[]DatabaseDelete((sObject[] recordsToDelete | RecordIDs LISTIDs) Boolean opt_allOrNone)
オプションの opt_allOrNoneパラメータは一部のみの成功を許可するかどうかを指定しますこのパラメータを偽に設定した場合レコードが失敗しても残りの DML 操作を成功させることができますこのメソッドは成功したレコード失敗したレコードおよびその理由の確認に使用できる結果オブジェクトを返します
ルールとガイドライン
sObjectレコードを削除する際は以下のルールとガイドラインを考慮してください
bull 参照の完全性を確実にするためにdeleteはカスケーディング削除をサポートします親オブジェクトを削除した場合各子レコードが削除可能な場合自動的に子オブジェクトも削除されます
例えばケースレコードを削除した場合Apexは自動的にそのケースに関連したCaseCommentCaseHistoryおよびCaseSolutionレコードを削除しますしかしながら特定の子レコードは削除不可能か現在使用中の場合親ケースレコード上のdelete操作は失敗します
bull 特定のsObjectsは削除不可能ですあるsObjectレコードを削除するにはsObjectのdeletableプロパティをTrueに設定しておく必要がありますsObjects That Do Not Support DML Operations (ページ 204)も参照してください
bull 最大1000のsObjectレコードを単一のdeleteメソッドに渡すことができます
参照 Version 180 | Delete 操作 | 191
DeleteResult オブジェクト
DatabaseDeleteResult オブジェクトの配列はdeleteデータベースメソッドで返されますSObject 列に関連した DeleteResult 列内の各エレメントはdeleteデータベースメソッドの sObject[]パラメータの列と一致しますつまりDeleteResult 列内の最初のエレメントはsObject 列内の最初のエレメントにマッチしますまた 2番目のエレメントは2 番目のエレメントに対応し 3 番目以降も同じです1つしかsObjectが渡されない場合DeleteResults列は1つのエレメントしか含みません
DatabaseDeleteResult オブジェクトには次のメソッドがあります
説明型名前
エラーが発生した場合エラーコードと説明を提供している1つ以上のデータベースエラーオブジェクト詳細は
DatabaseError[]getErrors
「データベースエラーオブジェクトメソッド」 (ページ277)を参照してください
削除しようとしているsObjectのIDこのフィールドがある値を含む場合オブジェクトの削除は成功しています
IDgetId
このフィールドが空白の場合はその操作はそのオブジェクトに対して成功していません
DML操作がこのオブジェクトに対して成功した場合TrueのBoolean値となるそうでない場合Falseとなる
BooleanisSuccess
DMLステートメント例
以下の例は「DotCom」と名づけられたアカウントの消去を示しています
Account[] doomedAccts = [select id name from account where name = DotCom] try deletedoomedAccts catch (DmlException e) Process exception here
メモ 処理DmlExceptionに関する詳細はBulk DML Exception Handling (ページ 205)を参照してください
データベースメソッド例
以下の例は「DotCom」と名づけられたアカウントの消去を示しています
public class DmlTest Account[] doomedAccts = [select id name from account where name =DotCom] DatabaseDeleteResult[] DR_Dels = Databasedelete(doomedAccts)
Insert 操作insert DML 操作は個別アカウントまたはコンタクトなどの1つ以上のsObjectをあなたの組織のデータに追加しますinsertはSQL の INSERT ステートメントを似ています
DMLステートメント構文insert sObject
参照 Version 180 | Insert 操作 | 192
insert sObject[]
データベースメソッド構文
bull SaveResult Databaseinsert(sObject recordToInsert Boolean opt_allOrNone | databaseDMLOptionsopt_DMLOptions)
bull SaveResult[] Databaseinsert(sObject[] recordsToInsert Boolean opt_allOrNone | databaseDMLOptionsopt_DMLOptions)
オプションの opt_allOrNoneパラメータは一部のみの成功を許可するかどうかを指定しますこのパラメータを偽に設定した場合レコードが失敗しても残りの DML 操作を成功させることができますこのメソッドは成功したレコード失敗したレコードおよびその理由の確認に使用できる結果オブジェクトを返します
例
DatabaseSaveResult[] MySaveResult = DatabaseInsert(MyAccounts false)
オプションのopt_DMLOptionsパラメータは割り当てルール情報または切り捨ての動作などトランザクションの追加データを指定します
例
AssignmentRuleHeader UseDefaultRule databaseDMLOptions dmo = new databaseDMLOptions()dmoAssignmentRuleHeaderUseDefaultRule= true
Lead l = new Lead(company=ABC lastname=Smith) lsetOptions(dmo)
insert l
詳細はデータベース DMLOptions メソッド (ページ 273)を参照してください
ルールとガイドライン
sObjectレコードを挿入する際は以下のルールとガイドラインを考慮してください
bull 特定のsObjectsは挿入不可能ですあるsObjectレコードを作成するにはsObjectのcreateableプロパティをTrueに設定しておく必要があります
bull すべての必要フィールドにnullではない値を入力する必要がありますbull 最大1000のsObjectレコードを単一のinsertメソッドに渡すことができますbull insertステートメントはすべての新規sObjectレコードのID値を自動的に設定しますすでにIDを持ってい
る すなわちすでに組織のデータ内に存在している レコードの挿入はエラーを発生させます詳細については「リスト (ページ 34)」 を参照してください
bull insertステートメントのみが関連sObjectレコードの外部キーIDを設定可能です関連レコードのフィールドはinsertでは更新できません例えば新規コンタクトを挿入した場合AccountIdフィールドの値を設定することによってコンタクトの関連アカウントレコードを指定可能ですしかしながらアカウント自体を更新せずに別のDMLコールを使ってアカウント名を変更することはできません
bull insertステートメントはいつくかのsObjectではサポートされませんDML操作をサポートしないsObject(ページ 204)を参照してください
bull この操作は重複ID値に関してレコードの各かたまりをチェックします重複がある場合は最初の 5 つが処理されます6番目とすべての追加重複IDについてはそのエントリ用のSaveResultが以下に類似したエラーによってマークされますMaximum number of duplicate updates in one batch (5allowed)Attempt to update Id more than once in this API call number_of_attempts
参照 Version 180 | Insert 操作 | 193
SaveResultオブジェクト
SaveResultオブジェクトの列はinsertとupdateのデータベースメソッドで返されますSObject列に関連したSaveResult列内の各エレメントはデータベースメソッド内のsObject[]パラメータの列と一致しますすなわちSaveResult列内の最初のエレメントはsObject列内の最初のエレメントにマッチしますまた二番目のエレメントは二番目のエレメントに対応し三番目以降も同じです1つしかsObjectが渡されない場合 SaveResults列は1つのエレメントしか含みません
SaveResultオブジェクトは以下のメソッドを持っています
説明型名前
エラーが発生した場合エラーコードと説明を提供している1つ以上の
DatabaseError[]getErrors
データベースエラーオブジェクト詳細は「データベースエラーオブジェクトメソッド」 (ページ277)を参照してください
挿入または更新しようとしているsObjectのIDこのフィールドがある値
IDgetId
を含む場合オブジェクトの挿入または更新は成功していますこのフィールドが空白の場合はその操作はそのオブジェクトに対して成功していません
DML操作がこのオブジェクトに対して成功した場合Trueに設定されたBooleanそうでない場合False
BooleanisSuccess
DMLステートメント例
以下の例は「Acme」と名づけられたアカウントの挿入を示しています
Account newAcct = new Account(name = Acme) try insert newAcct catch (DmlExceptione) Process exception here
メモ 処理DmlExceptionに関する詳細はBulk DML Exception Handling (ページ 205)を参照してください
データベースメソッド例
以下の例は「Acme」と名づけられたアカウントの挿入を示しています
Account a = new Account(name = Acme) DatabaseSaveResult[] lsr = Databaseinsert(newAccount[]a new Account(name = Acme) false)
Iterate through the Save Results for(DatabaseSaveResult srlsr) if(srisSuccess())DatabaseError err = srgetErrors()[0]
参照 Version 180 | Insert 操作 | 194
Merge ステートメントmergeステートメントは同じsObjectタイプの最大3つのレコードをレコードの1つにマージしその他を削除し関連レコードを再ペアレント化します
メモ このDML操作はマッチングデータベースシステムメソッドを持っていません
構文merge sObject sObject
merge sObject sObject[]
merge sObject ID
merge sObject ID[]
最初のパラメータは他のレコードのマージ先のマスターレコードを表します二番目のパラメータはマージされてから削除される1つまたは2つの他のレコードを表しますこれらの他のレコードを単一のsObjectレコードまたはIDとしてもしくは2つのsObjectレコードまたはIDとしてmergeステートメントにパスすることができます
ルールとガイドライン
sObjectレコードをマージする際は以下のルールとガイドラインを考慮してください
bull リード コンタクトおよびアカウントだけがマージ可能ですDML操作をサポートしないsObject (ページ204)を参照してください
bull マスターレコードと最大2つのsObjectを1つのmergeメソッドにパスすることができます
リード取引先取引先担当者の結合の詳細はSalesforcecom オンラインヘルプを参照してください
例
以下の例は2つの「Acme Inc」と「Acme」と名づけられたアカウントを1つのレコードにマージします
ListltAccountgt ls = new ListltAccountgtnew Account(name=Acme Inc)new Account(name=Acme)insert ls Account masterAcct = [select id name from account where name = Acme Inclimit 1] Account mergeAcct = [select id name from account where name = Acme limit 1]try merge masterAcct mergeAcct catch (DmlException e) Process exception here
メモ DmlExceptionの処理に関する詳細は「大量DML例外処理 (ページ 205)」を参照してください
Undelete 操作undeleteDML操作は個別アカウントまたはコンタクトなどの1つ以上のsObjectをあなたの組織のごみ箱から復元させますundeleteはSQLのUNDELETEステートメントを似ています
DMLステートメント構文undelete sObject | RecordID
参照 Version 180 | Merge ステートメント | 195
undelete sObject[] | LISTID[]
データベースメソッド構文
bull UndeleteResult DatabaseUndelete((sObject recordToUndelete | RecordID ID) Boolean opt_allOrNone)bull UndeleteResult[] DatabaseUndelete((sObject[] recordsToUndelete | RecordIDs LISTIDs) Boolean
opt_allOrNone)
オプションの opt_allOrNoneパラメータは一部のみの成功を許可するかどうかを指定しますこのパラメータを偽に設定した場合レコードが失敗しても残りの DML 操作を成功させることができますこのメソッドは成功したレコード失敗したレコードおよびその理由の確認に使用できる結果オブジェクトを返します
ルールとガイドライン
sObjectレコードを復元する際は以下のルールとガイドラインを考慮してください
bull 参照の完全性を確実にするためにundeleteは以下のタイプの関連性に関するレコード関連付けを復元させます
- 親取引先 (取引先の [親取引先]項目で指定)- 親ケース (ケースの [親ケース]項目で指定)- 翻訳ソリューションのマスタソリューション (ソリューションの [マスタソリューション]項目で指定)- 取引先責任者のマネージャ (取引先責任者の [上司]項目で指定)- 納入商品に関連付けられている商品 (納入商品の [商品]項目で指定)- 見積に関連付けられている商談 (見積の [商談]項目で指定)- すべてのカスタム参照関係- 取引先およびリレーショングループのリレーショングループメンバー (一部例外あり)- タグ- 記事のカテゴリ公開の状況および割り当てSalesforcecomオンラインヘルプの「記事の管理」を参照
してください
メモ Salesforcecom は置換されていない参照関係のみを復元しますたとえば納入商品が元の商品レコードが元に戻される前に別の商品と関連付けられている場合その納入商品と商品のリレーションは復元されません
bull 特定のsObjectsは復元不可能ですあるsObjectが復元不可能かどうか確認するためにはsObjectのundeletable
プロパティがTrueに設定されているか確認してくださいbull 最大1000のsObjectレコードを単一のundeleteメソッドに渡すことができますbull 結合の結果として削除されたレコードを復元できますが子オブジェクトは再ペアレント化されやり直す
ことはできませんbull マージの結果削除されたレコード含むレコードを削除するにはSOQL問い合わせundeleteを使ってくださ
いステートメントですべてのレコードを問い合わせる (ページ 60)を参照してくださいbull いくつかのsObjectでは復元はサポートされていませんDML操作をサポートしないsObject (ページ 204)を
参照してください
UndeleteResultオブジェクト
DatabaseUndeleteResult オブジェクトの配列はundeleteデータベースメソッドで返されますSObject 列に関連した UndeleteResult 列内の各エレメントはundeleteデータベースメソッドの sObject[]パラメータの列と
参照 Version 180 | Undelete 操作 | 196
一致しますつまりUndeleteResult 列内の最初のエレメントはsObject 列内の最初のエレメントにマッチしますまた 2 番目のエレメントは2 番目のエレメントに対応し3 番目以降も同じです1つしかsObjectがパスされない場合UndeleteResult列は1つのエレメントしか含みません
undeleteResultオブジェクトは以下のメソッドを持っています
説明型名前
エラーが発生した場合エラーコードと説明を提供している1つ以上の
DatabaseError[]getErrors
データベースエラーオブジェクト詳細は「データベースエラーオブジェクトメソッド」 (ページ277)を参照してください
復元しようとしているsObjectのIDこのフィールドがある値を含む場合
IDgetId
オブジェクトの復元は成功していますこのフィールドが空白の場合はその操作はそのオブジェクトに対して成功していません
DML操作がこのオブジェクトに対して成功した場合TrueのBoolean値となるそうでない場合Falseとなる
BooleanisSuccess
DMLステートメント例
以下の例は「Trump」と名づけられたアカウントの復元を示していますALL ROWSキーワードは削除されたレコードとアーカイブされたアクテビティを含むトップレベルと総関係の両方の全ての列を問い合わせます
Account a = new Account(name=AC1) insert(a) insert(newContact(lastName=CarteraccountId=aid))
Account[] savedAccts = [select id name from account where name = Trump ALL ROWS] try undelete savedAccts catch (DmlException e) Process exception here
メモ DmlExceptionの処理に関する詳細は「大量DML例外処理 (ページ 205)」を参照してください
データベースメソッド例
以下の例は「Trump」と名づけられたアカウントの復元を示していますALL ROWSキーワードは削除されたレコードとアーカイブされたアクテビティを含むトップレベルと総関係の両方の全ての列を問い合わせます
public class DmlTest2
public void undeleteExample() Account[] SavedAccts = [select id name from account wherename = Trump ALL ROWS] DatabaseUndeleteResult[] UDR_Dels = Databaseundelete(SavedAccts)for(integer i =0 ilt 10 i++) if(UDR_Dels[i]getErrors()size()gt0) Process any errorshere
参照 Version 180 | Undelete 操作 | 197
Update 操作updateDML操作は個別アカウントまたはコンタクトなどの1つ以上の既存sObjectをあなたの組織のデータを修正します updateはSQLのUPDATEステートメントを似ています
DMLステートメント構文update sObject
update sObject[]
データベースメソッド構文
bull UpdateResult Update(sObject recordToUpdate Boolean opt_allOrNone | databaseDMLOptions opt_DMLOptions)bull UpdateResult[] Update(sObject[] recordsToUpdate[] Boolean opt_allOrNone | databaseDMLOptions
opt_DMLOptions)
オプションの opt_allOrNoneパラメータは一部のみの成功を許可するかどうかを指定しますこのパラメータを偽に設定した場合レコードが失敗しても残りの DML 操作を成功させることができますこのメソッドは成功したレコード失敗したレコードおよびその理由の確認に使用できる結果オブジェクトを返します
オプションのopt_DMLOptionsパラメータは割り当てルール情報または切り捨ての動作などトランザクションの追加データを指定します
詳細はデータベース DMLOptions メソッド (ページ 273)を参照してください
ルールとガイドライン
sObjectレコードを更新する際は以下のルールとガイドラインを考慮してください
bull 特定のsObjectsは更新不可能ですあるsObjectレコードを更新するにはsObjectのupdateableプロパティをTrueに設定しておく必要があります
bull 必要なフィールドを更新する際はnullではない値を入力する必要がありますbull Forcecom Web Services APIの場合とは違ってApexはsObjectレコード上のfieldsToNull列を更新せずに
フィールド値をnullにすることが可能です多くのSOAPプロバイダによるnull値の一貫性のない処理が行われたためAPI はこの列の更新を要求しますApexはForcecomプラットフォーム上だけで実行されるのでこの回避方法は不要です
bull 更新されたsObjectレコードのIDは修正不可能ですが関連レコードIDは修正可能ですbull この操作は重複ID値に関してレコードの各かたまりをチェックします重複がある場合は最初の 5 つ
が処理されます6番目とすべての追加重複IDについてはそのエントリ用のSaveResultが以下に類似したエラーによってマークされますMaximum number of duplicate updates in one batch (5allowed)Attempt to update Id more than once in this API call number_of_attempts
bull updateステートメントはLastModifiedDateLastModifiedByIdSystemModstampなどの特定のフィールドを自動的に修正しますApexスクリプトにてこれらの値を明示的に指定することはできません
bull 最大1000のsObjectレコードを単一のupdateメソッドに渡すことができますbull 単一のupdateステートメントは一度にたった1つのタイプのsObjectしか修正できません例えば修正さ
れたことのある既存コンタクトを通してアカウントフィールドを更新する場合以下の2つのupdateステートメントが必要です
Use a SOQL query to access data for a contact Contact c = [select accountname fromcontact where lastName = Carter limit 1]
参照 Version 180 | Update 操作 | 198
Now we can change fields for both the contact and its associated accountcaccountname = salesforcecom clastName = Roth
データベースを更新するには2 種類のレコードを 個別に更新する必要があります update c 連絡先の名前のみ変更します update caccount 取引先名を更新します
bull いくつかのsObjectでは更新はサポートされていませんDML操作をサポートしないsObject (ページ 204)を参照してください
SaveResultオブジェクト
SaveResultオブジェクトの列はinsertとupdateのデータベースメソッドで返されますSObject列に関連したSaveResult列内の各エレメントはデータベースメソッド内のsObject[]パラメータの列と一致しますすなわちSaveResult列内の最初のエレメントはsObject列内の最初のエレメントにマッチしますまた二番目のエレメントは二番目のエレメントに対応し三番目以降も同じです1つしかsObjectが渡されない場合 SaveResults列は1つのエレメントしか含みません
SaveResultオブジェクトは以下のメソッドを持っています
説明型名前
エラーが発生した場合エラーコードと説明を提供している1つ以上の
DatabaseError[]getErrors
データベースエラーオブジェクト詳細は「データベースエラーオブジェクトメソッド」 (ページ277)を参照してください
挿入または更新しようとしているsObjectのIDこのフィールドがある値
IDgetId
を含む場合オブジェクトの挿入または更新は成功していますこのフィールドが空白の場合はその操作はそのオブジェクトに対して成功していません
DML操作がこのオブジェクトに対して成功した場合Trueに設定されたBooleanそうでない場合False
BooleanisSuccess
DMLステートメント例
以下の例は「Acme」と名づけられた1つのアカウント上のbillingcityフィールドを更新します
Account a = new Account(name=Acme2) insert(a)
Account myAcct = [select id name billingcity from account where name = Acme2 limit 1]myAcctbillingcity = San Francisco try update myAcct catch (DmlException e) Process exception here
メモ DmlExceptionの処理に関する詳細は「大量DML例外処理 (ページ 205)」を参照してください
参照 Version 180 | Update 操作 | 199
データベースメソッド例
以下の例は「Acme」と名づけられた1つのアカウント上のbillingcityフィールドを更新します
Account myAcct = [select id name billingcity from account limit 1] myAcctbillingcity =San Francisco
DatabaseSaveResult SR = databaseupdate(myAcct) for(DatabaseError err SRgetErrors()) process any errors here
Upsert操作upsertDML操作は既存オブジェクトの存在を決定する任意のカスタムフィールドを使って1つのステートメント内で新規sObjectレコードを作成し既存のsObjectレコードを更新します
DMLステートメント構文upsert sObject opt_external_id
upsert sObject[] opt_external_id
opt_external_idは組織のデータ内にすでに存在しているレコードにマッチするために使われるカスタムフィールドを指定する任意の変数ですカスタムフィールドは選択されたExternal Id属性で作成される必要がありますさらに項目に選択された Unique属性がない場合upsertが誤って重複レコードを挿入しないようにコンテキストユーザ「すべてを参照」オブジェクトレベルの権限か「すべてのデータを参照」権限が必要です
opt_external_idが指定されていない場合sObjectレコードのIDフィールドは規定値で使われます
メモ カスタムフィールドがフィールド定義の一部として「一意」と「ABC と abc を重複した値として扱う (大文字小文字の区別なし)」属性を選択している場合のみカスタムフィールドは大文字と小文字を区別しませんこの場合「ABC123」は「abc123」と一致します詳細はSalesforcecom オンラインヘルプの「項目とリレーションの追加」を参照してください
データベースメソッド構文
bull UpsertResult DatabaseUpsert(sObject recordToUpsert SchemaSObjectField External_ID_Field Booleanopt_allOrNone)
bull UpsertResult[] DatabaseUpsert(sObject[] recordsToUpsert SchemaSObjectField External_ID_Field Booleanopt_allOrNone)
External_ID_Fieldパラメータは組織のデータ内にすでに存在しているレコードにマッチするために使われるカスタムフィールドを指定する任意の変数ですカスタムフィールドは選択されたExternal Id属性で作成される必要がありますさらに項目に選択された Unique属性がない場合upsertが誤って重複レコードを挿入しないようにコンテキストユーザ「すべてを参照」オブジェクトレベルの権限か「すべてのデータを参照」権限が必要です
External_ID_Fieldは SchemaSObjectFieldつまり項目トークンですfields特殊メソッドを使用して項目のトークンを検索しますたとえばSchemaSObjectField f = AccountFieldsMyExternalIdとなります
External_ID_Fieldが指定されていない場合sObjectレコードのIDフィールドは規定値で使われます
参照 Version 180 | Upsert操作 | 200
メモ カスタムフィールドがフィールド定義の一部として「一意」と「ABC と abc を重複した値として扱う (大文字小文字の区別なし)」属性を選択している場合のみカスタムフィールドは大文字と小文字を区別しませんこの場合「ABC123」は「abc123」と一致します詳細はSalesforcecom オンラインヘルプの「項目とリレーションの追加」を参照してください
オプションの opt_allOrNoneパラメータは一部のみの成功を許可するかどうかを指定しますこのパラメータを偽に設定した場合レコードが失敗しても残りの DML 操作を成功させることができますこのメソッドは成功したレコード失敗したレコードおよびその理由の確認に使用できる結果オブジェクトを返します
Upsertが挿入または更新を選ぶ方法
Upsertは新規オブジェクトレコードを作成するか既存のものを更新するか決定するためにsObjectのレコードのプライマリキー または指定されている場合外部ID を使います
bull キーがマッチしない場合新規オブジェクトのレコードは作成されませんbull キーがマッチする場合既存オブジェクトのレコードが更新されますbull キーが複数回マッチする場合はエラーが生成されオブジェクトレコードは挿入も更新もされません
ルールとガイドライン
sObjectレコードを upsert する際は以下のルールとガイドラインを考慮してください
bull 特定のsObjectsは挿入も更新も不可能ですあるsObjectレコードを挿入するにはsObjectのcreateableプロパティをTrueに設定しておく必要がありますあるsObjectレコードを更新するにはsObjectのupdateable
プロパティをTrueに設定しておく必要がありますbull レコードが挿入されるすべての必要フィールドにnullでない値を入力する必要がありますbull sObjectレコードのIDは修正不可能ですが関連レコードIDは修正可能ですこのアクションは更新とし
て解釈されますbull upsertステートメントはLastModifiedDateLastModifiedByIdSystemModstampなどの特定のフィー
ルドを自動的に修正しますApexスクリプトにてこれらの値を明示的に指定することはできませんbull 各upsertステートメントは2つの操作から成ります1つはレコードの挿入で1つはレコードの更新で
すこれらの各操作はinsertとupdateのランタイムリミットにそれぞれ制限されます例えば200を超えるレコードをupsertする場合ですべてが更新中の場合エラーが発生します 実行ガバナと制限を理解するを参照してください
bull upsertステートメントのみが関連sObjectレコードのIDを設定可能です関連レコードのフィールドはupsertでは修正できません例えば既存コンタクトを更新する場合AccountIdフィールドの値を設定することによってコンタクトの関連アカウントレコードを指定可能ですしかしながらアカウント自体を更新せずに別のDMLステートメントを使ってアカウント名を変更することはできません
bull いくつかのsObjectではUpsertはサポートされていませんDML操作をサポートしないsObject (ページ204)を参照してください
bull 参照フィールドとして設定されている場合sObjectレコードをupsertするために外部キーを使用可能です詳細はForcecom Web Services API Developers Guide内のhttpwwwsalesforcecomusdeveloperdocsapiindex_CSHhtmfield_typeshtmを参照してください
UpsertResultオブジェクト
DatabaseUpsertResult オブジェクトの配列はupsertデータベースメソッドで返されますSObject列に関連したUpsertResult列内の各エレメントはupsertデータベースメソッドの sObject[]パラメータの列と一致しますつまりUpsertResult列内の最初のエレメントはsObject列内の最初のエレメントにマッチしますまた 2
参照 Version 180 | Upsert操作 | 201
番目のエレメントは2 番目のエレメントに対応し3 番目以降も同じです1つしかsObjectがパスされない場合UpsertResult列は1つのエレメントしか含みません
UpsertResultオブジェクトは以下のメソッドを持っています
説明型名前
エラーが発生した場合エラーコードと説明を提供している1つ以上の
DatabaseError[]getErrors
データベースエラーオブジェクト詳細は「データベースエラーオブジェクトメソッド」 (ページ277)を参照してください
更新または挿入しようとしているsObjectのIDこのフィールドがある値
IDgetId
を含む場合オブジェクトの更新または挿入は成功していますこのフィールドが空白の場合はその操作はそのオブジェクトに対して成功していません
レコードが作成された場合Trueに設定されたBoolean値レコードが更新された場合False
BooleanisCreated
DML操作がこのオブジェクトに対して成功した場合TrueのBoolean値となるそうでない場合Falseとなる
BooleanisSuccess
DMLステートメント例
以下の例は更新します以前Bombayとして知られていた都市の中に位置するすべての既存アカウント用に都市名を更新しSan Franciscoに位置する新規アカウントを挿入します
Account[] acctsList = [select id name billingcity from account where billingcity =Bombay] for (Account a acctsList) abillingcity = Mumbai Account newAcct = newAccount(name = Acme billingcity = San Francisco) acctsListadd(newAcct) try upsertacctsList catch (DmlException e) Process exception here
メモ DmlExceptionの処理に関する詳細は「大量DML例外処理 (ページ 205)」を参照してください
この次の例はアセットと商談ラインアイテムの一対一の関係を保持するためにupsertとAssetオブジェクト上の外部IDフィールド Line_Item_Id__cを使いますupsertを外部IDと一緒に使うことはコード内のDMLステートメントの数を減らしガバナリミットに当たること防ぐことに役立ちます(実行ガバナとリミットを理解するを参照)
参照 Version 180 | Upsert操作 | 202
メモ この例ではLine_Item_Id__cと名づけられたAssetオブジェクト上のカスタムテキストフィールドの追加が必要ですこのフィールドは外部IDとしてフラグ付けされる必要がありますカスタムフィールドに関する詳細はSalesforcecom オンラインヘルプをご覧ください
public void upsertExample() Opportunity opp = [Select Id Name AccountId (Select IdPricebookEntryProduct2Id PricebookEntryName From OpportunityLineItems) From OpportunityWhere HasOpportunityLineItem = true Limit 1]
Asset[] assets = new Asset[]
Create an asset for each line item on the opportunity for (OpportunityLineItemlineItemoppOpportunityLineItems)
This code populates the line item Id AccountId and Product2Id for each asset Asset asset= new Asset(Name = lineItemPricebookEntryName Line_Item_ID__c = lineItemId AccountId= oppAccountId Product2Id = lineItemPricebookEntryProduct2Id)
assetsadd(asset)
try upsert assets Line_Item_ID__c This line upserts the assets list with theLine_Item_Id__c field specified as the Asset field that should be used for matching the record that should be upserted catch (DmlException e) Systemdebug(egetMessage())
DMLステートメント例
以下はデータベースupsertメソッドを使った例です
This class demonstrates and tests the use of the partial processing DML operations
public class dmlSamples
This method accepts a collection of lead records and creates a task for the owner(s) ofany leads that were created as new that is not updated as a result of the upsert operation public static ListltDatabaseupsertResultgt upsertLeads(ListltLeadgt leads)
Perform the upsertIn this case the unique identifier for the insert or update decisionis the Salesforce record ID If the record ID is null the row will be inserted otherwisean update will be attempted ListltDatabaseupsertResultgt uResults =Databaseupsert(leadsfalse)
This is the list for new tasks that will be inserted when new leads are createdListltTaskgt tasks = new ListltTaskgt() for(DatabaseupsertResult resultuResults) if(resultisSuccess() ampamp resultisCreated()) tasksadd(new Task(subject = Follow-up whoId= resultgetId()))
If there are tasks to be inserted insert them Databaseinsert(tasks)
return uResults
public static testMethod void testUpsertLeads() We only need to test the insert sideof upsert ListltLeadgt leads = new ListltLeadgt()
Create a set of leads for testing for(Integer i = 0i lt 100 i++) leadsadd(newLead(lastName = testLead company = testCompany))
Switch to the runtime limit context TeststartTest()
Exercise the method ListltDatabaseupsertResultgt results = DmlSamplesupsertLeads(leads)
Switch back to the test context for limits TeststopTest()
ID set for asserting the tasks were created as expected SetltIdgt ids = new SetltIdgt()
参照 Version 180 | Upsert操作 | 203
Iterate over the results asserting success and adding the new ID to the set for use inthe comprehensive assertion phase below for(DatabaseupsertResult resultresults) Systemassert(resultisSuccess()) idsadd(resultgetId())
Assert that exactly one task exists for each lead that was inserted for(Lead l[selectid (select subject from Tasks) from lead where Id in ids]) SystemassertEquals(1ltaskssize())
DML 操作をサポートしない sObjects
DML操作はApex内の以下のsObjectではサポートされません
bull AccountTerritoryAssignmentRulebull AccountTerritoryAssignmentRuleItembull ApexComponentbull ApexPagebull BusinessHoursbull BusinessProcessbull CategoryNodebull CurrencyTypebull DatedConversionRatebull ProcessInstancebull プロファイルbull RecordTypebull SelfServiceUserbull StaticResourcebull UserAccountTeamMemberbull UserTerritorybull WebLink
Forcecom Web Services API内のこれらのsObjectを作成更新または削除することはできません
DML 操作内で一緒に使用できない sObject
一部の SObject はDML 操作をトランザクションごとに1つのタイプでのみ実行する必要がありますたとえば取引先の挿入ユーザグループグループメンバの挿入は1つのトランザクション内ではできません次の sObjects を 1 つのトランザクション内で同時に使用することはできません
bull Group3
bull GroupMemberbull QueueSObjectbull User4
bull UserRole
3 他の sObjects とともに 1 つのトランザクション内でグループを挿入および更新できます他の DML 操作は使用できません
4roleidが Null として指定されている場合他の sObjects とトランザクション内でユーザを挿入できます
参照 Version 180 | DML 操作をサポートしない sObjects | 204
bull UserTerritorybull テリトリー
重要 主な例外はテスト内でrunAsメソッドを使用している場合です詳細は「システムメソッド」(ページ 285)を参照してください
以下のプロセスを使って1つのクラスで複数タイプのsObjectにおいてDML操作を実行することができます
1 1つのタイプのsObjectにおいてあるDML操作を行うメソッドを作成してください2 二番目のsObjectタイプを操るためのfutureアノテーションを使う二番目のメソッドを作成してください
カスタムコントローラでVisualforceページを使っている場合は1つの要求またはアクションで1つのタイプのObjectにおいてのみDML操作可能ですしかしながら続く要求においてはDML操作を異なるタイプのObjectで実行可能ですたとえば保存ボタンでアカウントを作成した後に送信ボタンでユーザを作成可能です
大量DML例外処理バルク DML 呼び出しの例外処理方法 (トリガ内の再帰的DML操作も含む) は呼び出し元の場所によって異なる処理がされます
bull Apex DMLステートメントから直接発生したバルクDML呼び出しのためにエラーが発生した場合またはデータベースDMLメソッドの all_or_noneパラメータがTrueとして指定されている場合ランタイムエンジンは「オールオアナッシング」ツールに従います1 回の操作の間すべてのレコードを正常に更新する必要がありまたは全体の操作はDMLステートメントの前の時点に即座に戻ります
bull Forcecom Web Services APIから発生したバルクDML呼び出しのせいでエラーが発生した場合ランタイムエンジンは少なくとも部分保存しようとします
1 最初の試行中ランタイムエンジンはすべてのレコードを処理します有効リールや独自のインデックス違反などの問題によるエラーを生成したレコードは除外されます
2 最初の試行中にエラーがある場合ランタイムエンジンはエラーを生成しなかったレコードのみを含む二回目の試行を行います最初の試行中にエラーをい生成しなかったすべてのレコードが処理されレコードがエラーを生成した場合 おそらくレース状態のせいで それも除外されます
3 二回目の試行中に追加エラーがあった場合ランタイムエンジンは初回と二回目にエラーを生成しなかったレコードのみを含む三回目と最後の試行を行いますレコードがエラーを生成した場合全体操作は失敗しエラーメッセージ「Too many batch retries in the presence of Apex triggers and partial failures」が表示されます
メモ二回目と三回目の試行中にガバナ制限は最初の試行の前のオリジナル状態にリセットされます詳細は「実行ガバナーと制限の理解」を参照してください
Apex 標準クラスおよび標準メソッド
Apex にはプリミティブデータ型の式やより複雑なオブジェクト向けの静的メソッドやインスタンスメソッドを含む標準クラスがあります
参照 Version 180 | 大量DML例外処理 | 205
標準静的メソッドは Java に似ており常に次のような形式となります
Classmethod(args)
プリミティブデータ型の標準静的メソッドに暗黙的なパラメータはなくオブジェクトコンテキストを使用せずに呼び出されますたとえば次の式は 175 の値をその他の値を使用せずに最も近い整数に丸めます
MathroundToLong(175)
すべてのインスタンスメソッドはリストセットまたは文字列など特定のデータ型の式に作成されます例
String s = Hello world
Integer i = slength()
メモ メソッドが nullに評価するオブジェクト式で呼び出される場合Apex ランタイムエンジンはNull ポインタの例外を投げます
一部のクラスではそれらのメソッドのグループ化メカニズムとして名前空間を使用しますたとえばmessage
クラスではApexPages 名前空間を使用します
ApexPagesMessage myMsg = new ApexPagesMessage(ApexPagesFATAL エラーメッセージ)
Apex 標準クラスは次のカテゴリに分類されます
bull Primitivesbull Collectionsbull Enumbull sObjectbull Systembull 例外
Primitives メソッド
Apex Primitive メソッドApex の多くのプリミティブデータ型にはデータの追加処理に使用できるメソッドがありますメソッドのあるプリミティブは次のとおりです
bull Blobbull Booleanbull Datebull Datetimebull Decimalbull Doublebull Longbull String
参照 Version 180 | Primitives メソッド | 206
bull Time
Blob メソッド
次にBlob のシステム静的メソッドを示します
説明戻り値の型引数名前
指定した String Sを Blob に投入します例
String myString = StringToBlob BlobmyBlob = Blobvalueof(myString)
BlobString SvalueOf
次にBlob のインスタンスメソッドを示します
説明戻り値の型引数名前
blob の文字数を返します例String myString = StringToBlob BlobmyBlob = Blobvalueof(myString) Integersize = myBlobsize()
Integersize
blob を String にキャストしますStringtoString
Blob の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
Boolean メソッド
次はBoolean の静的メソッドを示します
説明戻り値の型引数名前
データ型 anyType の履歴管理表の項目である xをBoolean に投入しますanyType データ型の詳細
BooleananyTypexvalueOf
は『Forcecom Web Services API Developers Guide』の「項目のデータ型」を参照してください
Boolean の詳細は詳細はプリミティブデータ型 (ページ 27)を参照してください
Date メソッド
次にDate のシステム静的メソッドを示します
参照 Version 180 | Apex Primitive メソッド | 207
説明戻り値の型引数名前
指定された yearおよび monthの月の日数を返します (1= 1 月)次の例では1960 年の 2 月のに数を示しています
Integer numberDays =datedaysInMonth(1960 2)
IntegerInteger year
Integer month
daysInMonth
指定したyearがうるう年の場合真を返しますBooleanInteger yearisLeapYear
yearmonth (1= 1 月)dayの Integer 表現からDate を構築します次の例では1960 年 2 月 17日を作成します
Date myDate = datenewinstance(1960 217)
DateInteger year
Integer month
Integer date
newInstance
文字列から Date を構築します文字列の形式はローカルの日付形式によって異なります次の例はいくつかのロケールで機能しますdate mydate = dateparse(12272009)
DateString Dateparse
現在の日付を現在のユーザーのタイムゾーンで返します
Datetoday
指定した String の値を含む Date を返しますStringは現地のタイムゾーンの標準の日付形式「yyyy-MM-dd HHmmss」を使用します例string year = 2008 string month =10 string day = 5 string hour =
DateString svalueOf
12 string minute = 20 stringsecond = 20 string stringDate = year+ - + month + - + day + + hour+ + minute + + second
Date myDate = datevalueOf(stringDate)
データ型 anyType の履歴管理表の項目である xをDate に投入しますanyType データ型の詳細は
DateanyTypexvalueOf
『Forcecom Web Services API Developers Guide』の「項目のデータ型」を参照してください
次にDate のインスタンスメソッドを示します
説明戻り値の型引数名前
指定した addlDays数を Date に追加します例
date myDate = datenewInstance(1960 217) date newDate = mydateaddDays(2)
DateInteger addlDaysaddDays
参照 Version 180 | Apex Primitive メソッド | 208
説明戻り値の型引数名前
addlMonthsの指定した数を Date に追加しますDateInteger addlMonthsaddMonths
addlYearsの指定した 数を Date に追加しますDateInteger addlYearsaddYears
Date の day-of-month のコンポーネントを返しますたとえば1999 年 2 月 5 日はday 5 となります
Integerday
Date の day-of-year のコンポーネントを返しますたとえば1999 年 2 月 5 日はday 36 となります
IntegerdayOfYear
メソッドを呼び出した Date と compDateの間の日数を返しますメソッドを呼び出す Date が
IntegerDate compDatedaysBetween
compDateの後に発生する場合戻り値は負となります例
date startDate = datenewInstance(20081 1) date dueDate =datenewInstance(2008 1 30) integernumberDaysDue =startDatedaysBetween(dueDate)
Date を文字列として返しますStringformat
メソッドを呼び出した Date が compDateと同じ場合真を返します例
date myDate = datetoday() date dueDate= datenewInstance(2008 1 30)
BooleanDate compDateisSameDay
boolean dueNow =myDateisSameDay(dueDate)
Date の day-of-month のコンポーネントを返します(1=1 月)
Integermonth
メソッドを呼び出した Date と compDateの間の月数を返します日付の差異は無視されますたと
IntegerDate compDatemonthsBetween
えば同じ年の 3 月 1 日と 3 月 30 日の場合その間の月数は 0 となります
メソッドを呼び出した Date の月の最初の日を返しますたとえば1999 年 7 月 14 日の場合は1999年 7 月 1 日を返します
DatetoStartOfMonth
コンテキストユーザーのロケールに応じてメソッドを呼び出した Date の週の開始日を返しますた
DatetoStartOfWeek
とえばアメリカのロケールでは週は日曜日に始まりヨーロッパでは月曜日に始まります例date myDate = datetoday() dateweekStart = myDatetoStartofWeek()
参照 Version 180 | Apex Primitive メソッド | 209
説明戻り値の型引数名前
Date の year のコンポーネントを返しますIntegeryear
Date の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
Datetime メソッド
次にDatetime のシステム静的メソッドを示します
説明戻り値の型引数名前
DateTime を構築し1970 年 1 月 1 日 000000(GMT) 以降の指定したミリ秒数を表すように初期化します
DatetimeLong lnewInstance
ローカルタイムゾーンの dateおよび timeからDateTime を構築します
DatetimeDate Date
Time Time
newInstance
タイムゾーンの0時にyearmonth (1= 1 月)day
の Integer 表現から Datetime を構築します例
datetime myDate =datetimenewInstance(2008 12 1)
DatetimeInteger year
Integer month
Integer day
newInstance
現地のタイムゾーンで yearmonth (1= 1 月)dayhourminuteおよび secondの Integer 表現から Datetime を構築します例
Datetime myDate =datetimenewInstance(2008 12 1 1230 2)
DatetimeInteger year
Integer month
Integer day
Integer hour
Integer minute
Integer second
newInstance
GMT タイムゾーンの dateおよび timeからDateTime を構築します
DatetimeDate date
Time time
newInstanceGmt
GMT タイムゾーンの0時に yearmonth (1= 1月)dayの Integer 表現から Datetime を構築します
DatetimeInteger year
Integer month
Integer date
newInstanceGmt
GMT タイムゾーンで yearmonth (1= 1 月)dayhourminuteおよび secondの Integer 表現から Datetime を構築します
DatetimeInteger year
Integer month
Integer date
newInstanceGmt
Integer hour
Integer minute
Integer second
参照 Version 180 | Apex Primitive メソッド | 210
説明戻り値の型引数名前
GMT カレンダーに基づいて現在の Datetime を返します例datetime myDateTime = datetimenow()
Datetimenow
返される日付の形式はMMDDYYYY HHMM
PERIODです
ローカルタイムゾーンおよび形式の datetimeから DateTime を構築します次の例はいくつかのロケールで機能します
datetime myDateTime = datetimenow()string mydtstring = mydatetimeformat()
DatetimeString datetimeparse
systemassertequals(12272009 1146AM mydtstring)
指定した String の値を含む Datetime を返しますString は現地のタイムゾーンの標準の日付形式「yyyy-MM-dd HHmmss」を使用します例string year = 2008 string month =10 string day = 5 string hour =
DatetimeString svalueOf
12 string minute = 20 stringsecond = 20 string stringDate = year+ - + month + - + day + + hour+ + minute + + second
Datetime myDate =datetimevalueOf(stringDate)
データ型 anyType の履歴管理表の項目である xをDatetime に投入しますanyType データ型の詳細
DatetimeanyTypexvalueOf
は『Forcecom Web Services API Developers Guide』の「項目のデータ型」を参照してください
指定した String の値を含む Datetime を返しますString はGMT のタイムゾーンの標準の日付形式「yyyy-MM-dd HHmmss」を使用します
DatetimeString svalueOfGmt
次にDatetime のインスタンスメソッドを示します
説明戻り値の型
引数名前
指定した addlDays数を Datetime に追加します例
datetime myDate = datetimenewInstance(1960 2 17) datetime newDate =mydateaddDays(2)
DatetimeInteger addlDaysaddDays
参照 Version 180 | Apex Primitive メソッド | 211
説明戻り値の型
引数名前
指定した addlHoursの数を Datetime に追加しますDatetimeInteger addlHoursaddHours
指定した addlMinutesの数を Datetime に追加しますDatetimeInteger addlMinutesaddMinutes
指定した addlMonthsの数を Datetime に追加しますDatetimeInteger addlMonthsaddMonths
指定した addlSecondsの数を Datetime に追加しますDatetimeInteger addlSecondsaddSeconds
addlYearsの指定した 数を Datetime に追加しますDatetimeInteger addlYearsaddYears
コンテキストユーザーの現地のタイムゾーンで Datetimeの Date のコンポーネントを返します
Datedate
GMT タイムゾーンで Datetime の Date のコンポーネントを返します
DatedateGMT
コンテキストユーザーの現地のタイムゾーンで Datetimeの day-of-month のコンポーネントを返しますたとえ
Integerday
ば1999 年 2 月 5 日 午前 8 時 30 分 12 秒はday 5 となります
GMT タイムゾーンで Datetime の day-of-month のコンポーネントを返しますたとえば1999 年 2 月 5 日午前 8 時 30 分 12 秒はday 5 となります
IntegerdayGmt
コンテキストユーザーの現地のタイムゾーンで Datetimeの day-of-year のコンポーネントを返しますたとえば
IntegerdayOfYear
2008 年 2 月 5 日午前 8 時 30 分 12 秒はday 36 となりますDatetime myDate = datetimenewInstance(2008 2 5 8 30 12) systemassertEquals(myDatedayOfYear() 36)
GMT タイムゾーンで Datetime の day-of-year のコンポーネントを返しますたとえば1999 年 2 月 36 日 午前8 時 30 分 12 秒はday 5 となります
IntegerdayOfYearGmt
現在のユーザーの現地のタイムゾーンを使用してDatetime を文字列として返しますタイムゾーンを指定できない場合はGMT が使用されます
Stringformat
提供された Java の簡単な日付形式と現在のユーザーの現地のタイムゾーンを使用してDatetime を文字列と
StringString dateFormatformat
して返しますタイムゾーンを指定できない場合はGMT が使用されます例datetime myDT = Datetimenow() StringmyDate = myDTformat(hmm a)
Java の簡単な日付形式の詳細はhttpjavasuncomj2se142docsapijavatextSimpleDateFormathtmlを参照してください
参照 Version 180 | Apex Primitive メソッド | 212
説明戻り値の型
引数名前
提供された Java の簡単な日付形式とタイムゾーンを使用してDatetime を文字列として返します提供され
StringString dateFormat
String timezone
format
たタイムゾーンが適切でない場合GMT が使用されます
Java の簡単な日付形式の詳細はhttpjavasuncomj2se142docsapijavatextSimpleDateFormathtmlを参照してください
提供された Java の簡単な日付形式と GMT タイムゾーンを使用してDatetime を文字列として返します
Java の簡単な日付形式の詳細はhttpjavasuncomj2se142docsapijavatextSimpleDateFormathtmlを参照してください
StringString dateFormatformatGmt
秒やタイムゾーンなど現在のユーザーの現地のタイムゾーンを使用してDatetime を文字列として返します
StringformatLong
この DateTime オブジェクトで表された 1970 年 1 月 1日 0 時 0 分 0 秒 (GMT) 以降のミリ秒数を返します
LonggetTime
コンテキストユーザーの現地のタイムゾーンで Datetimeの hour のコンポーネントを返します
Integerhour
GMT タイムゾーンで Datetime の hour のコンポーネントを返します
IntegerhourGmt
コンテキストユーザーの現地のタイムゾーンでメソッドを呼び出した Datetime と compDtが同じ場合真を返します例
datetime myDate = datetimenow() datetimedueDate = datetimenewInstance(2008 1 30)boolean dueNow = myDateisSameDay(dueDate)
BooleanDatetime compDtisSameDay
コンテキストユーザーの現地のタイムゾーンで Datetimeの millisecond のコンポーネントを返します
Integermillisecond
GMT タイムゾーンで Datetime の millisecond のコンポーネントを返します
IntegermillisecondGmt
コンテキストユーザーの現地のタイムゾーンで Datetimeの minute のコンポーネントを返します
Integerminute
GMT タイムゾーンで Datetime の minute のコンポーネントを返します
IntegerminuteGmt
コンテキストユーザーの現地のタイムゾーンで Datetimeの month のコンポーネントを返します (1=1 月)
Integermonth
参照 Version 180 | Apex Primitive メソッド | 213
説明戻り値の型
引数名前
GMT タイムゾーンで Datetime の month のコンポーネントを返します (1= 1 月)
IntegermonthGmt
コンテキストユーザーの現地のタイムゾーンで Datetimeの second のコンポーネントを返します
Integersecond
GMT タイムゾーンで Datetime の second のコンポーネントを返します
IntegersecondGmt
コンテキストユーザーの現地のタイムゾーンで Datetimeの time のコンポーネントを返します
Timetime
GMT タイムゾーンで Datetime の time のコンポーネントを返します
TimetimeGmt
コンテキストユーザーの現地のタイムゾーンで Datetimeの year のコンポーネントを返します
Integeryear
GMT タイムゾーンで Datetime の year のコンポーネントを返します
IntegeryearGmt
Datetime の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
Decimal メソッド
次にDecimal のシステム静的メソッドを示します
説明戻り値の型引数名前
指定した Double の値を含む Decimal を返しますDecimalDouble dvalueOf
指定した Long の値を含む Decimal を返しますDecimalLong lvalueOf
指定した String の値を含む Decimal を返しますJava と同様文字列は署名付きの Decimal を示すものとして解釈されます例String temp = 124567 DecimalmyDecimal = decimalvalueOf(temp)
DecimalString svalueOf
次にDecimal のインスタンスメソッドを示します
説明戻り値の型引数名前
Decimal の絶対値を返しますDecimalabs
参照 Version 180 | Apex Primitive メソッド | 214
説明戻り値の型引数名前
この Decimal を divisorで割りスケールつまり scaleを使用した結果の小数位の数値を設定します次の例でD は 0190 の値を持っています
Decimal D = 19 DDivide(100 3)
DecimalDecimal divisorInteger scale
divide
この Decimal を divisorで割りスケールつまり scaleを使用した結果の小数位の数値を設定し
DecimalDecimal divisorInteger scaleObjectroundingMode
divide
ますそして必要に応じてroundingModeを使用して値を丸めますroundingModeに対して有効な値の詳細は「丸めモード」 (ページ217)例
Decimal myDecimal = 124567 DecimaldivDec = myDecimaldivide (7 2SystemRoundingModeUP)systemassertEquals(divDec 178)
Decimal の Double の値を返しますDoubledoubleValue
指数が必要な場合科学的記数法を使用してこの Decimal の String の値を返します
Stringformat
Decimal の Integer の値を返しますIntegerintValue
Decimal の Long の値を返しますLonglongValue
exponentの指数まで累乗したこの小数の値を返しますexponentの値は -32768 32767 です例
Decimal myDecimal = 412 Decimal powDec= myDecimalpow(2)systemassertEquals(powDec 169744)
DecimalInteger exponentpow
Decimal の桁数を返しますたとえばDecimal の値が 12345 の場合precisionは 5 を返します
Integerprecision
Decimal の値が 123123 の場合precisionは 6を返します例
Decimal D1 = 12345 Integer precision1= D1precision()systemassertEquals(precision1 5)
Decimal D2 = 123123 Integer precision2= D2precision()systemassertEquals(precision2 6)
Decimal の丸められた近似値を返します数値は均等丸めモードを使用して0 の小数位に丸めま
Longround
すつまり2 つの近隣が等距離にない限りは「最
参照 Version 180 | Apex Primitive メソッド | 215
説明戻り値の型引数名前
近隣」に等距離にある場合このモードは均等な近隣に対して丸めますこの丸めモードは統計的に連続する計算に対して繰り返し適用される場合累積エラーを最小化します均等丸めモードの詳細は 「丸めモード」 (ページ 217)を参照してください例
Decimal D1 = 55 Long L1 = D1round()systemassertEquals(L1 6)
Decimal D2= 52 Long L2= D2round()systemassertEquals(L2 5)
Decimal D3= -57 Long L3= D3round()systemassertEquals(L3 -6)
Decimal の丸められた近似値を返します数値はroundingModeで指定された丸めモードを使用し
LongSystemRoundingModeroundingMode
round
て0 の小数位に丸められますroundingModeに対して有効な値の詳細は 「丸めモード」 (ページ 217)
Decimal のスケールつまり小数位の数を返します
Integerscale
必要に応じて均等丸めモードを使用しDecimalのスケールを小数位の指定された数に設定します
DecimalInteger scalesetScale
均等丸めモードは2 つの近隣が等距離にない限りは「最近隣」に等距離にある場合このモードは均等な近隣に丸めます均等丸めモードの詳細は 「丸めモード」 (ページ 217)を参照してくださいscaleの値は -33 33 です
Decimal のスケールを明示的に設定しない場合スケールは Decimal が作成された項目によって指定されます
bull Decimal がクエリの一部として作成される場合スケールはクエリから返される項目のスケールに基づきます
bull Decimal が String から作成される場合スケールは String の小数点の後の文字数となります
bull Decimal が小数以外の数値から作成される場合スケールは数値を String に変換し小数点以下の文字数を指定して決定します
必要に応じて roundingMode で指定された丸めモードを使用しDecimal のスケールを小数位の
DecimalInteger scaleSystemRoundingModeroundingMode
setScale
指定された数に設定しますroundingModeに対
参照 Version 180 | Apex Primitive メソッド | 216
説明戻り値の型引数名前
して有効な値の詳細は 「丸めモード」 (ページ217)scaleの値は -32768 32767 です
Decimal のスケールを明示的に設定しない場合スケールは Decimal が作成された項目によって指定されます
bull Decimal がクエリの一部として作成される場合スケールはクエリから返される項目のスケールに基づきます
bull Decimal が String から作成される場合スケールは String の小数点の後の文字数となります
bull Decimal が小数以外の数値から作成される場合スケールは数値を String に変換し小数点以下の文字数を指定して決定します
後続の 0 を削除した Decimal を返しますDecimalstripTrailingZeros
科学的記数法を使用せずにDecimal の String の値を返します
StringtoPlainString
Decimal の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
丸めモード
丸めモードでは小数部を破棄できる数値演算の丸め動作を指定します各丸めモードでは丸められた結果の返される下位の桁をどのように計算するかを指定します次はroundingModeの有効な値を示します
説明名前
正の無限大に丸めますつまり結果が正の場合このモードはUP丸めモードと同じ動作をします結果が負の場合DOWN丸めモードと同じ動作をしますこの丸めモードで計算された値は小さくなりません例
CEILING
bull 入力値 55 CEILING丸めモードの結果 6bull 入力値 11 CEILING丸めモードの結果 2bull 入力値 -11 CEILING丸めモードの結果 -1bull 入力値 -27 CEILING丸めモードの結果 -2
0 に丸めますこの丸めモードは常に端数 (小数部分) を実行前に破棄しますこの丸めモードを使用しても計算された値の絶対値は大きくなりません例
DOWN
bull 入力値 55 DOWN丸めモードの結果 5bull 入力値 11 DOWN丸めモードの結果 1bull 入力値 -11 DOWN丸めモードの結果 -1bull 入力値 -27 DOWN丸めモードの結果 -2
参照 Version 180 | Apex Primitive メソッド | 217
説明名前
負の無限大に丸めますつまり結果が正の場合このモードはDOWN丸めモードと同じ動作をします結果が負の場合UP丸めモードと同じ動作をしますこの丸めモードで計算された値は大きくなりません例
FLOOR
bull 入力値 55 FLOOR丸めモードの結果 5bull 入力値 11 FLOOR丸めモードの結果 1bull 入力値 -11 FLOOR丸めモードの結果 -2bull 入力値 -27 FLOOR丸めモードの結果 -3
2 つの近隣が等距離にない限りは「最近隣」に丸め等距離にある場合このモードは端数を切り捨てます破棄した端数 (小数部分が) 05 より大きい場合
HALF_DOWN
この丸めモードはUP丸めモードと同じ動作をします05 より小さい場合はDOWN丸めモードと同じ動作をします例bull 入力値 55 HALF_DOWN丸めモードの結果 5bull 入力値 11 HALF_DOWN丸めモードの結果 1bull 入力値 -11 HALF_DOWN丸めモードの結果 -1bull 入力値 -27 HALF_DOWN丸めモードの結果 -2
2 つの近隣が等距離にない限りは「最近隣」に丸め等距離にある場合このモードは均等な近隣に丸めます破棄した端数 (小数部分) の左側の桁が奇数の
HALF_EVEN
場合この丸めモードは HALF_UP丸めモードと同じ動作をします偶数である場合HALF_DOWN丸めメソッドと同じ動作をします例bull 入力値 55 HALF_EVEN丸めモードの結果 6bull 入力値 11 HALF_EVEN丸めモードの結果 1bull 入力値 -11 HALF_EVEN丸めモードの結果 -1bull 入力値 -27 HALF_EVEN丸めモードの結果 -3
この丸めモードは統計的に連続する計算に対して繰り返し適用される場合累積エラーを最小化します
2 つの近隣が等距離にない限りは「最近隣」に丸め等距離にある場合このモードは端数を切り上げます破棄した端数 (小数部分が) 05 以上の場合この
HALF_UP
丸めモードはUP丸めメソッドと同じ動作をします05 以下の場合はDOWN
丸めメソッドと同じ動作をします例bull 入力値 55 HALF_UP丸めモードの結果 6bull 入力値 11 HALF_UP丸めモードの結果 1bull 入力値 -11 HALF_UP丸めモードの結果 -1bull 入力値 -27 HALF_UP丸めモードの結果 -3
要求された演算によって正確な結果が出たことを確認しますつまり丸めは必要ありませんこの丸めモードが正確でない結果を生成する演算に指定されて場合Exception が投げられます例
UNNECESSARY
bull 入力値 55 UNNECESSARY丸めモードの結果 Exceptionbull 入力値 10 UNNECESSARY丸めモードの結果 1
参照 Version 180 | Apex Primitive メソッド | 218
説明名前
0 から遠い方向に丸めますこの丸めモードは常に端数 (小数部分) を実行前に切り捨てますこの丸めモードを使用しても計算された値の絶対値は小さくなりません例
UP
bull 入力値 55 UP丸めモードの結果 6bull 入力値 11 UP丸めモードの結果 2bull 入力値 -11 UP丸めモードの結果 -2bull 入力値 -27 UP丸めモードの結果 -3
Double メソッド
次にDouble のシステム静的メソッドを示します
説明戻り値の型引数名前
データ型 anyType の履歴管理表の項目である xをDouble に投入しますanyType データ型の詳細は
DoubleanyTypexvalueOf
『Forcecom Web Services API Developers Guide』の「項目のデータ型」を参照してください
指定した String の値を含む Double を返しますJava と同様String は署名付きの Double を示すものとして解釈されます例Double DD1 = doublevalueOf(314159)
DoubleString svalueOf
次にDouble のインスタンスメソッドを示します
説明戻り値の型引数名前
この Double の文字列値を返しますStringformat
Double の Integer の値を Integer に投入して返します例Double DD1 = doublevalueOf(314159)Integer value = DD1intValue()systemassertEquals(value 3)
IntegerintValue
この Double の Long の値を返しますLonglongValue
この Double の丸めた値を返します数値は均等丸めモードを使用して0 の小数位に丸めますつ
Longround
まり2 つの近隣が等距離にない限りは「最近隣」に等距離にある場合このモードは均等な近隣に対して丸めますこの丸めモードは統計的に連続する計算に対して繰り返し適用される場合累積エラーを最小化します均等丸めモードの詳
参照 Version 180 | Apex Primitive メソッド | 219
説明戻り値の型引数名前
細は 「丸めモード」 (ページ 217)を参照してください例
Double D1 = 55 Long L1 = D1round()systemassertEquals(L1 6)
Double D2= 52 Long L2= D2round()systemassertEquals(L2 5)
Double D3= -57 Long L3= D3round()systemassertEquals(L3 -6)
Double の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
Integer メソッド
次にInteger のシステム静的メソッドを示します
説明戻り値の型引数名前
データ型 anyType の履歴管理表の項目である xをInteger に投入しますanyType データ型の詳細は
IntegeranyTypexvalueOf
『Forcecom Web Services API Developers Guide』の「ファイルのデータ型」を参照してください
指定した String の値を含む Integer を返しますJava と同様String は署名付きの 10 進数整数を示すものとして解釈されます例Integer myInt = integervalueOf(123)
IntegerString svalueOf
次にInteger のインスタンスメソッドを示します
説明戻り値の型引数名前
Integer を文字列として返しますStringformat
Integer の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
Long メソッド
次にLong のシステム静的メソッドを示します
参照 Version 180 | Apex Primitive メソッド | 220
説明戻り値の型引数名前
指定した String の値を含む Long を返しますJavaと同様文字列は符号付きの小数 Long を示すものとして解釈されます例Long L1 = longvalueOf(123456789)
LongString svalueOf
次にLong のインスタントメソッドを示します
説明戻り値の型引数名前
この Long の文字列形式を返しますStringformat
Long の Integer の値を返しますIntegerintValue
Long の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
String メソッド
次にString のシステム静的メソッドを示します
説明戻り値の型引数名前
String sの単一引用符の前にエスケープ文字 () を追加した String を返しますこのメソッドは動的
StringString sescapeSingleQuotes
SOQL ステートメントを作成する場合に役に立ちSOQL インジェクションを回避します動的SOQL の詳細は「動的 SOQL」 (ページ 140)を参照してください
現在の文字列をapexoutputText と同じ方法で置換に使用するパターンとして扱います
StringString s
ListltStringgtarguments
format
整数のリストの値から文字列を返しますStringListltIntegergtcharArray
fromCharArray
指定した Date を示す String を標準の「yyyy-MM-dd」形式で返します例Date myDate = DateToday() String sDate= StringvalueOf(myDate)
StringDate dvalueOf
指定した Datetime を示す String を現地のタイムゾーンの標準「yyyy-MM-dd HHmmss」形式で返します
StringDatetime dtvalueOf
指定された Decimal を示す String を返しますStringDecimal dvalueOf
参照 Version 180 | Apex Primitive メソッド | 221
説明戻り値の型引数名前
データ型 anyType の履歴管理表の項目である xをString に投入します例
Double myDouble = 1234 String myString= StringvalueOf(myDouble)SystemassertEquals(1234 myString)
StringanyType xvalueOf
anyType データ型の詳細は『Forcecom Web ServicesAPI Developers Guide』の「項目のデータ型」を参照してください
指定した Datetime を示す String を GMT タイムゾーンの標準「yyyy-MM-dd HHmmss」形式で返します
StringDatetime dtvalueOfGmt
次にString のインスタンスメソッドを示します
説明戻り値の型引数名前
String の各文字の Unicode 値に基づいて2 つの文字列を辞書編集的に比較します結果は次のとおりです
IntegerString compStringcompareTo
bull メソッドをコールした String が辞書編集的にcompStringの前に来る場合は負の Integer
bull メソッドをコールした String が辞書編集的にcompStringの後に来る場合は正の Integer
bull Strings が等しい場合 0
Strings が異なる索引位置がない場合辞書編集的には短い String が長い String の後に来ます例
String myString1 = abcde StringmyString2 = abcd Integer result =myString1compareTo(myString2)SystemassertEquals(result 1)
equalsメソッドが真を返す場合このメソッドは 0 を返します
メソッドをコールした String に compStringの指定した連続する文字が含まれている場合にのみtrueを返します例
String myString1 = abcde StringmyString2 = abcd Boolean result =
BooleanString compStringcontains
myString1contains(myString2)SystemassertEquals(result true)
参照 Version 180 | Apex Primitive メソッド | 222
説明戻り値の型引数名前
メソッドをコールした String が suffixで終わる場合trueを返します
BooleanString suffixendsWith
compStringが null でなくメソッドをコールした String と同じ 2 進数列の文字を示す場合true
BooleanString compStringequals
を返しますcompareToメソッドが 0 を返す場合このメソッドは真を返します例
String myString1 = abcde StringmyString2 = abcd Boolean result =myString1equals(myString2)SystemassertEquals(result false)
==演算子は String も比較も行いますが大文字と小文字を区別して Apex セマンティックに一致させます(==はID を比較する場合も同じ理由で大文字と小文字を区別します)
compStringが null でなくメソッドをコールした String と同じ連続する文字を示す場合trueを返します大文字と小文字は無視します例
String myString1 = abcd StringmyString2 = ABCD Boolean result =
BooleanString compStringequalsIgnoreCase
myString1equalsIgnoreCase(myString2)SystemassertEquals(result true)
指定したサブ文字列が最初に発生した索引を返しますサブ文字列がない場合このメソッドは -1を返します
IntegerString subStringindexOf
索引 iの位置から指定されたサブ文字列が最初に発生する索引を返しますサブ文字列がない場合このメソッドは -1 を返します例
String myString1 = abcd StringmyString2 = bc Integer result =
IntegerString substring
Integer i
indexOf
myString1indexOf(myString2 0)SystemassertEquals(result 1)
指定したサブ文字列が最後に発生した索引を返しますサブ文字列がない場合このメソッドは -1を返します
IntegerString substringlastIndexOf
String に含まれる 16 ビット Unicode 文字の数を返します例String myString = abcd Integer result= myStringlength()SystemassertEquals(result 4)
Integerlength
参照 Version 180 | Apex Primitive メソッド | 223
説明戻り値の型引数名前
リテラルターゲットシーケンス targetに一致する文字列のサブ文字列と指定したリテラル置換シーケンス replacementと置き換えます
StringString target
String replacement
replace
正規表現 regExpに一致する文字列のサブ文字列と置換シーケンス replacementと置き換えま
StringString regExp
String replacement
replaceAll
す正規表現の詳細はhttpjavasuncomj2se150docsapijavautilregexPatternhtmlを参照してください
正規表現 regExpに一致する文字列の最初のサブ文字列と置換シーケンスreplacementと置き換
StringString regExp
String replacement
replaceFirst
えます正規表現の詳細はhttpjavasuncomj2se150docsapijavautilregexPatternhtmlを参照してください
文字列の各サブ文字列を含むリストを返しますこのサブ文字列は正規表現regExpまたは文字
String[]String regExp
Integer limit
split
列の末尾に達したことにより終了します正規表現の詳細はhttpjavasuncomj2se150docsapijavautilregexPatternhtmlを参照してください
このサブ文字列は文字列の中で発生した順序でリストに記述されます regExpが String の一部に一致しない場合結果リストには元の文字列を含む要素が 1 つだけ含まれます
オプションの limitパラメータはパターンが適用された回数を制御するためリストの長さに影響を与えます
bull limitが 0 より大きい場合パターンは最大limit - 1 回適用されたことになりますまたリストの長さは最大 limitとなりリストの最後のエントリには最後に一致した区切り文字移行のすべての入力が含まれます
bull limitが正の値でない場合パターンを何度でも適用することが可能となりリストの長さも任意となります
bull limitが 0 の場合パターンは何度でも適用することが可能となりリストの長さも任意となりますが残りの続く空の文字列は破棄されます
たとえばString s = booandfooの場合次のようになります
bull ssplit( 2)は boo andfooを生成します
参照 Version 180 | Apex Primitive メソッド | 224
説明戻り値の型引数名前
bull ssplit( 5)はboo and foo
を生成しますbull ssplit( -2)は boo and
fooを生成しますbull ssplit(o 5)は b andf
を生成しますbull ssplit(o -2)は b andf
を生成しますbull ssplit(o 0)は b andf
を生成します
メソッドをコールした String が prefixで始まる場合trueを返します
BooleanString prefixstartsWith
指定した startIndexの文字で始まり String の末尾まで続く新しい String を返します
StringInteger startIndexsubstring
指定した startIndexの文字で始まり endIndex -1 の文字まで続く新しい String を返します例
hamburgersubstring(4 8) Returnsurge
StringInteger startIndex
Integer endIndex
substring
smilessubstring(1 5) Returnsmile
String のすべての文字をデフォルトのロケールの規則を使用して小文字に変換します
StringtoLowerCase
String のすべての文字を指定したロケールの規則を使用して小文字に変換します
StringString localetoLowerCase
String のすべての文字をデフォルトのロケールの規則を使用して大文字に変換します例String myString1 = abcd StringmyString2 = ABCD myString1 =
StringtoUpperCase
myString1toUpperCase() Boolean result= myString1equals(myString2)SystemassertEquals(result true)
String のすべての文字を指定したロケールの規則を使用して大文字に変換します
StringString localetoUpperCase
先頭末尾のスペースタブ改行文字など空白文字を含まない String を返します
Stringtrim
String の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
参照 Version 180 | Apex Primitive メソッド | 225
Time メソッド
次にTime のシステム静的メソッドを示します
説明戻り値の型引数名前
hourminutessecondsおよびmilliseconds
の Integer 表現から Time を構築します次の例では1820220 の時間を作成します
Time myTime = TimenewInstance(18 302 20)
TimeInteger hour
Integer minutes
Integer seconds
Integermilliseconds
newInstance
次にTime のインスタンスメソッドを示します
説明戻り値の型引数名前
指定した addlHoursの数を Time に追加しますTimeInteger addlHoursaddHours
指定した addlMillisecondsの数を Time に追加します
TimeIntegeraddlMilliseconds
addMilliseconds
指定した addlMinutesの数を Time に追加します例
Time myTime = TimenewInstance(18 302 20)
TimeIntegeraddlMinutes
addMinutes
Integer myMinutes = myTimeminute()myMinutes = myMinutes + 5
SystemassertEquals(myMinutes 35)
指定した addlSecondsの数を Time に追加します
TimeIntegeraddlSeconds
addSeconds
Time の hour のコンポーネントを返します例Time myTime = TimenewInstance(18 302 20)
Integerhour
myTime = myTimeaddHours(2)
Integer myHour = myTimehour()SystemassertEquals(myHour 20)
Time の millisecond のコンポーネントを返しますIntegermillisecond
Time の minute のコンポーネントを返しますIntegerminute
Time の second のコンポーネントを返しますIntegersecond
Time の詳細は「プリミティブデータ型」 (ページ 27)を参照してください
参照 Version 180 | Apex Primitive メソッド | 226
Apex Collection メソッド
Apex Collection メソッドApex のすべてのコレクションにはそれらに関連するメソッドがありデータを割り当て取得および処理しますコレクションは次のとおりです
bull Listbull Mapbull Set
メモ 保持できる項目の数については制限はありませんただしヒープサイズには制限があります
List メソッド
リストメソッドはすべてのインスタンスメソッドでリストの特定のインスタンスに操作されますたとえば次のコードは myListからすべての要素を削除します
myListclear()
clearメソッドにはパラメータは含まれませんがそれをコールするリスト自身が暗黙的なパラメータです
次にList のインスタンスパラメータを示します
メモ 以下の表ではList_elemはリストと同じデータ型の単一の要素を示します
説明戻り値の型引数名前
リストの最後に要素 eを追加します例
ListltIntegergt myList = newListltIntegergt() myListadd(47) Integer
VoidAny typeeadd
myNumber = myListget(0)systemassertEquals(myNumber 47)
要素 eをリストの索引位置 iで追加します次の例では 6 つの要素を持つリストが作成され整数が最初と 2 番目の索引位置に追加されます
ListltIntegergt myList = new Integer[6]myListadd(0 47) myListadd(1 52)systemassertEquals(myListget(1) 52)
VoidInteger i
Any typee
add
リスト lのすべての要素がメソッドをコールするリストに追加されます2 つのリストは同じデータ型である必要があります
VoidList laddAll
参照 Version 180 | Apex Collection メソッド | 227
説明戻り値の型引数名前
セット sのすべての要素がメソッドをコールするリストに追加されますセットとリストのタイプは同じでなければなりません
VoidSet saddAll
すべての要素をリストから削除し続いてリストの長さを 0 に設定します
Voidclear
リストの複製コピーを作成します
これが sObject レコードのリストである場合複製リストはリストの浅いコピーとなりますつま
List (同じデータ型)clone
り複製には各オブジェクトに対する参照がありますがsObject レコード自体は複製されません例
Account a = new Account(name=Acmebillingcity=New York) Account b = newAccount() Account[] l1 = newAccount[]ab Account[] l2 =l1clone() l1[0]billingcity = SanFrancisco SystemassertEquals(l1[0]billingcity San Francisco)SystemassertEquals( l2[0]billingcitySan Francisco)
sObject レコードもコピーするにはdeepClone
メソッドを使用する必要があります
sObject レコード自体を含めsObject レコードのリストの複製コピーを作成します例Account a = new Account(name=Acmebillingcity=New York) Account b = new
List (同じオブジェクトタイプ)
Booleanopt_preserve_id
deepClone
Account() Account[] l1 = newAccount[]ab Account[] l2 =l1deepClone() l1[0]billingcity = SanFrancisco SystemassertEquals(l1[0]billingcity San Francisco)SystemassertEquals( l2[0]billingcityNew York)
メモ deepCloneはプリミティブデータ型のリストではなくsObject のリストにのみ動作します
オプションの opt_preserve_id引数は元のオブジェクトの ID を複製で保持するかまたは削除するかを指定します
リストが含む sObject レコードを複製せずにリストの浅いコピーを作製するにはclone()メソッドを使用します
参照 Version 180 | Apex Collection メソッド | 228
説明戻り値の型引数名前
索引 iに保存されたリスト要素を返します例
ListltIntegergt myList = newListltIntegergt() myListadd(47) Integer
Array_elemInteger iget
myNumber = myListget(0)systemassertEquals(myNumber 47)
プリミティブデータ型または sObjects の一次元リストの要素を参照するためにリスト名の後に要素の索引の位置を大かっこで囲んで表記します例
ListltStringgt colors = new String[3]colors[0] = Red colors[1] = Bluecolors[2] = Green
sObject のリストを構成する sObjects タイプのトークンを返します定義情報とともに使用してリ
SchemaSObjectTypegetSObjectType
ストに特定の種類の sObjects を含むかどうかを指定します例public class listTest 一般的なsObject 変数 s を作成 SObject s =Databasequery (SELECT Id FROM AccountLIMIT 1)
sObject 変数が 取引先のトークンであるかを確認SystemassertEquals(sgetSObjectType()AccountsObjectType)
一般的な sObjects のリストを作成ListltsObjectgt l = new Account[]
sObject のリストに 取引先のトークンが含まれているかを確認SystemassertEquals(sgetSObjectType()AccountsObjectType)
このメソッドは sObjects から構成されているリストとともにのみ使用できます
詳細は「Apex 定義情報について」 (ページ 135)を参照してください
リストの要素が 0 の場合True を返しますBooleanisEmpty
イタレータのインスタンスを返しますイタレータから反復可能なメソッドhasNextおよびnext
を使用してリスト内で反復できます例
global class CustomIterable implementsIteratorltAccountgt ListltAccountgt accs
イタレータiterator
get set Integer i get set public
参照 Version 180 | Apex Collection メソッド | 229
説明戻り値の型引数名前CustomIterable() accs = [SELECT idname numberofEmployees FROM AccountWHERE name = false] i = 0 globalboolean hasNext() if(i gt= accssize())return false else return true global Account next() if(i == 8) i++return null i=i+1 return accs[i-1]
メモ リストで iterableメソッドを使用するために iterableインターフェースを使用する必要はありません
リストの i番目の索引で保存された要素を削除し削除された要素を返します例
ListltStringgt colors = new String[3]colors[0] = Red colors[1] = Blue
Array_elemInteger iremove
colors[2] = Green String S1 =colorsremove(2)systemassertEquals(S1 Green)
eをリストの索引 iの位置に割り当てます例
ListltIntegergt myList = new Integer[6]myListset(0 47) myListset(1 52)systemassertEquals(myListget(1) 52)
VoidInteger i
Any typee
set
プリミティブデータ型または sObjects の一次元リストの要素を設定するためにリスト名の後に要素の索引の位置を大かっこで囲んで表記します例
ListltStringgt colors = new String[3]colors[0] = Red colors[1] = Bluecolors[2] = Green
リストの要素の数を返します例ListltIntegergt myList = newListltIntegergt() Integer size =
Integersize
myListsize() systemassertEquals(size0)
ListltIntegergt myList2 = new Integer[6]Integer size2 = myList2size()systemassertEquals(size2 6)
リスト内の項目を昇順で並べ替えますプリミティブデータ型で構成されているリストとともにのみ
Voidsort
このメソッドを使用できます次の例でリストには 3 つの要素がありますリストを並べ替える
参照 Version 180 | Apex Collection メソッド | 230
説明戻り値の型引数名前
場合最初の要素には値が割り当てられていないため null で2 番目の要素の値は 5 となりますListltIntegergt L1 = new Integer[3] Assign values to the first twoelements L1[0] = 10 L1[1] = 5L1sort() First element is nullsecond is 5systemassertEquals(L1get(1) 5)
リストについての詳細はリスト (ページ 34)を参照してください
Map メソッド
マップメソッドはすべてのインスタンスメソッドでマップの特定のインスタンスに操作されます次にマップのインスタンスメソッドを示します
メモ 以下の表では次のようになります
bull Key_typeはマップキーのプリミティブデータ型を示しますbull Value_typeマップ値のプリミティブまたは sObject データ型を示しま
す
説明戻り値の型引数名前
マップからすべてのキー値マッピングを削除しますVoidclear
マップの複製コピーを作成します
これが sObject レコード値のマップである場合複製マップはマップの浅いコピーとなりますつまり複製
Map (同じデータ型)
clone
には各オブジェクトレコードに対する参照がありますがsObject レコード自体は複製されません例
Account a = new Account(name=Acmebillingcity=New York)
MapltInteger Accountgt map1 = newMapltInteger Accountgt
map1put(1 a)
MapltInteger Accountgt map2 = map1clone()
map1get(1)billingcity = San Francisco
SystemassertEquals(map1get(1)billingcitySan Francisco)SystemassertEquals(map2get(1)billingcitySan Francisco)
sObject レコードもコピーするにはdeepCloneメソッドを使用する必要があります
参照 Version 180 | Apex Collection メソッド | 231
説明戻り値の型引数名前
マップに指定された keyのマッピングが含まれている場合は真を返します例
Mapltstring stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Booleanキータイプ keycontainsKey
FF0000) colorCodesput(Blue0000A0) Boolean contains =colorCodescontainsKey(Blue)SystemassertEquals(contains True)
sObject レコード値を含むマップである場合sObject レコードなどの複製コピーを作成します例Account a = new Account(name=Acmebillingcity=New York)
Map (同じデータ型)
deepClone
MapltInteger Accountgt map1 = newMapltInteger Accountgt map1put(1 a)
MapltInteger Accountgt map2 =map1deepClone()
map1get(1)billingcity = San Francisco
SystemassertEquals(map1get(1)billingcity San Francisco)SystemassertEquals(map2get(1)billingcity New York)
リストが含む sObject レコードを複製せずにマップの浅いコピーを作製するにはclone()メソッドを使用します
指定した keyがマップされる値またはマップにこのキーの値が含まれていない場合nullを返します例
MapltString Stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Value_typeキータイプ keyget
FF0000) colorCodesput(Blue0000A0) String code =colorCodesget(Blue)SystemassertEquals(code 0000A0)
次はマップ内の 色ではありません Stringcode2 = colorCodesget(Magenta)SystemassertEquals(code2 null)
マップ値を構成する sObjects タイプのトークンを返します定義情報とともに使用してマップに特定の種類の sObjects を含むかどうかを指定します例public class mapTest 一般的な sObject変数 s を作成 SObject s = Databasequery
SchemaSObjectTypegetSObjectType
(SELECT Id FROM Account LIMIT 1)
sObject 変数が 取引先のトークンであるかを確認 SystemassertEquals(sgetSObjectType()
参照 Version 180 | Apex Collection メソッド | 232
説明戻り値の型引数名前AccountsObjectType)
一般的な sObjects のマップを作成 MapltIntegerAccountgt M = new MapltInteger Accountgt()
sObjects のリストに 取引先のトークンが含まれているかを確認SystemassertEquals(MgetSObjectType()AccountsObjectType)
このメソッドは sObjects 値を持つマップとともにのみ使用できます
詳細は「Apex定義情報について」 (ページ135)を参照してください
マップに内のキー値ペアが空の場合True を返します例MapltString Stringgt colorCodes = newMapltString Stringgt() Boolean empty =
BooleanisEmpty
colorCodesisEmpty()systemassertEquals(empty true)
マップのすべてのキーを含むセットを返します例MapltString Stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Key_typeのセット
keySet
FF0000) colorCodesput(Blue0000A0) Set ltStringgt colorSet = newSetltStringgt() colorSet =colorCodeskeySet()
指定した valueとマップの keyを関連付けますマップぬすでにこのキーのマッピングを含む場合以前の値はメソッドで返されその後置き換えられます例
MapltString Stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Value_typeKey key
Value value
put
ff0000) colorCodesput(RedFF0000) Red is now FF0000
指定したマップmからのすべてのマッピングを元のマップにコピーしますmからの新しいマッピングは元のマップにのマッピングを置き換えます
VoidMap mputAll
マップが sObjects に対する IDs または Strings である場合sObject レコード lのリストをこの入力のマップコンストラクタと同じ方法でマップに追加します
sObject[] lputAll
keyこのキーのマッピング (ある場合) をマップから削除します値はメソッドで返され削除されます例
MapltString Stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Value_typeKey keyremove
参照 Version 180 | Apex Collection メソッド | 233
説明戻り値の型引数名前FF0000) colorCodesput(Blue0000A0) String myColor =colorCodesremove(Blue) String code2 =colorCodesget(Blue)SystemassertEquals(code2 null)
マップのキー値のペアの数を返します例MapltString Stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Integersize
FF0000) colorCodesput(Blue0000A0) Integer mSize =colorCodessize()systemassertEquals(mSize 2)
マップのすべての値を含むリストを順不同で返します例MapltString Stringgt colorCodes = newMapltString Stringgt() colorCodesput(Red
Value_typeのリスト
values
FF0000) colorCodesput(Blue0000A0) ListltStringgt colors = newListltStringgt() colors =colorCodesvalues()
マップについての詳細はマップ (ページ 36)を参照してください
Set メソッド
Set メソッドはセットつまり setキーワードを使用して初期化されたプリミティブの順序が指定されていないコレクションに機能しますSet メソッドはすべてのインスタンスメソッドでセットの特定のインスタンスに操作されます次にSet のインスタンスメソッドを示します
メモ 以下の表ではSet_elemはセットと同じデータ型の単一の要素を示しますSet にはプリミティブデータ型のみを含みます
説明戻り値の型引数名前
まだ存在しない場合は要素を Set に追加します
このメソッドは元のセットがコールの結果として変更された場合に真を返します例
setltstringgt myString = newSetltStringgta b c Boolean
BooleanSet 要素 eadd
result result = myStringadd(d)systemassertEquals(result true)
まだ存在しない場合指定されたリストのすべての要素をセットに追加しますこのメソッドは
BooleanList laddAll
リストとセットの union を生成しますリストは
参照 Version 180 | Apex Collection メソッド | 234
説明戻り値の型引数名前
メソッドをコールするセットと同じ型でなければなりません
このメソッドは元のセットがコールの結果として変更された場合に trueを返します
まだ存在しない場合指定されたセットのすべての要素をメソッドをコールするセットに追加しま
BooleanSet saddAll
すこのメソッドは2 つのセットの unionを生成します指定されたセットはメソッドをコールする元のセットと同じ型でなければなりません
このメソッドは元のセットがコールの結果として変更された場合に真を返します例
setltstringgt myString = newSetltStringgta b setltstringgtsString = new SetltStringgtc
Boolean result1 result1 =myStringaddAll(sString)systemassertEquals(result1 true)
セットからすべての要素を削除しますVoidclear
セットの複製コピーを作成しますSet (同じデータ型)clone
セットに指定した要素がある場合trueを返します例
setltstringgt myString = newSetltStringgta b Boolean result
BooleanSet 要素 econtains
result = myStringcontains(z)systemassertEquals(result false)
指定したリストにすべての要素がある場合真を返しますリストはメソッドをコールするセットと同じ型でなければなりません
BooleanList lcontainsAll
指定したセットにすべての要素がある場合真を返します指定されたセットはメソッドをコー
BooleanSet scontainsAll
ルする元のセットと同じ型でなければなりません例setltstringgt myString = newSetltStringgta b setltstringgtsString = new SetltStringgtcsetltstringgt rString = newSetltStringgta b c
Boolean result1 result2 result1 =myStringaddAll(sString)systemassertEquals(result1 true)
参照 Version 180 | Apex Collection メソッド | 235
説明戻り値の型引数名前result2 = myStringcontainsAll(rString)systemassertEquals(result2 true)
セットの要素が 0 の場合True を返します例Setltintegergt mySet = new Setltintegergt()Boolean result result =
BooleanisEmpty
mySetisEmpty()systemassertEquals(result true)
存在する場合は指定した要素をセットから削除します
このメソッドは元のセットがコールの結果として変更された場合に真を返します
BooleanSet 要素 eremove
存在する場合は指定したリストの要素をセットから削除しますこのメソッドは2 つのセットの
BooleanList lremoveAll
relative compliment を生成しますリストはメソッドをコールするセットと同じ型でなければなりません
このメソッドは元のセットがコールの結果として変更された場合に真を返します例
Setltintegergt mySet = new Setltintegergt12 3 Listltintegergt myList = newListltintegergt1 3 Boolean result =mySetremoveAll(myList)SystemassertEquals(result true)
Integer result2 = mySetsize()SystemassertEquals(result2 1)
存在する場合は指定したセットの要素を元のセットから削除しますこのメソッドは2 つのセッ
BooleanSet sremoveAll
トの relative compliment を生成します指定されたセットはメソッドをコールする元のセットと同じ型でなければなりません
このメソッドは元のセットがコールの結果として変更された場合に真を返します
指定したリストに含まれるこのセットの要素のみを保持しますこのメソッドはリストとセット
BooleanList lretainAll
の intersection を生成しますリストはメソッドをコールするセットと同じ型でなければなりません
このメソッドは元のセットがコールの結果として変更された場合に真を返します例
Setltintegergt mySet = new Setltintegergt12 3 Listltintegergt myList = new
参照 Version 180 | Apex Collection メソッド | 236
説明戻り値の型引数名前Listltintegergt1 3 Boolean result =mySetretainAll(myList)
SystemassertEquals(result true)
指定したセットに含まれる元のセットの要素のみを保持しますこのメソッドは2 つのセットの
BooleanSet sretainAll
intersection を生成します指定されたセットはメソッドをコールする元のセットと同じ型でなければなりません
このメソッドは元のセットがコールの結果として変更された場合に真を返します
セットの要素の数 (基数) を返します例Setltintegergt mySet = new Setltintegergt12 3 Listltintegergt myList = new
Integersize
Listltintegergt1 3 Boolean result =mySetretainAll(myList)
SystemassertEquals(result true)
Integer result2 = mySetsize()SystemassertEquals(result2 2)
セットについての詳細は「セット」 (ページ 35)を参照してください
Enum メソッドEnum 値はユーザー定義のメソッドを追加できませんがシステム Enum 値を含むすべての Enum 値は次のメソッドを Apex で定義します
説明戻り値の型引数名前
Enum 項目の名前を String として返します
Stringname
0 から始まる Enum 値のリスト内の項目の位置を返します
Integerordinal
Enum 項目の値を String として返します
Stringvalues
例
Integer I = StatusCodeDELETE_FAILEDordinal() String S = MyEnumXname()
Enum についての詳細は「Enum 値」 (ページ 38)を参照してください
参照 Version 180 | Enum メソッド | 237
sObject メソッド
Apex sObject メソッド用語 sObjectはSalesforcecom プラットフォームデータベースに保存できるオブジェクトのことをいいます次の Apex sObject メソッドにはsObject 構造の説明に使用する一般的なクラスのほかすべての sObject と使用できるメソッドが含まれます
bull Schemabull sObjectbull sObject 定義結果bull 項目定義結果bull カスタム設定
Schema メソッド
次の表ではSchema の静的システムメソッドを示しています
説明戻り値の型引数名前
組織で定義された標準オブジェクトおよびカスタムオブ
MapltStringSchemaSObjectTypegt
getGlobalDescribe
ジェクトのすべての sObject名 (キー) のマップをsObjectトークン (値) に返します例MapltStringSchemaSObjectTypegt gd=SchemagetGlobalDescribe()
詳細は「すべての sObjectsへのアクセス」 (ページ 138)を参照してください
指定したオブジェクトに関連するカテゴリグループのリス
ListltSchemaDescribeDataCategoryGroupResultgt
StringListltsObjectNamesgt
describeDataCategoryGroups
トを返します次のsObjectNames のいずれかを指定できますbull KnowledgeArticleVersion
記事タイプに関連するカテゴリグループを取得します
bull Question 記事タイプに関連するカテゴリグループを取得します
参照 Version 180 | sObject メソッド | 238
説明戻り値の型引数名前
describeDataCategoryGroupsの使用についての詳細およびコード例は「sObject に関連するすべてのカテゴリのアクセス」を参照してください
記事および質問に関する詳細はSalesforcecomオンラインヘルプ「記事の管理」「Answers の概要」を参照してください
要求で指定されたオブジェクトのデータカテゴリ構造とと
ListltSchemaDescribeDataCategoryGroupStructureResultgt
pairstopCategoriesOnly
describeDataCategoryGroupStructures
もに使用できるカテゴリグループを返しますdescribeDataCategoryGroupStructuresの使用についての詳細およびコード例は「sObject に関連するすべてのカテゴリのアクセス」を参照してください
データカテゴリグループ構造定義の引数
describeDataCategoryGroupStructuresメソッドはデータカテゴリ構造とともに使用できるカテゴリグループを返します次にこのメソッドの引数を示します
説明戻り値の型名前
SchemaDataCategoryGroupSobjectTypePair を問い合わせる 1 つまたは複数のカテゴリグ
ListltSchemaDataCategoryGroupSobjectTypePairgtpairs
ループおよびオブジェクトを指定します指定されたオブジェクトの表示可能なデータカテゴリを取得します
カテゴリグループ表示の詳細はSalesforcecom オンラインヘルプの「カテゴリグループ表示設定の概要」を参照してください
trueを指定してオブジェクとを分類する上位表示カテゴリだけを返しますfalseを
BooleantopCategoriesOnly
指定して表示できるすべての親カテゴリおよび子カテゴリを返します両方の値はユーザのロールカテゴリグループ表示設定によって異なりますカテゴリグループ表示の
参照 Version 180 | Apex sObject メソッド | 239
説明戻り値の型名前
詳細はSalesforcecom オンラインヘルプの「カテゴリグループ表示設定の概要」を参照してください
SchemaDataCategoryGroupSobjectTypePair オブジェクト
SchemaDataCategoryGroupSobjectTypePair はカテゴリグループと関連オブジェクトを指定しますdescribeDataCategoryGroupStructuresメソッドで使用してこのオブジェクトに使用できるカテゴリを返します次の表はSchemaDataCategoryGroupSobjectTypePair のすべてのメソッドを示しています
説明戻り値の型引数名前
データカテゴリグループにアクセスするAPIで使用される一意の名前を返します
StringgetDataCategoryGroupName
データカテゴリグループに関連するオブジェクト名を返します
StringgetSobject
データカテゴリグループにアクセスするAPIで使用される一意の名前を指定します
StringsetDataCategoryGroupName
sObjectNameはデータカテゴリグループに関連するオブジェクト名です有効な値は次のとおりです
VoidString sObjectNamesetSobject
bull KnowledgeArticleVersion 記事タイプの場合
bull Question Answers の質問の場合
SchemaDescribeDataCategoryGroupResult オブジェクト
describeDataCategoryGroups メソッドは指定のオブジェクトに関連するカテゴリグループのリストを含むSchemaDescribeDataCategoryGroupResult オブジェクトを返します
次にデータカテゴリグループ定義結果オブジェクトのインスタンス化方法の例を示します
List ltStringgt objType = new ListltStringgt() objTypeadd(KnowledgeArticleVersion)objTypeadd(Question)
ListltSchemaDescribeDataCategoryGroupResultgt describeCategoryResult =SchemadescribeDataCategoryGroups(objType)
describeDataCategoryGroups の使用についての詳細およびコード例は「sObject に関連するすべてのカテゴリのアクセス」を参照してください
以下の表はデータカテゴリグループ定義結果の一部として利用可能なメソッドを示しています引数をとるメソッドはありません
参照 Version 180 | Apex sObject メソッド | 240
説明戻り値の型名前
データカテゴリグループの表示データカテゴリ数を返します
IntegergetCategoryCount
データカテゴリグループの説明を返しますStringgetDescription
Salesforcecomユーザインターフェースで使用するデータカテゴリグループのラベルを返します
StringgetLabel
データカテゴリグループにアクセスするAPIで使用される一意の名前を返します
StringgetName
データカテゴリグループに関連するオブジェクト名を返します
StringgetSobject
SchemaDescribeDataCategoryGroupStructureResult オブジェクト
describeDataCategoryGroupStructuresメソッドは指定したオブジェクトのカテゴリグループおよびカテゴリを含む SchemaDescribeDataCategoryGroupStructureResult オブジェクトのリストを返します
次にデータカテゴリグループ構造定義結果オブジェクトのインスタンス化方法の例を示します
List ltDataCategoryGroupSobjectTypePairgt pairs = new ListltDataCategoryGroupSobjectTypePairgt()
DataCategoryGroupSobjectTypePair pair1 = new DataCategoryGroupSobjectTypePair()pair1setSobject(KnowledgeArticleVersion) pair1setDataCategoryGroupName(Regions)
DataCategoryGroupSobjectTypePair pair2 = new DataCategoryGroupSobjectTypePair()pair2setSobject(Questions) pair2setDataCategoryGroupName(Regions)
pairsadd(pair1) pairsadd(pair2)
ListltSchemaDescribeDataCategoryGroupStructureResultgtresults =SchemadescribeDataCategoryGroupStructures(pairs true)
describeDataCategoryGroupStructuresの使用についての詳細およびコード例は「sObject に関連するすべてのカテゴリのアクセス」を参照してください
以下の表はデータカテゴリグループ構造定義結果の一部として利用可能なメソッドを示しています引数をとるメソッドはありません
説明戻り値の型名前
データカテゴリグループの説明を返しますStringgetDescription
Salesforcecomユーザインターフェースで使用するデータカテゴリグループのラベルを返します
StringgetLabel
データカテゴリグループにアクセスするAPIで使用される一意の名前を返します
StringgetName
データカテゴリグループに関連するオブジェクト名を返します
StringgetSobject
参照 Version 180 | Apex sObject メソッド | 241
説明戻り値の型名前
ユーザのカテゴリグループ表示設定に基づく上位表示カテゴリを含むSchemaDataCategory
ListltSchemaDataCategorygtgetTopCategories
オブジェクトを返しますカテゴリグループ表示の詳細はSalesforcecomオンラインヘルプの「カテゴリグループ表示設定の概要」を参照してください
SchemaDataCategory オブジェクト
SchemaDataCategory オブジェクトはカテゴリグループ内のカテゴリを示しますSchemaDataCategory オブジェクトは getTopCategoriesメソッドによって返されます次の表はSchemaDataCategory のすべてのメソッドを示しています引数をとるメソッドはありません
説明戻り値の型名前
データカテゴリの表示サブカテゴリを含む再帰オブジェクトを返します
ListltSchemaDataCategorygtgetChildCategories
Salesforcecomユーザインターフェースで使用するデータカテゴリのラベルを返します
StringgetLabel
データカテゴリにアクセスするAPIで使用される一意の名前を返します
StringgetName
sObject メソッド
sObject メソッドはすべてのインスタンスメソッドで取引先または連絡先などsObject の特定のインスタンスにコールされ操作します次にsObject のインスタンスメソッドを示します
説明戻り値の型引数名前
カスタムエラーメッセージでレコードをマークしDML 操作が行われないようにします
before insertトリガおよび before updateトリガの Triggernewにbefore deleteトリガ
VoidString errorMsgaddError
の Triggeroldに使用するとアプリケーションインターフェースにエラーメッセージが表示されます
「トリガ」 (ページ 65)および「トリガの例外」(ページ 77)を参照してください
Visualforce コントローラで使用すると生成されたメッセージがそのページのエラーのコレクションに追加されます詳細は『Visualforce DevelopersGuide』の「入力規則と標準コントローラ」を参照してください
参照 Version 180 | Apex sObject メソッド | 242
説明戻り値の型引数名前
指定したエラーメッセージをアプリケーションインターフェースのこのメソッドをコールする項目
VoidString errorMsgfieldaddError
に投入しDML 操作が行われないようにします例TriggernewmyField__CaddError(bad)
メモ
bull before insertトリガおよび before update
トリガの Triggernewにbefore deleteトリガのTriggeroldに使用するとアプリケーションインターフェースにエラーが表示されます
bull Visualforce コントローラで使用するとinputFieldコンポーネントが項目に結合される場合メッセージがコンポーネントに添付されます詳細は『Visualforce Developers Guide』の「入力規則と標準コントローラ」を参照してください
bull 項目識別子は実際に呼び出しオブジェクトではなくsObject が呼び出し元であるためこのメソッドは高度に専門化されます項目を使用してエラーの表示に使用する項目を識別します
bull このメソッドは今後のバージョンの Apex で変更される可能性があります
「トリガ」 (ページ 65)および「トリガの例外」(ページ 77)を参照してください
すべての項目値をクリアしますVoidclear
sObject レコードのコピーを作成します
オプションの opt_preserve_id引数は元のオブジェクトの ID を複製で保持するかまたは削除するかを指定します
sObject (同じデータ型)
Booleanopt_preserve_idBooleanopt_IsDeepClone
clone
オプションの opt_IsDeepClone引数はメソッドが sObject の完全コピーを作成するか単なる参照を作成するかを指定します
bull trueに設定するとメソッドは sObject の完全コピーを作成しますリレーション項目などsObject のすべての項目はメモリで複製されますその結果複製された sObject の項目に変更を行っても元の sObject は影響されません
bull falseに設定するとメソッドは元の sObjectへの参照を作成しますその結果複製された
参照 Version 180 | Apex sObject メソッド | 243
説明戻り値の型引数名前
sObject の項目に変更を行っても元の sObjectも影響を受けます
AccountNumberなどfieldNameで指定された項目の値を返します
詳細は「動的 SOQL」 (ページ140)を参照してください
オブジェクトString fieldNameget
項目トークン SchemasObjectField (例SchemaAccountAccountNumber) で指定された項目の値を返します
詳細は「動的 SOQL」 (ページ140)を参照してください
オブジェクトSchemasObjectFieldField
get
sObject の databaseDMLOptions オブジェクトを返します
詳細は「データベース DMLOptions メソッド(ページ 273)」を参照してください
DatabaseDMLOptionsgetOptions
fieldNameで指定された項目の値を返しますこのメソッドは主に動的 DML とともに使用して外部 ID の値にアクセスします
詳細は「動的 DML」 (ページ142)を参照してください
sObjectString fieldNamegetSObject
項目トークン SchemafieldName (例SchemaAccountMyExternalId) で指定された
sObjectSchemaSObjectFieldfieldName
getSObject
項目の値を返しますこのメソッドは主に動的DML とともに使用して外部 ID の値にアクセスします
詳細は「動的 DML」 (ページ142)を参照してください
fieldNameで指定された項目の値を返しますこのメソッドは主に動的 DML とともに使用して
sObject[]String fieldNamegetSObjects
子関係など関連オブジェクトの値にアクセスします
詳細は「動的 DML」 (ページ142)を参照してください
項目トークン SchemafieldName (例SchemaAccountContact) で指定された項目の
sObject[]SchemaSObjectTypefieldName
getSObjects
値を返しますこのメソッドは主に動的 DMLとともに使用して子関係など関連オブジェクトの値にアクセスします
参照 Version 180 | Apex sObject メソッド | 244
説明戻り値の型引数名前
詳細は「動的 DML」 (ページ142)を参照してください
この sObject のトークンを返しますこのメソッドは定義情報で使用されます
詳細は「Apex 定義情報について」 (ページ 135)を参照してください
SchemaSObjectTypegetSObjectType
fieldNameで指定された項目の値を設定し項目の以前の値を返します
詳細は「動的 SOQL」 (ページ140)を参照してください
オブジェクトString fieldNameObject value
put
項目トークン SchemasObjectField (例SchemaAccountAccountNumber) で指定された項目の値を設定し項目の以前の値を返します
詳細は「動的 SOQL」 (ページ140)を参照してください
オブジェクトSchemaSObjectFieldfieldName Objectvalue
put
fieldNameで指定された項目の値を設定しますこのメソッドは主に動的 DML で使用して外
sObjectString fieldNamesObject value
putSObject
部 ID の値に設定しますメソッドは項目の以前の値を返します
詳細は「動的 SOQL」 (ページ140)を参照してください
トークンSchemasObjectTypeで指定される項目の値を設定しますこのメソッドは主に動的
sObjectSchemasObjectTypefieldName sObjectvalue
putSObject
DML で使用して外部 ID の値に設定しますメソッドは項目の以前の値を返します
詳細は「動的 SOQL」 (ページ140)を参照してください
sObject の DMLOptions オブジェクトを設定します
詳細は「データベース DMLOptions メソッド(ページ 273)」を参照してください
VoiddatabaseDMLOptionsDMLOptions
setOptions
sObjects についての詳細は「sObject 型」 (ページ 30)を参照してください
sObject 定義結果メソッド
以下の表はsObject定義結果に利用可能なメソッドであるDescribeSObjectResultオブジェクトを示しています引数をとるメソッドはありません
参照 Version 180 | Apex sObject メソッド | 245
説明データ型名前
単独では使用すべきでない特別データタイプを返しますfieldsは項目メンバー変数名ま
Specialfields
たはgetMapメソッドのいづれかによって続かれるべきです例
SchemaDescribeFieldResult F =SchemaSObjectTypeAccountfieldsName
詳細は「Apex 定義情報について」 (ページ135)を参照してください
表示されるsObjectの外部キーを持ったsObjectの名前である子関係のリストを返します例え
ListltSchemaChildRelationshipgtgetChildRelationships
ばAccountオブジェクトは子関係としてContactsとOpportunitiesを含みます
オブジェクトのために3文字プレフィックスコードを返しますレコードIDはオブジェクトの
StringgetKeyPrefix
タイプを指定する3文字コードを前に置きます 例えば取引先は001のプレフィックスを持ち商談は006のプレフィックスを持ちます)
DescribeSobjectResultオブジェクトは安定したプレフィックスを持つオブジェクトのための値を返します安定したまたは予測可能なプレフィックスを持たないオブジェクトタイプに関しては項目は空白ですこれらのコードに依存するクライアントアプリケーションは上位互換性を確実にするためにこのオブジェクトタイプの決定方法を使用可能です
オブジェクト名にマッチするかもしれないししないかもしれないオブジェクトのレーベル
StringgetLabel
を返します例えば医療産業のある組織はAccountのレーベルをPatientに変えるかもしれませんこのラベルはSalesforcecomユーザインターフェースにて使用されます詳細はSalesforcecomオンラインヘルプを参照してください
オブジェクト名にマッチするかもしれないししないかもしれないオブジェクトの複数レー
StringgetLabelPlural
ベルを返します例えば医療産業のある組織はAccountの複数レーベルをPatientに変えるかもしれませんこのラベルはSalesforcecomユーザインターフェースにて使用されます詳細はSalesforcecomオンラインヘルプを参照してください
参照 Version 180 | Apex sObject メソッド | 246