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
BryanTSCBryanTSC 

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!

Best Answer chosen by Admin (Salesforce Developers) 
David81David81

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

David81David81

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;

}

 

 

 

Message Edited by David81 on 03-23-2010 02:39 PM
BryanTSCBryanTSC

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?

 

David81David81

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);

 

Message Edited by David81 on 03-23-2010 09:23 PM
Message Edited by David81 on 03-23-2010 09:34 PM
BryanTSCBryanTSC

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];

 

 

David81David81
Are you on the newest version? Spring '10? What API version is the trigger using? Should be 18.0 if available.
BryanTSCBryanTSC
Oh, jeesh, I didn't even think about that - let me verify!
BryanTSCBryanTSC

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.

David81David81

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; }

 

 

 

BryanTSCBryanTSC

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

 

 

 

 

David81David81

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; }

 


 

 

BryanTSCBryanTSC

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. 

David81David81

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; }

 

 

 

This was selected as the best answer
Rohit AlladiRohit Alladi

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....

Custom ThesisCustom Thesis
I am new in this forum. I think tghis is a common issue faced by programmers. I am new in this area, and it is not my favorite one. I am an essay writer at perfect essay writing services (http://customthesis.org/). We offer best academic writings for students. I was searching for problems that can be occured during programming for write an essay about the issues faced by programmers. I got a little of information from your post. 
Bruno Araujo 2Bruno Araujo 2
Thanks a lot for all your replies. It is finally works for my site https://eliteessaywriting.com/blog/essay-outline. Problem occured in an old library!
Chuck BurtonChuck Burton
We have two custom objects (related via lookup field on auto object):  Something like this might possibly work. https://canadasautoloan.ca/bad-credit-car-loans-bc/ Not tested on our main bad credit car loan website so beware of typo errors. 
 
Lakudra BledeLakudra Blede
It may appear to be an outrageous case - however right? Fixation, unfortunate connections and rising degrees of sex cams club (https://www.sexcams.club/) in youth is the truth of simple access to explicit material.

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.
Lakudra BledeLakudra Blede
The improvement of the online hotfallingdevil (https://www.sexcams.club/cam/hotfallingdevil/) heightened this pattern. Not at all like film reels and old photos, videocassettes were anything but difficult to store, duplicate, and disseminate.

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.
will war 1will war 1
PayMyDoctor online portal has been launched in the United States to conceive the experience of the cases in the countryside easy to a great extent.  Any pay my doctor client can pay their hospital or clinic bill by using paymydoctor.com
https://peryourhealth.ninja/paymydoctor/
Jason LeenJason Leen
Hello! Do you need help of high level of assignment writing for students? Professional typers provide the coolest custom master-paper.com (https://master-paper.com/) writing service. Get writing help from this online agency at low price!
Erick KintighErick Kintigh
Howdy! I am a college student, but I don't always have enough time to complete my written work. And here's the service https://customessayorder.com/write-my-research-paper which helps me learn well.