-1

How to unchecked duplicate account record that have opportunity/contact or both. Default duplicate__c is false.

Example:

Suppose, there are total 3 duplicate name record, with one duplicate name record having either opportunity or contact or both and rest 2 duplicate name record don't have opportunity and contact then the result should marked two checkbox(duplicate__c) true. In my case it is returning 1 record as checked

Similarly for 4 duplicate name records , if one record is having opportunities or contact and the rest 3 don't have relationship with opportunity and contact.In my case it is marking 2 record true(checked). But it should be 3 record to be true(checked).

I cannot build up logic help me to sole above cases.

List<Account> actLst = new List<Account>();
Set<String> userNames = new Set<String>();

Map<Id,Account> accAll= new Map<Id,Account>();
    for(Account a:[Select Id, Name from Account])
        {accAll.put(a.Id,a);}

Map<Id,Account> accDup = new Map<Id,Account>();
    for(Account a:[SELECT Id,Name,duplicate__c FROM Account where Id Not In (Select AccountId from Contact) And 
                    Id Not In (Select Account_Name__c from Opportunity__c)])
        {accDup.put(a.Id,a);}

Map<Id,Account> accCont = new Map<Id,Account>();
     for(Account a:[SELECT Id,Name,duplicate__c FROM Account where Id In (Select AccountId from Contact)])
        {accCont.put(a.Id,a);}

Map<Id,Account> accOpp =new Map<Id,Account>();
     for(Account a:[SELECT Id,Name,duplicate__c FROM Account where Id In (Select Account_Name__c from Opportunity__c)])
        {accOpp.put(a.Id,a);}

for(Account account_i : accAll.values())
{    
if(!(accCont.containsKey(account_i.Id)) )  //|| (!accOpp.containsKey(account_i.Name))) 
   {   
     if((accDup.containsKey(account_i.Id)) )
        {
            if(!(userNames.contains(account_i.Name)) ) 
              {
                userNames.add(account_i.Name);
                system.debug('UserName');
                System.debug(account_i.Id);   
              }
            else
            {
               account_i.duplicate__c = true;
               actLst.add(account_i);
               System.debug('1');
               System.debug(account_i.Id); 
            }
        }
       else
         {
            System.debug('Relationship record ' +account_i.Id);       
         }
   }
    else
    {
       System.debug('2');
       System.debug(account_i.Id);  
    }

}
    system.debug('actLst >> ' + actLst);
update actLst;
  • according to console it is not reaching here else if(accCont.containsKey(account_i.Name)) i.e the condition(false) is not getting satisfied if((!accCont.containsKey(account_i.Name)) ) – Palash Jun 27 at 7:17
  • 1
    Please don't post the same question repeatedly. Instead, edit your existing post to improve it. – David Reed Jun 27 at 12:12
1

This Map constructor pattern:

Map<String,Account> accCont = new Map<String,Account>([
    SELECT Id,Name,duplicate__c
    FROM Account
    where Id In (Select AccountId from Contact)
]);  

always takes the Id value from the query and uses it as the key. So while you can use Map<String,Account>, better to make it Map<Id,Account>. From the Map Class documentation:

Creates a new instance of the Map class and populates it with the passed-in list of sObject records. The keys are populated with the sObject IDs and the values are the sObjects.

So any other logic must also be based on Id values i.e.:

if((!accCont.containsKey(account_i.Id)) )

The idea behind having a unique identifier field as well as a name field is to ensure that each table row can be separately found. For example, multiple people could have the Name "Palash", but the record including your data will have a distinct Id value.

If you definitely want to do some logic based on the name, you have to use a loop to grab the data but the last row with a particular name will be the only one left in the map:

Map<String,Account> accCont = new Map<String,Account>();
for (Account a : [
        SELECT Id,Name,duplicate__c
        FROM Account
        where Id In (Select AccountId from Contact)
        ]) {
    accCont.put(a.Name, a);
}

Note that queries like this with no where limits on the number of rows returned will very likely run into governor limits. You need to think about that now not later as it will likely change the design.

The platform has a built-in duplicate rules mechanism. Using that instead will save you a lot of pain. If the requirements you are working to don't match those capabilities, it is well worth re-negotiating the requirements.

  • we can directly put the soql query in assigning walue that is Map<String,Account> accCont = new Map<String,Account>([SELECT Id,Name,duplicate__c FROM Account where Id In (Select AccountId from Contact)]) – Palash Jun 27 at 11:48
  • @Palash I don't understand your point. Yes that code will execute, but the Map key will be the Id field value not the Name field value. – Keith C Jun 27 at 11:52
  • actually i want to compare name that's why i take name as key. – Palash Jun 27 at 11:55
  • @Palash OK, to do that you will need to use the last piece of code I posted. – Keith C Jun 27 at 12:23
  • 1
    @Palash Sorry, no that is your job. – Keith C Jun 27 at 13:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.