function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Julio HernandezJulio Hernandez 

Pulling report with APEX controller

Hi, 

I created an APEX controller which in theory should pull the data given by the report. Unfortunatly I dont think it's pulling the report at all. Here is the Controller Code.
 
public class reportData{


private static Integer LOWER = 4;
    private static Integer MID = 8;

    public String gaugeColor {
        get;
        set;
    }

    public class GaugeData {
        public String name {
            get;
            set;
        }

        public Integer size {
            get;
            set;
        }

        public GaugeData(String name, Integer size) {
            this.name = name;
            this.size = size;
        }
    }

    public List<GaugeData> data {
        get;
        set;
    }

    public reportData() {
        this.data = new List<GaugeData>();

        List<Report> reportList = [
            select Id, DeveloperName 
            from Report
            where DeveloperName = 'Active_Solution_Hawks'
        ];
        String reportId = (String)reportList.get(0).get('Id');


        Reports.ReportResults results = Reports.ReportManager.runReport(reportId, true);
        Reports.Dimension dim = results.getGroupingsDown();

        Integer numberOfCases = 0;

        for (Reports.GroupingValue groupingVal : dim.getGroupings()) {
            String factMapKey = groupingVal.getKey() + '!T';
            Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails)results.getFactMap().get(factMapKey);
            Reports.SummaryValue sumVal = factDetails.getAggregates()[0];
            numberOfCases += Integer.valueOf(sumVal.getLabel());
        }

        this.data.add(new GaugeData('Cases', numberOfCases ));

        if (numberOfCases < LOWER) {
            this.gaugeColor = '#093, #ddd';
        } else if (numberOfCases < MID) {
            this.gaugeColor = '#ff6, #ddd';
        } else {
            this.gaugeColor = '#c00, #ddd';
        }
    }
}

I know it doesnt work because numberOfCases stays at zero even though the report has data in it. 
NagendraNagendra (Salesforce Developers) 
Hi Julio Hernandez,

Please refer to the similar example and modify it as per your requirement.

Apex Controller:
public with sharing class AsyncReportController {

public List<SelectOption> availableReports { get; set; }
public Id reportId { get; set; }
public Id instanceId { get; set; }
public Boolean reportIsRunning { get; set; }
private transient Reports.ReportResults reportResults;

public AsyncReportController() {
    availableReports = retrieveAvailableReports();
}

public List<SelectOption> retrieveAvailableReports() {
    List<SelectOption> reptOpts = new List<SelectOption>();
    for (Report r : [
         Select Id, Name
         From Report
         Where Format = 'Tabular'
         Order By Name
    ]) {
        reptOpts.add(new SelectOption(r.Id, r.Name));
    }
    return reptOpts;
}

public PageReference runReport() {
    Reports.ReportInstance reportInstance = Reports.ReportManager.runAsyncReport(reportId, true);
    instanceId = reportInstance.getId();
    processInstance(reportInstance);

    return null;
}

public PageReference checkForReportResults() {
    Reports.ReportInstance reportInstance = Reports.ReportManager.getReportInstance(instanceId);
    processInstance(reportInstance);

    return null;
}

private void processInstance(Reports.ReportInstance reportInstance) {
    reportIsRunning = reportInstance.getStatus() == 'Running' || reportInstance.getStatus() == 'New';
    if (!reportIsRunning) {
        reportResults = reportInstance.getReportResults();
    }
}

public Reports.ReportResults getReportResults() {
    return reportResults;
}
}

VisualForce Page:

To run the report from page:
<apex:form >
      <apex:actionPoller action="{!checkForReportResults}" id="poller" reRender="reportResults" interval="5" enabled="{!reportIsRunning}" />
      <apex:commandButton action="{!runReport}" reRender="poller,reportResults" value="Run Report"/>
 </apex:form>
Set column values in table:
<apex:repeat value="{!reportResults.reportMetadata.detailColumns}" var="colName">
              <th><apex:outputText value="{!reportResults.reportExtendedMetadata.detailColumnInfo[colName].label}"/></th>
           </apex:repeat>
Set row values :
<tbody>
           <apex:repeat value="{!reportResults.factMap['T!T'].rows}" var="row">
               <tr>
                   <apex:repeat value="{!row.dataCells}" var="cell">
                       <td><apex:outputText value="{!cell.label}"/></td>
                   </apex:repeat>
               </tr>
           </apex:repeat>
       </tbody>

Please mark this as solved if it helps.

Best Regards,
Nagendra.P
Leafen SandyLeafen Sandy
Hi Nagendra, 

I too exactly need the one which you have given, so thanks for posting.

Anyways, I'm still getting the following error.

Visualforce Error:
 
System.NoDataFoundException: The data you’re trying to access is unavailable.
Error is in expression '{!runReport}' in component <apex:commandButton> in page runreport: Class.reports.ReportManager.runAsyncReport: line 33, column 1
Class.AsyncReportController.runReport: line 28, column 1
An unexpected error has occurred. Your solution provider has been notified. (reports)



Kindly let me know where I went wrong or what has to be modified.

Thanks,
Leafen.