Skip to contents

[Experimental]

Get summary data with or without details by running a report synchronously or asynchronously through the API. When you run a report, the API returns data for the same number of records that are available when the report is run in the Salesforce user interface. Include the filters argument in your request to get specific results on the fly by passing dynamic filters, groupings, and aggregates in the report metadata. Finally, you may want to use sf_run_report.

Usage

sf_execute_report(
  report_id,
  async = FALSE,
  include_details = TRUE,
  labels = TRUE,
  guess_types = TRUE,
  bind_using_character_cols = deprecated(),
  as_tbl = TRUE,
  report_metadata = NULL,
  verbose = FALSE
)

Arguments

report_id

character; the Salesforce Id assigned to a created analytics report. It will start with "00O".

async

logical; an indicator, by default set to TRUE, which executes the report asynchronously. If executed asynchronously, this function will return a list of attributes of the created report instance. The results can be pulled down by providing the report id and instance id to the function sf_get_report_instance_results. Refer to the details of the documentation on why executing a report asynchronously is preferred.

include_details

logical; an indicator applying to a synchronous indicating whether the run should return summary data with details.

labels

logical; an indicator of whether the returned data should be the label (i.e. formatted value) or the actual value. By default, the labels are returned because these are what appear in the Salesforce dashboard and more closely align with the column names. For example, "Account.Name" label may be "Account B" and the value 0016A0000035mJEQAY. The former (label) more accurately reflects the "Account.Name".

guess_types

logical; indicating whether or not to use col_guess() to try and cast the data returned in the recordset. If TRUE then col_guess() is used along with anytime() and anydate(). If FALSE then all fields will be returned as character. Specifying FALSE helpful when guessing the column data type will result in NA values and you would like to return the results as strings and then cast in your script according to your unique specifications.

bind_using_character_cols

logical; an indicator of whether to cast the data to all character columns to ensure that bind_rows does not fail because two paginated recordsets have differing datatypes for the same column. Set this to TRUE rarely, typically only when having this set to FALSE returns an error or you want all columns in the data to be character.

as_tbl

logical; an indicator of whether to convert the parsed JSON into a tbl_df.

report_metadata

list; a list with one element named "reportMetadata" having additional list elements underneath. All possible elements of reportMetadata are documented HERE, but you will most commonly only need to specify the following 3 elements to filter or query the results of an existing report:

reportFormat

A character specifying the format of the report with possible values: "TABULAR", "SUMMARY", "MATRIX", or "MULTI_BLOCK".

reportBooleanFilter

A character denoting how the individuals filters specified in reportFilters should be combined. For example, "(1OR4)AND2AND3"

.
reportFilters

A list of reportFilter specifications. Each must be a list with 3 elements: 1) column, 2) operator, and 3) value. You can find out how certain field types can be filtered by reviewing the results of sf_list_report_filter_operators.

verbose

logical; an indicator of whether to print additional detail for each API call, which is useful for debugging. More specifically, when set to TRUE the URL, header, and body will be printed for each request, along with additional diagnostic information where available.

Value

tbl_df by default, but a list when as_tbl=FALSE, which means that the content from the API is converted from JSON to a list with no other post-processing.

Details

Run a report synchronously if you expect it to finish running quickly. Otherwise, we recommend that you run reports through the API asynchronously for these reasons:

  • Long running reports have a lower risk of reaching the timeout limit when run asynchronously.

  • The 2-minute overall Salesforce API timeout limit doesn’t apply to asynchronous runs.

  • The Salesforce Reports and Dashboards REST API can handle a higher number of asynchronous run requests at a time.

  • Since the results of an asynchronously run report are stored for a 24-hr rolling period, they’re available for recurring access.

Before you filter a report, it helpful to check the following properties in the metadata that tell you if a field can be filtered, the values and criteria you can filter by, and filters that already exist in the report:

  • filterable

  • filterValues

  • dataTypeFilterOperatorMap

  • reportFilters

Examples

if (FALSE) { # \dontrun{
# first, get the Id of a report in your Org
all_reports <- sf_query("SELECT Id, Name FROM Report")
this_report_id <- all_reports$Id[1]

# then execute a synchronous report that will wait for the results
results <- sf_execute_report(this_report_id)

# alternatively, you can execute an async report and then grab its results when done
#   - The benefit of an async report is that the results will be stored for up to
#     24 hours for faster recall, if needed
results <- sf_execute_report(this_report_id, async=TRUE)

# check if completed and proceed if the status is "Success"
instance_list <- sf_list_report_instances(report_id)
instance_status <- instance_list[[which(instance_list$id == results$id), "status"]]
if(instance_status == "Success"){
  results <- sf_get_report_instance_results(report_id, results$id)
}

# Note: For more complex execution use the report_metadata argument.
# This can be done by building the list from scratch based on Salesforce 
# documentation (not recommended) or pulling down the existing reportMetadata 
# property of the report and modifying the list slightly (recommended). 
# In addition, for relatively simple changes, you can leverage the convenience 
# function sf_report_wrapper() which makes it easier to retrieve report results
report_details <- sf_describe_report(this_report_id)
report_metadata <- list(reportMetadata = report_details$reportMetadata)
report_metadata$reportMetadata$showGrandTotal <- FALSE
report_metadata$reportMetadata$showSubtotals <- FALSE
fields <- sf_execute_report(this_report_id,
                            report_metadata = report_metadata)
} # }