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
jverdjverd 

How do I get report data (not metadata) through Web Services API?

I'm not sure if this is the right place to ask this--I'm still not sure about the relationships amon Apex, AppExchange, Force.com, and the Web Services and Metada APIs.

I want to get a report's data through the Web Services API. I'm coding in Java, but my understanding is the implementation language shouldn't matter.

As near as I can tell, what I'll have to do is first get the report's metadata with the Metadata API, then use that to construct a SOQL query that I'll execute to get the report data. Is this the only way, or is there a more direct way through the Web Services API to just say, "Run this report and give me the results?" I've been studying the API for a couple of days now and haven't found anything, but I'm hoping I missed something.

Alternatively, if I schedule a report through the website, is it possible to retrieve its results via the API?

Thanks in advance for any light you can shed on this subject.

Jeff

RickyGRickyG
Jeff -

You cannot access reports through the Web Services API.  Reports are not accessible through the Metadata API. You would run a SOQL query to get the data used by a report. 

Hope this helps.


jverdjverd
Thanks. That's kind of what I thought, but I was hoping it'd be otherwise. :-)

So, use the Metadata API to get the report definition--which columns, etc.--then write my own code to build one or more SOQL queries from that metadata, yes?
RickyGRickyG
Not so fast, dude.  You can't access reports through the Metadata API, so you can't get the data in the reports that way either.

There is an intermediate solution.  You could use reports to create an analytic snapshot, which is essentially holding the data selected by a report in another custom object.  You could certainly use the Metadata API to get the fields in that custom object.  Not sure whether this approach would buy you much in your current situation - you would still have to create the custom object that is the destination of the report data, so you could probably just create SOQL statements while looking at the report as easily.  Neither one of these options addresses the scenario that concerns a change in fields in a report.

Hope this clarifies things a bit.
jverdjverd

RickyG wrote:
Not so fast, dude.  You can't access reports through the Metadata API, so you can't get the data in the reports that way either.



I think we're not on the same page, or one of us is confused. I can and have fetched report metadata via the metadata API. I can only do that for reports that I created in folders that I created, not for the standard ones, so maybe that's what you meant? That's a pain in the butt, to be sure, but the work around is to manually create (through the website) copies of standard reports that we want to access this way.


The code for retrieving report metadata, once we have the custom folder and customer report we want, is roughly this (error handling, etc. removed for brevity).
Code:
    final RetrieveRequest retrieveRequest =
new RetrieveRequest (apiVersion, packageNames, singlePackage, specificFiles, unpackaged);

final AsyncResult asyncRetrieveResult = metadatabinding.retrieve (retrieveRequest);
final String id = asyncRetrieveResult.getId ();
final String[] ids = {id};

AsyncResult resultStatus;
int count = 0;

do {
final AsyncResult[] resultStatuses = metadatabinding.checkStatus (ids);
resultStatus = resultStatuses[0];
Thread.sleep (2000);
} while (count++ < 10 && !resultStatus.isDone ());

final RetrieveResult retrieveResult = metadatabinding.checkRetrieveStatus (id);
final byte[] zipFile = retrieveResult.getZipFile ();

final ByteArrayInputStream bais = new ByteArrayInputStream (zipFile);
final ZipInputStream zis = new ZipInputStream (bais);
ZipEntry entry;

while ((entry = zis.getNextEntry ()) != null) {
final String str = entry.toString ();
System.out.println ("zipEntry: " + str);
String uncompressedAsString = "";
final byte[] uncompressed = new byte[64 * 1024];
int bytesRead;

while ((bytesRead = zis.read (uncompressed)) != -1) {
uncompressedAsString += new String (uncompressed, 0, bytesRead);"
}

 

RickyG wrote:

There is an intermediate solution.  You could use reports to create an analytic snapshot, which is essentially holding the data selected by a report in another custom object.  You could certainly use the Metadata API to get the fields in that custom object.  Not sure whether this approach would buy you much in your current situation - you would still have to create the custom object that is the destination of the report data, so you could probably just create SOQL statements while looking at the report as easily.  Neither one of these options addresses the scenario that concerns a change in fields in a report.



I don't entirely follow you here. I'll ruminate on it a bit later, but for now I'm going to see if I can construct the SOQL from the report metadata (which I do have).

Thanks again!

Jeff


RickyGRickyG
Jeff -

My bad - I am living in the past.  Yes, you can retrieve report data, and yes, it has to be in a custom folder.  My apologies.  The whole point about the analytic snapshots was a workaround, which you will not need.

jverdjverd
Thanks. It's always comforting to know I'm not losing my mind. Or at least to not have direct evidence that I am. :-)

hamayoun65hamayoun65

Can I regular user get report data via the Metadata API, or only a System Admin?

 

Thx,

Hamayoun