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
Che SFDCChe SFDC 

Need help adding query outside FOR loop

Hello. I need help with adding my SOQL queires outside the 'For' Loops. I`m new to Apex coding and I was reading the article about governor limits. I tried adding by queries outside 'for' loop but they are not working. Can someone please give me an example on how to do this by using List or maps?? Also, is the code below correct or will it hit governor limit?
 
Trigger VisitNotification on Event (after insert){
		
    List<Messaging.SingleEmailMessage> newEmails = new List<Messaging.SingleEmailMessage>();
    for(Event e :Trigger.new){
            String fullTaskURL;
            String Facility;
            Datetime startDate;
            Datetime endDate;
            String Purpose;
            String Salesexec;

            // Query to populate CreatedBy name in html template
            String createdByID = E.CreatedByID;
            String createdByName = [SELECT Name from User WHERE id=: createdByID limit 1].Name;
            
            // Query to populate Opportunity name in html template
            String oppID = E.whatId;  
            String oppName = [SELECT Name, Account.Name from Opportunity WHERE id=: oppID limit 1].Name;
    
        if(E.Visit__C){
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                
            mail.setSubject('Automated Alert: A New Record is Created');
            mail.setSaveAsActivity(false);
            mail.setTargetObjectId('00580000005HreR') ;        

            fullTaskURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + E.Id;
            Facility = E.Facility__c;
            startDate = E.StartDateTime;
            endDate = E.EndDateTime;
            Purpose = E.Purpose__c;
            Salesexec = E. Salesexec__c;
   
   
            //Generate email template
                String emailBody;
                emailBody = '<html><body>Hi<br> <br> A New Record has been created: <a href="' + fullTaskURL + '">' + E.Id + '</a><br></body></html>' + '<br> <br> Site/Facility: ' + Facility+ '<br> Start Date/Time: ' + StartDate + '<br> End Date/Time: ' +endDate + '<br> Purpose: ' + Purpose + '<br> Sales VP: '+ Salesexec +  '<br> <br> Thank you <br> <br> Salesforce Admin' ; 
                mail.setHtmlBody(emailBody );

            newEmails.add(mail);
        }
    }

    messaging.sendEmail(newEmails);
}

 
Best Answer chosen by Che SFDC
SarfarajSarfaraj
Hi Chetan

This is the bulkified code,
Trigger VisitNotification on Event (after insert){
		
    List<Messaging.SingleEmailMessage> newEmails = new List<Messaging.SingleEmailMessage>();
	List<Id> whatIds = new List<Id>();
	List<Id> createdByIds = new List<Id>();
	for(Event e :Trigger.new)
	{
		createdByIds.add(E.CreatedByID);
		whatIds.add(E.whatId);
	}
	Map<Id, User> users = new Map<Id, User>([SELECT Id, Name from User WHERE Id in :createdByIds]);
	Map<Id, Opportunity> opportunities = new Map<Id, Opportunity>([SELECT Name, Account.Name from Opportunity WHERE Id in :whatIds]);
    for(Event e :Trigger.new){
            String fullTaskURL;
            String Facility;
            Datetime startDate;
            Datetime endDate;
            String Purpose;
            String Salesexec;

            // Query to populate CreatedBy name in html template
            Id createdByID = E.CreatedByID;
            String createdByName = users.get(createdByID).Name;
            
            // Query to populate Opportunity name in html template
            String oppID = E.whatId;  
            String oppName = opportunities.get(oppID).Name;
    
        if(E.Visit__C){
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                
            mail.setSubject('Automated Alert: A New Record is Created');
            mail.setSaveAsActivity(false);
            mail.setTargetObjectId('00580000005HreR') ;        

            fullTaskURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + E.Id;
            Facility = E.Facility__c;
            startDate = E.StartDateTime;
            endDate = E.EndDateTime;
            Purpose = E.Purpose__c;
            Salesexec = E.Salesexec__c;
   
   
            //Generate email template
                String emailBody;
                emailBody = '<html><body>Hi<br> <br> A New Record has been created: <a href="' + fullTaskURL + '">' + E.Id + '</a><br></body></html>' + '<br> <br> Site/Facility: ' + Facility+ '<br> Start Date/Time: ' + StartDate + '<br> End Date/Time: ' +endDate + '<br> Purpose: ' + Purpose + '<br> Sales VP: '+ Salesexec +  '<br> <br> Thank you <br> <br> Salesforce Admin' ; 
                mail.setHtmlBody(emailBody );

            newEmails.add(mail);
        }
    }

    messaging.sendEmail(newEmails);
}

--Akram

All Answers

SarfarajSarfaraj
Hi Chetan

This is the bulkified code,
Trigger VisitNotification on Event (after insert){
		
    List<Messaging.SingleEmailMessage> newEmails = new List<Messaging.SingleEmailMessage>();
	List<Id> whatIds = new List<Id>();
	List<Id> createdByIds = new List<Id>();
	for(Event e :Trigger.new)
	{
		createdByIds.add(E.CreatedByID);
		whatIds.add(E.whatId);
	}
	Map<Id, User> users = new Map<Id, User>([SELECT Id, Name from User WHERE Id in :createdByIds]);
	Map<Id, Opportunity> opportunities = new Map<Id, Opportunity>([SELECT Name, Account.Name from Opportunity WHERE Id in :whatIds]);
    for(Event e :Trigger.new){
            String fullTaskURL;
            String Facility;
            Datetime startDate;
            Datetime endDate;
            String Purpose;
            String Salesexec;

            // Query to populate CreatedBy name in html template
            Id createdByID = E.CreatedByID;
            String createdByName = users.get(createdByID).Name;
            
            // Query to populate Opportunity name in html template
            String oppID = E.whatId;  
            String oppName = opportunities.get(oppID).Name;
    
        if(E.Visit__C){
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                
            mail.setSubject('Automated Alert: A New Record is Created');
            mail.setSaveAsActivity(false);
            mail.setTargetObjectId('00580000005HreR') ;        

            fullTaskURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + E.Id;
            Facility = E.Facility__c;
            startDate = E.StartDateTime;
            endDate = E.EndDateTime;
            Purpose = E.Purpose__c;
            Salesexec = E.Salesexec__c;
   
   
            //Generate email template
                String emailBody;
                emailBody = '<html><body>Hi<br> <br> A New Record has been created: <a href="' + fullTaskURL + '">' + E.Id + '</a><br></body></html>' + '<br> <br> Site/Facility: ' + Facility+ '<br> Start Date/Time: ' + StartDate + '<br> End Date/Time: ' +endDate + '<br> Purpose: ' + Purpose + '<br> Sales VP: '+ Salesexec +  '<br> <br> Thank you <br> <br> Salesforce Admin' ; 
                mail.setHtmlBody(emailBody );

            newEmails.add(mail);
        }
    }

    messaging.sendEmail(newEmails);
}

--Akram
This was selected as the best answer
SarfarajSarfaraj
I can see you have hardcoded one id at line 34. Check if it is really what you want.
Che SFDCChe SFDC
Thank you Akram, this works great! Thanks for all your help.