You need to sign in to do that
Don't have an account?
SeanCeno
Make Sales Summary For Loop More Efficient?
My for loop updates sales summary fields. This code iterates 200 records as a time in a batch job, and works fine until an Account gets to about 5000+ trades in it. At this point, the CPU Limit begins to double and reaches the governor limit. If I insert 50 - 100 trades at a time, the CPU Limit seems to be avoided. I was hoping someone might be able to help me modify my for loop in order to avoid this limit in the future. Here is the below code:
public class Account_RollupTrades { public Static Account_Setting__c setting = Account_Setting__c.getInstance(); public Static boolean inprog = false; public static void execute (Set<Id> accountIds, List<Account> accountsList) { Map<Id, Account> accounts = new Map<Id, Account> (AccountsList); system.debug ('execute'); if(setting.Disable_RollupTrades__c != true) { //Map<Id, Account> accounts = new Map<Id, Account>(); for(Id accountId:accountIds) { system.debug(accountid); accounts.put(accountId, new Account( Id=accountId, YTD_NIOR_I_Sales__c = 0, YTD_NIOR_I_Shares__c = 0, QTD_NIOR_I_Sales__c = 0, QTD_NIOR_I_Shares__c = 0, MTD_NIOR_I_Sales__c = 0, MTD_NIOR_I_Shares__c = 0, PY_NIOR_I_Sales__c = 0, PY_NIOR_I_Shares__c = 0, Total_NIOR_I_Sales__c = 0, Total_NIOR_I_Shares__c = 0, YTD_NS_Income_Sales__c = 0, YTD_NS_Income_Shares__c = 0, QTD_NS_Income_Sales__c = 0, QTD_NS_Income_Shares__c = 0, MTD_NS_Income_Sales__c = 0, MTD_NS_Income_Shares__c = 0, PY_NS_Income_Sales__c = 0, PY_NS_Income_Shares__c = 0, Total_NS_Income_Sales__c = 0, Total_NS_Income_Shares__c = 0, Total_NS_HI_Sales__c = 0, Total_NS_HI_Shares__c = 0, YTD_NS_HI_Sales__c = 0, YTD_NS_HI_Shares__c = 0, QTD_NS_HI_Sales__c = 0, QTD_NS_HI_Shares__c = 0, MTD_NS_HI_Sales__c = 0, MTD_NS_HI_Shares__c = 0, PY_NS_HI_Sales__c = 0, PY_NS_HI_Shares__c = 0, Total_NS_Income_II_Sales__c = 0, Total_NS_Income_II_Shares__c = 0, YTD_NS_Income_II_Sales__c = 0, YTD_NS_Income_II_Shares__c = 0, QTD_NS_Income_II_Sales__c = 0, QTD_NS_Income_II_Shares__c = 0, MTD_NS_Income_II_Sales__c = 0, MTD_NS_Income_II_Shares__c = 0, PY_NS_Income_II_Sales__c = 0, PY_NS_Income_II_Shares__c = 0, Rollup_Trades__c = DateTime.now() ) ); } Map<String, SObjectField[]> ytd = new map<string, sobjectfield[]> { '3910' => new sobjectfield[] { account.YTD_NIOR_I_Sales__c , account.YTD_NIOR_I_Shares__c}, '3911' => new sobjectfield[] { account.YTD_NS_Income_Sales__c , account.YTD_NS_Income_Shares__c }, '3912' => new sobjectfield[] { account.YTD_NS_HI_Sales__c , account.YTD_NS_HI_Shares__c }, '3915' => new sobjectfield[] { account.YTD_NS_Income_II_Sales__c , account.YTD_NS_Income_II_Shares__c } }, qtd = new map<string, sobjectfield[]> { '3910' => new sobjectfield[] { account.QTD_NIOR_I_Sales__c , account.QTD_NIOR_I_Shares__c}, '3911' => new sobjectfield[] { account.QTD_NS_Income_Sales__c , account.QTD_NS_Income_Shares__c }, '3912' => new sobjectfield[] { account.QTD_NS_HI_Sales__c , account.QTD_NS_HI_Shares__c }, '3915' => new sobjectfield[] { account.QTD_NS_Income_II_Sales__c , account.QTD_NS_Income_II_Shares__c } }, mtd = new map<string, sobjectfield[]> { '3910' => new sobjectfield[] { account.MTD_NIOR_I_Sales__c , account.MTD_NIOR_I_Shares__c}, '3911' => new sobjectfield[] { account.MTD_NS_Income_Sales__c , account.MTD_NS_Income_Shares__c }, '3912' => new sobjectfield[] { account.MTD_NS_HI_Sales__c , account.MTD_NS_HI_Shares__c }, '3915' => new sobjectfield[] { account.MTD_NS_Income_II_Sales__c , account.MTD_NS_Income_II_Shares__c } }, py = new map<string, sobjectfield[]> { '3910' => new sobjectfield[] { account.PY_NIOR_I_Sales__c , account.PY_NIOR_I_Shares__c}, '3911' => new sobjectfield[] { account.PY_NS_Income_Sales__c , account.PY_NS_Income_Shares__c }, '3912' => new sobjectfield[] { account.PY_NS_HI_Sales__c , account.PY_NS_HI_Shares__c }, '3915' => new sobjectfield[] { account.PY_NS_Income_II_Sales__c , account.PY_NS_Income_II_Shares__c } }, total = new map<string, sobjectfield[]> { '3910' => new sobjectfield[] { account.Total_NIOR_I_Sales__c , account.Total_NIOR_I_Shares__c}, '3911' => new sobjectfield[] { account.Total_NS_Income_Sales__c , account.Total_NS_Income_Shares__c }, '3912' => new sobjectfield[] { account.Total_NS_HI_Sales__c , account.Total_NS_HI_Shares__c }, '3915' => new sobjectfield[] { account.Total_NS_Income_II_Sales__c , account.Total_NS_Income_II_Shares__c } }; // We make the select in a "for" so instead of selecting to many records at once hitting the heap size limit the for it will take only 200 records to work with at each iteration. for(Trades__c[] tradesList : [select Dollar_Amount_of_the_transaction__c, Fund_Number__c, Number_of_Shares_of_the_transaction__c, Resolved_Firm_Trading_ID__c, Resolved_Firm_Trading_IDs__c, Trade_Date__c from Trades__c where Resolved_Firm_Trading_ID__c in :accountIds and Fund_Number__c in ('3910', '3911', '3912', '3915') and Dollar_Amount_of_the_transaction__c != null and Number_of_Shares_of_the_transaction__c != null and Trade_Date__c != null and Dollar_Amount_of_the_transaction__c >= 0 and Number_of_Shares_of_the_transaction__c >= 0]){ for(trades__c trade: tradesList) { if(date.today().year() == trade.trade_date__c.year()) { system.debug(ytd); accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c); accounts.get(trade.Resolved_Firm_Trading_ID__c).put(ytd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(ytd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c); system.debug(qtd); //( (date.ValueOf(date.today().month()).divide(3, 0) == date.ValueOf(trade.trade_date__c.month()).divide(3, 0)) ) if((((date.today().month() - 1) / 3) + 1) == (((trade.Trade_Date__c.month() - 1) / 3) + 1)) { accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c); accounts.get(trade.Resolved_Firm_Trading_ID__c).put(qtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(qtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c); system.debug(mtd); if(date.today().month()==trade.trade_date__c.month()) { accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c); accounts.get(trade.Resolved_Firm_Trading_ID__c).put(mtd.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(mtd.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c); } } } else if(date.today().year()-1==trade.trade_date__c.year()) { accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c); accounts.get(trade.Resolved_Firm_Trading_ID__c).put(py.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(py.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c); } accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[0], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[0]))+trade.Dollar_Amount_of_The_Transaction__c); accounts.get(trade.Resolved_Firm_Trading_ID__c).put(total.get(trade.fund_number__c)[1], ((Decimal)accounts.get(trade.Resolved_Firm_Trading_ID__c).get(total.get(trade.fund_number__c)[1]))+trade.Number_of_Shares_of_the_transaction__c); } } } inprog = true; update accounts.values(); inprog = false; } }
You may get a minor speed improvement by moving your date calculations outside of the loop. Since (((date.today().month() - 1) / 3) + 1) will be the same for the entire loop, there's no point in calculating it for every record (same with date.today().year(), date.today().month() & date.today().year()-1)