You need to sign in to do that
Don't have an account?
![jjnh jjnh](https://dfc-org-production.my.site.com/img/userprofile/default_profile_45_v2.png)
updating account fields based on contact fields?
I am having trouble creating a solution for this request.
I am looking to update specific account fields (text, picklist, url fields) based on the originating fields inside the contact. In this many-to-one situation, I need to pull the most recently updated field out of the contacts group and the oldest field out of the same group and bring it into the account.
ex.
Account and Contact Field: Most_recent_visit__c
Contact 1 = Most recent visit = 11/11/09 so the account would need to be updated to that.
Contact 2 comes in and his most recent visit was 11/15/09, now I would need the Account field to be updated to 11/15/09.
All help is appreciated.
Hi,
You need a subquery to get Contact details for your Account, then you need to order and limit the subquery to return the one you want.
Then you can use the Account.Contacts relationship to set your Account-level data,
something like:
Account acc = [SELECT a.Name, (SELECT c.Name, c.Most_recent_visit__c FROM a.Contacts c order by Most_recent_visit__c desc) FROM Account a WHERE a.Id =: accountId]; // I am assuming you will know this
if (acc.Contacts.size() > 0)
acc.Most_recent_visit__c = acc.Contacts[0].Most_recent_visit__c;
HTH, Ian
:)
Couple of questions:
1 - by 'batch' do you mean a) Updating many Accounts at once, b) Updating many Contacts at once, or c) Something else?
2 - I'm not sure I understand your requirement to update based on field history, could you please elaborate?
Let me know, and I'll try to help if I can :)
Cheers, Ian
1. by batch i mean updating many accounts at once from the contact fields, also there will be 9 or 10 fields that will need to be updated in the account
2. using field history timestamp i think i could use that to decide if the picklist in contact1 is more recent than the picklist in contact2 and then update the picklist at the account level
Thank you for the help :)
OK - so try creating a trigger on the Account object. Triggers will naturally handle batch inserts and updates and expose a handy property 'New' which is a collection of SObjects being changed...
the trigger will look something like:
trigger UpdateAccountFromContacts on Account(before insert, before update) {
Set<Id> accountIds = new Set<Id>();
for (Account a : Trigger.new)
accountIds.add(a.Id);
// Paste your select statement in here.
// Remember to add each required Contact field to the sub-query
// Change your Account 'where' query to get all the accounts in the trigger.
Map<Id, Account> accounts = new Map<Id, Account>( [ SELECT {blah} FROM Account WHERE Id in: accountIds ] );
for (Account a : Trigger.new) {
Account accFromMap = accounts.get(a.Id);
if (accFromMap.Contacts.size() > 0) {
a.field1 = accFromMap.Contacts[0].field1;
a.field2 = accFromMap.Contacts[0].field2;
a.field3 = accFromMap.Contacts[0].field3;
etc...
}
} }
This is untested - so have a play and see if you can get it to work ;)
If you want to be tricky with which Contact's field to write to the Account on a case-by-case basis (e.g. the 'Last Visited' date from Contact1, but the 'Favourite Sports Team' from Contact 2, you can remove the LIMIT 1 restriction on the subquery, then your account's 'Contacts' object will contain every contact for that account... you can loop through and pick and choose as you please...
HTH, Ian
***edit*** i got it working on the simple path, not the tricky part yet
trigger UpdateAccountFromContacts on Account(before insert, before update) { Set<Id> accountIds = new Set<Id>(); for (Account a : Trigger.new) accountIds.add(a.Id); Map<Id, Account> accounts = new Map<Id, Account>( [ Select a.Id, (Select Most_Recent_Conversion__c, Most_Recent_Inbound_Marketing_Code__c, Most_Recent_Lead_Source__c, Most_Recent_Referring_URL__c, Most_Recent_Visit__c, Original_Inbound_Marketing_Code__c, Original_Lead_Source__c, Original_Referring_URL__c, Original_Visit__c From Contacts) from Account a ] ); for (Account a : Trigger.new) { Account accFromMap = accounts.get(a.Id); if (accFromMap.Contacts.size() > 0) { a.Most_Recent_Conversion__c = accFromMap.Contacts[0].Most_Recent_Conversion__c; a.Most_Recent_Inbound_Marketing_Code__c = accFromMap.Contacts[0].Most_Recent_Inbound_Marketing_Code__c; a.Most_Recent_Lead_Source__c = accFromMap.Contacts[0].Most_Recent_Lead_Source__c; a.Most_Recent_Referring_URL__c = accFromMap.Contacts[0].Most_Recent_Referring_URL__c; a.Most_Recent_Visit__c = accFromMap.Contacts[0].Most_Recent_Visit__c; a.Original_Inbound_Marketing_Code__c = accFromMap.Contacts[0].Original_Inbound_Marketing_Code__c; a.Original_Lead_Source__c = accFromMap.Contacts[0].Original_Lead_Source__c; a.Original_Referring_URL__c = accFromMap.Contacts[0].Original_Referring_URL__c; a.Original_Visit__c = accFromMap.Contacts[0].Original_Visit__c; } } }
next is to have this update the account when the contact is updated and to have the contact1 vs contact2 situation come into play
Excellent!
Hint: Write another trigger, this time against the Contact object that loops through each inserted/updated Contact, and writes data to the Contact.Account object
(this was the point of me asking whether you were catering for changes to the Account, or the Contact)
Good work :)
Cheers, Ian
feel like dropping some more hints as i bang my head on the wall, hehehe
thanks for the help, i will post back when I get further along, switching up to the contact object is throwin me off a bit.
Hi,
The Contact trigger is very similar to the Account-level one in structure: You still need to iterate through the collection of changed records and build a map of account objects that will be updated within the trigger. The difference is that the trigger is going to insert/update your Contact (or Contacts) so you will manually need to update the Account(s) yourself...
Should look something like this (you'll need to add in all your fields)
trigger UpdateAccountFromContact on Contact (before insert, before update) { Set<Id> accountIds = new Set<Id>(); for (Contact c : Trigger.new) { accountIds.add(c.AccountId); } Map<Id, Account> accountsToUpdate = new Map<Id, Account>([SELECT Id FROM Account where Id in: accountIds]); for (Contact c : Trigger.new) { Account a = accountsToUpdate.get(c.AccountId); a.Most_Recent_Conversion__c = c.Most_Recent_Conversion__c;
// add in other fields here.... } update accountsToUpdate.values(); }