AR17 - Page Report - Programmatically Add DataSource

Posted by: mlocke on 24 April 2023, 8:07 am EST

    • Post Options:
    • Link

    Posted 24 April 2023, 8:07 am EST

    I have a page report that I am programmatically adding a table to. The datasource for this table is built in the code, it’s a list of objects. I have tried converting my list of objects into a generic System.Data.DataTable added to a System.Data.DataSet but I cannot figure out how to set that as the datasource for the report.

    I found code for using a query and SQL and create a datasource and dataset from that. https://www.grapecity.com/blogs/how-to-programmatically-bind-data-in-rdl-page-report-using-net

    But that doesn’t work for me because my dataset actually has to be manually compiled because the columns count/names are variable and built around a number of inputs from the user on a webform.

    I found this: https://www.grapecity.com/activereportsnet/docs/versions/v15/online/bind-page-reports-to-a-datasource.html

    Which talks about using an ArrayList that uses a static class Dog. I cannot do this either as the number of columns for my table is variable as are the column names, so I cannot create a class called MyObject.

    Is there anyway to bind a System.Data.DataTable or System.Data.DataSet as the report datasource? If not, how can I use my data that has variable column names (and number of columns) as the Report DataSource? I have already created my table with a header row and detail row so this is just the last step to get data to actually show up.

    Example of columns I’m working with:

    Print (boolean)

    Client Type (string)

    Report Type (string)

    Name (string)

    Amount (decimal)

    Percent (decimal)

    Column with dynamic Name (decimal) * there can be any number of these columns with no preset names

    Thanks!

  • Posted 24 April 2023, 8:49 pm EST

    Hi Melissa,

    Yes, you can assign a DataTable with variable numbers of columns as the DataSource to your PageReport. However, within the Report’s DataSet, you’ll also need to add the required fields (column name) for each column to be able to access that column’s data in your report.

    Please find attached a sample implementing your requirements.

    Regards,

    Anand

    DataTableDataSource.zip

  • Posted 25 April 2023, 6:35 am EST - Updated 25 April 2023, 6:40 am EST

    I think I must be missing a step on utilizing the dataset. I have a report that has a top section that consists of a bunch of text fields. It has a datasource (called MyDataSource) and dataset that is hooked up to a query. Then in code I am building a table and adding it to this report. This table will have display the data from the datatable dataset.

    From a web page, a user will select a report to generate and it will export the report to a PDF without displaying the report in a viewer or anything. I have it working, except the data is not populating from the datatable dataset.

    This is my code to create the table in the code. I create a table, then create my header row. Then I create the details row. The textbox or checkbox values in my detail row come across as “=Fields!Print.Value”, “=Fields!CompType.Value”, etc.

                //Create a Table
                    Table table = new Table();
                    table.Name = "tblCompensationDetails";
                    //create header row
                    TableRow trHeader = new TableRow();
                    trHeader.Height = "1.25cm";
                    table.Height += "1.25cm";
                    table.Width = (totalWidth <= 8 ) ? "8in" : "11in";
    
                    TextBox tb = new TextBox();
                    TableCell tc = new TableCell();
                    TableColumn tcol = new TableColumn();
    
                    //Loop over header values to build header row
                    for (int i = 0; i < headerDetails.Count; i++)
                    {
                        //build a textbox holding the header string
                        HeaderProperty hp = properties.Where(p => p.Name == headerDetails[i].ColumnName).ToList()[0];
    
                        tb = new TextBox();
                        tb.Name = "txtHeader" + headerDetails[i].ColumnName.Replace(" ", "").Replace("-", "");
                        tb.Value = headerDetails[i].ColumnName;
                        tb.Style.PaddingBottom = tb.Style.PaddingLeft = tb.Style.PaddingRight = tb.Style.PaddingTop = ExpressionInfo.FromString("2pt");
                        tb.Style.TextAlign = ExpressionInfo.FromString("Left");
                        tb.Style.VerticalAlign = ExpressionInfo.FromString("Middle");
                        tb.Style.FontSize = ExpressionInfo.FromString("7pt");
                        tb.Style.FontWeight = ExpressionInfo.FromString(hp.FontWeight);
                        tb.Style.WrapMode = ExpressionInfo.FromString("WordWrap");
                        tc = new TableCell();
                        tc.ReportItems.Add(tb);
                        tc.ReportItems[0].Style.BackgroundColor = ExpressionInfo.FromString(_headerFooterColor);
    
                        tcol = new TableColumn();
                        tcol.Width = hp.Width;
                        tcol.FixedHeader = true;
                        table.TableColumns.Add(tcol);
                        trHeader.TableCells.Add(tc);
                    }
    
                    table.Header.TableRows.Add(trHeader);
    
                    //loop over 1 data row create the detail data row object for the table
                        TableRow trData = new TableRow();
    
                        foreach (MFSRecordDetailGrid obj in tableRowData[1])
                        {
                            //build a textbox holding text
                            HeaderProperty hp = properties.Where(p => p.Name == obj.ColumnName).ToList()[0];
                            tc = new TableCell();
                            switch (hp.ColumnType)
                            {
                                case "CheckBox":
                                    GrapeCity.ActiveReports.PageReportModel.CheckBox cb = new GrapeCity.ActiveReports.PageReportModel.CheckBox();
                                    cb.Name = "chk" + obj.ColumnName.Replace(" ", "").Replace("-","") + obj.RowNumber;
                                    cb.Checked = ExpressionInfo.FromString("=Fields!" + obj.ColumnName.Replace(" ", "").Replace("-", "") +".Value");
                                    cb.Style.PaddingBottom = cb.Style.PaddingLeft = cb.Style.PaddingRight = cb.Style.PaddingTop = ExpressionInfo.FromString("2pt");
                                    //tb.Style.TextAlign = ExpressionInfo.FromString("Left");
                                    cb.Style.VerticalAlign = ExpressionInfo.FromString("Middle");
                                    cb.Style.FontSize = ExpressionInfo.FromString("7pt");
                                    tc.ReportItems.Add(cb);
                                    break;
                                case "TextBox":
                                    tb = new TextBox();
                                    tb.Name = "txt" + obj.ColumnName.Replace(" ", "").Replace("-", "") + obj.RowNumber;
                                    tb.Value = "=Fields!" + obj.ColumnName.Replace(" ", "").Replace("-", "") + ".Value";
                                    tb.Style.PaddingBottom = tb.Style.PaddingLeft = tb.Style.PaddingRight = tb.Style.PaddingTop = ExpressionInfo.FromString("2pt");
                                    tb.Style.TextAlign = ExpressionInfo.FromString("Left");
                                    tb.Style.VerticalAlign = ExpressionInfo.FromString("Middle");
                                    tb.Style.FontSize = ExpressionInfo.FromString("7pt");
                                    tb.Style.WrapMode = ExpressionInfo.FromString("WordWrap");
                                    tb.Style.Color = ExpressionInfo.FromString((obj.IsProgramDefaultRow.GetValueOrDefault()) ? _programDefaultColor : "#000000");
                                    tc.ReportItems.Add(tb);
                                    break;
                            }
    
                            tc.ReportItems[0].Style.BackgroundColor = ExpressionInfo.FromString("=IIF(RowNumber() Mod 2 = 0, \"#E5E5E6\", \"#cececf\")");
    
                            trData.TableCells.Add(tc);
                        }
                        table.Details.TableRows.Add(trData);
           
                    //Position the table on the page - the top needs to be far enough down on the page it does not cover the top section of the report;
                    table.Top = (table.Width == "11in") ? "7cm" : "3.6in";
                    table.Left = "0.0in";
                    table.DataSetName = "CustomDataSet";
                    //add report to page
                    //pageReport.Report.Body.ReportItems.Add(table);
                    pageReport.Report.ReportSections[0].Body.ReportItems.Add(table);
                    //create a generic datasource and add fields to our report
                    CreateReportDataSource(pageReport, headerDetails);
                    BuildDataTable(tableRowData, headerDetails);
    
                    pageReport.Document.LocateDataSource += Document_LocateDataSource;
                    pageReport.Run();
    
                           // Provide settings for your rendering output.
                    GrapeCity.ActiveReports.Export.Pdf.Page.Settings pdfSetting = new GrapeCity.ActiveReports.Export.Pdf.Page.Settings();
    
                    // Set the rendering extension and render the report.
                    GrapeCity.ActiveReports.Export.Pdf.Page.PdfRenderingExtension pdfRenderingExtension = new
                            GrapeCity.ActiveReports.Export.Pdf.Page.PdfRenderingExtension();
                    System.IO.DirectoryInfo outputDirectory = new System.IO.DirectoryInfo(@"C:\MyPDF");
                    outputDirectory.Create();
                    GrapeCity.ActiveReports.Rendering.IO.FileStreamProvider outputProvider = new GrapeCity.ActiveReports.Rendering.IO.FileStreamProvider(outputDirectory,
                            System.IO.Path.GetFileNameWithoutExtension(fileName));
    
                    // Overwrite output file if it already exists
                    outputProvider.OverwriteOutputFile = true;
    
                    pageReport.Document.Render(pdfRenderingExtension, outputProvider, pdfSetting);

    Here is my code using your information from this ticket to create my datatable dataset.

    
      private void CreateReportDataSource(PageReport report, List<MFSRecordDetailGrid> headerDetails)
            {
                // Creating our report DataSource and choosing the DataProvider as Dataset provider
                DataSource ds = new DataSource() { ConnectionProperties = new ConnectionProperties() { DataProvider = "DATASET" }, Name = "DataSource1" };
    
                // Creating a dataset for our report
                GrapeCity.ActiveReports.PageReportModel.DataSet dataSet = new GrapeCity.ActiveReports.PageReportModel.DataSet() { Name = "CustomDataSet", Query = new Query() { DataSourceName = "DataSource1" } };
    
                // Adding all the required fields to the dataset to be able to use within report's controls.
                foreach (MFSRecordDetailGrid item in headerDetails)
                {
                    dataSet.Fields.Add(new Field() { Name = item.ColumnName.Replace(" ", "").Replace("-",""), DataField = item.ColumnName.Replace(" ", "").Replace("-", "") });
                }
               
                // Adding the DataSource and DataSet to our report.
                report.Report.DataSources.Add(ds);
                report.Report.DataSets.Add(dataSet);
            }
    
            private void BuildDataTable(Dictionary<int, List<MFSRecordDetailGrid>> tableRowData, List<MFSRecordDetailGrid> headerDetails)
            {
                // Create a new DataTable.
                System.Data.DataTable dt = new System.Data.DataTable("CompensationDetails");
                System.Data.DataColumn dtColumn;
                foreach (MFSRecordDetailGrid item in headerDetails)
                {
                    dtColumn = new System.Data.DataColumn();
                    switch (item.SavedValueType)
                    {
                        case "INT":
                            dtColumn.DataType = typeof(Int32);
                            break;
                        case "VARCHAR":
                            dtColumn.DataType = typeof(String);
                            break;
                        case "MONEY":
                            dtColumn.DataType = typeof(Decimal);
                            break;
                    }
    
                    dtColumn.ColumnName = item.ColumnName.Replace(" ", "").Replace("-", "");
                    dtColumn.Caption = item.ColumnName;
                    dtColumn.ReadOnly = true;
                    dtColumn.Unique = false;
                    dt.Columns.Add(dtColumn);
                }
                _ds.Tables.Add(dt);
    
                for (int i = 1; i < tableRowData.Keys.Count; i++)
                {
                    System.Data.DataRow newRow;
                    newRow = _ds.Tables[0].NewRow();
                    for (int n = 0; n < tableRowData[i].Count; n++)
                    {
                        switch (tableRowData[i][n].SavedValueType)
                        {
                            case "VARCHAR":
                                newRow[tableRowData[i][n].ColumnName.Replace(" ","").Replace("-", "")] = tableRowData[i][n].SavedValueVarChar;
                                break;
                            case "MONEY":
                                newRow[tableRowData[i][n].ColumnName.Replace(" ", "").Replace("-", "")] = tableRowData[i][n].SavedValueMoney;
                                break;
                            case "INT":
                                newRow[tableRowData[i][n].ColumnName.Replace(" ", "").Replace("-", "")] = (tableRowData[i][n].SavedValueInt == 1) ? true : false;
                                break;
                        }
                        
                    }
                    _ds.Tables[0].Rows.Add(newRow);
                  
                }
            }
    
            void Document_LocateDataSource(object sender, GrapeCity.ActiveReports.LocateDataSourceEventArgs args)
            {
                args.Data = _ds;
            }
    

    My generated PDF looks like this even though there are 10 rows of data in the dataset.table[0].

    The first screenshot shows my dataset’s fields. The second shows my report PDF. I had to blank out the top data except the date because it’s sensitive and the top part is populating appropriately from my first datasource that is connected to a Stored Procedure. The Header Row is populating, but the data rows are missing in my table.

  • Posted 25 April 2023, 7:31 am EST - Updated 25 April 2023, 7:36 am EST

    Wanted to add what the _ds looks like in the LocateDataSource code:

  • Posted 26 April 2023, 2:45 pm EST

    Hi Melissa,

    It looks like you are trying to assign a DataSet to the ‘args.Data’ property. Instead, you’ll need to assign your DataTable to the ‘args.Data’ property, so the code should look something like:

    args.Data = _ds.Tables[0];
    

    We tried to create a sample using the code you provided. However, unfortunately, we were not able to run the same due to missing variables/classes.

    If the issue persists could you please try sharing a stripped-down runnable sample with dummy data replicating this issue or modify our attached sample such that it replicates the issue so we could further investigate the same?

    Regards,

    Anand

    DataTableDataSource.zip

  • Posted 27 April 2023, 7:29 am EST - Updated 27 April 2023, 7:37 am EST

    Hello!

    I have attached the sample project. I swapped out custom objects for a generic custom object and I created my own dataset instead of doing calls to the database to get data. Even with the recommend change of using _ds.Tables[0], the header prints but the table details do not.

    Notable things:

    1. The project folder is in a folder on my C called “My Dev” so you’ll need to either use that or update line 53 to utilize the correct location of wherever you put this.
    2. The save directory is a folder on C called “My PDF”.

    Sample Project (2).zip

  • Posted 27 April 2023, 7:35 am EST - Updated 27 April 2023, 7:41 am EST

    Here’s what I’m getting from this sample project.

  • Posted 30 April 2023, 3:05 pm EST

    Hi Melissa,

    We were able to replicate the issue on our end, and are debugging the cause for the same.

    Due to the complex nature of the sample, the ETA for a resolution is 24-48 hours.

    Thanks for your patience.

    Regards,

    Anand

  • Posted 1 May 2023, 4:04 pm EST

    Hi Melissa,

    In your sample, we could observe that you have not specified any height for your ‘trData’ row due to which it takes ‘0in’ as its height by default and therefore does not appear to render any row in the report preview.

    Updating the code to specify a height to ‘trData’ as

    trData.Height = "0.7cm";
    fixes the issue.

    Please find attached the updated sample for the same.

    Regards,

    Anand

    Sample Project Updated.zip

  • Posted 11 May 2023, 5:43 am EST

    Thank you!

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels