Greetings.
I have a parameter field in my crystal report called job. When i'm calling this report from web page, it prompts me for an input value ("Job1" or "Job2"). After i choose one, it displays in report. But when i try to export report to MS Word with
crystalReport.ExportToDisk(ExportFormatType.WordForWindows, "C:\\foo.doc");
i'm getting "Parameter value is missing" exception.
If i'm setting value manually with
crystalReport.SetParameterValue("job", value);
everything works fine, but i don't need to set a value manually. I want to use a value, chosen in crystal report prompt.
How can this be done?
Are you using a webform or a winform?
If you are using a webform make sure that you initialize ,load, set parameter of the reports on each postback.
private void ShowReport_click()
{
..do initializing,loading,provide logoninfo for data access, provide parameters
... show report
}
private void buttonExport_click()
{
ShowReport_click();
...Your Export Logic goes here
}
same can be applied to winforms too.
Related
We have a custom built application, based on silverlight, which manages our report subscriptions. The problem is that whenever you add a new subscription, it sets the Locale value in the Subscriptions table to 'en-US'.
When you create subscriptions directly in Report Manager, the value in the Locale field is determined by your browser language settings (this is exactly what we want to achieve).
We can't find a way to set the Locale field before we call the CreateSubscription method as it doesn't seem to accept the Locale parameter and it defaults to en-US (which I believe is a server setting).
Do you know of any way to set Locale when creating subscriptions in SSRS?
As far as I can see there is no way to do this; I've been using the service via C#.
I decided upon a solution of obtaining the language/locale of the report via the service, and then making the changes directly in the ReportServer database, as an UPDATE statement on the SubscriptionID.
To get the language/locale of the report I use something like:
private static void Main()
{
ReportingService2010 service = new ReportingService2010();
service.Url = "URL of service";
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
string reportItemPath = "Path of report";
string language = GetReportPropertyValue(service, reportItemPath, "Language", "en-GB");
// Create the subscription, then update the database using the returned SubscriptionID.
}
private static string GetReportPropertyValue(ReportingService2010 service, string itemPath, string propertyName, string defaultValue)
{
Property[] properties = service.GetProperties(itemPath, null);
if (properties.Any(p => p.Name == propertyName))
return properties.First(p => p.Name == propertyName).Value;
else
return defaultValue;
}
I haven't tried it via the SOAP API yet, but shouldn't it be possible to set the Accept-Language header?
I'm doing this when rendering reports in different languages. The language of each report is set to =User!Language.
When using WCF to access the reporting service, you can do (example as VB.NET)
Using oReportingService As New ReportingService2010SoapClient
oReportingService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation
Using oScope As OperationContextScope = New OperationContextScope(oReportingService.InnerChannel)
If i_oSubscription.Language IsNot Nothing Then
' Accept-Language
Dim oHttpRequestProperty As New HttpRequestMessageProperty
oHttpRequestProperty.Headers.Add(HttpRequestHeader.AcceptLanguage, i_oSubscription.Language)
OperationContext.Current.OutgoingMessageProperties(HttpRequestMessageProperty.Name) = oHttpRequestProperty
End If
oReportingService.CreateSubscription(New ReportingService2010.TrustedUserHeader(), i_oSubscription.Path, oExtensionSettings, i_oSubscription.Description, "TimedSubscription", sMatchData, lstParameters.ToArray(), sSubscriptionId)
Return sSubscriptionId
End Using
End Using
Edit: This is the way I'm doing it myself and it seems to work :)
i_oSubscription is just a simple container with properties like Description
Note: this seems to work for the most part. However, the "Days" field in a MonthlyRecurrence is to be formatted locale-dependent (see: https://stackoverflow.com/questions/16011008/ssrs-monthlyrecurrence-formatting-for-different-languages)
Ok so I made some changes and got somewhere. However the issue is still their. I figured out that when the main report is generated the Hyperlinks are not added to some of the fields. However when we re-run the report again with the same parameter (we have a link that re-runs the report only changing the year parameter) those fields now have links. This is very weird. For an example I run the report for 2012 press the link to go back to 2011 and then press the link to go forward to 2012 the links now work in 2012.
Do you only assign the 'ReportDocument' object to the CrystalReportViewer on the first page load? You should try storing your report document in session and ensure that on postbacks the CrystalReportViewer control's 'ReportSource' property is set again.
if (!IsPostBack)
{
// do a bunch of Crystal Report's loading stuff
ReportDocument yourReportDocument = new ReportDocument();
// etc, etc.
// store the report document in server memory
yourViewerControl.ReportSource = yourReportDocument;
Session["theReportDocument"] = yourReportDocument;
}
else
{
yourViewerControl.ReportSource = Session["theReportDocument"];
yourViewerControl.Show();
}
I have a site of about 60 tabular report pages. Want to convert this to Zend. The report has two states: empty report and filled in with data report. Each report has its own set of input boxes and select drop downs to narrow down searches. You click on submit and it retrieves the data. Thats all each page does.
Do I create 60 controllers with each one with default index action and getData action? All I have read online do not really describe how to architect a real site.
If the method of fetching and retrieving data is pretty similar as you mention between all 60 reports. It would seem silly to create 60 controllers (+PHP files).
It seems that you are trying to solve this problem with the default rewrite router. You can add a route to the router that will automatically store your report name, and you can abstract and delegate the logic off to some report-runner-business-object-thingy.
$router = $ctrl->getRouter(); // returns a rewrite router by default
$router->addRoute(
'reports',
new Zend_Controller_Router_Route('reports/:report_name/:action',
array('controller' => 'reports',
'action' => 'view'))
);
And then something like this in your controller...
public function viewAction() {
$report = $this->getRequest()->getParam("report_name");
// ... check to see if report name is valid
// ... stuff to set up for viewing report...
}
public function runAction() {
$report = $this->getRequest()->getParam("report_name");
// ... check to see if report name is valid
// Go ahead and pass the array of request params, as your report might need them
$reportRunner = new CustomReportRunner( $report, $this->getRequest()->getParams() );
$reportRunner->run();
}
You get the point; hope this helps!
How do I call a stored procedure from Jasper Report?
The JasperReports Ultimate Guide contains this information about using store procedure:
Certain conditions must be met to put stored procedure calls in the SQL query string of a report template:
The stored procedure must return a java.sql.ResultSet when called through JDBC.
The stored procedure cannot have OUT parameters.
Below are the steps to call a stored procedure to build a report using iReport 4.5/4.5.1 JasperReport and using Oracle Express database.... hope this helps....
1.In your iReport designer go to Tools --> Options --> and in the Classpath Tab click Add JAR and add the OJDBC14.jar to the classpath.
2.Go to Query Executer tab and set the following Language: plsql Query Executer Factory: com.jaspersoft.jrx.query.PlSqlQueryExecuterFactory Fields Provider Class: com.jaspersoft.ireport.designer.data.fieldsproviders.SQLFieldsProvider
3.Select Database JDBC Connection
4.Select Oracle as the JDBC Driver as shown in the image below and verify the connection by clicking the Test button (Make sure you check the Save Password check box)
5.Create a blank report by giving a report name and save it.
6.Open the report in the designer and right click on the report name and click on Edit Query
7.Set the query language to plsql
8.Call your procedure with in { }
{call PUBLISHER_AND_BOOKS(&P(P_PUBLISHER_ID), &P(ORACLE_REF_CURSOR))}
Note: P_PUBLISHER_ID is of type string and ORACLE_REF_CURSOR is of type java.sql.ResultSet data type custom parameter. You can create this by clicking the New Parameter button. If you have more input parameters use ‘,’ as your delimiter as shown in the above example.
9.Click Ok and proceed with the report design.
10.In the designer window right click on Fields and add click Add Fields and make sure all the field name matches the column name in your stored procedure
11.Now right click on the parameters and add the parameters matching the stored procedure NOTE: make sure you uncheck the "Use for Prompt" in the property for your out parameter in our example its ORACLE_REF_CURSOR is the out parameter.
12.Drag and drop the fields in the report detail band as shown below
13.Click preview to run the report you will be prompted with the input parameter
All the steps are captured in detail with images and available in the below link hope this helps...
http://meezageekyside.blogspot.com/#!/2012/04/jasper-reports-ireport-45-using-oracle.html
<queryString>
<![CDATA[Call procedure_name ($P{parm1},$P{parm2},"$P!{parm3}","$P!{parm4}","$P!{parm5}",$P{parm6},$P{parm7});]]>
</queryString>
With MySQL You can call the stored procedure just like you call any other query, using the queryString.
Here is how i tackled the issue, you can easily do this by using a JR scriptlet (java bean).
Below is the sample java code and once you have the jar file add it to the jasper report
classpath and reference the same on your report properties.
-- Please make sure you use identicle names as given in your report when accessing variable/parameter
values and in setting Variable values (you can't set parameter values, just the vaiables)
package com.scriptlets;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRScriptletException;
public class Icdf extends JRDefaultScriptlet {
public void afterReportInit() throws JRScriptletException {
// get the current connection from report via parameters
Connection conn = (Connection) this
.getParameterValue("REPORT_CONNECTION");
int userId = 100; //use this.get__ to access from report
try {
if (conn != null)
callOracleStoredProcOUTParameter(conn, userId); // SP call
} catch (SQLException e) {
e.printStackTrace();
}
}
private void callOracleStoredProcOUTParameter(Connection conn, int userId)
throws SQLException {
CallableStatement callableStatement = null;
String getDBUSERByUserIdSql = "{call someStoredProcedureName(?,?,?)}";
try {
callableStatement = conn.prepareCall(getDBUSERByUserIdSql);
// setting parameters of the callablestatement
callableStatement.setInt(1, userId);
callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(3, java.sql.Types.DATE);
// execute getDBUSERByUserId store procedure
callableStatement.executeUpdate();
// get the required OUT parameters from the callablestatement
String userName = callableStatement.getString(2);
Date createdDate = callableStatement.getDate(3);
// --just to check, you can view this on iReport console
System.out.println("UserName : " + userName + "CreatedDate : " + createdDate);
// set the values to report variables so that you can use them in
// the report
this.setVariableValue("variable_name1", userName);
this.setVariableValue("variable_name2", createdDate);
} catch (SQLException e) {
e.printStackTrace();
} catch (JRScriptletException e) {
e.printStackTrace();
}
}
}
very easy:
1. At tab outline. Right click to file jasper --> select Dataset & Query ...
2. Select DB, language plsql, & call with query follow
Exp:
{call packageName.procedureName( $P{a}, $P{b}, $P{c}, $P{d}) }
Good luck!
JasperReport doesn't support calling stored procedure/function directly from his SQL datasource. The best way I found to overcome that limitation is to create a Java bean that calls the stored procedure (via JDBC or Hibernate) and returns a collection of objects which represent the result set. If you're using iReport, just change the Data Source Expression to use that Java bean. There's good section on data sources in the (not free) iReport manuals.
Two possibilities for calling a procedure from Jasper reports,
If your procedure returns some result set and if you would like to
use in the report, then you have to create a function, type and type
table (for holding the result set) for calling the procedure.
If the procedure does some DML operation, then you can call directly
(without a function)
In jasper studio(I'm using v5.5.1) you can call sp like this:
Select SQL as language
just Exec your sp and pass parameters to it
here is my sp that take to DateTime parameters and returns a set of result
EXEC dbo.SP_Report #p1=$P{date_from}, #p2=$P{date_to}
In jasper report using queryString we can call a procedure like this
example:
<![CDATA[{call PACKAGE.PROCEDURENAME($P{PARAM_NAME1},$P{PARAM_NAME2},$P{PARAM_NAME3},$P{PARAM_NAME4},$P{PARAM_NAME5},$P{PARAM_NAME6},$P{PARAM_NAME7},$P{OUT_PARAM_NAME8})}]]>
We can pass IN as well as OUT paramters and If you use cursor as out parameter and parameter class should be resultset(java.sql.ResultSet)
When using Business Objects' CrystalReportViewer control, how can you detect and manually print the report the user has currently drilled into? You can print this automatically using the Print() method of the CrystalReportViewer, but I want to be able to do a manual printing of this report.
It is possible to print the main ReportSource of the CrystalReportViewer, but I need to know what report the user has drilled into and then do a manual printing of that particular drill down. Any ideas?
I'm not sure which version of Crystal Reports you are using, but if it is XIR2 or earlier then this isn't possible. I haven't used the newer versions so I can't tell you. One thing that I've done to solve this in the past was to have the drill actually link to another report altogether. It depends on how your viewers actually view the reports (either via a thick-client viewer, the developer, or the web portal) on whether this will work however. Good luck!
detect: yes!
webpage:
<CR:CrystalReportViewer ...
ondrill="CrystalReportViewer1_Drill"
ondrilldownsubreport="CrystalReportViewer1_DrillDownSubreport" />
code behind:
protected void CrystalReportViewer1_Drill(object source, CrystalDecisions.Web.DrillEventArgs e)
{
//drill from graph to list of elements
}
protected void CrystalReportViewer1_DrillDownSubreport(object source, CrystalDecisions.Web.DrillSubreportEventArgs e)
{
//drill from main report to subreports
}
print current: no!
protected void CrystalReportViewer1_DrillDownSubreport(object source, CrystalDecisions.Web.DrillSubreportEventArgs e)
{
reportDocument.OpenSubreport(e.NewSubreportName).ExportToHttpResponse(format, Response, true, title);
}
exporting subreports throws an exception "not allowed for subreports".
solution
CrystalReportsViewer's button works also on drilldown...
<CR:CrystalReportViewer HasExportButton="true" ....