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
Zuhair ShaikhZuhair Shaikh 

Need help with creating a class that calls for data from a standard Contact field, makes a comma-separated list and then updates it to a custom field in Account.

Hello. First time poster. I feel like this is an easy problem but I seem to be stuck at actually updating the records. So essentially, I need to create a class that will, for each account in system, update Contact_Email_List__c (which I have created) with the list of email ids (comma separated) from Contact related list of account.
public class EmailListMaker {   
    public void EmailListMaker(){
        List<String> emails = new List<String>();
        for (Contact em : [Select Email FROM Contact ORDER BY Name]){
            emails.add(em.Email);
        }
        String emailList = String.join(emails, ', ');           
        upsert emailList Account.Fields.Contact_Email_List__c;
    }
}

It gives the following problem, "DML requires SObject or SObject list type: String". I feel like I need to transfer the string to a SObject but I can't seem to figure out how. 



 
Best Answer chosen by Zuhair Shaikh
LBKLBK
If you want to run through all your accounts and update the Email list, here is the code.
 
public class EmailListMaker {
	public void EmailListMaker(){
		List<Account> lstAccount = [SELECT Id, Name FROM Account];
		List<Contact> lstContact = [SELECT Id, Email, AccountId FROM Contact];
        List<Account> lstAccountUpdate = new List<Account>();
		
		Map <Id, String> mapEmailList = new Map <Id, String>();
		for (Contact c : lstContact){
			String sEmailList = mapEmailList.get(c.AccountId);
			if(sEmailList == null)
			{
				sEmailList = '';
			}
            if(c.Email != null){
                sEmailList += c.Email + ', ';
                mapEmailList.put(c.AccountId, sEmailList);
            }
		}
		
		for(Account a : lstAccount){
            if(mapEmailList.get(a.Id) != null){
                
                String sEmailList = (String)mapEmailList.get(a.Id).trim();
                if(sEmailList.length() > 0){
                    sEmailList = sEmailList.left(sEmailList.length() - 1);
                }
                a.Contact_Email_List__c =sEmailList;
                System.debug(a.Name + ': ' + sEmailList);
                lstAccountUpdate.add(a);
            }
		}
		upsert lstAccountUpdate;
	}
}

 

All Answers

Nagendra ChinchinadaNagendra Chinchinada
Hi Zuhair,
Here  is the modified code which updates concatinated string of email ids to respective account.

This method takes AccountId as parameter, updates that acount's contact email ids in Contact_Email_List__c field.
 
public class EmailListMaker {   
    public void EmailListMaker(Id AccId){
        List<String> emails = new List<String>();
        for (Contact em : [Select Email FROM Contact WHERE AccountId=:AccId ORDER BY Name ]){
            emails.add(em.Email);
        }
        String emailList = String.join(emails, ', ');
        
        // Update email string in corresponding Account
            Account accUpdate = new Account(Id=AccId);
            accUpdate.Contact_Email_List__c = emailList;
            update accUpdate;
    }
}

If you want to update all accounts, you need to go for a Batch apex class.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm

Thanks,
Nagendra Prasad
 
LBKLBK
If you want to run through all your accounts and update the Email list, here is the code.
 
public class EmailListMaker {
	public void EmailListMaker(){
		List<Account> lstAccount = [SELECT Id, Name FROM Account];
		List<Contact> lstContact = [SELECT Id, Email, AccountId FROM Contact];
        List<Account> lstAccountUpdate = new List<Account>();
		
		Map <Id, String> mapEmailList = new Map <Id, String>();
		for (Contact c : lstContact){
			String sEmailList = mapEmailList.get(c.AccountId);
			if(sEmailList == null)
			{
				sEmailList = '';
			}
            if(c.Email != null){
                sEmailList += c.Email + ', ';
                mapEmailList.put(c.AccountId, sEmailList);
            }
		}
		
		for(Account a : lstAccount){
            if(mapEmailList.get(a.Id) != null){
                
                String sEmailList = (String)mapEmailList.get(a.Id).trim();
                if(sEmailList.length() > 0){
                    sEmailList = sEmailList.left(sEmailList.length() - 1);
                }
                a.Contact_Email_List__c =sEmailList;
                System.debug(a.Name + ': ' + sEmailList);
                lstAccountUpdate.add(a);
            }
		}
		upsert lstAccountUpdate;
	}
}

 
This was selected as the best answer
Zuhair ShaikhZuhair Shaikh
Thanks LBK, that worked perfectly. I am not familiar with some of the syntax you used, so I am going to spend some time trying to understand it all.

Nagendra, sorry for being unclear, I shouldn't have said Ids. I also didn't want to input any parameter. However, thanks for replying.
rajat Maheshwari 6rajat Maheshwari 6

Hi Zuhair,

Please use below code snippet on your requirement, It will help you definately :)

 

trigger RestrictContactByName on Contact (after insert, after update) {
    
    Set<Id> st_Id = new Set<Id>();
    List<Account> acc_List;
  
  
  
  
  if(Trigger.isAfter && Trigger.isInsert)
   {
      For (Contact c : Trigger.New) {
         st_Id.add(c.AccountId);
        }
   }
   
   if(Trigger.isAfter && Trigger.isUpdate)
    {
       For (Contact c : Trigger.New) {
         if(c.Email!=Trigger.oldMap.get(c.id).Email)
           st_Id.add(c.AccountId);
        }
    }
        
        if(st_Id!=null && !st_Id.isEmpty())
         {
       acc_List = new List<account>([Select Id,Name,Email_List__c,(Select Id,Email from Contacts) from Account where Id IN:st_Id]);
      
      
      
      for(Account acc : acc_List)
         {
            acc.Email_List__c = '';
            for(Contact con : acc.Contacts)
               {
                  if(con.Email!=null)
                       acc.Email_List__c += con.Email +',';
               }
         }
         
       }
         
         if(acc_List !=null && acc_List.size()>0)
            update acc_List;
                  
      
      
      
      

    }


If you want to utilize in apex class, please let me know :)

Thanks

Zuhair ShaikhZuhair Shaikh
Thank Rajat. I currently do not need to use a Trigger, so if you could just modify it to make a class, it would be helpful.
rajat Maheshwari 6rajat Maheshwari 6

Hi Zuhair,

Below is class code snippet, please use the same and let me know :)

public class EmailListMaker {
  List<Account> acc_List;
  
	public void EmailListMaker(Id AccountId){
		acc_List = new List<account>([Select Id,Name,Email_List__c,(Select Id,Email from Contacts) from Account where Id =:AccountId]);
	
 for(Account acc : acc_List)
       {
           acc.Email_List__c = '';
           for(Contact con : acc.Contacts)
              {
                 if(con.Email!=null)
                      acc.Email_List__c += con.Email +',';
               }
       }
          
   if(acc_List !=null && acc_List.size()>0)
            upsert acc_List;
		
	}

 

Please let me know, If it works 

Thanks

Zuhair ShaikhZuhair Shaikh
Sorry Rajat but I do not want provide an input parameter. I just want to create a class that would, for each account, take emails from Contact, make a list separated by commas, and then insert it into the custom field Contact_Email_List__c in Account. For now I have a solution so thank you for trying.
rajat Maheshwari 6rajat Maheshwari 6

Hi Zuhair,

Thanks :)