+ Start a Discussion
RedtagRedtag 

Simple Apex code to update Account with ID from custom object

I'm new to Apex and I've looked at the online references but need help for my first code. What I've got is a lookup field, Master_Account_Name__c on the Account object that looks up a custom object MasterAccount__c. Each object has an external ID field: Master_Account_ID__c on the Account Object and Account_ID__c on the Master Account Object.
 
What I want to do with a trigger (after insert, after update) is to populate the lookup field, Master_Account_Name__c on the Account Object with the correct id from the Master Account object to create the relationship (where the external ID fields are the same).
 
This will be used in nightly batch updates after upserts occur to each of the objects with master accounts being upserted first. Any help with this greatly appreciated.
 


Message Edited by Redtag on 07-13-2008 05:00 AM
MCunninghamMCunningham
Hey Redtag

below is a simple trigger I use to insert a SF product record ID (received as text) into a product lookup field whenever a lead is received -

a few tweaks and it should do as you need.

- welcome to the dark side of Force.com

regards

Michael

trigger LeadProduct on Lead (before insert, before update) {
For (Lead nlead:Trigger.new)
// If the Card_Interest__c field is not empty, then use it to set the Card_Product field
    {If (nlead.Card_Interest__c <> NULL)
      {
       nlead.Card_Product__c = nlead.Card_Interest__c;
       }
     }
}
RedtagRedtag

Thanks for responding Michael,

I have two issues with your proposed solution:

1) This operation will be done in bulk each night with over 2,000 Master Accounts and probably 30000 Accounts  - so I think I'll have to use Map or List methods to avoid exceeding limits?

2) I'm probably missing something obvious, but I can't see how I can get the MasterAccountid into the lookup field on Account when I have to update the field only when the value of an externalID field in Account = value of an externalID field in MasterAccount.

It might help to explain the manual process:

After upserting both Accounts and MasterAccounts I export two tables: one with AccountID and ExternalID field and the other with MasterAccountID and External ID field. Using Access I then create a query to join the two tables using the External ID fields as the primary and foreign keys. I then have a one to many relationship between MasterAccounts and Accounts. I then upsert the resulting table into Accounts using AccountID as unique field and mapping MasterAccountID into the Lookup field in Accounts.

I'm tying myself in knots over this but the key seems to be able to find Accounts where Account External ID field = Master Account External ID field.

Steve

 

MCunninghamMCunningham
Guess you need some conditional login to query both objects at the start of the loop which check they match in the IF condition ..

anyhow - heres a bulkified for loop for the trigger; 

for(Integer i=0; i < Trigger.new.size(); i++)  {

            if (Trigger.new[i].Master_Id__c == 'NOT SURE WHAT YR MATCHING AGAINST') {

INSERT CODE HERE
}
}


RedtagRedtag
Thanks - I'll give it a try.
JakesterJakester
I tried to modify your code to do something similar but on another object. What I'm trying to do is set a boolean field on the Opportunity called Has_Kiosk_Hardware__c to True if a product (which is of type "Kiosk Hardware" in the Product_Group__c picklist) is added to that opportunity.

Here's what I came up with:

Code:
trigger updateHasKioskHardware on OpportunityLineItem (after insert) {
For (OpportunityLineItem nOLI:Trigger.new)
// 
    {If (nOLI.pricebookentry.product2.product_group__c == 'Kiosk Hardware')
      {
       nOLI.Opportunity.Has_Kiosk_Hardware__c = True;
       }
     }
}

It compiles and I get no errors when I add the product, but it does not update the Has_Kiosk_Hardware__c when I add a kiosk hardware product. To troubleshoot, I changed the If statement to always be true like so:

Code:
trigger updateHasKioskHardware on OpportunityLineItem (after insert) {
For (OpportunityLineItem nOLI:Trigger.new)
// 
    {If (True)
      {
       nOLI.Opportunity.Has_Kiosk_Hardware__c = True;
       }
     }
}

And I got this error sent via email:
updateHasKioskHardware: execution of AfterInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.updateHasKioskHardware: line 6, column 8

What am I doing wrong?


Message Edited by Jakester on 07-17-2008 03:24 PM
MCunninghamMCunningham
Have you considered a workflow rule instead?

detect event : Product_Group__c = "whatever" and HAS_KIOSK_HARDWARE__c = false
action: field update Has_Kiosk_Hardware__c=True

its much easier to manage. 

btw - if you must use an apex trigger try and isnull() condition check


JakesterJakester
That's a really good idea, and it works great - thank you! What I just realized, though, is that I also need to uncheck the box if all products in that product group have been deleted. I double-posted (I know, that's lame - sorry!) and Jason aka TehNrd has been helping me work through the whole thing and has come up with an awesome trigger that does both the checking and the unchecking.
 
Thanks for the idea!
RedtagRedtag

Hi Michael,

I get an error message when I try to save the code below on line 28.

Save error: unexpected token: a.Master_Account_ID__c. Think it's how I'm trying to pass

the field value from the Master Account to the Account. Any ideas greatly appreciated.

 

trigger UpdateAccountMasters on Account (after insert, after update) {

 

//The map keeps track of Accounts that have

//Master Accounts and need to be updated

Map<id, Account> AccountswithMasterAccounts = new Map<id, Account>();

 

//Trigger.new is an array of Accounts

//that will be updated. This loop iterates over the list and adds any Accounts

//that have Master Accounts to the AccountswithMasterAccounts Map

for(Integer i=0; i < Trigger.new.size(); i++) {

if (Trigger.old[i].Master_Account_ID__c <>

NULL){

AccountswithMasterAccounts.put (Trigger.old[i].id,Trigger.new[i]);

}

}

list<Account> updatedAccounts = new list<Account>();

//What I want to do here is to list the accounts from the Trigger

//where the a.Master_Account_ID__c field (an external key) equals

//the MasterAccount__c.Account_ID__c field.

for( Account a :[select id, Master_Account_Name__c

FROM Account where id in :AccountswithMasterAccounts.keySet()]){

//Now I want to return the value of the MasterAccount__c.id

//into the a.Master_Account_Name__c field

a.Master_Account_Name__c = [select a.Master_Account_Name__r.id FROM MasterAccount__c

WHERE MasterAccount__c.Account_ID__c = a.Master_Account_ID__c] ;

//The Accounts are now added to a list and bulk inserted.

updatedAccounts.add(a);

}

update updatedAccounts;

}

RedtagRedtag
Hi,
 
I agree with Michael - I'd handle this with a Workflow rule associated with a Field update.
 
 
Steve
MCunninghamMCunningham

having only had a quick scan of your code I think its because your not specifying which record in the list to operate on;  suggest it might be as follows;


a[i].Master_Account_Name__c = [select a.Master_Account_Name__r.id FROM MasterAccount__c

WHERE MasterAccount__c[i].Account_ID__c = a[x].Master_Account_ID__c] ;


where x is the count variable for the second loop
Shawn@CliffsShawn@Cliffs

Can you use that work flow to update a search field? We are having real problems with the search fields. What I want to do is create a custom pick list and have the value  selected automatically populate into a search field.