Salesforce.com has a mind-blowing reporting structure but it limits on data that is available on the system. Can we report on Data that is not present in the system?
For e.g., in a time-sheet management system, can we identify the people who have not filled time-sheets for a particular day? Can we report on data that is not present in the system? Can we identify records that are not created?
There is one thing I have learned working on Force.com platform for last 7 years, there is No No answer in Salesforce. Think a little bit and the answer will reach you. It is somewhat like climbing mount Everest, can you do it? Sure yes, in how many days depends on how fit I am (or how crazy I am)
Ok that Everest thing came up because someone did ask me that a few weeks back, moving on. Someone did also ask me about creating a report on missing details and I gave it a thought. The short answer is Yes we can, the long answer is we write a Visualforce page, anyone can tell you that. But what I really wanted to do was create a reusable code that I could use for a generic tabular report component.
The code is fairly simple, the pseudo code for the code is.
1. Generate a set of String for Rows
2. Generate a set of String for Columns
3. Prepare a map with Key as Row+Column and store the data accordingly.
4. Create a Dynamic table on Visualforce.
For e.g., in a time-sheet management system, can we identify the people who have not filled time-sheets for a particular day? Can we report on data that is not present in the system? Can we identify records that are not created?
There is one thing I have learned working on Force.com platform for last 7 years, there is No No answer in Salesforce. Think a little bit and the answer will reach you. It is somewhat like climbing mount Everest, can you do it? Sure yes, in how many days depends on how fit I am (or how crazy I am)
Ok that Everest thing came up because someone did ask me that a few weeks back, moving on. Someone did also ask me about creating a report on missing details and I gave it a thought. The short answer is Yes we can, the long answer is we write a Visualforce page, anyone can tell you that. But what I really wanted to do was create a reusable code that I could use for a generic tabular report component.
The code is fairly simple, the pseudo code for the code is.
1. Generate a set of String for Rows
2. Generate a set of String for Columns
3. Prepare a map with Key as Row+Column and store the data accordingly.
4. Create a Dynamic table on Visualforce.
Apex Class for the page
public with sharing class TabularReportController { public Setrows{get;set;} public Set Cols {get;set;} public Map dataMap {get;set;} public TabularReportController(){ prepareDataForReport(); } public string getURLParam(String paramName){ return ApexPages.currentPage().getParameters().get(paramName); } //Get the data for the rows public Map getrow(){ return new Map ([Select id, name, Accountid from Contact]); } //Get the data for the columns public Map getColumns(){ return new Map ([Select id, name from Account]); } //This is where the magic happens public void prepareDataForReport(){ rows= new Set (); cols= new Set (); dataMap= new Map (); Map columnsData=getColumns(); Map rowData= getRow(); //Geronimo for(Account a: columnsData.values()){ cols.add(a.name); for(Contact c: rowData.values()){ rows.add(c.name); String key= a.name+c.name; //Key is the key in which we set the data that we want to display. //Do some hazy logic here. This is where the key lies, you perfom your calculations and simply prepare the data //For display //For this example I am going to check if Contact is related to account if(c.accountid==a.id){ dataMap.put(key,'Related'); }else{ dataMap.put(key,'Unrelated'); } } } } }
Visualforce page for the code
<apex:page controller="TabularReportController" sidebar="false"> <style type="text/css"> .Related { background-color: #0B610B; color: #FBF8EF !important; } .Unrelated{ background-color: #A4A4A4; } </style> <apex:sectionHeader title="Documents" subtitle="Report"/> <apex:form > <apex:pageBlock id="TheTable" title="Are the Accounts and Contact related?"> <table border="0" cellpadding="2" cellspacing="2" style="table-layout:auto" class="list"> <colgroup span="2"></colgroup> <thead class=""> <tr class=" headerRow"> <th class=" headerRow" scope="col" colspan="1">Contact</th> <apex:repeat value="{!rows}" var="row"> <th class=" headerRow">{!row}</th> </apex:repeat> </tr> </thead> <tbody > <apex:repeat value="{!cols}" var="col"> <tr class="dataRow"> <td class="dataCell" colspan="1" style="white-space:nowrap"><span>{!col}</span></td> <apex:repeat value="{!rows}" var="row" > <!-- This is the Key, so to speak, for the entire page. Generating the key on the visualforce page --> <apex:variable var="key" value="{!col}{!row}"/> <td class="{!dataMap[key]}">{!dataMap[key]}</td> </apex:repeat> </tr> </apex:repeat> </tbody> </table> </apex:pageBlock> </apex:form> </apex:page>
You can see the output of the report here
You can enhance the code using the same structure. Here are couple different thing I tried
- Adding a link to the data using wrapper
- Model window editing for the data
- Adding complex many to many relationships
- Plotting records that are not present
The list can go on.
0 comments:
Post a Comment