"Is it possible to write a query to extract a specific report? I am using an external system where I want to retrieve a report from Salesforce named 'Booked Inquiry', but I'm unsure which query to use."
Hi Samiksha!
Definitely possible, we made a little video accomplishing it with Apex that will output the data in the format of your choice. If you're trying to do it via API, it'll depend a bit on the language of the API/etc.. but our solution basically breaks out as follows:
- Query Report
- Get Details for Columns
- Get Details for Records
- Correlate Column Details and Record Details
- Can then structure data however you want (JSON, XML, etc...)
And that Apex looks like this:
public with sharing class ReportHelper {
/**
* Derived from the code provided by Salesforce
* at https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_analytics_report_data.htm
*/
public static String getReportData(String reportName){
List <Report> reportList = [
SELECT Id, DeveloperName FROM Report
WHERE DeveloperName = :reportName
OR Name = :reportName
];
String reportId = (String)reportList.get(0).get('Id');
// Run a report synchronously
Reports.reportResults results = Reports.ReportManager.runReport(reportId, true);
Reports.ReportMetadata reportMetdata = results.getReportMetadata();
LIST<String> columns = reportMetdata.getDetailColumns();
// Get the first down-grouping in the report
Reports.Dimension dim = results.getGroupingsDown();
Reports.GroupingValue groupingVal = dim.getGroupings()[0];
// 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];
List<Map<String,Object>> response = new List<Map<String,Object>>();
// Get the field value from the first data cell of the first row of the report
for ( Integer i=0; i<factDetails.getRows().size(); i++ ){
Reports.ReportDetailRow detailRow = factDetails.getRows()[i];
List<Reports.ReportDataCell> cells = detailRow.getDataCells();
Map<String,Object> jsonRow = new Map<String,Object>();
for ( Integer j=0; j<cells.size(); j++ ){
jsonRow.put( columns[j], cells[j].getLabel() );
}
response.add(jsonRow);
}
return JSON.serialize(response);
}
}
And here's a video of us walking through this solve and reaching that point if you need more insight.
And, if this helps you solve it, please be sure to mark this best answer so other folks searching this query will find it.
Thanks!!