Here's a somewhat hacky possible idea. I tried it with Asset as the example object and it seems to work. Unfortunately it relies on the fact that an object's 3-character prefix is indicative of the object type, so it's not stable for change set deployment unless the object already exists with the same prefix in both orgs.
Create a custom lookup on Activity, not included in page layouts, for the specific object whose data you want to retrieve from its related tasks. For example Asset__c
.
Now create a Process Builder to execute whenever a Task is created/updated. Action criteria:
[Task].WhatId != [Task].Asset__c &&
OR(LEFT([Task].WhatId, 3) = '02i', ISBLANK([Task].WhatId))
The first line ensures the rule only fires when WhatId
is not the same as Asset__c
, and the second line ensures it also only fires when the WhatId
is an Asset or blanked out.
Then add an Update Field action which, under these conditions, assigns the value of WhatId
to Asset__c
. Process Builder will allow you to do this!
I tested by 1) adding a Task to an Account. No error was fired. Then 2) I added a Task to an Asset. I can confirm the ID got copied to Asset__c
.
For existing Tasks you'd want to do a one-time backfill. You could accomplish this in Data Loader by exporting Id, WhatId
for all the tasks with a WhatId
matching the right prefix and then running the CSV back through in Update mode to fill the Asset__c
field.
Once you've gone to all this trouble, what's the difference? Well, now Asset__c
is a standard lookup rather than polymorphic. So you can query any field you want from the relationship. :) You could even add a custom lookup for each type of object you want to do this with, and then have one Process Builder decide which field to fill if any.