function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
KeronKeron 

取引先のカスタム項目に配下の取引先責任者の数を入れたい

取引先のカスタム項目に「責任者数」というカスタム項目を作った場合、

配下の取引先責任者の合計数を入れたい。

 

しかし、数式項目でも積み上げ集計項目でもできなさそうなので、

もはや標準機能では実現ができないのか…と頭を悩ませています。

ただ、取引先の関連リストには取引先責任者のリストが表示されている訳ですから、

そのリスト数を取ってくるななんて、簡単そうで…なかなか手ごわいです。

 

まさかInsertトリガで「責任者数」に+1し、Deleteトリガで「責任者数」に-1するとか、

ワークフロールールで項目自動更新を使うにも追加時の+1はできても削除時の-1は

できないですよね…。

 

何か良い方法はないでしょうか?ご教授下さい。

 

Best Answer chosen by Admin (Salesforce Developers) 
KeronKeron

Taikiさん、サンプルソースありがとうございます。

 

実は全く同じ考えで私も実装致しました。

Triggerを使って+1、-1では何かあった時に値がずれると思い、

Triggerを使って件数をカウントしカスタム項目へセットする方式です。

 

色々テストもしましたが、特に問題なく使えております。

今回の件は色々と頭を悩ませましたが、とても勉強になりました。

ありがとうございました。

All Answers

Taiki YoshikawaTaiki Yoshikawa

取引先責任者って積み上げ集計できなかったんですね...。

 

Visualforceで件数を取得して詳細ページに埋め込む方法とか...ダメですか。

画面に表示されてるだけで、レポート等で集計できませんけど。

 

トリガーで+1、-1するのは個人的には厳しい気がします...。

何かのキッカケで値がずれると修正できませんし。

KeronKeron

taikiさん、いつもご回答ありがとうございます。

 

実は、取引先ホームに表示する取引先一覧の1項目として、

配下の責任者数を表示したいのです。

 

<apex:page showHeader="true" tabstyle="Account">
    <apex:sectionHeader title="取引先" subTitle="ホーム" />
    <apex:enhancedList height="600" type="Account" />
</apex:page>

 

で表示されるリストの項目に入れたいと思い、

取引先責任者数というカスタム項目を取引先オブジェクトに追加し、

そこへなんとか値を算出して代入した状態でリスト表示に移りたいのです。

 

どこで、算出処理をフックすれば良いかが、いまひとつ閃かない感じです。

Taiki YoshikawaTaiki Yoshikawa

enhancedListとListViewsはVFページ内でビューを表示しているだけなので

Apexクラスの処理で値を変更というのは難しいと思います。

 

 

ちょっとApexトリガーで対応する方法を考えてみました。

 

取引先取得処理時にサブクエリで取引先責任者の件数を取得し、

件数用のカスタム項目に値をセットして取引先を更新します。

 

この方法なら現在の件数から+1, -1するわけではないので、万が一件数がずれても

次にTriggerが実行された際に最新の件数に更新されるのではないかと思います。

 

以下サンプルです。

 

Apex Trigger

trigger ContactTrigger on Contact (after delete, after insert, after undelete) {
	System.debug('◆◆◆◆ContactTrigger:START');
    
    // Handlerクラス
    ContactTriggerHandler handler = new ContactTriggerHandler();
    
    if (Trigger.isAfter) {
        if (Trigger.isInsert) {
        	// 取引先に紐付く取引先責任者件数更新
            handler.updateContactCnt(Trigger.new);
        } else if (Trigger.isUpdate) {
        	
        	/* Updateの処理 */
            
        } else if (Trigger.isDelete) {
        	// 取引先に紐付く取引先責任者件数更新
        	handler.updateContactCnt(Trigger.old);
        	
        } else if (Trigger.isUnDelete) {
        	// 取引先に紐付く取引先責任者件数更新
        	handler.updateContactCnt(Trigger.new);
        }
    }

    System.debug('◆◆◆◆ContactTrigger:END');
}

 Apex Class(Handlerクラス)

public with sharing class ContactTriggerHandler {
	
	// Actionクラス
	private ContactTriggerAction action;
	
	/*
	 * コンストラクタ
	 * @param	: なし
	 * @return	: なし
	 */
	public ContactTriggerHandler() {
		// Actionクラス
		this.action = new ContactTriggerAction(); 
	}
	
	/*
	 * 取引先に紐付く取引先責任者件数更新
	 * @param	: 取引先責任者
	 * @return	: なし
	 */
	public void updateContactCnt(List<Contact> prmContacts) {
		System.debug('◆◆◆◆updateContactCnt:START');
		
		// 取引先ID取得
		Set<Id> accountIds = this.action.getAccountId(prmContacts);
		// 取引先取得
		List<Account> objAccounts = this.action.getAccounts(accountIds);
		// 取引先の更新値取得
		objAccounts = this.action.getUpdateAccounts(objAccounts);
		// 取引先更新
		update objAccounts;
		
		System.debug('◆◆◆◆updateContactCnt:END');
	}
}

 

 

 Apexクラス(Actionクラス)

public with sharing class ContactTriggerAction {
	
	/*
	 * コンストラクタ
	 * @param	: なし
	 * @return	: なし
	 */
	public ContactTriggerAction() {
		
	}
	
	/*
	 * 取引先ID取得
	 * @param	: 取引先責任者	[prmContacts]
	 * @return	: 取引先ID
	 */
	public Set<Id> getAccountId(List<Contact> prmContacts) {
		System.debug('◆◆◆◆getAccountId:START');
		
		Set<Id> accountIds = new Set<Id>();
		for (Contact c : prmContacts) {
			accountIds.add(c.AccountId);
		}
		
		System.debug('◆◆◆◆getAccountId:END');
		return accountIds;
	}
	
	/*
	 * 取引先取得
	 * @param	: 取引先ID	[prmAccountIds]
	 * @return	: 取引先
	 */
	public List<Account> getAccounts(Set<Id> prmAccountIds) {
		return [
			select
				Id
				,(select Id from Contacts)
			from
				Account
			where
				Id IN: prmAccountIds
		];
	}
	
	/*
	 * 取引先の更新値をセット
	 * @param	: 取引先
	 * @return	: 取引先
	 */
	public List<Account> getUpdateAccounts(List<Account> prmAccounts) {
		System.debug('◆◆◆◆getUpdateAccounts:START');
		
		for (Account objAccount : prmAccounts) {
			// 取引先責任者件数
			objAccount.ContactCnt__c = objAccount.Contacts.size();
		}
		
		System.debug('◆◆◆◆getUpdateAccounts:END');
		return prmAccounts;
	}
}

 

一応画面から1件追加、削除、復元を試してみましたが、特に問題なさそうに感じました。

後は取引先責任者に紐付く取引先更新時の処理も必要になると思います。

 

大丈夫だとは思うのですが、取引先に紐付く取引先責任者の件数が多かったり、

データローダ等で一括処理した際に正常に動作するかなどの確認は必要だと思います。

KeronKeron

Taikiさん、サンプルソースありがとうございます。

 

実は全く同じ考えで私も実装致しました。

Triggerを使って+1、-1では何かあった時に値がずれると思い、

Triggerを使って件数をカウントしカスタム項目へセットする方式です。

 

色々テストもしましたが、特に問題なく使えております。

今回の件は色々と頭を悩ませましたが、とても勉強になりました。

ありがとうございました。

This was selected as the best answer
Taiki YoshikawaTaiki Yoshikawa

解決してよかったです。