Print Page | Close Window

Running Crystal Reports in a batch service

Printed From: Crystal Reports Book
Category: Crystal Reports .NET 2003
Forum Name: Data Connectivity
Forum Discription: How to connect to data sources and export reports
URL: http://www.crystalreportsbook.com/forum/forum_posts.asp?TID=589
Printed Date: 05 May 2024 at 7:18am


Topic: Running Crystal Reports in a batch service
Posted By: RichardP
Subject: Running Crystal Reports in a batch service
Date Posted: 26 Apr 2007 at 7:53am
I have set up a batch service to run a crystal report, as described on pages 381 - 384 of  Mr. Bischof's book"Crystal Reports .NET Programming". But I have problems trying to access my database. To get it to log in, I've added the code shown below to my batch service:-
 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

'Put user code to initialize the page here

Dim crReport As CrystalDecisions.CrystalReports.Engine.ReportObject

Dim crConnectionInfo As New ConnectionInfo

Dim crConnServer As String = ConfigurationSettings.AppSettings("CrConnServer")

Dim crConnDbName As String = ConfigurationSettings.AppSettings("CrConnDbName")

Dim crConnUserId As String = ConfigurationSettings.AppSettings("CrConnUserId")

Dim crConnPassword As String = ConfigurationSettings.AppSettings("CrConnPassword")

crConnectionInfo.ServerName = crConnServer

crConnectionInfo.DatabaseName = crConnDbName

crConnectionInfo.UserID = crConnUserId

crConnectionInfo.Password = crConnPassword

Dim myTable As Table

Dim myTables As Tables

Dim myLogonInfo As New TableLogOnInfo

CrystalReportViewer1.ReportSource = "http://localhost/WebServ5/STDPOReportService.asmx"

myTables = CrystalReportViewer1.ReportSource.Tables

For Each myTable In myTables

myLogonInfo.ConnectionInfo = crConnectionInfo

Next

End Sub

 

But when I attempt to run it I get the following errors:-

Server Error in '/WebApp5' Application.
--------------------------------------------------------------------------------

Public member 'Tables' on type 'ProxyReportSource' not found.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.MissingMemberException: Public member 'Tables' on type 'ProxyReportSource' not found.

Source Error:


Line 53:
Line 54:         CrystalReportViewer1.ReportSource = " http://localhost/WebServ5/STDPOReportService.asmx - http://localhost/WebServ5/STDPOReportService.asmx "
Line 55:         myTables = CrystalReportViewer1.ReportSource.Tables
Line 56:         For Each myTable In myTables
Line 57:             myLogonInfo.ConnectionInfo = crConnectionInfo
 

Source File: c:\inetpub\wwwroot\WebApp5\WebForm1.aspx.vb    Line: 55

Stack Trace:


[MissingMemberException: Public member 'Tables' on type 'ProxyReportSource' not found.]
   Microsoft.VisualBasic.CompilerServices.LateBinding.LateGet(Object o, Type objType, String name, Object[] args, String[] paramnames, Boolean[] CopyBack)
   WebApp5.WebForm1.Page_Load(Object sender, EventArgs e) in c:\inetpub\wwwroot\WebApp5\WebForm1.aspx.vb:55
   System.Web.UI.Control.OnLoad(EventArgs e)
   System.Web.UI.Control.LoadRecursive()
   System.Web.UI.Page.ProcessRequestMain()

 


--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:1.1.4322.2032; ASP.NET Version:1.1.4322.2032

Any ideas anyone?



Replies:
Posted By: hilfy
Date Posted: 26 Apr 2007 at 9:13am
In order to work with the "Tables" property, I think you need to work with the ReportDocument object model, not the CrystalReportViewer object model for your report (Brian, please correct me if I'm wrong...).
 
Here's the code we use for loading a report into the viewer:
  private void Page_Init(object sender, EventArgs e)
  {
     crReport = new ReportDocument();
   
    string reportName = Request.QueryString["ReportName"];
    string qServer = Request.QueryString["qServer"];
    string rptPath = Request.PhysicalPath.Substring(0, 2) + ConfigurationManager.AppSettings["rptDefinitionsPath"];
    crReport.Load(@rptPath + reportName);
    ParameterDiscreteValue discreteVal = new ParameterDiscreteValue();
    ParameterRangeValue rangeVal = new ParameterRangeValue();
    ParameterValues curvalues = new ParameterValues();
    foreach (ParameterFieldDefinition parafld in crReport.DataDefinition.ParameterFields)
    {
      if (parafld.DiscreteOrRangeKind.ToString() == "DiscreteValue")
      {
        discreteVal.Value = Request.QueryString[parafld.ParameterFieldName];
        if (discreteVal.Value != null)
        {
          curvalues.Add(discreteVal);
          parafld.ApplyCurrentValues(curvalues);
        }
      }
    }
    CrystalDecisions.Shared.ConnectionInfo connectionInfo = new CrystalDecisions.Shared.ConnectionInfo();
  
    connectionInfo.ServerName = qServer;
    connectionInfo.UserID = "reporting";
    connectionInfo.Password = "rlrootg";
    // set report connection for main report
    SetDBLogonForReport(connectionInfo, crReport, qServer);
    // set report connection for any subreports
    SetDBLogonForSubreports(connectionInfo, crReport, qServer);
    // set group tree function off        
    crystalReportViewer.DisplayGroupTree = false;
    // view report
   
    crystalReportViewer.ReportSource = crReport;
   
  }
  private void SetDBLogonForReport(CrystalDecisions.Shared.ConnectionInfo connectionInfo, ReportDocument reportDocument, string qServer)
  {
    Tables tables = reportDocument.Database.Tables;
    foreach (CrystalDecisions.CrystalReports.Engine.Table table in tables)
    {
      TableLogOnInfo tableLogonInfo = table.LogOnInfo;
      tableLogonInfo.ConnectionInfo = connectionInfo;
      table.ApplyLogOnInfo(tableLogonInfo);
    }
  }
  private void SetDBLogonForSubreports(CrystalDecisions.Shared.ConnectionInfo connectionInfo, ReportDocument reportDocument, string qServer)
  {
    Sections sections = reportDocument.ReportDefinition.Sections;
    foreach (Section section in sections)
    {
      ReportObjects reportObjects = section.ReportObjects;
      foreach (ReportObject reportObject in reportObjects)
      {
        if (reportObject.Kind == ReportObjectKind.SubreportObject)
        {
          SubreportObject subreportObject = (SubreportObject)reportObject;
          ReportDocument subReportDocument = subreportObject.OpenSubreport(subreportObject.SubreportName);
          SetDBLogonForReport(connectionInfo, subReportDocument, qServer);
         
        }
      }
    }
 }
 
Using the ReportDocument object model gives you MUCH more flexibilty in terms of setting properties of the report prior to viewing it.  There's a comparison/explanation of the differences between the two object models http://devlibrary.businessobjects.com/BusinessObjectsXIR2/en/en/CrystalReports_dotNET_SDK/crsdk_net_doc/doc/crsdk_net_doc/html/crconsdkfundamentalswhichobjectmodel.htm - here .
-Dell


-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 27 Apr 2007 at 2:16am

Thank you for your help, Hilfy, but do you need to put any special "import" lines in VB code to get it to find request?

At the moment I have got the following import lines in my code:-

Imports System.Configuration                    'Database Connection

Imports CrystalDecisions.CrystalReports.Engine  'Required For Crystal Reports
Imports CrystalDecisions.ReportSource.ReportSourceFactory
Imports CrystalDecisions.Shared                 'Required for Crystal Reports
Imports System.Resources.ResourceReader
Imports CrystalDecisions.Web.ReportAgent
Imports System.IO                               'Required to create directory
 
but when I type:-
 

Dim reportName As Request.QueryString = "STDPOReport"

I get it flagged with the error "Type 'Request.QueryString' is not defined.


Posted By: hilfy
Date Posted: 27 Apr 2007 at 6:33am

I'm working in C#, so I have "Using" instead of "Imports".  Here's the entire set from our app:

 
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System.Collections.Specialized;
using System.Diagnostics;

 
"Request" is part of the URL coming from the page that called this one.  We use it to send session information, the name of the report, the database server to connect to (same data structure, but different db name for each of our clients) and the path to where all of the report files are located.  Your app may be getting this information from somewhere else, so you would need to modify that part of the code.
 
-Dell


-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 30 Apr 2007 at 2:12am
Thanks again for your help Hilfy, but I am still unable to get the line:-
 

Dim reportName As Request.QueryString = "STDPOReport" 

to compile

I've used all the import lines you suggested except "System.Web.UI.WebControls.WebParts" which I dont seem to have.
 
 


Posted By: hilfy
Date Posted: 30 Apr 2007 at 7:25am

If you're not passing the name of the report into the page as part of the URL, you don't need to use the Request object.  You would just declare reportName as a string and set its value.

If you are getting the report name as part of the URL, I suggest that you search Help for the Request class and find out which assembly you'll need to include to have it compile.
 
-Dell


-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 02 May 2007 at 2:40am
I have now found a way round the previous poblem and my code is now:-
 

Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

'Put user code to initialize the page here

Dim crConnectionInfo As New ConnectionInfo

Dim crConnServer As String = ConfigurationSettings.AppSettings("CrConnServer")

Dim crConnDbName As String = ConfigurationSettings.AppSettings("CrConnDbName")

Dim crConnUserId As String = ConfigurationSettings.AppSettings("CrConnUserId")

Dim crConnPassword As String = ConfigurationSettings.AppSettings("CrConnPassword")

crConnectionInfo.ServerName = crConnServer

crConnectionInfo.DatabaseName = crConnDbName

crConnectionInfo.UserID = crConnUserId

crConnectionInfo.Password = crConnPassword

 

crReport.Load("http://localhost/WebServ5/STDPOReportService.asmx")

 

 

SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "due_in")

SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "stores_item")

SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "unit_info")

CrystalReportViewer1.ReportSource = crReport

Dim myTable As CrystalDecisions.CrystalReports.Engine.Table

Dim MyLogonInfo As CrystalDecisions.Shared.TableLogOnInfo

For Each myTable In crReport.Database.Tables

'[With MyLogonInfo.ConnectionInfo

'End With

MyLogonInfo.ConnectionInfo = crConnectionInfo

myTable.ApplyLogOnInfo(MyLogonInfo)

Next

End Sub

 

Private Sub SetLogOnInfo(ByVal server As String, ByVal database As String, _

ByVal userID As String, ByVal password As String, ByVal _

table As String)

Dim logOnInfo As New TableLogOnInfo

logOnInfo = crReport.Database.Tables.Item(table).LogOnInfo

' Set the connection information for the table in the report.

logOnInfo.ConnectionInfo.ServerName = server

logOnInfo.ConnectionInfo.DatabaseName = database

logOnInfo.ConnectionInfo.UserID = userID

logOnInfo.ConnectionInfo.Password = Password

logOnInfo.TableName = table

End Sub

End Class

But now I get the message:-

Server Error in '/WebApp5' Application.

Load report failed.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: CrystalDecisions.CrystalReports.Engine.LoadSaveReportException: Load report failed.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[LoadSaveReportException: Load report failed.]
   .I(String , EngineExceptionErrorID )
   .E(String , Int32 )
   CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String reportName, OpenReportMethod openMethod, Int16 parentJob)
   CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String reportName)
   WebApp5.WebForm1.Page_Load(Object sender, EventArgs e)
   System.Web.UI.Control.OnLoad(EventArgs e)
   System.Web.UI.Control.LoadRecursive()
   System.Web.UI.Page.ProcessRequestMain()
Any ideas anyone?


Posted By: hilfy
Date Posted: 02 May 2007 at 6:26am
You're trying to load a .asmx file - you need to load a .rpt file.
 
-Dell


-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 02 May 2007 at 7:09am
Thanks, Hilfy. I've changed my code accordingly but am still getting the same message!
 
Revised code:-
 

Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

'Put user code to initialize the page here

'CrystalReportViewer1.ReportSource = New WebServ5.STPMBReportService

'Dim NewServ1 As New WebServ5.service

Dim crConnectionInfo As New ConnectionInfo

Dim crConnServer As String = ConfigurationSettings.AppSettings("CrConnServer")

Dim crConnDbName As String = ConfigurationSettings.AppSettings("CrConnDbName")

Dim crConnUserId As String = ConfigurationSettings.AppSettings("CrConnUserId")

Dim crConnPassword As String = ConfigurationSettings.AppSettings("CrConnPassword")

Dim err As String

Try

 

 

crConnectionInfo.ServerName = crConnServer

crConnectionInfo.DatabaseName = crConnDbName

crConnectionInfo.UserID = crConnUserId

crConnectionInfo.Password = crConnPassword

crReport.Load("http://localhost/WebServ5/STDPOReport.rpt")

 

 

SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "due_in")

SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "stores_item")

SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "unit_info")

CrystalReportViewer1.ReportSource = crReport

Dim myTable As CrystalDecisions.CrystalReports.Engine.Table

Dim MyLogonInfo As CrystalDecisions.Shared.TableLogOnInfo

For Each myTable In crReport.Database.Tables

MyLogonInfo.ConnectionInfo = crConnectionInfo

myTable.ApplyLogOnInfo(MyLogonInfo)

Next

End Sub



Posted By: hilfy
Date Posted: 02 May 2007 at 7:23am
I'm not sure what the problem is at this point - does the .rpt file exist?
 
Also, I'm seeing other issues in your code -
SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "due_in")
SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "stores_item")
SetLogOnInfo(crConnServer, crConnDbName, crConnUserId, crConnPassword, "unit_info")

CrystalReportViewer1.ReportSource = crReport

Dim myTable As CrystalDecisions.CrystalReports.Engine.Table
Dim MyLogonInfo As CrystalDecisions.Shared.TableLogOnInfo
For Each myTable In crReport.Database.Tables
'[With MyLogonInfo.ConnectionInfo
'End With
MyLogonInfo.ConnectionInfo = crConnectionInfo
myTable.ApplyLogOnInfo(MyLogonInfo)
The section of code after you set the report source does nothing meaningful - you've already set the connection info with your calls to SetLogonInfo.  If you have other tables that need to be set, you need to do this before you set the report source.


-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 02 May 2007 at 9:15am
Hi Hilfy,
 
Yes, the .rpt definitely exists.
 
As for the code which you say is not needed, I can comment it out.


Posted By: hilfy
Date Posted: 02 May 2007 at 9:27am
Do you ever create the report object prior to trying to load a report into it?
 
-Dell 


-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 03 May 2007 at 2:42am
Thanks again, Hilfy.
 
I think I see what you're getting at (after having re-read Ch. 15 of "Crystal Report .NET Programming" and looked at the code that prints a report on my on-line project where the user clicks a button).
 
I'll let you know how I get on.
 
Thanks!


Posted By: RichardP
Date Posted: 04 May 2007 at 1:56am
I am now getting the following failure message:-
 
Server Error in '/WebApp5' Application.
--------------------------------------------------------------------------------
Invalid report file path.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: CrystalDecisions.CrystalReports.Engine.LoadSaveReportException: Invalid report file path.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 
Stack Trace:

[LoadSaveReportException: Invalid report file path.]
   CrystalDecisions.Web.ReportAgent.h()
   CrystalDecisions.Web.ReportAgentBase.set_ReportSource(Object value)
   CrystalDecisions.Web.ReportAgent.set_ReportSource(Object value)
   CrystalDecisions.Web.CrystalReportViewerBase.set_ReportSource(Object value)
   WebApp5.WebForm1.Page_Load(Object sender, EventArgs e)
   System.Web.UI.Control.OnLoad(EventArgs e)
   System.Web.UI.Control.LoadRecursive()
   System.Web.UI.Page.ProcessRequestMain()
 

--------------------------------------------------------------------------------
Version Information: Microsoft .NET Framework Version:1.1.4322.2032; ASP.NET Version:1.1.4322.2032
 
My code is now:-
 

Public Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

Dim crConnectionInfo As New ConnectionInfo

Dim crConnServer As String = ConfigurationSettings.AppSettings("CrConnServer")

Dim crConnDbName As String = ConfigurationSettings.AppSettings("CrConnDbName")

Dim crConnUserId As String = ConfigurationSettings.AppSettings("CrConnUserId")

Dim crConnPassword As String = ConfigurationSettings.AppSettings("CrConnPassword")

Dim err As String

Dim objReport As New report

Dim myTable As CrystalDecisions.CrystalReports.Engine.Table

Dim MyLogonInfo As CrystalDecisions.Shared.TableLogOnInfo

Try

 

 

crConnectionInfo.ServerName = crConnServer

crConnectionInfo.DatabaseName = crConnDbName

crConnectionInfo.UserID = crConnUserId

crConnectionInfo.Password = crConnPassword

For Each myTable In crReport.Database.Tables

myTable.ApplyLogOnInfo(MyLogonInfo)

Next

crReport.Load("c:\inetpub\wwwroot\WebServ5\STDPOReport.rpt")

Catch ex As Exception

err = ex.Message

End Try

If Not objReport.ErrorMessage Is Nothing Then

Response.Write(objReport.ErrorMessage)

End If

'Export the report. SD 04/08/06.

objReport.Export(crReport, "STDPOReport", ExportFormatType.PortableDocFormat)

If Not objReport.ErrorMessage Is Nothing Then

Response.Write(objReport.ErrorMessage)

End If

'Print the report. SD 04/08/06.

objReport.PrintToPrinter(crReport, PaperOrientation.Landscape)

If Not objReport.ErrorMessage Is Nothing Then

Response.Write(objReport.ErrorMessage)

End If

 

CrystalReportViewer1.ReportSource = crReport

 End Sub

 

I have checked the address of the report and have confirmed that it is

c:\inetpub\wwwroot\WebServ5\STDPOReport.rpt

In fact I cut and pasted that address.
 
 
So any ideas anybody?


Posted By: hilfy
Date Posted: 04 May 2007 at 11:41am
When you're loading a file in a website, you can't use dpecific drive paths - you have to use a path relative to the website.  So, in this case, you would use (I think...):
 
crReport.Load("..\WebServ5\STDPOReport.rpt")
 
You need to figure out where the report is relative to your WebApp5 application inside IIS
 
-Dell



-------------
Proviti, Data & Analytics Practice
http://www.protiviti.com/US-en/data-management-advanced-analytics - www.protiviti.com/US-en/data-management-advanced-analytics


Posted By: RichardP
Date Posted: 08 May 2007 at 2:59am
Thanks, Hilfy. I'll try and figure this out.



Print Page | Close Window