I have come across this use case recently during answering a question in Salesforce stackexchange.
Use Case
Family records are being captured as follows:
Expected result should look like this:
Solutions
I could think of preparing the data using GROUP BY ROLLUP.
SOQL will look like this:
SELECT GrandParent__c, Parent__c, Child__c, SUM(Weight__c), SUM(Workout_Hours__c) , GROUPING (GrandParent__c) grpGrantPt, GROUPING(Parent__c) grpPT FROM Family__c GROUP BY ROLLUP(GrandParent__c, Parent__c,Child__c) ORDER BY GrandParent__c, Parent__c, Child__c
Query Result
The above query returns expected result, only thing I need to eliminate first record which is giving total summation. and two columns GROUPING (GrandParent__c) grpGrantPt, GROUPING(Parent__c) grpPT which are not needed to show in visualforce.
Controller
Now it is time to prepare the data so that it can be displayed into visualforce in a most efficient way. For this I have taken a help of Wrapper class (FamilyData)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | public class FamilyClass { public List<FamilyData> lstFamilyRecord {get;set;} public PageReference displayData() { Boolean firstRecord = true; lstFamilyRecord = new List<FamilyData>(); AggregateResult[] lstFamily = [SELECT GrandParent__c, Parent__c, Child__c, SUM(Weight__c) weightTotal, SUM(Workout_Hours__c) whTotal , GROUPING (GrandParent__c) grpGrantPt, GROUPING(Parent__c) grpPT FROM Family__c GROUP BY ROLLUP(GrandParent__c, Parent__c,Child__c) ORDER BY GrandParent__c, Parent__c, Child__c]; for(AggregateResult familyObj:lstFamily) { if(!firstRecord) { FamilyData wrapper = new FamilyData(); wrapper.GrantParent = (String) familyObj.get('GrandParent__c'); wrapper.Parent = (String) familyObj.get('Parent__c'); wrapper.Child = (String) familyObj.get('Child__c'); if(familyObj.get('GrandParent__c') !=null && familyObj.get('Parent__c') !=null && familyObj.get('Child__c') !=null) { wrapper.isChildRecord = true; } else if (familyObj.get('GrandParent__c') !=null && familyObj.get('Parent__c') !=null && familyObj.get('Child__c') ==null) { wrapper.isParentRecord = true; } else if(familyObj.get('GrandParent__c') !=null && familyObj.get('Parent__c') ==null && familyObj.get('Child__c') ==null) { wrapper.isGrantParentRecord = true; } wrapper.Weight = familyObj.get('weightTotal')!=null? ((Decimal)familyObj.get('weightTotal')).intValue():null; wrapper.WorkoutHours = familyObj.get('whTotal')!=null? ((Decimal)familyObj.get('whTotal')).intValue() :null; lstFamilyRecord.add(wrapper); } firstRecord = false; } return null; } public class FamilyData { public String GrantParent {get;set;} public String Parent {get;set;} public String Child {get;set;} public Integer Weight {get;set;} public Integer WorkoutHours {get;set;} public Boolean isGrantParentRecord {get;set;} public Boolean isParentRecord {get;set;} public Boolean isChildRecord {get;set;} } } |
Visualforce
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <apex:page id="familyPage" controller="FamilyClass" action="{!displayData}" showheader="true" sidebar="false"> <table id="familytable" border="1"> <tr> <th>Parents</th> <th>Weight</th> <th>Work Hours</th> </tr> <apex:repeat id="myRepeat" value="{!lstFamilyRecord}" var="key"> <tr> <td> <apex:outputText style="color: red;" value="{!key.GrantParent}" rendered="{!key.isGrantParentRecord}"/> <apex:outputText style="color: blue;" value="{!key.Parent}" rendered="{!key.isParentRecord}"/> <apex:outputText value="{!key.Child}" rendered="{!key.isChildRecord}"/> </td> <td> <apex:outputText value="{!key.Weight}"/> </td> <td> <apex:outputText value="{!key.WorkoutHours}"/> </td> </tr> </apex:repeat> </table> </apex:page> |
Final Output
Conclusion
Usually, looking at the requirements we think of preparing the data and logic in apex or visualforce in a complex way. But if we can leverage SOQL logic efficiently like this we may end up nice implementation.
Sharing with you, if it helps!
Link to stackExchange question:
http://salesforce.stackexchange.com/questions/164382/how-to-iterate-repetitive-rows-in-table-to-calculate-count-and-show-the-sum/164394#164394
Croma campus do guide our participants for respective Certifications for Salesforce Training in Noida which is an added advantage to the current market.
ReplyDeleteThanks for sharing nice information SalesForce Online Training
ReplyDelete