+ Start a Discussion
Yuta.NakagawaYuta.Nakagawa 

Variable does not existというエラーについて

商談で主取引先責任者の「取引先責任者ID」を取得し、商談のカスタム項目で作成した、取引先責任者の参照項目に当てはめたいのですが、実現可能でしょうか。

Listで主取引先責任者の抽出はできたのですが、
主取引先責任者のContactIDを挿入する際に、
Variable does not exist: カスタム項目というエラーが生じます。
ご教授よろしくお願いします。
Shun KosakaShun Kosaka
簡易ではありますが、下記のようなプログラムで実現できました。
商談には、API参照名が「Primary_Contact__c」という、取引先責任者への参照関係をもつカスタム項目を設定しています。
List<OpportunityContactRole> ocrList = [SELECT ContactId, OpportunityId FROM OpportunityContactRole WHERE IsPrimary = True];
List<Opportunity> opportunityListToUpdate = new List<Opportunity>();
for(OpportunityContactRole ocr : ocrList){
	opportunityListToUpdate.add(
		new Opportunity(
			Id = ocr.OpportunityId,
			Primary_Contact__c = ContactId		
		)
	);
}

update opportunityListToUpdate;
ご要望との認識齟齬がございましたらお知らせください。
Yuta.NakagawaYuta.Nakagawa
Shun Kosakaさん
早速のご回答ありがとうございます。
早速実装を試みたのですが、
主取引先責任者選択時は変化なし
商談保存時に下記のエラーが出ています。
原因などわかりますでしょうか。
「エラーメッセージ」
execution of AfterUpdate caused by: System.ListException: Duplicate id in list: 006p0000003mesoAAA: Class.クラス名:(update opportunityListToUpdateの行)
Shun KosakaShun Kosaka

Nakagawaさん
実装を試みた、とありますが、商談(Opportunity)に対するApexトリガを実装されているという理解でよろしいでしょうか。
・主取引先責任者の情報はOpportunityContactRoleに格納されていますので、関連リストを変更しても、Opportunityへのトリガは起動しません。
・一方で、残念ながら、直接OpportunityContactRoleに対してトリガを実装することはできません。。

トリガをどのように実装いただいているのかは不明ですが、ご記載いただいたエラーは、Idが同じインスタンスをリストに格納し、Updateしたために発生したものと思われます。上記のサンプルコードをトリガに用いる際は、例えば下記のような考慮が追加で必要かと思います。
・Trigger.newやTrigger.oldをループに用いて、Idの重複を避ける
・トリガを再帰させないため、本当に更新が必要なOpportunityのみリストに追加する
⇒カスタム項目と、OpportunityContactRoleのContactIdに差異がある場合、リストにレコードを追加する。
(関連リストに主取引責任者がある場合、カスタム項目を同じ値に更新)
⇒Opportunityのカスタム項目に値があり、OpportunityContactRolenのisPrimaryがfalseの場合、リストにレコードを追加する。
(関連リストから主取引先責任が無くなった場合に、カスタム項目を空白に更新)
等です。

また、差し支えなければ、商談のカスタム項目に、主取引先責任者を当てはめたいのはどのような背景からか、ご共有いただけませんでしょうか。
・主取引先責任者を、他のプログラム等で一括更新し、カスタム項目に値を連係させたい
・見た目上の問題で、標準の関連リストとは別で、主取引先責任者の名前を表示させたい
等でしょうか。後者の場合は、トリガではなく、Visualforce + コントローラ拡張という選択肢があります。

よろしくお願いします。

Yuta.NakagawaYuta.Nakagawa
Shun Kosakaさん
エラー解決しました。ありがとうございます。
商談に対するApexトリガを実装したという理解であっています。
(after insertとafter updateの動作に対してです。)

・主取引先責任者の情報はOpportunityContactRoleに格納されていますので、関連リストを変更しても、Opportunityへのトリガは起動しません。
とありますが、主担当の編集時に商談の標準項目「最終更新者」の更新時間が更新されていますが、商談自体は更新されていないという認識でよろしいでしょうか。

主取引先責任者を商談のカスタム項目にあてはめたい背景は下記のとおりです。
・主取引先責任者の別項目を参照して、商談での動作を制限したいと考えています。
(ex.活動履歴の標準ボタン「メールの送信」でポップアップを表示させ、警告を表示する)
そのため、商談作成時もしくは、主取引先責任者の更新時をトリガとして、主取引先責任者の情報を商談に持たせたいと考えています。

よろしくお願いします。
Shun KosakaShun Kosaka
Nakagawaさん

主従関係の場合、従オブジェクトを変更すると、主オブジェクト側の最終更新項目が連動して更新されてしまうようです。
(カスタムオブジェクトでも同様の挙動を確認しましたが、公式のドキュメント等は見つけられませんでした…。申し訳ありません。)

主取引先責任者の更新に合わせて商談を更新する場合、英語ではありますが、下記の質問(&Tbomさんの回答)が参考になるかと思います。
https://developer.salesforce.com/forums/?id=906F00000008vxnIAA
・OpportunityContactRoleの情報を元にOpportunityのカスタム項目を更新するメソッドを、コントローラ拡張に実装し、Visualforceページのロード時に呼び出す
・Visualforceページは、標準の商談のページレイアウトにサイズ0で埋め込む
・主取引先責任者を標準の関連リストから更新すると、商談の詳細ページがリロードされますので、上記メソッドが呼び出され、商談のカスタム項目が更新される
という仕掛けのようです。
Yuta.NakagawaYuta.Nakagawa
Shun Kosakaさん

いただいたアドバイスを元に実現することができました。
ありがとうございます。

もう1点ご質問なのですが、
主取引先責任者の値は更新されるのですが、主取引先責任者の編集後に開く商談ページでは、値が古いまま表示されます。
編集後に開く商談ページで最新の値を表示する。または、編集後に1度商談ページを再読みするといったことは可能でしょうか。

1度手動でページを更新すると、値は最新の状態になります。
手動でページ更新する前に、レポートなどでレコード情報を見ると値自体は最新になっています。

ご教授ください。よろしくお願いします。
Shun KosakaShun Kosaka
Nakagawaさん

埋め込んだVFページから、親のページを更新するという処理で実現が可能かもしれません。
参考になりそうなリンクを共有いたします。
https://developer.salesforce.com/forums/?id=906F0000000D8AOIA0
https://www.xgeek.net/ja/salesforce/refresh-standard-detail-page-from-visualforce-page-in-iframe/
Yuta.NakagawaYuta.Nakagawa
Shun Kosakaさん

ありがとうございます。
いただいたURL先の解決方法としては、ボタンやURLをクリックしてページを更新する認識でよろしいでしょうか。
商談のカスタム項目が更新されたタイミングで、自動でページ更新することは難しいのでしょうか。
Shun KosakaShun Kosaka
Nakagawaさん

残念ながら、標準の関連リスト更新時のアクションを上書きするのは難しいかと思います。
一例で恐縮ですが、埋め込むVisualforceページで、取引先責任者の役割の関連リストを自作するのはいかがでしょうか。
(標準の取引先責任者の役割はページレイアウトから非表示にする)