Local Report - Adding Datasources Programmatically

Using the LocalReport object you can add a datasource:

LocalReport.DataSources.Add("myDataTable")

I'd like to add DataSources to my report this way at runtime.  This is so my business objects can run out the the database, grab data, scrub it, and then pass the dataset to the Local Report.

I can see how to add the datasource, what I don't understand is how to reference the datasource in my report.  Take a textbox, the value property is usually set this way:

=Fields!myDataField

I don't know how to bind data this way out of dynamically added datasources (datatables).  I tried:

=Datasources(0)!Fields!myDataField

That doesn't work - I thought maybe datasources was an indexed collection but apparently not.  Assuming I add several datasources (datatables) how would I bind a particular datasource to a textbox or a grid



Answer this question

Local Report - Adding Datasources Programmatically

  • Alastair Q

    try:

    =Fields!name.Value

    =First(Fields!name.Value)

    =First(Fields!name.Value, "DataSet3")

    DataSet3 is a datasource name.


  • DCWCore

    Thanks for this post. It was very helpdful. I added this code to my application. But I do have a question, how to I get the table adapter to fill dynamically Currently when I use you code, I do not see any data. I know there is data because it comes back when I run the stored procedure independant of the application.
  • SSRS Jon

    Then this is no better than Crystal Reports .NET, with Crystal Rpt you need to design a .rpt file at design time.

    What would be good is a way to generate the .rdlc file at runtime. If anyone knows how, please post links on how to do this.


  • w014nd

    I'm having a similar problem. I can't quite seem to figure out how to get a report to work without putting it all together at design time. This is what I have

    private void Form1_Load(object sender, EventArgs e)
    {
    DataTable dtMain = null;
    LocalReport lr = null;
    dtMain = workHorse.loadPDSMain();
    reportViewer1.ProcessingMode = ProcessingMode.Local;
    lr = reportViewer1.LocalReport;
    lr.ReportPath = "PDS.rdlc";
    lr.DataSources.Add(new ReportDataSource("main",dtMain));
    reportViewer1.RefreshReport();
    }

    And my text box in my report contains this

    =Fields!TOGAC_SALE_NO.Value

    where TOGAC_SALE_NO is a field in my DataTable. The error I receive is:

    "An Error occurred during local report processing.
    The definition of the report "Main Report" is invalid.
    the Value expression for the textbox 'txtSale' refers to the field 'TOGAC_SALE_NO'.
    Report item expressions can only refer to fields within the current data set scope or, if inside an aggregate, the specified data set scope."

    I've tried quite a few things and I can't seem to figure out what it is that I need to do to make things work. I've been doing quite a bit of searching for the last 3 days, I would be really thankful for any suggestions.



  • EDV Gradl

    I tried adding =First(Fields!FirstName.Value, "dsReportData") but get the error below:

    The Value expression for the textbox ‘textbox1’ has a scope parameter that is not valid for an aggregate function. The scope parameter must be set to a string constant that is equal to either the name of a containing group, the name of a containing data region, or the name of a data set.

    This is the code that adds the data set into the report viewer where dsReportdata has already been defined.

    Dim ReportViewer1 As New ReportViewer

    ReportViewer1.LocalReport.ReportPath = "Reports\Report1.rdlc"

    ReportViewer1.LocalReport.DataSources.Add(New ReportDataSource("dsReportData", dsReportData.Tables("DataTable1")))



  • jorisp

    You can go through the Design experience, which generates code for you, but this is not a requirement. See http://www.gotreportviewer.com Some examples on that site are VS projects, but many were written using Notepad.


  • Leonard Lee

    The only way I can think to accomplish this is by designing the report, setting up report parameters for each field on the report, then setting the fields to those report parameters. Then, during runtime, create the dataset and, using part of the code I posted above set each report parameter to the value from the field in the dataset.

    Basically, use report parameters as a way of exposing the fields on the report to your application.

  • fatquack

    Did anyone find a solution for this I would appreciate any feedback.

  • Keyu

    I've the same issue entirely.

    I'd like to avoid all the extra design time files but it looks as if they may be required.

    If the design time files/connections and so forth are required is there a way to make 'thin' ignorant files that can serve as report source definitions (until I pass in an actual valid report datasource object) - something without connection string information   How do I make very thin xsd files since I'm NOT going to be using them to actually fetch and save data   My only use for them is to allow the building of the report so I can =!Fields!MyData

    I'd like to be able to use: =Fields!MyData with as little overhead as possible.

    On a related note, I see that ReportDataSources allows for a collection of datasets - if I had two datasets in there how would I pick which one's data I wanted to display.  Is there a way to pick one like =Datasources("tablename")!Fields!MyData


  • steveareno

    You can create the dataset your going to use, then design the report in the report designer using that dataset as the datasource for the report. Then, in your .net code, you can load up the dataset whenever you want and pass it to your report. The datasource name you give it when passing it to your report just has to match the dataset name that is stored in the report. For example, if I have a report with a datasource called "ds_test" then in my code, I could write something like this:

    Dim rptDs As Microsoft.Reporting.WinForms.ReportDataSource
    Dim rptParam As Microsoft.Reporting.WinForms.ReportParameter
    Dim paramList As New List(Of Microsoft.Reporting.WinForms.ReportParameter)
    Dim index As Integer

    'Load the report. The resource name must be the fully
    'qualified name of the report.


    Me.ReportViewer1.LocalReport.ReportEmbeddedResource = "myNamespace.rptCertifiedList.rdlc"


    'Load the datasource. Replace "datasetName_dataTable" with
    'the name of the datasource in the report. Replace
    'BindingSource1 with the binding source for the
    'dataset/datatable.


    rptDs = New Microsoft.Reporting.WinForms.ReportDataSource("datasetName_dataTable", BindingSource1)
    Me.ReportViewer1.LocalReport.DataSources.Add(rptDs)


    'Set the report parameters
    rptParam = New Microsoft.Reporting.WinForms.ReportParameter("ParameterName", "ParameterValue")

    paramList.Add(rptParam)


    Me.ReportViewer1.LocalReport.SetParameters(paramList)

    'Refresh the report
    Me.ReportViewer1.RefreshReport()


    I hope this helps.

  • Wolvenshade

    I'm finding the reporting control to be very frustrating to use.

    I don't want schema files, connection strings, and various other supports files strewn all over my application (along with fill statements, update statements and so forth) just so that I can build a freakin' report. I want to be able to add a dataset to my local report and have it know what to do with it without tons of support files flying all over the place.

    In an attempt to make a tiered application I have a business object.dll that can return a dataset to any report that requests one - but to get the report ready to receive a dataset I have to attach it to XSD files that have all kinds of things going on in the background. Why cannot I just add datatables to my local report and have the report grab whatever datatable it wants to out of it's collection of datatables and display the data in the report

    With a DataDynamics active report I'd just create a dataset - pass the dataset to the report and the report could display it (in a disconnected way). I'm finding it frustrating that I've got to define an xsd file, add the xsd file to the reports datasources, and have all this extra stuff going on. Why cannot it be simplier than this


  • Mike36

    This is what I'm doing now, but I did not want to have to create the dataset at design time first. I wanted to add the fields I needed then add in the reportsource then run the report. I think this will be ok for now.

    Thank you for your help.



  • et381

    Hi,

    Assume u created a design time dataset called dsCompanyInfo.xsd. This by default resides in app_code folder or app_data folder. In this dataset, you/wizard would have created a method to "fill a table" / "return a table" using fill or get methods.

    Let us say you created a dataadapter inside this dataset for "Employee" table. So you'll have GetEmployeeData as a method in this dataadapter.
    As you mentioned, this method does not run and fetch the data unless called. So your application at runtime will not have any data on the screen or report. To get that working use code below which is given in VB.
    Dim daCMP as New dsCompanyInfoTableAdapters.EmployeeTableAdapter
    Dim Employees as dsCompanyInfo.EmployeeDataTable
    Dim Employee as dsCompanyInfo.EmployeeRow
    Employees = daCMP.GetEmployeeData()
    for each Employee in Employee
    msgbox Employee("Employee Name") & " gets a bonus this month."
    next
    Good luck
    RV

  • Surya Suluh

    For anyone trying to do this with webforms I got this to work to set the datasource programmatically. Although still reliant on designing the report with a xsd reference for now.
    C#:
    protected void Page_Init(object sender, EventArgs e)
    {
    MySql.Data.MySqlClient.MySqlConnection myCon = new MySql.Data.MySqlClient.MySqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
    MySql.Data.MySqlClient.MySqlDataAdapter da = new MySql.Data.MySqlClient.MySqlDataAdapter(<Your sqlstring goes here>, myCon);
    DataTable dt = new DataTable();
    dt.BeginLoadData();
    da.Fill(dt);
    dt.EndLoadData();

    ReportDataSource rpds = new ReportDataSource();
    rpds.Name = "<the exact name used in your report.rdlc datasource>";
    rpds.Value = dt;
    rpvTimeEntry.LocalReport.DataSources.Clear();
    rpvTimeEntry.LocalReport.DataSources.Add(rpds);
    rpvTimeEntry.LocalReport.ReportPath = "reports\\report.rdlc";
    }

  • Local Report - Adding Datasources Programmatically