Crystal Report : How to use Hyperlink for desktop Base program - c#

I am using Crystal Report with C#.
For Desktop.
I want to hyperlink to another report with some parameter.
eg. I show Invoice's Summary (invoice.rpt) like its number (named InvNo), date, items and TotalAmount.
If i click InvNo "0001", then it will passing the InvNo to Item's Summary (item.rpt)
Is it possible?
IF possible, i think it will need some code in crystal report formula, please give me the formula example too.

At first, I thought the answer was 'not possible', but after some experimentation I got farther than I expected.
I created two reports based on the Xtreme.mdb file, named customers.rpt and order.rpt.
The customer.rpt has two columns: Customer Name and Order ID. The order.rpt has three columns: Order ID, Order Date, and Order Amount.
The goal: if I click on the Order ID field in the customers report it opens the order report and generates it for that Order ID.
I added the following to the condition formula associated with the Order ID's Hyperlink:
"file:///C:/Documents and Settings/Administrator/Desktop/order.rpt " + ToText({Orders.Order ID},"#")
When I click on the link, I get the following dialog:
Unfortunately, Crystal Reports' EXE doesn't support command-line arguments, so the action fails:
To get this to work, you would need to create an application that can process the command-line arguments for Crystal Reports. It would have the following characteristics:
packaged as an EXE
'wrap' the Crystal Report Viewer control (you probably don't need any 'design' functionality)
handle database authentication
most importantly, it needs to support command-line arguments. in this regard, you could probably model your argument list on BusinessObjecs's URL Reporting.

Related

Sorting by FormulaField in Crystal Reports

I've begun the task of bringing our CR to the 21st century. The templates were created more than 10 years ago, as well as the report generator application written in Visual Basic that allows a user to pick different options before they click a button for generating a report.
So far the process hasn't been too bad but I've stumbled upon something that I can't figure out.
In VB, there's a line of code that sorts the report by a database table field:
Report.RecordSortFields.Add Report.Database.Tables(1).fields.GetItemByName("Name"), crAscendingOrder
I've successfully got that same logic working using the lines below
DatabaseFieldDefinition databaseFieldDefinition = Report.Database.Tables["Bureau"].Fields["Name"];
SortField sortField = Report.DataDefinition.SortFields[0];
sortField.Field = databaseFieldDefinition;
sortField.SortDirection = SortDirection.AscendingOrder;
The other type of sorting is what I'm struggling with. The problem is if that DataDefinition only contains a single SortField using a database tables field, I can't seem to make it order using a formula field. If you iterate through the formula fields you can see multiple fields like #Name, #XX, however if you look in the sort field it looks like it's specifying just a table like 'Assets.Name'
In the original code, this was done simply using the this VB line of code:
Report.RecordSortFields.Add Report.FormulaFields.GetItemByName("AssetName"), crAscendingOrder
For report files that already have a sort field with an #XXX, it works because I'm just replacing the SortField with this new FormulaDefinition that I've got from the below code (that also uses the #XXX), however if the sort field is only using a 'Table.Field' it doesn't work
Report.DataDefinition.FormulaFields["AssetName"];
My obvious first guess is that I need to modify the report file to get this working, however the report files are still allowing sorting via formulafield even in our old VB app, meaning if they could do it back 10+ years ago in vb I should be able to do it in C# without modifying the report.

How to remove Database fields from Crystal report programmatically [duplicate]

I have a section in a Crystal Report that I want to suppress. I need to suppress it if there are 0 rows in a particular table in the dataset I am using. How would I do this? The Record Number special field provided appears to be an internal count of records in the report, and does not relate to the rows in the underlying data table.
I am creating the report from C#, but I cannot suppress the section from the code (it doesn't fit the project structure) - I must be able to do it from the report itself. The table concerned is definitely being passed to the report in the dataset, but it contains 0 rows. There must be a way to establish this inside the report itself.....
Can anyone please point me in the right direction?
In the Crystal Reports designer, view the properties of your section and there should be an option to Suppress, which you can give it a formula to return the appropriate boolean value.
You could then use the Count() function within that formula and (I believe) you can pass the name of your dataset to the Count() function to get the number of rows in that dataset.
I did the same thing on a complex report about 3 months ago but I don't have access to the report any more having changed jobs so I'm sorry I cannot be more specific, but hoepfully this gives you a starting point.
Just had a quick Google - try this.
If the section does only contain database fields and f.e. no text fields, then you could use the setting "Suppress Blank Section" in the "Section Export" (rightclick section) for that section.
As an alternative you could use the following formula in the "Suppress" in the "Section Export" for that section:
IsNull({table.field})
"{table.field}" is one of the fields in the dataset.
Hope this helps.
Go to "Section Expert" and click "Supress (No Drill-Down)" and try adding this:
IF {"DragYourFieldHere"} = "" then true else false
Create one dummy group,check on its header for each page,add the header in the group header of the dummy group.

SSRS reports in multi culture language

I have MS Report server with a RDL file showing a nice report in English language. I have a web application with a report viewer to show this report within side a ASPX page.
The problem i have is I want to show same report in multiple languages?? How would I do it??
1) Store the localisation text in a database
2) Select the localised version of the text in a second dataset.
3) Set up a parameter for the user to select the language.
4) Use lookup functions to include the text in the report.
Useful if you want to apply the localisation system to many reports.
1) Add custom function to the custom code (Report Properties, Code) that accepts 'Section_Name' and 'Language' variables (e.g. "ReportName, French") and returns the localised text e.g.:
function Localise(Section as String) as string
if Report.Parameters!Language.Value = 1 then
select Section
case "Report_Name"
Localise = "Report Name in English"
case "Report_Description"
Localise = "Report Description in English"
end select
elseif Report.Parameters!Language.Value = 2 then
select Section
case "Report_Name"
Localise = "Report Name in French"
case "Report_Description"
Localise = "Report Description in French"
end select
end if
end function
2) Add a parameter for the user to select the language (in this example using integers as values)
3) Reference the code in the report textboxes as required, e.g.:
=code.localise("Report_Name")
This will be fairly quick to implement and maintain over a single report
Create one report per language and allow the user to choose the language by selecting a different report.
This will be quickest to implement but may make maintenance of the report difficult.

How to create report (RDLC) without database?

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.

How do Microsoft reports (RDL) query the data?

I am not creating RDL from scratch so maybe this is a problem -- I work on already prepared files.
MSDN states that CommandText in RDL file can contain T-SQL query. Ok, this I understand, but what else it can contains?
I am asking because the phrasing clearly indicates you can put some other expression there
So if I understand correctly, I can look at RDL code (in Visual Studio, RMB on RDL file, "view code") and the interesting parts would be...?
DataSourceName -- this is a "link" to database via definitions of data sources
CommandText -- I thought this is the place to put query, like SELECT... but from what I see there are no queries used
Reporting service, loads the rdl file into it, and starts parsing and reading the command according to their sections like
data source, report params, etc.
gets the values of params (if any). start using the data source database connection. execute the query/ sp command. get the data, and store in seperate data fields which are also mentioned in rdl. binds their values with controls (text box, grid columns etc), if there is any expression written into it, execute them as well.
Generate the output (html/ pdf).
And there you Go.
I just tried to explain in short and simple words. you can check out msdn for complete detail.
Regards,
Mazhar Karimi
You can create reports manually and fill them with any data that you would like to.
Sth like:
ReportDataSource reportDataSource = new ReportDataSource();
reportViewer.Reset();
reportDataSource.Name = "DataSetOdczyty_klienci_adresy";
reportDataSource.Value = klienciadresyBindingSource;
reportViewer.LocalReport.DataSources.Add(reportDataSource);
reportViewer.LocalReport.ReportEmbeddedResource = "Wodociagi.Reports.ReportListaKlientow.rdlc";
You can open the report file *.rdl with an XML editor like Notepad++. Then, search for <DataSets> and you will find the datasets used in the report.
The field names of each data set are in the <Fields> section
In the <Query> section of each data set you can find <CommandText> and <QueryParameters> as shown in the example below
Example:
<Query>
<DataSourceName>MyDataSource</DataSourceName>
<CommandType>StoredProcedure</CommandType>
<CommandText>usp_QueryCustomers</CommandText>
<QueryParameters>
<QueryParameter Name="#CustomerId">
<Value>=Parameters!PersSysId.Value</Value>
</QueryParameter>
<QueryParameter Name="#RowsCnt">
<Value>=Parameters!RowsCnt.Value</Value>
</QueryParameter>
</QueryParameters>
</Query>
I didn't find a way to see that in Visual Studio's report editor easily. Maybe the bounty I have started helps here (does someone like to earn the 50 reputation points)?
Initially, I was not sure why both the OP and #Matt are reading the XML directly instead of editing the query in Visual Studio (I only resort to that in extreme cases). But now I think you might have failed victims of the missing "Report Data" pane.
Open the report in Visual Studio BIDS like normally, then from View menu select "Report Data". If it's not there, click on the report canvas anywhere, then it should appear. In the "Report Data" pane that will appear, you're interested in Data Sources (where's the data coming from?) and Datasets (what are the queries, parameters, expressions?).

Categories