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
TiratTirat 

Apex trigger to set field value prior to inserting record

Hello all,

 

I need to write a trigger which will set a field to a combination of values entered for other fields, including a master-detail relationship field, and to a count of prior records.

Example:

field1 is set to: A

field2 is set to: B  (field 2 is a detail in an M-S relationship)

field 3 needs to be set to: A_B_XX where XX is the number of existing A_B records plus 1.

if the database already has two records with field1=A and field2=B, then I need to set field3=A_B_03.

 

Thank you all for your help.

Shashikant SharmaShashikant Sharma

Here comes your trigger

 

trigger setField on ObjectAPIName(before insert)
{
	
	
        Set<String> set_Field1 = new Set<String>();
        Set<String> set_Field2 = new Set<String>();
 
	for(ObjectAPIName__c obj : trigger.new)
            {
            
	    	set_Field1.add(obj.Field1_APIName);
		set_Field2.add(obj.Field2_APIName);
            }

        MAP<String , Integer> mapField3 = new MAP<String , Integer>();

        List<ObjectAPIName__c> listExisting = List<ObjectAPIName__c>();
        for(ObjectAPIName__c obj : [Select id From ObjectAPIName__c where Field1_APIName in: set_Field1 and Field2_APIName in: set_Field2])
            {
		if(mapField3.ContainsKey(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName)))
                	{
				Integer itemNo = mapField3.get(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName)) + 1;
				mapField3.put(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName) , 1);
			}
	 	else
		      mapField3.put(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName) , 1);		
            } 

        for(ObjectAPIName__c obj : trigger.new)
            {
            
		Integer itemNo = 1;
                if(mapField3.ContainsKey(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName)))
                	{
				itemNo = mapField3.get(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName)) + 1;
				mapField3.put(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName) , 1);
			}
	 	else
			{
		               
			       mapField3.put(String.valueOF(obj.Field1_APIName) + '_' + String.valueOF(obj.Field2_APIName) , 1);	    	
                        }

                 obj.Field3_APIName = obj.Field1_APIName + '_' + obj.Field2_APIName + '_' + String.valueOf(itemNo);

            }  
        
        
	
}

 I think you will need similar trigger on before update also becoz ur req gives such impression to me.

 

To know more about triggers : http://forceschool.blogspot.com/   , you will find every thing about triggers there.

TiratTirat

Hello Shashikant Sharma,

 

It almost worked. Here is a record already in the db:

field1: L1 (Name from a master object record)

field2: ATE (Name from a master object record)

field3: L1_ATE_01

 

Now when I try to add a new record with

field1 set to: L1

field2 set to: ATE

field3 should be set to: L1_ATE_02

 

However when I run your script I get

field3 set to: a0BC000000ErfTyMAJ_a0AC000000JSHbKMAX_2

 

That is, it sets field3 to the ID fields of the master object record instead of the Name field. Could you please take a look at the trigger below exactly as I have it and let me know what I could change to make it work.

 

Thank you.

 

trigger SetStationName on Station__c (before insert) {
       
    Set<String> set_Field1 = new Set<String>();
    Set<String> set_Field2 = new Set<String>();
 
    for(Station__c obj : trigger.new)
        {   
        set_Field1.add(obj.ProductionLine__c);
        set_Field2.add(obj.ProductionArea__c);
        }

    MAP<String , Integer> mapField3 = new MAP<String , Integer>();

    List<Station__c> listExisting = new List<Station__c>();
    for(Station__c obj :
    [Select id, ProductionLine__c, ProductionArea__c
     From Station__c
     where ProductionLine__c in: set_Field1 and ProductionArea__c in: set_Field2])
        {
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            Integer itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);    
        }

    for(Station__c obj : trigger.new)
        {
        Integer itemNo = 1;
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            {
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionLine__c) , 1);        
            }

            obj.Name = obj.ProductionLine__c + '_' + obj.ProductionArea__c + '_' + String.valueOf(itemNo);

        } 
       
}

Shashikant SharmaShashikant Sharma

istead of refeence field directly you should use Name field of refernece records using relationship. Like for this 

 

ProductionLine__c you should do like this Relationship__r.Name where 

You can find out relationship name in the lookup field itself. If you ahve any trouble in finding relationship name the then ,

1)Open the object on wheich this lookup field is 

2)Go to validation rule

3)Click new

4)Insert field

5)Find ProductionLine > in the fields , select that you will find another list ,select Name from thid , click insert or copy directly the complete name with relationship, Use that field  

 

Please check the comment in the trigger , you have used ProductionLine__c where you need to use other field name

 



trigger SetStationName on Station__c (before insert) {
       
    Set<String> set_Field1 = new Set<String>();
    Set<String> set_Field2 = new Set<String>();
 
    for(Station__c obj : trigger.new)
        {   
        set_Field1.add(obj.ProductionLine__c);
        set_Field2.add(obj.ProductionArea__c);
        }

    MAP<String , Integer> mapField3 = new MAP<String , Integer>();

    List<Station__c> listExisting = new List<Station__c>();
    for(Station__c obj :
    [Select id, ProductionLine__c, ProductionArea__c
     From Station__c
     where ProductionLine__c in: set_Field1 and ProductionArea__c in: set_Field2])
        {
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            Integer itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);    
        }

    for(Station__c obj : trigger.new)
        {
        Integer itemNo = 1;
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            {

                                                                                                        // obj.ProductionLine__c to obj.ProductionArea__c
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionLine__c) , 1);        
            }

            obj.Name = obj.ProductionLine__c + '_' + obj.ProductionArea__c + '_' + String.valueOf(itemNo);

        } 
       

 

 


TiratTirat

Thank you Shashikant Sharma,

 

I did try using the master objects Name fields but that did not work. Field3 got set to: null_null_1.

 

       
    Set<String> set_Field1 = new Set<String>();
    Set<String> set_Field2 = new Set<String>();
 
    for(Station__c obj : trigger.new)
        {   
        set_Field1.add(obj.ProductionLine__r.Name);
        set_Field2.add(obj.ProductionArea__r.Name);
        }

    MAP<String , Integer> mapField3 = new MAP<String , Integer>();

    List<Station__c> listExisting = new List<Station__c>();
    for(Station__c obj :
    [Select id, ProductionLine__r.Name, ProductionArea__r.Name
     From Station__c
     where ProductionLine__r.Name in: set_Field1 and ProductionArea__r.Name in: set_Field2])
        {
        if(mapField3.ContainsKey(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name))
            {
            Integer itemNo = mapField3.get(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name) + 1;
            mapField3.put(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name , 1);
            }
        else
            mapField3.put(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name , 1);    
        }

    for(Station__c obj : trigger.new)
        {
        Integer itemNo = 1;
        if(mapField3.ContainsKey(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name))
            {
            itemNo = mapField3.get(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name + 1);
            mapField3.put(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name , 1);
            }
        else
            {
            mapField3.put(obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name , 1);        
            }

            obj.Name = obj.ProductionLine__r.Name + '_' + obj.ProductionArea__r.Name + '_' + String.valueOf(itemNo);

        }  

 

Thanks again.

Shashikant SharmaShashikant Sharma

Use this now, should work now I used amap in this t keep name foe ids.

 

trigger SetStationName on Station__c (before insert) {
       
    Set<String> set_Field1 = new Set<String>();
    Set<String> set_Field2 = new Set<String>();
 
    for(Station__c obj : trigger.new)
        {   
        set_Field1.add(obj.ProductionLine__c);
        set_Field2.add(obj.ProductionArea__c);
        }

    MAP<String , Integer> mapField3 = new MAP<String , Integer>();
    Map<ID , Name> mapID_Name = new mAP<ID< NAme>();

    List<Station__c> listExisting = new List<Station__c>();
    for(Station__c obj :
    [Select id, ProductionLine__c, ProductionArea__c , ProductionLine__r.Name , ProductionArea__r.Name 
     From Station__c
     where ProductionLine__c in: set_Field1 and ProductionArea__c in: set_Field2])
        {
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            Integer itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);    

           mapID_Name.put(ProductionLine__c , ProductionLine__r.Name);
           mapID_Name.put(ProductionArea__c , ProductionArea__r.Name);
        }

    for(Station__c obj : trigger.new)
        {
        Integer itemNo = 1;
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            {
                                                                                                        // obj.ProductionLine__c to obj.ProductionArea__c
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionLine__c) , 1);        
            }

            String productionLineName;
            if(mapID_Name.containsKey(obj.ProductionLine__c))
		productionLineName = mapID_Name.get(obj.ProductionLine__c);
            
            String productionAreaName;
            if(mapID_Name.containsKey(obj.ProductionArea__c))
		productionArea = mapID_Name.get(obj.ProductionArea__c);


            obj.Name = productionLineName + '_' + productionAreaName + '_' + String.valueOf(itemNo);

        } 



}

 

TiratTirat

It still does not work as intended. i. e.

 

1. if there is already an existing Station__c record L1_ATE_1 then the trigger adds:

L1_ATE_2 

This was good. but then if I add again it keeps adding L1_ATE_2 and never goes to L1_ATE_3.

 

2. If there is no existing Station__c record let's say for area "Repair" then it should add the first station L1_Repair_1, instead it adds null_null_1.

 

Thanks.

Shashikant SharmaShashikant Sharma

Try this one

 

trigger SetStationName on Station__c (before insert) {
       
    Set<String> set_Field1 = new Set<String>();
    Set<String> set_Field2 = new Set<String>();
 
    for(Station__c obj : trigger.new)
        {   
        set_Field1.add(obj.ProductionLine__c);
        set_Field2.add(obj.ProductionArea__c);
        }

    MAP<String , Integer> mapField3 = new MAP<String , Integer>();
    Map<ID , Name> mapID_Name = new mAP<ID< NAme>();

    List<Station__c> listExisting = new List<Station__c>();
    for(Station__c obj :
    [Select id, ProductionLine__c, ProductionArea__c , ProductionLine__r.Name , ProductionArea__r.Name 
     From Station__c
     where ProductionLine__c in: set_Field1 and ProductionArea__c in: set_Field2])
        {
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            Integer itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);
            }
        else
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , 1);    

           
        }

    
    for(ProductionLine__c obj : [Select id, Name From ProductionLine__c where id in: set_Field1])
        {
           mapID_Name.put(obj.id , obj.Name);
        }

    for(ProductionArea__c obj : [Select id, Name From ProductionArea__c where id in: set_Field2])
        {
           mapID_Name.put(obj.id , obj.Name);
        } 

    

    for(Station__c obj : trigger.new)
        {
        Integer itemNo = 1;
        if(mapField3.ContainsKey(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)))
            {
            itemNo = mapField3.get(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c)) + 1;
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea__c) , itemNo);
            }
        else
            {
                                                                                                        
            mapField3.put(String.valueOF(obj.ProductionLine__c) + '_' + String.valueOF(obj.ProductionArea_c) , itemNo);        
            }

            String productionLineName;
            if(mapID_Name.containsKey(obj.ProductionLine__c))
		productionLineName = mapID_Name.get(obj.ProductionLine__c);
            
            String productionAreaName;
            if(mapID_Name.containsKey(obj.ProductionArea__c))
		productionArea = mapID_Name.get(obj.ProductionArea__c);


            obj.Name = productionLineName + '_' + productionAreaName + '_' + String.valueOf(itemNo);

        } 



}