まず言いたい
主従関係への変更に障害がなければ、主従関係に変更しましょう。
参照関係の項目のデータ型を主従関係に変更する場合の影響については、「参照関係を主従関係に変更する場合の考慮事項」を参照してください。
選択肢一覧
- DLRS/Rollup Helper
- フロー
- Apexトリガ
- レポート
- BI(Tableau CRM/Tableau)
- SF外での集計
選択肢
■DLRS/Rollup Helper
AppExchange。おすすめ。DLRSの詳細は「DLRS(Declarative Lookup Rollup Summaries Tool)設定マニュアル」を参照。Rollup Helperのリンクはこちら。
■フロー
非推奨。フローでの実装は「潜在的に環境を破壊する行為」といっても過言ではありません。
「子レコードの作成/更新/削除時に親レコードに更新をかける」ような処理の場合、子レコードに対するバッチ処理時に容易に’maximum number of duplicate updates in one batch’エラーが発生します。非同期化すればある程度緩和されますが、制限は依然として厳しく、子レコードをまとめて作成/更新/削除する際に制限超過するリスク(別の言い方をすれば、子レコードに一括処理をかけらないという制約)に永久に支配されることとなります。
■Apexトリガ
DLRSでは対応できないような処理がある場合・既存のFrameworkに載せたい場合などはこれかなと思います。
サンプルコード↓
trigger BillingDetailTrigger on BillingDetail__c (after delete, after insert, after update) {
Set<id> billingIds = new Set<id>();
List<billing__c> billingsToUpdate = new List<billing__c>();
if(Trigger.isInsert){
for (BillingDetail__c billingdetail : Trigger.new){
billingIds.add(billingdetail.BillingNo__c);
}
}
if (Trigger.isUpdate) {
for (BillingDetail__c billingdetail : Trigger.new){
BillingDetail__c oldBd = Trigger.oldMap.get(billingdetail.Id);
if(billingdetail.Amount__c != oldBd.Amount__c){
billingIds.add(billingdetail.BillingNo__c);
}
}
}
if (Trigger.isDelete) {
for (BillingDetail__c billingdetail : Trigger.old){
if(billingdetail.Amount__c != null && billingdetail.Amount__c != 0){
billingIds.add(billingdetail.BillingNo__c);
}
}
}
// get a map of the billings with the number of billingdetails
Map<id,Billing__c> billingMap = new Map<id,Billing__c>([select id, Num_BillingDetails__c,BasicCharge__c,Discount__c,InitialFee__c,OptionalCharge__c,RecordedAmount__c,Revenue__c,UsageCharge__c from Billing__c where id IN :billingIds]);
// query the billings and the related inventory billingdetails and add the size of the inventory billingdetails to the billing's Num_BillingDetails__c
for (Billing__c billing : [select Id, Name, Num_BillingDetails__c,(select id,BasicChargeAuto__c,DiscountAuto__c,InitialFeeAuto__c,OptionalChargeAuto__c,SalesAmountTaxSeparated__c,RevenueAuto__c,UsageChargeAuto__c from BillingNo__r) from Billing__c where Id IN :billingIds]) {
Decimal Sum_BasicChargeAuto = 0;
Decimal Sum_DiscountAuto = 0;
Decimal Sum_InitialFeeAuto = 0;
for(BillingDetail__C bd:billing.BillingNo__r){
Sum_BasicChargeAuto += bd.BasicChargeAuto__c;
Sum_DiscountAuto += bd.DiscountAuto__c;
Sum_InitialFeeAuto += bd.InitialFeeAuto__c;
}
billingMap.get(billing.Id).Num_BillingDetails__c = billing.BillingNo__r.size();
billingMap.get(billing.Id).BasicCharge__c = Sum_BasicChargeAuto;
billingMap.get(billing.Id).Discount__c = Sum_DiscountAuto;
billingMap.get(billing.Id).InitialFee__c = Sum_InitialFeeAuto;
// add the value/billing in the map to a list so we can update it
billingsToUpdate.add(billingMap.get(billing.Id));
}
update billingsToUpdate;
}
■レポート
レポートの集計関数で問題が解決するなら、それに越したことはありません。
■BI(Tableau CRM/Tableau)
同上
■SF外での集計
同上