views:

1092

answers:

1

I've checked through the history of questions, hit google, and other results and still am completely baffled about the C# reportViewer. It appears to only want to work with "typed" datasets. As many other people have inquired and I saw no real answers, maybe a fresh post will pull something new.

In its simplest form, I have a business object that performs a query from a database. I know what the resulting columns are and want to have it plugged into a specific report that is properly "formatted" as I need, as opposed to a simple columnar dump.

Since the query returns a "DataTable" object, but no known columns are "typed", I'm hosed.

As mentioned in other posts, if I have a system of 200+ tables, 400+ views and 200+ stored procedures, I don't want to type-cast everything. Especially if I am doing a NEW query that is a result of individual tables joined from some NEW stored procedure.

It shouldn't be this difficult to draw a report. If I type the column wrong, or SUM(), COUNT(), or whatever incorrectly, that's my fault, but at least let me get an untyped table into a report.

Help...

+1  A: 

The DataTable's columns don't need to be typed, they can all use the default of string.

What I did was I added a DataSet to my project, and designed the DataSet to match my query. I left all columns as strings. In the RDLC, I set up a table using this DataSet as my datasource, strictly for design time purposes.

At runtime, I instead dynamically swapped in a DataTable I generated and made sure it matched the design time DataSet (since they are all strings, I just need to make sure my DataTable has the same number of columns and the column names match).

        DataTable dt = new DataTable();
        DataColumn dc = dt.Columns.Add();
        dc.ColumnName = "DataColumn1";

        dc = dt.Columns.Add();
        dc.ColumnName = "DataColumn2";

        dt.Rows.Add(new object[] { "Frank", 32 });

        this.reportViewer1.LocalReport.DataSources.Clear();
        this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1_DataTable1", dt));

        this.reportViewer1.RefreshReport();  

At runtime the ReportViewer loads this DataTable as its data source and uses it to populate the table.

Is that what you are after?

Matt Greer
Close, I was already viewing other samples of this basis. However, when I try to design the report, I keep getting error messages about exception field / value settings. So, from your sample above, how would you identify the "value" element for the report textbox output... something like =First( Fields!DataColumn1.Value, "DataSet1_DataTable1" ) ??? My attempt had compiler errors...
DRapp
Yeah, that is exactly how you would do it. If you only have one datasource in the report, you don't need to name the datasource in the textbox. DataColumn1 is the name of the column in the DataSet. When you design a DataSet in VS using the DataSet designer, and add a table then add a column, "DataColumnX" is the default name for it. I have a blog entry that talks about the approach I took: http://blogs.msdn.com/magreer/archive/2008/10/16/setting-the-datasource-for-a-report-at-runtime.aspx that *might* be helpful, or it might not, there is a LOT of different ways you can set up the viewer
Matt Greer
The difference between my blog entry and what I suggest here is you don't have to actually define a strong type for each column if you don't want, just leave them as string. You can setup DataSets that are pretty generic, just have X columns in them, all named "Column0" through "ColumnX", and at runtime you can setup your DataTable to fit this schema. The report does expect a certain schema for the data, that does limit how dynamic a report can be here, the alternative is to generate the RDL dynamically, which is a whole other ball game.
Matt Greer
Ok, what a bunch of crud to jump through... Historically developing in VFP, you put anything you wanted for your textbox controls at design time. At run-time, if it didn't find what you wanted, it choked and you fixed your query. Yes, strong typecasting is great, but if you build queries dynamically -- fields, columns, etc I can see why so many people would be frustrated with such a locked-down reporting mechanism that prevents someone from shooting themselves in the foot.
DRapp