In part 1 I created an AddIn to Microsoft Word and listed all reports on a Reporting Services solution in a Custom Task Pane.
I now want the task pane to show the parameters in the custom task pane when the user selects a report.
Developers new to Reporting Services should really start by reading Identifying Execution State, as this a good introduction to loading and rendering reports.
Having read that I discarded the on ReportingServices2005.GetReportParameters() and used ReportExectionService.LoadReport() (MSDN) instead:
Exec.ReportExecutionService execService = new Exec.ReportExecutionService();
execService.Credentials = CredentialCache.DefaultCredentials;
string historyID = null;
Exec.ExecutionInfo execInfo = new Exec.ExecutionInfo();
Exec.ExecutionHeader execHeader = new Exec.ExecutionHeader();
execService.ExecutionHeaderValue = execHeader;
execInfo = execService.LoadReport(reportPath, historyID);
The report path is the path the RS report return by CatalogItem (MSDN).
The reason for this is that it will populate the ExecutionInfo (MSDN) data structure. One of the properties is the collection of ReportParameter (MSDN). And the ReportParameter class contains a collection ValidValues (MSDN). The list of ValidValues are populated if Reporting Services can do so with the given parameters. So if you have a report which lets the user choose a customer from a drop-down (probably fetched from a database somewhere and presented a Parameter with DataSet backing). Reporting Services will run that query for you and put the list of customers into ValidValues.
Now some parameter values depend on the user choosing other parameters first. If the customers before had projects, the Project parameter should of course only show the projects of the customer not all projects. Reporting Services allows for that by parameterized Datasets and will enforce that by disabling the parameters until the required parameters are set. The same thing happens in code.
In the above example of Customer -> Project relationship, Reporting Services will populate the ValidValues for the customer parameter, but not for the project parameter. What Reporting Services will do is to populate two other properties – State (MSDN) and Dependencies (MSDN).
State will have one of the four values of ParameterStateEnum (MSDN). The one we are interested in here is HasOutstandingDependencies. It tells us that the valid values cannot be calculated because some of other parameter has to be filled out first. The list of these dependencies is in the Dependencies collection.
The way to specify these parameters I by using ReportExectionService.SetExecutionParameters() (MSDN). . This method returns a new ExecutionInfo (MSDN) object which can be examined for valid values. Thus you keep calling SetExecutionParameters() until all the parameters in the resulting ExecInfo has State equal to HasValidValue.
Now all the parameters are valid and we are ready to call ReportExectionService.Render() (MSDN). The MSDN documentation on this is pretty decent, so I’ll skip that and go to the result:
result = execService.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);
Globals.ThisAddIn.InsertInDocument(format, result, extension);
If the format is “IMAGE” the result is the TIFF image, so, InsertInDocument is something like:
internal void InsertInDocument(string format, byte[] result, string extension)
{
Word.Selection selection = Globals.ThisAddIn.Application.Selection;
string tempFile = Path.GetTempFileName() + "." + extension;
FileStream stream = File.Create(tempFile, result.Length);
stream.Write(result, 0, result.Length);
stream.Close();
selection.InlineShapes.AddPicture(tempFile);
}
And presto, we have inserted the report as an embedded image in the Word Document. Only caveat here is that Reporting Services renders TIFF as full page, so the image might have to be cropped
You could probably find code for auto-cropping or you can insert render the report as MHTML and insert that instead.