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
Rafael MottaRafael Motta 

Loop must iterate over collection: Attachment

Hi everyone.

I have an request to clone attachment but i can´t solve this isue. in account i have 2 record types account and Prospect, Both are arecord types from Account.


CORRECT FLOW:
1.- IF a record with record type Prospect has the same Sap_Number(custom field) of record  with Account Recod type.
2.- Clone Attachments of Prospect Record and set in Account Record.

if i run the class Salesforce Show Me:
"Error: Invalid Data. 
Review all error messages below to correct your data.
Apex trigger ActualizaAttachmente caused an unexpected exception, contact your administrator: ActualizaAttachmente: execution of AfterUpdate caused by: System.QueryException: List has more than 1 row for assignment to SObject: Class.Set_attachments.GetAccounts: line 34, column 1"


I know that i have most of 1 attachment and I try to set in For sentence to get all attachments. but salesforce Show me:
"Loop must iterate over collection: Attachment"

this is an extract of code whit the error:

   Attachment GetattAchment = New Attachment();
                   
        IF(GetattAchment!=null){
             
          GetattAchment =[SELECT id,Body,Name, Description, ParentId FROM Attachment WHERE ParentId IN (SELECT id FROM Account WHERE RecordTypeid='01236000001A0hVAAS')];
                 For (attachment att: GetattAchment){
                GetattAchment = new Attachment();
                }
         System.debug('attachment'+ GetattAchment);
                    System.debug('¿Alcanzo el parent?'+ GetattAchment.ParentId);

I show you complete apex class:

public class Set_attachments {
public static void GetAccounts(list<Account>Accountlist){
    
    //Create Variables
    
    //Name=Account Id=01236000001A0hQAAS
    //Name=Prospect RecordType:Id=01236000001A0hVAAS
    List<RecordType> GetRecord = New List<RecordType>();
    List<Account> GetAccount = New List<Account>();
    List<Account> GetProspect = New List<Account>();
    List<Attachment> GetAttachacc = New List<Attachment>();
    List<Attachment> lstattachment= new List <Attachment>();
    
    
    //QUERYS RECORDTYPES, ACCOUNTS ACCOUNT AND ACCOUNTS PROSPECT
    GetRecord =[SELECT id, Name FROM RecordType];
    GetAccount =[SELECT id, Name, ONTAP_SAP_Number__c FROM Account WHERE ONTAP_SAP_Number__c !=null AND RecordTypeid='01236000001A0hQAAS' ];
    GetProspect =[SELECT id, Name, ONTAP_SAP_Number__c FROM Account WHERE ONTAP_SAP_Number__c !=null AND RecordTypeid='01236000001A0hVAAS' ];
    
For (Account accp: GetProspect){        
    For (Account acc: GetAccount){    
    
    IF(GetAttachacc!=null){
    GetAttachacc =[SELECT id,Body,Name, Description, ParentId FROM attachment WHERE ParentId IN (SELECT id FROM Account WHERE RecordTypeid='01236000001A0hQAAS') ];
       System.debug('los attachment son : ' +GetAttachacc);
    
    //GET ACCOUNTS OF PROSPECT WITH SAP_NUMBER 
                IF(accp.ONTAP_SAP_Number__c==acc.ONTAP_SAP_Number__c ){
         
                    
        //TRY TO GET ALL ATTACHMENTS, OF PROSPECT BUT sALESFORCE DISPLAY ME 
        //************************************************************************************
        //"Error: Invalid Data. 
        //Review all error messages below to correct your data.
        //Apex trigger ActualizaAttachmente caused an unexpected exception, contact your administrator: ActualizaAttachmente: execution of AfterUpdate caused by: System.QueryException: 
        //List has more than 1 row for assignment to SObject: Class.Set_attachments.GetAccounts: line 34, column 1"
        //************************************************************************************            
          Attachment GetattAchment = New Attachment();
                   
        IF(GetattAchment!=null){
             
          GetattAchment =[SELECT id,Body,Name, Description, ParentId FROM Attachment WHERE ParentId IN (SELECT id FROM Account WHERE RecordTypeid='01236000001A0hVAAS')];
                 For (attachment att: GetattAchment){
                GetattAchment = new Attachment();
                }
         System.debug('attachment'+ GetattAchment);
                    System.debug('¿Alcanzo el parent?'+ GetattAchment.ParentId);
            
              
             /* attachment newFile = new Attachment();
                      newFile = GetattAchment.clone();
                    newFile.id= GetattAchment.id;
                    newFile.Name= GetattAchment.name;
                    newFile.Body= GetattAchment.Body;
                    newFile.ParentId=GetattAchment.ParentId;
                    lstattachment.add(newFile);
                    newFile = new Attachment();
                    }
                    if(!lstattachment.isEmpty()){
                    Insert lstattachment;
                    }*/
            
        
              
              
        
     }
}
}}
    
}}}
Steven NsubugaSteven Nsubuga
Hi Rafael, your code seemed overly complicated. I have reworked it as follows:
public class Set_attachments {

	public static void GetAccounts(list<Account>Accountlist){
		
		//Create Variables
		
		//Name=Account Id=01236000001A0hQAAS
		//Name=Prospect RecordType:Id=01236000001A0hVAAS
		List<RecordType> GetRecord = New List<RecordType>();
		List<Account> GetAccount = New List<Account>();
		List<Account> GetProspect = New List<Account>();
		List<Attachment> GetAttachacc = New List<Attachment>();
		List<Attachment> lstattachment= new List <Attachment>();
		
		
		//QUERYS RECORDTYPES, ACCOUNTS ACCOUNT AND ACCOUNTS PROSPECT
		GetRecord =[SELECT id, Name FROM RecordType];
		
		GetAccount =[SELECT id, Name, ONTAP_SAP_Number__c FROM Account WHERE ONTAP_SAP_Number__c !=null AND RecordTypeid='01236000001A0hQAAS' ];

        // Create a map of ONTAP_SAP_Number__c and Account
		Map<String, Account> ontapAccts1 = new Map<String, Account>();
		for (Account acc: GetAccount){ 
			ontapAccts1.put(acc.ONTAP_SAP_Number__c, acc);
		}
		
		GetProspect =[SELECT id, Name, ONTAP_SAP_Number__c FROM Account WHERE ONTAP_SAP_Number__c !=null AND RecordTypeid='01236000001A0hVAAS' ];

        // Create a map of ONTAP_SAP_Number__c and Account
        // the 2 maps ontapAccts1 and ontapProspectAccts will be used to link Accounts with the same  
        // ONTAP_SAP_Number__c 
                
		Map<String, Account> ontapProspectAccts = new Map<String, Account>();
		for (Account acc: GetProspect){ 
			ontapProspectAccts.put(acc.ONTAP_SAP_Number__c, acc);
		}
		
        // Create a set of Account Ids with matching ONTAP_SAP_Number__c 
		Set<Id> acctIds = new Set<Id>();
		for (Account acc: ontapProspectAccts){ 
			if (ontapAccts1.keyset().contains(acc.ONTAP_SAP_Number__c)) {
				acctIds.add(acc.Id);
			}
		}
		
		if (acctIds.size() > 0){
    
            // Query Salesforce to retrieve the relevant attachments 
			GetAttachacc = [SELECT id,Body,Name, Description, ParentId FROM attachment WHERE ParentId IN :acctIds];
			System.debug('los attachment son : ' +GetAttachacc);
			
            // Create a map of Attachments per Account Id 
			Map<String, List<Attachment>> attachmentsMap = new Map<String, List<Attachment>>();
			for (Attachment att: GetAttachacc){ 
				if (!attachmentsMap.keyset().contains(att.ParentId)){
					List<Attachment> atts = new List<Attachment>();
					attachmentsMap.put(att.ParentId, atts);
				}
				attachmentsMap.put(att.ParentId, attachmentsMap.get(att.ParentId).add(att));
			}
			
            // Iterate through the relevant prospect Accounts and clone their attachments
			for (Account acc: ontapProspectAccts){ 
				if (acctIds.contains(acc.Id)) {
					List<Attachment> attachments = attachmentsMap.get(acc.Id);
					
					Account acct = ontapAccts1.get(acc.ONTAP_SAP_Number__c);
					
					for (Attachment att: attachments){ 
						Attachment newAttachment = att.clone();
						newAttachment.ParentId = acct.Id;
						lstattachment.add(newAttachment);
					}
				}
			}
			insert lstattachment;
	    }
	}
}