Всем привет!
еще одно простая, но насущная задачка.
На записи должно быть поле хранящее кол-во связанных через лук-ап, но не дочерних записей.
вроде задача выглядит просто, но решить получается только через тригер.
причем тригер нужно ставить не на тот объект на котором стоит это "sum-up" поле, а на объект связанных записей, так получается?
но можно ли задачу решить по другому: а зачем это поле вообще нужно?
дело в том что на головной записи хранится цена (100) общая (суммарная) для всех связанных записей. А на каждой связанной записи есть формульное поле ("Усредненная цена на единицу"), которое должно вытянуть из головной записи эту цену и поделить на кол-во всех записей привязнных в головной записи. Для этого и создаем поле с кол-вом связанных записей на головной записи. Но может кол-во связанных записей можно как-то посчитать в формуле на самой связанной записи. не думаю.
спасибо
Всем привет! еще одно простая, но насущная задачка. На записи должно быть поле хранящее кол-во связанных через лук-ап, но не дочерних записей. вроде задача выглядит просто, но решить получается только через тригер. причем тригер нужно ставить не на тот объект на котором стоит это "sum-up" поле, а на объект связанных записей, так получается? но можно ли задачу решить по другому: а зачем это поле вообще нужно? дело в том что на головной записи хранится цена (100) общая (суммарная) для всех связанных записей. А на каждой связанной записи есть формульное поле ("Усредненная цена на единицу"), которое должно вытянуть из головной записи эту цену и поделить на кол-во всех записей привязнных в головной записи. Для этого и создаем поле с кол-вом связанных записей на головной записи. Но может кол-во связанных записей можно как-то посчитать в формуле на самой связанной записи. не думаю. спасибо
Такую задачу можно попробовать решить с помощью мастер-детейла, но указать что можно делать reparent для потомка. Решается через роллап саммари и через формула филд.
Если нельзя использовать мастер-дитейл, то только триггер.
[quote="Den Brown"]Всем привет! еще одно простая, но насущная задачка. На записи должно быть поле хранящее кол-во связанных через лук-ап, но не дочерних записей. вроде задача выглядит просто, но решить получается только через тригер. причем тригер нужно ставить не на тот объект на котором стоит это "sum-up" поле, а на объект связанных записей, так получается? но можно ли задачу решить по другому: а зачем это поле вообще нужно? дело в том что на головной записи хранится цена (100) общая (суммарная) для всех связанных записей. А на каждой связанной записи есть формульное поле ("Усредненная цена на единицу"), которое должно вытянуть из головной записи эту цену и поделить на кол-во всех записей привязнных в головной записи. Для этого и создаем поле с кол-вом связанных записей на головной записи. Но может кол-во связанных записей можно как-то посчитать в формуле на самой связанной записи. не думаю. спасибо[/quote] Такую задачу можно попробовать решить с помощью мастер-детейла, но указать что можно делать reparent для потомка. Решается через роллап саммари и через формула филд. Если нельзя использовать мастер-дитейл, то только триггер.
спасибо wilder за быстрый ответ.
эти связанные записи уже дочерние записи др объекта, не хочу никак мутить здесь воду через мастер-детейл только из-зи этого поля, и так все сложно.
придется пилить тригер. А этот связанный объект очень бизи - там кодом создаются записи пачками по тысячи. так что придется писать тригер очень аккуртно...
[quote="Den Brown"]попробовать решить с помощью мастер-детейла, но указать что можно делать reparent [/quote] спасибо wilder за быстрый ответ. эти связанные записи уже дочерние записи др объекта, не хочу никак мутить здесь воду через мастер-детейл только из-зи этого поля, и так все сложно. придется пилить тригер. А этот связанный объект очень бизи - там кодом создаются записи пачками по тысячи. так что придется писать тригер очень аккуртно...
Вот предложили посмотреть вариант - но это кажется интересным, но сложным:
Вот предложили посмотреть вариант - но это кажется интересным, но сложным: http://salesforce.stackexchange.com/questions/18097/count-total-child-records-on-parent-object-in-lookup-relationship
Ничего там сложного нет. Есть специальный класс который делает делает нужные манипуляции с дочерними объектами.
[quote="Den Brown"]Вот предложили посмотреть вариант - но это кажется интересным, но сложным: http://salesforce.stackexchange.com/questions/18097/count-total-child-records-on-parent-object-in-lookup-relationship[/quote] Ничего там сложного нет. Есть специальный класс который делает делает нужные манипуляции с дочерними объектами.
Я попробовал продумать логику тригера, и не могу решить серьезную проблему: не могу избежать установки Селекта в цикл...
Тригер должен стоять на объекте привязанных записей на апдейт, делит и анделит.
но все дело в том что, как изместно, в тригер записи могут прийти пачками, и у каждой записи нужно по признаку Головной записи пересчитать Cоunt()-ом сестринские записи и записать в поле Головной записи значение.
и я не могу как-то обобщить, вывести вне цикла Cоunt() операцию... считать приходится для каждой записи...
плюс еще Cоunt() считает только до 50000...
просто не могу поверить, что такая типичная задача - хранить значение связанных записей оборачивается такими проблемами!
PS: А нет, вроде нашел вариант с волшебным циклом (пример):
for (AggregateResult ar : [
Select Count(Id) numRecs, Account__c acctId
From NPS__c
Where Account__c In :Trigger.New
Group By Account__c
])
и здесь как я понимаю Count() "вставлен" в цикл - но при этом будет считаться единой (одной) операцией?
ОГО! найденный пример оказался даже более интересным чем кажется, посмотрите на AggregateResult:
http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_query_aggregateresult.htm
но проблема с 50000 наврное все равно остается... (еще нужно проверить платформенные лимиты - это возможно ли что по лук-ап связи висит более 50к записей, по мастер-дитейл вроде как был лимит об этом)
в том же примере вот эта логика кажется мне тоже хорошей:
for(Account a :[SELECT Id,(select id from NPS__r) FROM Account WHERE Id IN: trigger.new])
{
account_map.put(a.id,a.NPS__r.size());
}
только не пойму почему они ставят этот тригер на Головной объект, а не на "дочерний"?! возможно таковы были условия вопроса...
в том же примере вот эта логика кажется мне тоже хорошей:
for(Account a :[SELECT Id,(select id from NPS__r) FROM Account WHERE Id IN: trigger.new])
{
account_map.put(a.id,a.NPS__r.size());
}
только не пойму почему они ставят этот тригер на Головной объект, а не на "дочерний"?! возможно таковы были условия вопроса...
Я попробовал продумать логику тригера, и не могу решить серьезную проблему: не могу избежать установки Селекта в цикл... Тригер должен стоять на объекте привязанных записей на апдейт, делит и анделит. но все дело в том что, как изместно, в тригер записи могут прийти пачками, и у каждой записи нужно по признаку Головной записи пересчитать Cоunt()-ом сестринские записи и записать в поле Головной записи значение. и я не могу как-то обобщить, вывести вне цикла Cоunt() операцию... считать приходится для каждой записи... плюс еще Cоunt() считает только до 50000... просто не могу поверить, что такая типичная задача - хранить значение связанных записей оборачивается такими проблемами! PS: А нет, вроде нашел вариант с волшебным циклом (пример): for (AggregateResult ar : [ Select Count(Id) numRecs, Account__c acctId From NPS__c Where Account__c In :Trigger.New Group By Account__c ]) и здесь как я понимаю Count() "вставлен" в цикл - но при этом будет считаться единой (одной) операцией? http://salesforce.stackexchange.com/questions/25489/how-do-i-count-records-on-a-child-custom-object-from-the-parent ОГО! найденный пример оказался даже более интересным чем кажется, посмотрите на AggregateResult: http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_query_aggregateresult.htm но проблема с 50000 наврное все равно остается... (еще нужно проверить платформенные лимиты - это возможно ли что по лук-ап связи висит более 50к записей, по мастер-дитейл вроде как был лимит об этом) в том же примере вот эта логика кажется мне тоже хорошей: for(Account a :[SELECT Id,([b]select id from NPS__r[/b]) FROM Account WHERE Id IN: trigger.new]) { account_map.put(a.id,[b]a.NPS__r.size()[/b]); } только не пойму почему они ставят этот тригер на Головной объект, а не на "дочерний"?! возможно таковы были условия вопроса... в том же примере вот эта логика кажется мне тоже хорошей: for(Account a :[SELECT Id,([b]select id from NPS__r[/b]) FROM Account WHERE Id IN: trigger.new]) { account_map.put(a.id,[b]a.NPS__r.size()[/b]); } только не пойму почему они ставят этот тригер на Головной объект, а не на "дочерний"?! возможно таковы были условия вопроса...
И все-таки подскажите какой вариант более устойчив к Лимитам:
через Count():
for (AggregateResult ar : [
Select Count(Id) numRecs, Account__c acctId
From NPS__c
Where Account__c In :Trigger.New
Group By Account__c
]) {
Id acctId = (Id) ar.get('acctId');
Account acct = Trigger.newMap.get(acctId);
acct.NPS_Score_Trigger__c = (Decimal) ar.get('numRecs');
}
или через .size():
List<Account> accUpdateList = new List<Account>();
For(Account acc : [SELECT Contact_Recs__c,(SELECT id FROM Contacts) FROM Account WHERE id =: accIdList]){
acc.Contact_Recs__c = acc.Contacts.size();
accUpdateList.add(acc);
}
предполагается что связанных записей (подлежащий счету) будут многие тысячи. Хотя в с другой стороны тригер будет фильтровать пришедшие записи и работать только с теми у которых было изменение по связи.
И все-таки подскажите какой вариант более устойчив к Лимитам: через Count(): for (AggregateResult ar : [ Select [b]Count(Id[/b]) numRecs, Account__c acctId From NPS__c Where Account__c In :Trigger.New Group By Account__c ]) { Id acctId = (Id) ar.get('acctId'); Account acct = Trigger.newMap.get(acctId); acct.NPS_Score_Trigger__c = (Decimal) ar.get('numRecs'); } или через .size(): List<Account> accUpdateList = new List<Account>(); For(Account acc : [SELECT Contact_Recs__c,(SELECT id FROM Contacts) FROM Account WHERE id =: accIdList]){ acc.Contact_Recs__c = acc.[b]Contacts.size()[/b]; accUpdateList.add(acc); } предполагается что связанных записей (подлежащий счету) будут многие тысячи. Хотя в с другой стороны тригер будет фильтровать пришедшие записи и работать только с теми у которых было изменение по связи.