+ Start a Discussion
Garrett MillerGarrett Miller 

Can I create and save a public report with Apex?

Hello all,
 

I have been searching through the documentation and I can't find a clear answer. I am trying to use apex to create a report ( it requires calculations that aren't available in the normal report building ), and I want to be able to save it as a public report. Is this possible? 

If so, would it require a Visualforce Page? 

Amit Chaudhary 8Amit Chaudhary 8
You can not create the report by apex class
1) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_analytics_test_reports.htm
2) https://salesforce.stackexchange.com/questions/53380/create-reports-programatically-with-apex

Sample code
@isTest
public class ReportsInApexTest{

    @isTest(SeeAllData='true')
    public static void testAsyncReportWithTestData() {

      List <Report> reportList = [SELECT Id,DeveloperName FROM Report where
          DeveloperName = 'Closed_Sales_This_Quarter'];
      String reportId = (String)reportList.get(0).get('Id');
      
      // Create an Opportunity object.
      Opportunity opp = new Opportunity(Name='ApexTestOpp', StageName='stage',
          Probability = 95, CloseDate=system.today());
      insert opp;
    
      Reports.ReportMetadata reportMetadata =
          Reports.ReportManager.describeReport(reportId).getReportMetadata();
      
      // Add a filter.
      List<Reports.ReportFilter> filters = new List<Reports.ReportFilter>(); 
      Reports.ReportFilter newFilter = new Reports.ReportFilter();
      newFilter.setColumn('OPPORTUNITY_NAME');
      newFilter.setOperator('equals');
      newFilter.setValue('ApexTestOpp');
      filters.add(newFilter);
      reportMetadata.setReportFilters(filters);
      
      Test.startTest();
       
      Reports.ReportInstance instanceObj =
          Reports.ReportManager.runAsyncReport(reportId,reportMetadata,false);
      String instanceId = instanceObj.getId();
      
      // Report instance is not available yet.
      Test.stopTest();
      // After the stopTest method, the report has finished executing
      // and the instance is available.
     
      instanceObj = Reports.ReportManager.getReportInstance(instanceId);
      System.assertEquals(instanceObj.getStatus(),'Success');
      Reports.ReportResults result = instanceObj.getReportResults();
      Reports.ReportFact grandTotal = (Reports.ReportFact)result.getFactMap().get('T!T');
      System.assertEquals(1,(Decimal)grandTotal.getAggregates().get(1).getValue());
    }
  
    @isTest(SeeAllData='true')
    public static void testSyncReportWithTestData() {
    
      // Create an Opportunity Object.
      Opportunity opp = new Opportunity(Name='ApexTestOpp', StageName='stage',
          Probability = 95, CloseDate=system.today());
      insert opp;
      
      List <Report> reportList = [SELECT Id,DeveloperName FROM Report where
          DeveloperName = 'Closed_Sales_This_Quarter'];
      String reportId = (String)reportList.get(0).get('Id');
      
      Reports.ReportMetadata reportMetadata =
          Reports.ReportManager.describeReport(reportId).getReportMetadata();
      
      // Add a filter.
      List<Reports.ReportFilter> filters = new List<Reports.ReportFilter>(); 
      Reports.ReportFilter newFilter = new Reports.ReportFilter();
      newFilter.setColumn('OPPORTUNITY_NAME');
      newFilter.setOperator('equals');
      newFilter.setValue('ApexTestOpp');
      filters.add(newFilter);
      reportMetadata.setReportFilters(filters);
      
      Reports.ReportResults result =
          Reports.ReportManager.runReport(reportId,reportMetadata,false); 
      Reports.ReportFact grandTotal = (Reports.ReportFact)result.getFactMap().get('T!T');
      System.assertEquals(1,(Decimal)grandTotal.getAggregates().get(1).getValue());
    }
}

Let us know if this will help you
Bhavesh Jain 41Bhavesh Jain 41
hi @Amit I know this is a very old artcile

thank you for sharing this wonderful article I tried this the filters are getting set however not reflecting in the backend on the report am I missing anything