I'm having trouble coming up with a way to generate reports (either via xlsx or MS report viewer). The biggest issue is my dataset being dynamically created. Here's what I have:
One or more terminals periodically fill a cloud-hosted database with information about where the info is coming from, the global key and the value corresponding to the pair (origin, key).
So I end up with a table like:
TERMINAL_NO|GLOBAL_KEY|DECIMAL_VALUE
===========|==========|=============
123 |9876 |1.00
123 |9875 |0.50
123 |9872 |-4.00
234 |9876 |3.00
234 |9875 |5.45
234 |9872 |2.50
And I have made an app that transforms that into a DataSet with one column per TERMINAL_NO, and each row is every distinct GLOBAL_KEY, storing the corresponding DECIMAL_VALUES for each pair. However, that's the issue - I can't find a way to generate reports or xlsx files with dynamically created DataSets, as I understood both of them need typed DataSets to work with.
Is there an easier way to gather that data, or am I doing this wrong?
08-15-20 EDIT
As per #jdweng, I did try the method depicted there, but I can't make the reportViewer display the actual data. Currently I have the following:
ReportDataSource rds = new ReportDataSource("DataSetStock", LoadData());
//LoadData() returns a filled datatable.
RView.ProcessingMode = ProcessingMode.Local;
RView.LocalReport.DataSources.Clear();
RView.LocalReport.DataSources.Add(rds);
RView.LocalReport.ReportPath = "StockReport.rdlc";
RView.RefreshReport();
Yet, all I get is an empty reportviewer inside the winformshost control.
As per #nbk's suggestion, I went with a report generator code made by Nadir (https://www.codeproject.com/Tips/888174/Dynamically-Creating-an-RDLC-Report-Just-Using-a-D), by using the provided .cs files.
Just had to make a few changes on the xaml because I'm not using a logo image. I already had my dataset (just had to change the column names to be cls-compliant) and it worked flawlessly. I didn't have to use the userControl folder, as I'm working on WPF and already had a winforms host control with a reportviewer control on it.
I have used a dataset in many of my windows forms for datagrid. As you can see i have project level dataset created.
The problem is i would liek to resume that dataset inside code to assing source for crystal report as follow.
//sbmsDataSetAllis not recognized
ReportDocument cryRpt = new ReportDocument();
cryRpt.Load("rystalReport1.rpt");
cryRpt.SetDataSource(sbmsDataSetAll.Tables["recent_slide_dataset"].DataSet) ;
crystalReportViewer1.ReportSource = cryRpt;
crystalReportViewer1.Refresh();
OK, but you need to understand that these dataset items you see in the solution explorer are representing class types(things you can create) not object instances(things you have created) so you can only use object instances in your code
On the form where your dataset is created, with some code like
sbmsDataSetAll myDataset = new sbmsDatasetAll();
is where the instance of the dataset is. It is only on this form's code that you can link it to the report unless you have passed the dataset to another place via method parameters.
You should really pass one of the tables inside the dataset as the crystal report datasource, unless you already told crystal what table name to use (in design mode somewhere - I can't see it in your code). When you work with strongly typed datasets like these you don't need to use the .Tables collection. Every table in the set has a named property for the table:
cryRpt.SetDataSource(sbmsDataSetAll.recent_slide_dataset) ;
You also don't need to call a table's DataSet Property because that just points back to the dataset the table is in, which you already know when you chose the table:
cryRpt.SetDataSource(sbmsDataSetAll) ;
As another small critique, in c# we use PascalCase of object, property and method names, so your dataset entities should really be named like:
cryRpt.SetDataSource(SbmsDataSetAll.RecentSlides) ;
I'm trying to embed a local SSRS report into my MVC razor page for the very first time. I created a simple report to prove my concept, an .rdlc file. The report has a couple text boxes, logo and a couple tables.
With no tables and no datasets, I can get the report to run in the MVC view without issue. When I add the first dataset, the trouble begins as I cannot seem to come up with the correct way to pass data from my controller to the report.
Part of my problem, it seems ReportDataSource prefers an IEnumerable such as a list. In order to display a name and address at the top of the report, I don't need a list of objects, just one object, or a single database row. How can I pass this object as a datasource / dataset?
Here is my current controller code:
ReportViewer reportViewer = new ReportViewer();
reportViewer.ProcessingMode = ProcessingMode.Local;
reportViewer.LocalReport.ReportPath = Request.MapPath(Request.ApplicationPath) + #"Reports\AnnualFeeStatement_DRAFT.rdlc";
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", UserDAL.getMember("Simons", "12345", "1988")));
ViewBag.ReportViewer = reportViewer;
return View();
i try to custom on existing report to add some field name from Table ASMBTL (for example) into field list on existing report which have create and compile.
I know have to create an relation, i try different approach still fail due to i still new to C# and devexpress programming.
The Attachment of the image is what i try to learn and success by using C# coding and can extract any value from any table which not include inside the filed list of any original report. I try to learn this way so i would able to custom any existing report just using c# script anytime at anyplace.
Below is some code i learn from web and manage to add the tab "Assembly Custome Add On Table" inside the field list, but is not success to put it in under "Stock Assembly Master". I still can't understand how to add relation to proceed like the photo attachment result.
DataTable dtMyTable = GetCustomTableData();
dtMyTable.TableName = "Assembly Custome Add On Table";
AddCustomTable(ds, dtMyTable);
private void AddCustomTable(DataSet ds, DataTable dt) {
if (ds.Tables.Contains(dt.TableName) == false)
ds.Tables.Add(dt); }
private DataTable GetCustomTableData()
{Return __report.DBSetting.GetDataTable("Select DtlKey, DocKey, OrderQty" from ASMDTL", false);
This is what I try to accomplish
I have found the solution of my problem base on How to make relation between tables which are in same dataset? link had shown me the way to solution.
Problem
When you create a report (RDLC) the datasource seems to be only this or that database. Is there any way to convince VS to establish a link to memory data source? Something similar to WPF databinding.
The issue is, I would like to create a report with just a few data (entered by user), the whole point is layout, I don't have massive amount of data. So installing DB, writing data to DB, and then fetching them just to show the report is huge overkill.
So, I am looking for ability to create a report from memory data.
Background
I would like to design a layout, add images, set styles, font colors, etc. and add no more than few parameters like "first name", "last name" (of user) and "text". User would enter those 3 values, get a flyer and print it X times.
The layout has to be exact -- starting from paper size, the placement of images, size of fonts, etc.
Maybe there are better solutions than RDLC but it is built-in engine, and no matter how I search it always pops out in search results.
The datasource for an RDLC report can be anything that implements IEnumerable. If it is an enumeration of objects, then the properties on the object become fields in the report.
The thing about reports is they have their own internal notion of what the dataset is. At design time you need to provide the report designer with a dataset to work with. The report ingests that dataset internally and it is used to design the report. The reality is the report itself doesn't care about the actual dataset. It only cares about its schema. However, at runtime the objects you provide to satisfy that dataset can come from anywhere, as long as they satisfy that same schema.
I have a little blog post from back in my MS days that shows a trick on how to get good design time support, and then at runtime provide the report with any data you want:
http://blogs.msdn.com/b/magreer/archive/2008/10/16/setting-the-datasource-for-a-report-at-runtime.aspx
update Microsoft has since deleted my blog, but I found it in the wayback machine
https://web.archive.org/web/20160204041848/http://blogs.msdn.com/b/magreer/archive/2008/10/16/setting-the-datasource-for-a-report-at-runtime.aspx
I recently wrote a blog post on creating a reporting assembly and using it in a project. My reports accept a list of my classes as a datasource and dont read from the DB themselves.
If you have a look here:
http://wraithnath.blogspot.com/2011/02/visual-studio-2010-report-viewer-object.html
it should help. Basically you create a class library containing the datasources as VS 2010 has a real problem detecting object datasources. It works like 20% of the time which is why i decided to do it this way.
N
You can definitely bind to DataTables. Since you can create DataTables by hand, that's one way to do this without a database.
Here's an example where we programmatically load an RDLC control in order to render a PDF, using DataTables:
Dim Viewer As New ReportViewer
Viewer.LocalReport.ReportPath = "Physicians\Patients\OrderPlacement\DownloadRx\RxPdf.rdlc"
Me.LoadReport(orderID, Viewer)
Dim Renderer As New Code.Reporting.RenderToPDF
Renderer.Save(Viewer, FileFullPath)
And here are the contents of LoadReport:
Private Sub LoadReport(ByVal orderID As Integer, ByVal viewer As ReportViewer)
'This is adapted from here: http://www.codeproject.com/KB/reporting-services/RDLC_and_DataSet.aspx
'--Setup
viewer.LocalReport.DataSources.Clear()
viewer.LocalReport.EnableHyperlinks = True
'--Configure DataSources
Dim DocumentData As New RxDocumentData(orderID)
Me.SetupRxPdfDataSourceHeader(DocumentData, viewer)
Me.SetupRxPdfDataSourceMetrics(DocumentData, viewer)
Me.SetupRxPdfDataSourceOrderHeader(DocumentData, viewer)
Me.SetupRxPdfDataSourceOrderItems(DocumentData, viewer)
Me.SetupRxPdfDataSourceChainOfCustody(DocumentData, viewer)
Me.SetupRxPdfDataSourcePreTreatmentWorkupOrderTags(DocumentData, viewer)
Me.SetupRxPdfDataSourceTakeHomeMedicationsOrderTags(DocumentData, viewer)
viewer.LocalReport.Refresh()
End Sub
And here's one of those little configuration methods:
Private Sub SetupRxPdfDataSourceHeader(ByVal data As RxDocumentData, ByVal viewer As ReportViewer)
Dim Dset_Header As New ReportDataSource("Dset_Header", data.HeaderDataTable)
viewer.LocalReport.DataSources.Add(Dset_Header)
End Sub
data.HeaderDataTable is just a strongly typed DataTable that we create programmatically and put data into by hand.
There's nothing special about the DataTable, but getting to the point where this code was functional probably took a solid week. Hope this helps.
You can manually create a DataTable object, populate the Columns collection in there, then call NewRow(). Take the result of that and fill the fields, then pass it to Rows.Add(). That's what I've been doing (really don't like rdlc, it's so slow and clunky compared to html).
Return a list of your business objects and add it as the data source:
ReportViewer.LocalReport.DataSources.Add(new ReportDataSource("Report", new List<ReportDto> { new ReportDto(businessObj) }));
ReportDto is a wrapper for your business object where all formatting, concatenations and other report related modifications are done. It emits only the properties you need for the report.
Then go to add data set and pick the ReportDto's namespace as the data source and pick ReportDto as the dataset. Now all the properties you have included in ReportDto will be available in the designer.