Table of Contents
Possibilities
- Programmatic Access to report-data of report build in report-builder
- enables to integrate report-data in web- and mobile-apps (e.g. trigger a chatter post with a snapshot of report-data)
- visualization to animate data
- integration of report-data in custom objects
- integration of report-data in to rich visualizations and animations of data
- create custom report-dashboards
- automate reporting tasks
- enable to query and filter report data
- Run tabular, summary, or matrix reports synchronously or asynchronously
- filter specific data on the fly
- Query report data and metadata
Requirements and Limitations
Requirements
- Set Enable API to available for organization
Restriction apply to reports and dashboards API + general API limits
- unavailable when filtering data
- cross filters
- standard report filters
- filters by row limits
- historical tracking reports
- only matrix
- subscription not supported
- API process only reports up to 100 fields selected as columns
- List of up to 200 recently viewed reports can run
- Org request up to 500 synchronous report runs per hour
- API supports up to 20 synchronous report runs at a time
- return a List of up to 2000 instances of one asynchrone run report
- API supports up to 200 request at a time to get results of one report that was run asynchrone
- Orb supports up to 1200 requests per hour
- Results of asynchronously report runs are available within a 24-hour rolling period
- API return up to 2000 reports
- can add up to 20 custom field filters to run a report
- calls not allowed in Apex trigger (synchrone and asynchrone)
- no Apex method to list recently run reports
- governor limits of total number of rows retrieved by SOQL are 50.000 per transaction on synchronously report runs
- Apex tests, report runs always ignore SeeAllData annotation. report data include pre-existing data that the test did’nt create
- Apex tests, asynchrone report runs execute only after Test.stopTest
Run reports
Reports can run synchronous and asynchronous. Asynchronous is recommended:
- Long-running asynchronous reports have a lower risk of reaching timeout limits
- the 2 minutes timeout doesn’t apply for asynchronous jobs
- can handle a higher number of asynchronous runs at a time
- the results of an asynchronously report are stored for an 24 hour rolling period
Possibilities
To run reports about API needing report-ID. It can directly set to run report or find out with SOQL and the developername of the report.
Developername or ID can find out directly with Workbench. https://workbench.developerforce.com/
- Login at Org
- Jump to: Metadata Types & Components
- Select Report
In “Components” all report-folders include report developername listed.
Synchronous Run (Snippet)
Get the report ID = function .get().get(‘Id’)
List <Report> reportList = [SELECT Id,DeveloperName FROM Report where
DeveloperName = 'Closed_Sales_This_Quarter'];
String reportId = (String)reportList.get(0).get('Id');
Run the report = function runReport()
Reports.ReportResults results = Reports.ReportManager.runReport(reportId, true);
System.debug('Synchronous results: ' + results);
Get Metadata
Get the report metadata = function getReportMetaData()
Reports.ReportMetadata rm = results.getReportMetadata();
System.debug('Name: ' + rm.getName());
System.debug('ID: ' + rm.getId());
System.debug('Currency code: ' + rm.getCurrencyCode());
System.debug('Developer name: ' + rm.getDeveloperName());
Get grouping info for first grouping = function getGroupingsDown()[]
Reports.GroupingInfo gInfo = rm.getGroupingsDown()[0];
System.debug('Grouping name: ' + gInfo.getName());
System.debug('Grouping sort order: ' + gInfo.getSortOrder());
System.debug('Grouping date granularity: ' + gInfo.getDateGranularity())
Get aggregates = function getAggregates()[]
System.debug('First aggregate: ' + rm.getAggregates()[0]);
System.debug('Second aggregate: ' + rm.getAggregates()[1]);
Get detail columns = function getDetailColumn()
System.debug('Detail columns: ' + rm.getDetailColumns());
Get report format = function getReportFormat()
System.debug('Report format: ' + rm.getReportFormat());
Get Report Data
Get the first down-grouping in the report = function getGroupingsDown();
Reports.Dimension dim = results.getGroupingsDown();
Reports.GroupingValue groupingVal = dim.getGroupings()[0];
System.debug('Key: ' + groupingVal.getKey());
System.debug('Label: ' + groupingVal.getLabel());
System.debug('Value: ' + groupingVal.getValue());
Construct a fact map key, using the grouping key value
String factMapKey = groupingVal.getKey() + '!T';
Get the fact map from the report results
Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails)results.getFactMap().get(factMapKey);
Get the first summary amount from the fact map
Reports.SummaryValue sumVal = factDetails.getAggregates()[0];
System.debug('Summary Value: ' + sumVal.getLabel());
Get the field value from the first data cell of the first row of the report
Reports.ReportDetailRow detailRow = factDetails.getRows()[0];
System.debug(detailRow.getDataCells()[0].getLabel());
Asychnronous Run (Snippet)
- bis zu 2000 Instanzen eines Reports asynchron ausgeführt
Run Report
Get the report ID
List <Report> reportList = [SELECT Id,DeveloperName FROM Report where
DeveloperName = 'Closed_Sales_This_Quarter'];
String reportId = (String)reportList.get(0).get('Id');
Run the report
Reports.ReportInstance instance = Reports.ReportManager.runAsyncReport(reportId, true);
System.debug('Asynchronous instance: ' + instance);
Get List of asynchronous runs.
System.debug('List of asynchronous runs:
Reports.ReportManager.getReportInstances(reportId));
Filter Reports
Check some Filter Values before filtering:
- ReportTypeColumn.getFilterable = some fields can be filtered?
- ReportTypeColumn.filterValues = return all filter values for a field
- ReportManager.dataTypeFilterOperatorMap = field list of data types for using filtering
- ReportMetadata.getReportFilters = filters exist in the report
Get the report ID
List <Report> reportList = [SELECT Id,DeveloperName FROM Report where
DeveloperName = 'Closed_Sales_This_Quarter'];
String reportId = (String)reportList.get(0).get('Id');
Get the report metadata
Reports.ReportDescribeResult describe = Reports.ReportManager.describeReport(reportId);
Reports.ReportMetadata reportMd = describe.getReportMetadata();
Override filter and run report
Reports.ReportFilter filter = reportMd.getReportFilters()[0];
filter.setValue('2013-11-01');
Reports.ReportResults results = Reports.ReportManager.runReport(reportId, reportMd);
Reports.ReportFactWithSummaries factSum =(Reports.ReportFactWithSummaries)results.getFactMap().get('T!T');
System.debug('Value for November: ' + factSum.getAggregates()[0].getLabel());
Override filter and run report
filter = reportMd.getReportFilters()[0];
filter.setValue('2013-10-01');
results = Reports.ReportManager.runReport(reportId, reportMd);
factSum = (Reports.ReportFactWithSummaries)results.getFactMap().get('T!T');
System.debug('Value for October: ' + factSum.getAggregates()[0].getLabel());
Decode the Fact Map
The Fact Map contains the summary and record-level data values.
- fact map result after run the report
- can only contain summary
- can contain summary and detail data
- Pattern for fact map key can varies by the report format
Report Format | Fact MapKey Pattern | Description |
Tabular | T!T | grand total of the report. Record data values are respresented. |
Summary | 1_0_3!T | First level row grouping and second element_ Second level row grouping and first element_ Third level row grouping and fourth element!T |
Matrix | 1_0_3!1_0_2 | First level row grouping and second element_ Second level row grouping and first element_ third level row grouping and fourth element !First level column grouping and second element_ Second level column grouping and first element_ Third level column grouping and third element |
More information here.