I’ve begun developing reports in .NET, and just starting up the learning curve. Basic reports are pretty easy, but if you need anything complex things get convoluted in a hurry. I don’t know if my Visual FoxPro experience is getting in the way of wrapping my head around the .NET way, but it sure seemed things were a lot easier in Visual FoxPro!
Recently I had to do something quite simple: put a custom header on a report to show the name of the event. I added a textbox, and found what seemed like the perfect report variable to drop in there to use: Globals!ReportName. The docs said that was related to ReportViewer.LocalReport.DisplayName, but ok I can deal with a little inconsistency. I set the .DisplayName in my code to the custom info, ran the report, and voila! Huh? #Error appeared in the field.
I doublechecked the expression, which automagically changed itself to [&ReportName] or somesuch, so I changed it back, ran it again, and … #Error.
WTF? Was it not getting the ReportName properly? I changed it to another expression, this time Globals!TotalPages (and again it changed itself to &TotalPages), but to no avail.
I googled and found others were having a similar problem. Excellent, then there’d be a solution! Alas, Brad at Microsoft couldn’t reproduce the problem at all. I spent a lot more time researching possible solutions before coming to the conclusion that the Globals! idea just wasn’t going to work. I tried to use Parameters! too but those didn’t work either.
Finally I hit upon an idea for a workaround. I’d have to pass the custom information I wanted into the report in the same manner that I passed the data that appeared on the report: using a DataTable. I didn’t want to add a column to the existing DataTable because that would offend my refined sense of normalization. What I needed was a second DataTable in the DataSet.
Could this be done? Turns out it can. Here’s what you do:
1. Create a new data schema. (Right-click on the project, select Add New Item, pick DataSet). Give it a name like ReportInfo. Add all the columns you might want on a report, such as Title, Author, whatever.
2. Right+Click on your RDLC and say “Open With…” and pick XML Text Editor.
3. Under the DataSources section, add a new DataSource:
4. Under the DataSets section, add a new DataSet
5. Close your RDLC and re-open it in the designer. Drop a TextBox in the header, and select your new Title field. It’ll say =First(), but that’s ok.
6. Now in the code where you called your report, you need to create your DataTable and add it to your report’s DataSource, like this:
DataTable dtReportInfo = new DataTable("ReportInfo");
dtReportInfo.Columns.Add(new DataColumn("Title", System.Type.GetType("System.String")));
dtReportInfo.Rows.Add(this.ReportViewer1.LocalReport.DisplayName + " " + cTitle.ToString());
this.ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("ReportInfo_ReportInfo", this.ds.Tables));
(StringBuilder cTitle contains the title information that I built up).
There you go! Now you can get the info you need on your report with relying on the Globals! variables and getting an #Error. We’re still not sure why we were getting that, but at least we have a workaround. I hope you find this post and it doesn’t cost you hours and hours of unbillable time, like it did me.