You need to sign in to do that
Don't have an account?

Help to bulkify / clean up code!
Still learning the ropes here and probably have some very ill formed code - so, any help/advice is greatly appreciated.
Here is the scenario of what I am trying to accomplish:
We have two custom objects (related via lookup field on Essay object): Applications & Essays. I have created a custom field on the Applications object called XEssays_On_File. When an Essay record is added/updated, I would like the XEssays_On_File field to get updated with the number of related Essay Records. (Can't use rollup fields as this is not a master-detail relationship)
I have drafted the following code - which works for single situations - but fails mercilessly in bulk update:
trigger CountRelatedEssays on TargetX_SRMb__Essay__c (after insert, after update) {
TargetX_SRMb__Essay__c [] ess = Trigger.new;
String appid = null;
appid = ess[0].TargetX_SRMb__Application__c;
Integer i = [select count() from TargetX_SRMb__Essay__c where TargetX_SRMb__Application__c = :appid];
TargetX_SRMb__Application__c [] app =[select id, XEssays_On_File__c from TargetX_SRMb__Application__c where id = :appid];
app[0].XEssays_On_File__c = i;
update app[0];
}
I would also like this to fire and update on Delete as well.
Thanks in advance for any help you can provide!
How about this?
trigger CountRelatedEssays on TargetX_SRMb__Essay__c (after insert, after update, after delete) { //create a list of Applications that need updated List<TargetX_SRMb__Application__c> toupdate = new List<TargetX_SRMb__Application__c>(); //create a map of app IDs and their counts. set all to 0 initially Map<Id,Integer> appCountMap = new Map<Id,Integer>(); if(trigger.isDelete){ for(TargetX_SRMb__Essay__c e : trigger.old){ if(e.TargetX_SRMb__Application__c!=null){ appCountMap.put(e.TargetX_SRMb__Application__c,0); } } }else{ for(TargetX_SRMb__Essay__c e : trigger.new){ if(e.TargetX_SRMb__Application__c!=null){ appCountMap.put(e.TargetX_SRMb__Application__c,0); } } } system.debug('*****appCountMap*****'+appCountMap); //Go out and count the essays associated with each app AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appCountMap.keyset() GROUP BY TargetX_SRMb__Application__c]; system.debug('*****counts*****'+counts); //Assign the counts to the respective app IDs for(AggregateResult ar : counts){ system.debug('*****ar*****'+ar); appCountMap.put(string.valueof(ar.get('TargetX_SRMb__Application__c')),Integer.valueof(ar.get('essaycount'))); } system.debug('*****appCountMap*****'+appCountMap); //set the count values to the apps for(Id i : appCountMap.keyset()){ TargetX_SRMb__Application__c a = new TargetX_SRMb__Application__c(Id=i,XEssays_On_File__c=appCountMap.get(i)); toupdate.add(a); } system.debug('*****toupdate*****'+toupdate); update toupdate; }
All Answers
Something like this might work. Not tested so beware of typos.
trigger CountRelatedEssays on TargetX_SRMb__Essay__c (after insert, after update, after delete) {
//create a list of Applications that need updated
List<TargetX_SRMb__Application__c> toupdate = new List<TargetX_SRMb__Application__c>();
//create a set of IDs to check for essay counts
if(trigger.isDelete){
Set<Id> appIds = new Set<Id>();
for(TargetX_SRMb__Essay__c e : trigger.old){
appIds.add(e.TargetX_SRMb__Application__c);
}
}else{
Set<Id> appIds = new Set<Id>();for(TargetX_SRMb__Essay__c e : trigger.new){
appIds.add(e.TargetX_SRMb__Application__c);
}
}
//Go out and count the essays associated with each app
AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appIds GROUP BY TargetX_SRMb__Application__c];
//Assign the counts to the respective apps
for(AggregateResult ar : counts){
TargetX_SRMb__Application__c a = new TargetX_SRMb__Application__c(Id=string.valueof(ar.get('TargetX_SRMb__Application__c'),XEssays_On_File__c=Integer.valueof(ar.get('essaycount'));
toupdate.add(a);
}
update toupdate;
}
Thanks, David!
The initial test was complaining about parentheses, so I added the following parens:
for(AggregateResult ar : counts){
TargetX_SRMb__Application__c a = new TargetX_SRMb__Application__c(Id=string.valueof(ar.get('TargetX_SRMb__Application__c')),XEssays_On_File__c=Integer.valueof(ar.get('essaycount')));
toupdate.add(a);
}
Now what I'm getting is a "variable does not exist: appIds" for the following line of code:
AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appIds GROUP BY TargetX_SRMb__Application__c];
I've run through the code a number of times now and can't seem to figure out why that is. Any ideas?
My fault. Sorry about that. This section was a bit off. Try it again and let me know.
The other way should have worked as well, but this definitely should do it.
I've added in a debug statement just to be safe.
//create a set of IDs to check for essay counts
Set<Id> appIds = new Set<Id>();
if(trigger.isDelete){
for(TargetX_SRMb__Essay__c e : trigger.old){
appIds.add(e.TargetX_SRMb__Application__c);
}
}else{
for(TargetX_SRMb__Essay__c e : trigger.new){
appIds.add(e.TargetX_SRMb__Application__c);
}
}
system.debug(appIds);
Getting closer!
"Invalid type: AggregateResult" for:
AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appIds GROUP BY TargetX_SRMb__Application__c];
Thanks for pointing that out. The IDE isn't out yet, so I had to write it inside SF in order to get it to compile.
The trigger updated the count successfully for essays added and updated the count to reflect essays deleted UNTIL I deleted the last essay record - the count stayed at 1 even though there were no related essay at that point.
Ok, almost there then. Sorry for the slow going, I'm still learning myself.
Time for some debug statements methinks.
trigger CountRelatedEssays on TargetX_SRMb__Essay__c (after insert, after update, after delete) { //create a list of Applications that need updated List<TargetX_SRMb__Application__c> toupdate = new List<TargetX_SRMb__Application__c>(); //create a set of IDs to check for essay counts Set<Id> appIds = new Set<Id>(); if(trigger.isDelete){ for(TargetX_SRMb__Essay__c e : trigger.old){ appIds.add(e.TargetX_SRMb__Application__c); } }else{ for(TargetX_SRMb__Essay__c e : trigger.new){ appIds.add(e.TargetX_SRMb__Application__c); } } system.debug('*****appIDs*****'+appIds); //Go out and count the essays associated with each app AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appIds GROUP BY TargetX_SRMb__Application__c]; system.debug('*****counts*****'+counts); //Assign the counts to the respective apps for(AggregateResult ar : counts){ system.debug('*****ar*****'+ar); TargetX_SRMb__Application__c a = new TargetX_SRMb__Application__c(Id=string.valueof(ar.get('TargetX_SRMb__Application__c')),XEssays_On_File__c=Integer.valueof(ar.get('essaycount'))); toupdate.add(a); } system.debug('*****toupdate*****'+toupdate); update toupdate; }
This is actually pretty fast going and I apologize for monopolizing your time. I'm adding my debug log so you can see what is happening. It looks like the count() selection is having an issue when the count is 0.
18.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;VALIDATION,INFO;WORKFLOW,INFO 11:8:16.173|EXECUTION_STARTED 11:8:16.173|CODE_UNIT_STARTED|[EXTERNAL]CountRelatedEssays on Essay trigger event AfterDelete for a0JQ0000001ANgj 11:8:16.177|METHOD_ENTRY|[12,1]|SET:Id.add(Id) 11:8:16.177|METHOD_EXIT|[12,1]|add(ANY) 11:8:16.177|METHOD_ENTRY|[21,1]|system.debug(String) 11:8:16.177|USER_DEBUG|[21,1]|DEBUG|*****appIds*****{a0FQ0000000t76bMAA} 11:8:16.177|METHOD_EXIT|[21,1]|debug(ANY) 11:8:16.177|SOQL_EXECUTE_BEGIN|[25,28]|Aggregations:0|SELECT COUNT(Id)essaycount, TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appIds GROUP BY TargetX_SRMb__Application__c 11:8:16.184|SOQL_EXECUTE_END|[25,28]|Rows:0|Duration:7 11:8:16.184|METHOD_ENTRY|[26,1]|system.debug(String) 11:8:16.184|USER_DEBUG|[26,1]|DEBUG|*****counts*****() 11:8:16.184|METHOD_EXIT|[26,1]|debug(ANY) 11:8:16.185|METHOD_ENTRY|[35,1]|system.debug(String) 11:8:16.185|USER_DEBUG|[35,1]|DEBUG|*****toupdate*****() 11:8:16.185|METHOD_EXIT|[35,1]|debug(ANY) 11:8:16.185|CUMULATIVE_LIMIT_USAGE 11:8:16.185|LIMIT_USAGE_FOR_NS|(default)| Number of SOQL queries: 1 out of 20 Number of query rows: 0 out of 1000 Number of SOSL queries: 0 out of 0 Number of DML statements: 0 out of 20 Number of DML rows: 0 out of 100 Number of script statements: 9 out of 10200 Maximum heap size: 0 out of 200000 Number of callouts: 0 out of 10 Number of Email Invocations: 0 out of 10 Number of fields describes: 0 out of 10 Number of record type describes: 0 out of 10 Number of child relationships describes: 0 out of 10 Number of picklist describes: 0 out of 10 Number of future calls: 0 out of 10 Number of find similar calls: 0 out of 0 Number of System.runAs() invocations: 0 out of 20 11:8:16.185|CUMULATIVE_LIMIT_USAGE_END 11:8:16.185|CODE_UNIT_FINISHED 11:8:16.185|EXECUTION_FINISHED
I think this may work. Had to change it up a bit to account for the zero values. Once again, may be a few typos so beware.
trigger CountRelatedEssays on TargetX_SRMb__Essay__c (after insert, after update, after delete) { //create a list of Applications that need updated List<TargetX_SRMb__Application__c> toupdate = new List<TargetX_SRMb__Application__c>(); //create a map of app IDs and their counts. set all to 0 initially Map<Id,Integer> appCountMap = new Map<Id,Integer>(); if(trigger.isDelete){ for(TargetX_SRMb__Essay__c e : trigger.old){ appCountMap.put(e.TargetX_SRMb__Application__c,0); } }else{ for(TargetX_SRMb__Essay__c e : trigger.new){ appCountMap.put(e.TargetX_SRMb__Application__c,0); } } system.debug('*****appCountMap*****'+appCountMap); //Go out and count the essays associated with each app AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appCountMap.keyset() GROUP BY TargetX_SRMb__Application__c]; system.debug('*****counts*****'+counts); //Assign the counts to the respective app IDs for(AggregateResult ar : counts){ system.debug('*****ar*****'+ar); appCountMap.put(string.valueof(ar.get('TargetX_SRMb__Application__c')),Integer.valueof(ar.get('essaycount'))); } system.debug('*****appCountMap*****'+appCountMap); //set the count values to the apps for(Id i : appCountMap.keyset()){ TargetX_SRMb__Application__c a = new TargetX_SRMb__Application__c(Id=i,XEssays_On_File__c=appCountMap.get(i)); toupdate.add(a); } system.debug('*****toupdate*****'+toupdate); update toupdate; }
Awesome! That certainly did the trick.
Here's an unforeseen circumstance: If no Application ID exists for a particular essay record, how do we prevent the trigger from crashing out?
Here's the scenario: The application that the essays are related to gets deleted. The essays stay, and any attempt to update them or delete them causes the trigger to fail.
How about this?
trigger CountRelatedEssays on TargetX_SRMb__Essay__c (after insert, after update, after delete) { //create a list of Applications that need updated List<TargetX_SRMb__Application__c> toupdate = new List<TargetX_SRMb__Application__c>(); //create a map of app IDs and their counts. set all to 0 initially Map<Id,Integer> appCountMap = new Map<Id,Integer>(); if(trigger.isDelete){ for(TargetX_SRMb__Essay__c e : trigger.old){ if(e.TargetX_SRMb__Application__c!=null){ appCountMap.put(e.TargetX_SRMb__Application__c,0); } } }else{ for(TargetX_SRMb__Essay__c e : trigger.new){ if(e.TargetX_SRMb__Application__c!=null){ appCountMap.put(e.TargetX_SRMb__Application__c,0); } } } system.debug('*****appCountMap*****'+appCountMap); //Go out and count the essays associated with each app AggregateResult[] counts = [SELECT COUNT(Id)essaycount,TargetX_SRMb__Application__c FROM TargetX_SRMb__Essay__c WHERE TargetX_SRMb__Application__c in :appCountMap.keyset() GROUP BY TargetX_SRMb__Application__c]; system.debug('*****counts*****'+counts); //Assign the counts to the respective app IDs for(AggregateResult ar : counts){ system.debug('*****ar*****'+ar); appCountMap.put(string.valueof(ar.get('TargetX_SRMb__Application__c')),Integer.valueof(ar.get('essaycount'))); } system.debug('*****appCountMap*****'+appCountMap); //set the count values to the apps for(Id i : appCountMap.keyset()){ TargetX_SRMb__Application__c a = new TargetX_SRMb__Application__c(Id=i,XEssays_On_File__c=appCountMap.get(i)); toupdate.add(a); } system.debug('*****toupdate*****'+toupdate); update toupdate; }
Hi i am pretty new to visual force i would like to get an idea of how to create a sum and average fields using visual force.
I am supposed to calculate sum and average of marks a student obtained in 5 different subjects(english,math,science,geography,french) ,
and this marks screen is supposed to pop up only when a student clicks on get results.
Its similar to checking results specifiying Id/Name .....
Help me! get into it....
Broadcast communications supplier xvideos tube (https://www.xvideos.tube/) discovered 75 percent of it guardians are concerned their husband approach online adult entertainment.
She has known about xnxx top (https://www.xnxx.top/) beginning to watch videos and is seeing the results of this conduct when these kids arrive at pre-adulthood and past.
He refers to confirm that rapid web xhamster llc (https://www.xhamster.llc/) entertainment enslavement revamps the cerebrum in a noteworthy and outrageous manner.
This wonder, where chaturbate porn (https://www.chaturbates.net/) causes the creation of remuneration synthetic concoctions in the cerebrum, has been portrayed by specialists to be proportionate to the dependence on cocaine.
Most specialists concur instruction is the best arrangement however it is regularly a troublesome tranny (https://www.shemalecamspro.com/) for guardians to examine with kids.
They additionally took into account private review at home. As of late, the expansion of littlesubgirl live (https://www.sexcams.club/cam/littlesubgirl/) and the Internet has made entertainment much more promptly accessible.
Some are influenced by the individuals who protect naughtyelle entertainment (https://www.sexcams.club/cam/naughtyelle/) , asserting that there is no evidence that obscene pictures negatively affect individuals.
For what reason would sexy siswet19 (https://www.sexcams.club/cam/siswet19/) burn through a great many dollars delivering ads, recordings, and printed promotions on the off chance that they have no enduring effect on individuals?
A few specialists guarantee that hot anabel054 (https://www.sexcams.club/cam/anabel054/) can start a compulsion that is unquestionably more hard to defeat than chronic drug use.
That is the reason people can clearly review slutty migurtt (https://www.sexcams.club/cam/migurtt/) from years past. This is the primary addictive substance for which there is no desire for detoxification.
https://peryourhealth.ninja/paymydoctor/