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
pjaenickepjaenicke 

Populate Id field from string field

Greetings,

 

I have two fields on the account - a text "Zip Code" field, and a lookup field to a custom ZIP__c table.  I'd like to write a trigger to populate the value of the corresponding ZIP__c.id based on the text value entered.

 

The trigger should:

1.  Fire before insert and before update

2.  If before update, (to prevent unnecessary cpu cycles) only fire if the Billing_Zip_Code has changed.

3.  Remove the "Zip+4" and leading zeros, if they exist.

4.  Populate the id from the "Zip__c" table into the ZipID__c field on the Account, (or else use the "0" zip code id)

 

I was able to write this trigger as a "one-off" - works fine.  I'm struggling with "bulkifying" the trigger, (okay, I'm failing miserably).  I'm trying to group the accounts by zip code and do a bulk update.  Here's what I've come up with so far:

 

trigger setZipId on Account (before insert, before update) {

    // Get the Undefined Zip Id out of the way.. (important for bulkifying)
    Zip__c BadZipCode = [
        SELECT Id
          FROM Zip__c
         WHERE Name = '0' Limit 1
    ];
    String BillZip;
    integer Dashpos;

    Map<String, Account> accountMap = new Map<String, Account>();
    for (Account acct : System.Trigger.new) {
        if (System.Trigger.isInsert ||
            acct.BillingPostalCode != System.Trigger.oldMap.get(acct.Id).BillingPostalCode) {
            if (acct.BillingPostalCode != Null) {
                Dashpos = (Acct.BillingPostalCode + '-').indexof('-');
                BillZip = (Acct.BillingPostalCode.substring(0,Dashpos)).replaceAll('^0+(?!$)','');
            } else {
                BillZip = '0';
            }
            accountMap.put(BillZip, acct);
        }
    }
    for (Account acct : [
         SELECT BillingPostalCode
           FROM Account
          WHERE BillingPostalCode IN :accountMap.KeySet()
          ]) {
        Account newAcct = accountMap.get(acct.BillingPostalCode);
        if (newAcct.BillingPostalCode != Null) {
            List<Zip__c> ZipArray = [
                SELECT Id
                  FROM Zip__c
                 WHERE Name = :newAcct.BillingPostalCode limit 1
            ];
           
            if (ZipArray.size() > 0) {
                for (Zip__c ZipCode: ZipArray) {
                    newAcct.ZipId__c = ZipCode.id;
                 }
            } else {
                newAcct.ZipId__c = BadZipCode.Id;
            }
        }
    }
}

 

 

Thanks for any / all assistance,

Pete

Best Answer chosen by Admin (Salesforce Developers) 
BritishBoyinDCBritishBoyinDC

So instead of doing this

 

List<Zip__c> ZipArray = [
                SELECT Id
                  FROM Zip__c
                 WHERE Name = :newAcct.BillingPostalCode limit 1

 

 

Do an intial loop through the trigger records, and add the cleaned zips to a String set.

Then create a zip code map of <String,Id> and query the zipcode table for the Zips in the set created above, putting the zip in the key, and the Id in the value. Now you have your lookup table.

 

Now progress as you are, but instead of having to query for each Zip, you can just loop up the Account Billing Zip in the map above and set the Zip Code Id to the lookup on Account.

 

That's how I do it, and it works fine in bulk.