• Muhammad Sahil
  • NEWBIE
  • 0 Points
  • Member since 2023

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 1
    Replies
i want to upload a csv using vf page that would contain parent accounts with corresponding child accounts, and i want to merge them using batch instead of doing this manually but i am getting error " List has more than 1 row for assignment to SObject on line: 35" on my batch, 
my vf page is 
<apex:page controller="MergeChildAccountsController">
    <apex:form enctype="multipart/form-data">
        <apex:inputFile value="{!csvFile}" />
        <apex:commandButton action="{!processCsv}" value="Process CSV" />
    </apex:form>
</apex:page>
============================================
my controler is 
public class MergeChildAccountsController {
    public Blob csvFile { get; set; }
    
    public void processCsv() {
        String[] filelines = csvFile.toString().split('\n');
        List<Account> childAccounts = new List<Account>();
        Map<String, String> parentMap = new Map<String, String>();
        
        for (Integer i = 1; i < filelines.size(); i++) {
            String[] fields = filelines[i].split(',');
            String accountName = fields[0].trim();
            String parentName = fields[1].trim();
            
            Account child = new Account(Name = accountName);
            childAccounts.add(child);
            parentMap.put(accountName, parentName);
        }
        
        Database.executeBatch(new MergeChildAccountsBatch(childAccounts, parentMap));
    }
}
====================================

my batch is 
public class MergeChildAccountsBatch implements Database.Batchable<Account> {
    List<Account> childAccounts;
    Map<String, String> parentMap;
    
    public MergeChildAccountsBatch(List<Account> childAccounts, Map<String, String> parentMap) {
        this.childAccounts = childAccounts;
        this.parentMap = parentMap;
    }
    
    public Iterable<Account> start(Database.BatchableContext bc) {
        return [SELECT Id, Name, ParentId FROM Account WHERE Name IN :parentMap.keySet() OR Id IN :childAccounts];
    }
    
    public void execute(Database.BatchableContext bc, List<Account> parentAccounts) {
        try {
            Map<String, Account> nameToAccountMap = new Map<String, Account>();
            
            for (Account account : parentAccounts) {
                nameToAccountMap.put(account.Name, account);
            }
            
            Set<Account> accountsToMerge = new Set<Account>();
            for (Account child : childAccounts) {
                String parentName = parentMap.get(child.Name);
                if (parentName != null) {
                    List<Account> parentList = [SELECT Id, Name, ParentId FROM Account WHERE Name = :parentName];
                    accountsToMerge.addAll(parentList);
                }
            }
            
            Database.MergeResult[] mergeResults = Database.merge(nameToAccountMap.values(), new List<Account>(accountsToMerge), false);
           system.debug('mergeResults' +mergeResults);
            
            
           /* for (Database.MergeResult result : mergeResults) {
                if (result.isSuccess()) {
                    // do something with the merged account
                } else {
                    // handle the merge failure
                }
            } */
        } catch (Exception e) {
            System.debug('Error: ' + e.getMessage() + ' on line: ' + e.getLineNumber());
        }
    }
    
    public void finish(Database.BatchableContext bc) {
        // do nothing
    }
}
vf page
<apex:page controller="AccountsSearchController" >
    <div style="margin: 1%;">
        
    <apex:form >
        <apex:pageBlock >
            <span>Account Name:</span>
                        <apex:selectList value="{!selectedAccountId}" size="1">
                <apex:selectOptions value="{!accountOptions}" />
            </apex:selectList>
             <apex:commandButton action="{!getDetails}" value="Get Contacts"/>

           <apex:pageBlockSection id="display" title="Related Contacts">              
        <apex:pageBlockTable value="{!relatedContacts}" var="contact" style="border:1px solid black;">
        <apex:column >
        <apex:facet name="header">
        <input type="checkbox" id="checkAllBox" onclick="selectAllCheckboxes(this,'inputId')"/>
            <script>
                function selectAllCheckboxes(obj,receivedInputID){
                var inputCheckBox = document.getElementsByTagName("input");
                for(var i=0; i<inputCheckBox.length; i++){
                if(inputCheckBox[i].id.indexOf(receivedInputID)!=-1){
                inputCheckBox[i].checked = obj.checked;
            global var i = obj.checked;
                        }
                        }
                }
            
            </script>
                </apex:facet>
            
        <apex:inputCheckbox id="checkboxShowP" value="{!isChecked}">
            <apex:actionSupport event="onchange" action="{!click}"/>
        </apex:inputCheckbox>
            
        </apex:column>
        <apex:column headerValue="Contact Name" style="width:200px;border:1px solid black;">
                <apex:outputField value="{!contact.Name}" />
        </apex:column>
        <apex:column headerValue="Contact Email" style="width:200px;border:1px solid black;">
             <apex:outputField value="{!contact.Email}" />
        </apex:column>
        <apex:column headerValue="Owner ID" style="width:200px;border:1px solid black;">
             <apex:outputField value="{!contact.OwnerId}" />
        </apex:column>
        </apex:pageBlockTable>
             <apex:commandButton value="Update Selected"/>
        </apex:pageBlockSection>
        </apex:pageBlock>
        </apex:form>
        </div>
</apex:page>
controller:
public with sharing class AccountsSearchController {
  public List<Account> selectedAccount {get; set;}
  public Boolean isChecked{ get; set; }
  public List<Contact> relatedContacts {get; set;}
  public List<Contact> SelectedContacts {get; set;}
  public List<Contact> checkedCon {get; set;}
  public List<Contact> i {get; set;}
  public List<SelectOption> accountOptions {get; set;}
  public String selectedAccountId {get; set;}
  public String selected {get; set;}
  List<Contact> contacts = new List<Contact>();

    
  public AccountsSearchController() {
    accountOptions = new List<SelectOption>();
    for (Account acc : [SELECT Id, Name FROM Account]) {
      accountOptions.add(new SelectOption(acc.Id, acc.Name));
    }
  }

  public void getDetails() {
    selectedAccount = [SELECT Id, Name, Phone, (SELECT Id, Name, Email, AccountId, OwnerId FROM Contacts) FROM Account WHERE Id = :selectedAccountId LIMIT 1];
    relatedContacts = selectedAccount[0].Contacts;
  }
     

  
     public void click(){
        for (Contact con : Contacts) {
                    if(isChecked==true){
        con.LastName = 'Updated ' + contact.LastName;
            contacts.Add(con);
    } insert Contacts;
    update relatedContacts;
        }
        
    }
    
    
}
i want to upload a csv using vf page that would contain parent accounts with corresponding child accounts, and i want to merge them using batch instead of doing this manually but i am getting error " List has more than 1 row for assignment to SObject on line: 35" on my batch, 
my vf page is 
<apex:page controller="MergeChildAccountsController">
    <apex:form enctype="multipart/form-data">
        <apex:inputFile value="{!csvFile}" />
        <apex:commandButton action="{!processCsv}" value="Process CSV" />
    </apex:form>
</apex:page>
============================================
my controler is 
public class MergeChildAccountsController {
    public Blob csvFile { get; set; }
    
    public void processCsv() {
        String[] filelines = csvFile.toString().split('\n');
        List<Account> childAccounts = new List<Account>();
        Map<String, String> parentMap = new Map<String, String>();
        
        for (Integer i = 1; i < filelines.size(); i++) {
            String[] fields = filelines[i].split(',');
            String accountName = fields[0].trim();
            String parentName = fields[1].trim();
            
            Account child = new Account(Name = accountName);
            childAccounts.add(child);
            parentMap.put(accountName, parentName);
        }
        
        Database.executeBatch(new MergeChildAccountsBatch(childAccounts, parentMap));
    }
}
====================================

my batch is 
public class MergeChildAccountsBatch implements Database.Batchable<Account> {
    List<Account> childAccounts;
    Map<String, String> parentMap;
    
    public MergeChildAccountsBatch(List<Account> childAccounts, Map<String, String> parentMap) {
        this.childAccounts = childAccounts;
        this.parentMap = parentMap;
    }
    
    public Iterable<Account> start(Database.BatchableContext bc) {
        return [SELECT Id, Name, ParentId FROM Account WHERE Name IN :parentMap.keySet() OR Id IN :childAccounts];
    }
    
    public void execute(Database.BatchableContext bc, List<Account> parentAccounts) {
        try {
            Map<String, Account> nameToAccountMap = new Map<String, Account>();
            
            for (Account account : parentAccounts) {
                nameToAccountMap.put(account.Name, account);
            }
            
            Set<Account> accountsToMerge = new Set<Account>();
            for (Account child : childAccounts) {
                String parentName = parentMap.get(child.Name);
                if (parentName != null) {
                    List<Account> parentList = [SELECT Id, Name, ParentId FROM Account WHERE Name = :parentName];
                    accountsToMerge.addAll(parentList);
                }
            }
            
            Database.MergeResult[] mergeResults = Database.merge(nameToAccountMap.values(), new List<Account>(accountsToMerge), false);
           system.debug('mergeResults' +mergeResults);
            
            
           /* for (Database.MergeResult result : mergeResults) {
                if (result.isSuccess()) {
                    // do something with the merged account
                } else {
                    // handle the merge failure
                }
            } */
        } catch (Exception e) {
            System.debug('Error: ' + e.getMessage() + ' on line: ' + e.getLineNumber());
        }
    }
    
    public void finish(Database.BatchableContext bc) {
        // do nothing
    }
}