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
krishna casukhela 7krishna casukhela 7 

Preventing duplicate values of LastName in contact object

Hello friends
request your help in writing the trigger code. LastName in contact should be unqiue.

apex class code:
=============
public class Prevent
{
   public void Display(Id[] currentrecordId)
   {
          list<Contact> con=[select LastName from Contact where Id=:currentrecordId];
         for(Contact c:con)
          {
                if (con.size()>0)
                   c.LastName.AddError('LastName Already Exists');
          }
      }
}

Trigger Code:
==========
trigger trg_LastName on Contact (before insert,before update)
{
    if (trigger.isBefore)
    {
          if (trigger.isInsert || trigger.isUpdate)
          {
          
                Prevent obj=new Prevent();
          
                 for(Id consid:trigger.NewMap.KeySet())
                 {
                    obj.Display(consid);
                 }
          }
    }
}

When I save the trigger , I get error message as :Error: Compile Error: Method does not exist or incorrect signature: [Prevent].Display(Id) at line 12 column 21

Please let me know how to resolve this or any issue with the apex class code itself..

Regards
Krishna Casukhela
Best Answer chosen by krishna casukhela 7
Brenda S FinnBrenda S Finn
Krishna

I belive the issue is your method is defined to take an arry of Ids - 
public void Display(Id[] currentrecordId)

But when you invoke it, you are only providing a single Id.
obj.Display(consid);
So you either need to build an array of Ids in trigger and send those to Display or you need to call Display for each individual Id.

Another thought - you could achieve this with a workflow rule and a hidden field. Create a new custom field on Contact called LastName_Text or something similar. It will not be displayed on the page.  In the field definition, select the Unique checkbox which will default to 'Treat "ABC" and "abc" as duplicate values (case insensitive)'. Accept that default. Then create a workflow rule that fires every time you create or update a Contact that will update this field wit the LastName value. When the workflow runs, if there is already a Contact with that LastName, an error is reported to the user. So no need for Apex or triggers. We have done this successfully many times in our org. Workflow rule entry critera should be "Created and every time its edited" and should specify a Field Update action. Specify "formula evaluates to true" for "Run this rul if the following" picklist. Here is the logic to determine if workflow rule should fire:
OR (ISNEW(), 
     ( LastName != PRIORVALUE(LastName)), 
     true, false)


Please let us know how you get on!

All Answers

Brenda S FinnBrenda S Finn
Krishna

I belive the issue is your method is defined to take an arry of Ids - 
public void Display(Id[] currentrecordId)

But when you invoke it, you are only providing a single Id.
obj.Display(consid);
So you either need to build an array of Ids in trigger and send those to Display or you need to call Display for each individual Id.

Another thought - you could achieve this with a workflow rule and a hidden field. Create a new custom field on Contact called LastName_Text or something similar. It will not be displayed on the page.  In the field definition, select the Unique checkbox which will default to 'Treat "ABC" and "abc" as duplicate values (case insensitive)'. Accept that default. Then create a workflow rule that fires every time you create or update a Contact that will update this field wit the LastName value. When the workflow runs, if there is already a Contact with that LastName, an error is reported to the user. So no need for Apex or triggers. We have done this successfully many times in our org. Workflow rule entry critera should be "Created and every time its edited" and should specify a Field Update action. Specify "formula evaluates to true" for "Run this rul if the following" picklist. Here is the logic to determine if workflow rule should fire:
OR (ISNEW(), 
     ( LastName != PRIORVALUE(LastName)), 
     true, false)


Please let us know how you get on!
This was selected as the best answer
KaranrajKaranraj
In the class Prevent, the Display Method accepts List<Id>/Array of ID but in the trigger code in the line number 12 you are passing only single id.
Try the updated below class code
public class Prevent
{
   public void Display(Id currentrecordId)
   {
          list<Contact> con=[select LastName from Contact where Id=:currentrecordId];
         for(Contact c:con)
          {
                if (con.size()>0)
                   c.LastName.AddError('LastName Already Exists');
          }
      }
}

You can also avoid duplicate records using visual flow.
Check this blog post http://clicksandcode.blogspot.in/2015/02/avoid-duplicate-records-using-visualflow.html
 
krishna casukhela 7krishna casukhela 7
Hello Karanraj
Its easier to do with validation rule instead of using trigger.

The code is as follows

public class LastName
{
    public void Prevent(Id conId)
    {
        //string pid=conId;
        
        list<Contact> con=[select LastName from Contact where Id=:conId];
        
        for(Contact c:con)
        {
             if (con.size() > 0)
                  c.LastName.addError('LastName Already Exists');
         }
      
    }
}

trigger code:
trigger trg_LastName on Contact (before Insert,before Update)
{
     LastName ln=new LastName();
     
    for(Id cid:trigger.NewMap.KeySet())
    {
         ln.Prevent(cid);
    }

But I get the following exception.
Apex trigger trg_LastName caused an unexpected exception, contact your administrator: trg_LastName: execution of BeforeInsert caused by: System.NullPointerException: Attempt to de-reference a null object: Trigger.trg_LastName: line 5, column 1

Could u let me know where I am gping wrong?

Regards
Krishna
Brenda S FinnBrenda S Finn

Krishna

Good morning. I believe the issue is that you are trying to access the Id for the Contact in a beforeInsert trigger when there is no Id as of yet since the Contact has not been inserted into the database. So you should be passing LastName to your Prevent method, not Id as that is what you want to find. Your query in Prevent will not find duplicates - for an update, it would simply return the LastName for the Contact associated with ID, but it would not find any other Contacts with the same LastName value. Did you try using a workflow rule and a hidden field instead?
 

Brenda

krishna casukhela 7krishna casukhela 7
Hello Brenda
I have done the scenario using validation rule and also using hidden field. I know this approach is better and also I have given "Best Answer" to your post. Well, regarding the code I am working on it since I am a newbie.

Regards
krishna
Brenda S FinnBrenda S Finn

Krishna

Ok so are you still in need of help? I didnt quite understand your last post. Also - it is a workflow rule and hidden field, NOT validation rule and hidden field that I suggested.
 

Thanks
Brenda

krishna casukhela 7krishna casukhela 7
Hello Brenda
 One of the senior members in my team gave me the code and told me to work on it. Before I posted this post I did using workfow rule(sorry not using validation rule). As of now my query is resolved.