1

PDF にエクスポートしようとすると、InvalidComObjectException エラーが発生します。オラクルへの接続と関係があるのではないかと思いますが、よくわかりません。SetDatabaseLogon は Sql Server を支持しているようです。レポートは、データのストアド プロシージャを呼び出し、Business Objects XIR2 サービスを使用して動作しています。レポートを表示して、デザイナー内でも接続できます。

'CrystalDecisions.CrystalReports.Engine 13.0.2000.0 'Crystal Reports for .NET Framework 4.0

Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.ReportAppServer.DataDefModel
Imports CrystalDecisions.Shared
Imports CrystalDecisions.ReportSource

   Public Overloads Function CreateReport(ByVal reportFileName As String, ByVal reportTitle As String, ByVal outputDirectory As String, _
ByVal isFullPath As Boolean, ByVal outputFormat As OutputFormat, ByVal crystalParameter As CrystalParameter) As String


      Dim baseReportsSourcePath As String = "C:\ADSTAX\SUITES\RFL\Letters\"
      Dim baseReportsOutputPath As String = "C:\PDF_Exports\"

      Dim fullFilepath As String = baseReportsSourcePath + reportFileName

      'check report exists
      If File.Exists(fullFilepath) = False Then Throw New FileNotFoundException("File:" + fullFilepath + " does not exist", fullFilepath)

      Dim doc As ReportDocument = New ReportDocument()
      doc.Load(fullFilepath)

      'set parameters
      If crystalParameter.Name = CrystalParameterName.DistributionKey Then

         doc.SetParameterValue("DISTRIBUTIONKEY", crystalParameter.Value)

      ElseIf crystalParameter.Name = CrystalParameterName.RequestKey Then

         doc.SetParameterValue("REQUESTKEY", crystalParameter.Value)

      End If

      'user, pass, server, database
      doc.SetDatabaseLogon("user", "pass")


      'build full output filename
      Dim exportFileName As String = Path.GetFileNameWithoutExtension(reportFileName)
      exportFileName += Guid.NewGuid.ToString + ".pdf"
      Dim fullOuputFilePath As String = baseReportsOutputPath + exportFileName

      'export to pdf
      doc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, fullOuputFilePath)

      'check report created
      If File.Exists(fullFilepath) = False Then
         Return String.Empty
      End If

      Return fullOuputFilePath

   End Function

以下のエラー:

System.Runtime.InteropServices.InvalidComObjectException was unhandled
  Message=COM object that has been separated from its underlying RCW cannot be used.
  Source=mscorlib
  StackTrace:
       at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis, IntPtr pThread)
       at System.Runtime.InteropServices.ComTypes.IConnectionPoint.Unadvise(Int32 dwCookie)
       at CrystalDecisions.ReportAppServer.ISCDClientDocumentEvents_EventProvider.RemoveOnClosed(_ISCDClientDocumentEvents_OnClosedEventHandler handler)
       at CrystalDecisions.ReportAppServer.ISCDClientDocumentEvents_EventProvider.remove_OnClosed(_ISCDClientDocumentEvents_OnClosedEventHandler value)
       at CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.DisconnectEventRelay()
       at CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.InternalClose(Boolean bSetupForNextReport, Boolean bAutoClose)
       at CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.Dispose(Boolean bDisposeManaged)
       at System.ComponentModel.Component.Dispose()
       at CrystalDecisions.CrystalReports.Engine.ReportDocument.ClearCache(Boolean clearDocument)
       at CrystalDecisions.CrystalReports.Engine.ReportDocument.InternalClose(Boolean bSetupForNextReport)
       at CrystalDecisions.CrystalReports.Engine.ReportDocument.Close()
       at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExitHandler(Object sender, EventArgs e)
  InnerException: 
4

4 に答える 4

0

シュナイダー、

この問題は、接続の詳細やパラメーターの設定が原因ではないと思われます。私の疑いを確認するには、コードを単純な Web または Windows フォーム/ページに配置し、エクスポートする代わりに、CrystalReportViewer オブジェクトをそのページにドロップしてレポートを表示してみてください。(注: この作業にはいくつかの前提条件がありますが、Crystal が完全にインストールされている開発マシンを使用している場合は、これらの要件を簡単に満たすことができます。)

苦情が表示されないと仮定すると (つまり、パラメーターまたはデータベースの資格情報を求めるプロンプトが表示されます)、まったく別の理論に傾倒します。

手がかりはエラー メッセージにあります。「基礎となる RCW から分離された COM オブジェクトは使用できません。」このエラーは、Crystal Reports に固有のものではありません。

これを以前に見たのは、ガベージ コレクション (自動化されているか、コードによって発生する破棄/分解によるもの) またはマルチスレッド関連の課題に関連しています。

PDFパスを文字列として返す関数としてこれを呼び出していることに気付きました。おそらく、呼び出し元のスレッドから独立したスレッドに呼び出しをネストしましたか? おそらく、オブジェクトの破棄や、バッチ処理などのリソース/ロック関連の問題に関与する可能性のある他のイベントをトリガーする他のコードがありますか?

憶測を避ける 1 つの方法は、これらすべてをまったく新しい非常に単純な基本的な Windows アプリケーションに配置することです。エクスポートをトリガーするための絶対的な最小値のみを実行します。Windows アプリケーションがローカル フォルダーに書き込み、ローカル ディレクトリからレポートを読み取るだけであることを確認します。ファイルのアクセス許可やネットワークの問題 (ネットワークを介した読み取り/書き込み) に干渉されたくありません。

幸運を祈ります。

于 2012-04-10T03:17:16.207 に答える
0

このコードを見ることをお勧めします:

Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared
Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Button1.Click
        Dim cryRpt As New ReportDocument
        Dim crtableLogoninfos As New TableLogOnInfos
        Dim crtableLogoninfo As New TableLogOnInfo
        Dim crConnectionInfo As New ConnectionInfo
        Dim CrTables As Tables
        Dim CrTable As Table

        cryRpt.Load("PUT CRYSTAL REPORT PATH HERE\CrystalReport1.rpt")

        With crConnectionInfo
            .ServerName = "YOUR SERVER NAME"
            .DatabaseName = "YOUR DATABASE NAME"
            .UserID = "YOUR DATABASE USERNAME"
            .Password = "YOUR DATABASE PASSWORD"
        End With

        CrTables = cryRpt.Database.Tables
        For Each CrTable In CrTables
            crtableLogoninfo = CrTable.LogOnInfo
            crtableLogoninfo.ConnectionInfo = crConnectionInfo
            CrTable.ApplyLogOnInfo(crtableLogoninfo)
        Next

        CrystalReportViewer1.ReportSource = cryRpt
        CrystalReportViewer1.Refresh()
    End Sub
End Class

http://vb.net-informations.com/crystal-report/vb.net_crystal_report_load_dynamically.htmから

おそらく、アスタリスクがある場所にブレークポイントを配置します。

        For Each CrTable In CrTables
            *crtableLogoninfo = CrTable.LogOnInfo
            crtableLogoninfo.ConnectionInfo = crConnectionInfo
            CrTable.ApplyLogOnInfo(crtableLogoninfo)
        Next

次に、既存の CrTable.TableLogonInfo を分析します

うまくいけば、これを今後も使用できます。

于 2012-04-09T21:45:51.327 に答える
0
  1. データセットを実行して、Oracle ストアドプロシージャからデータを入力します。データセット内のテーブル名が、レポートの設計に基づいたデータベース オブジェクトの名前と同じであることを確認してください (この場合はストアド プロシージャ名)。

  2. ログオン情報を提供しないでください。これは重要です。

  3. すべてのレポート パラメーターを設定しますが、データセットには既にフィルター処理されたデータが含まれているため、データ フィルターは指定しません。

  4. データバインディングを手動で行います。

    doc.SetDataSource=yourdatasource;

通常どおりレポートのエクスポートを続行します。

これは、レポートに入力するプッシュ モデルの方法です。通常、レポートの設計にはオラクル用のoledb dataadapterを使用します。しかし、ストアド プロシージャを扱っている場合は、プッシュ モデルが唯一の方法です。デザイナは Oracle SP にアクセスしてレポートを生成できますが、アプリケーションで処理する必要があります。そうしないと、ストアド プロシージャ パラメータの値を尋ねる迷惑なポップアップが表示されます。

ここにいくつかのコードがあります

OracleConnection cn = new OracleConnection("Data Source=yourdbname;User ID=someid;password=somepw;Pooling=true;Connection Lifetime=30;Min Pool Size=5;Max Pool Size=100");

OracleParameter DETAILS = new OracleParameter();
DETAILS.ParameterName = "DETAILS";
DETAILS.Direction = ParameterDirection.Output;

OracleParameter NN = new OracleParameter();
NN.ParameterName = "PRODUCT";
NN.Direction = ParameterDirection.Input;
NN.Value = 1000; // Some product id

OracleParameter DD = new OracleParameter();
DD.ParameterName = "TRDATE";
DD.Direction = ParameterDirection.Input;
DD.Value = “09-DEC-2008”; // Some Date


// for Oracle.DataAccess.Client use the following
DETAILS.OracleDbType = OracleDbType.RefCursor;
NN.OracleDbType = OracleDbType.Varchar2;
DD.OracleDbType = OracleDbType.Date;


// for System.Data.OracleClient use the following
//DETAILS.OracleType = OracleType.Cursor;
//NN.OracleType = OracleType.VarChar;
//DD.OracleType = OracleType.DateTime;



OracleCommand cmd = new OracleCommand("Myschemaname.GETSTOCK", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(NN);
cmd.Parameters.Add(DD);
cmd.Parameters.Add(DETAILS);
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds,"GETSTOCK"); //Name must be same as Procedure
ReportDocument rptDoc = new ReportDocument();
rptDoc.Load(Server.MapPath("FINC//abc.rpt"));
rptDoc.SetDataSource(ds);
CRT.ReportSource = rptDoc; // CRT is the name of Crystal report viewer control
    // your export routine goes here
于 2012-04-10T02:29:56.397 に答える