As I mentioned here, one of the projects I've done at Countrywide was build a group of WebParts for Reporting Services (I'm still looking into releasing these at some point). Recently I added an Export Report webpart that allows the user to export the report shown in the Report Viewer webpart. It worked fine when I developed it but it seemed there was a problem when it was deployed. The problem was that the URL it was getting was empty. I figured out a solution and I thought it might of use to other webpart developers.
Here is a screen shot of some of the webparts in action.
The RS Folder View uses some client side script to call the Reporting Services webservice from the clients machine. It then fills itself with all the reports in the RS folder (the folder and server are specified as properties). When the user clicks on a specific report it sends the server URL and the report path to the RS Report Viewer as a row. It also sends the same row to the RS Report Parameters webpart which also hits the RS webservice to get the list of parameters and values for the selected report. When a user selects parameters they also get sent as a row to the RS Report Viewer. The RS Report Viewer takes both the rows and generates a URL which it loads in an iframe.
The RS Report Export webpart is the last piece of the puzzle. It takes the URL from RS Report Viewer and uses that to allow the user to export the report to the selected format. The problem I was having was that this value was getting sent to the export webpart before the other values were received so the URL was incorrect. The code in the RS Report Viewer that would send the value was triggered as follows:
PartCommunicationMain() OnCellReady()
OnCellReady()
Sub
So I knew that I needed to fire the OnCellReady not just when the parts communicated, but also the values were received. What I didn't know, but figured out, was that you can call this method as many times as you want. So this made it a lot easier since I didn't need to figure out the perfect time to call this method but instead just added another call here:
Public
IRowConsumer.RowReady
Then
'' The first row has the data needed
DataRow = rowReadyArgs.Rows(0) _serverUrl = dr("ServerUrl") _reportPath = dr("ReportPath")
_serverUrl = dr("ServerUrl")
_reportPath = dr("ReportPath")
DataRow = rowReadyArgs.Rows
Int32
dr.Length _parameters.Add(dr(i - 1)("Name"), dr(i - 1)("Value"))
_parameters.Add(dr(i - 1)("Name"), dr(i - 1)("Value"))
Next
If
So this meant that everytime I got new information I would pass it back out to the export webpart. This is very useful when you're developing parts that all need to work together like these do.