2012-04-11 3 views
3

Derzeit verwende ich die folgende Methode, um allen Berichtsabschnitten Verbindungsinformationen zuzuweisen. Aber da ich viele Abschnitte im Bericht habe, wird der Bericht nach fast 10 Sekunden angezeigt. Das sieht wirklich langsam aus. Gibt es eine andere Methode, mit der wir Anmeldeinformationen für alle CRs festlegen können, wenn sie auf der Clientseite installiert werden?Anwendung wird langsam ausgeführt, wenn DB-Protokollierungsinformationen auf die einzelnen Crystal Reports-Abschnitte angewendet werden

JFYI: Alle CRs verbinden sich mit derselben Datenbank mit denselben Anmeldedaten. Vielen Dank im Voraus.

readDiamondBillReport = new RealDiamondBill(); 
         crConnectionInfo.ServerName = db.Connection.DataSource; 
         crConnectionInfo.DatabaseName = db.Connection.Database; 
         crConnectionInfo.UserID = "client"; 
         crConnectionInfo.Password = "client"; 
         crConnectionInfo.IntegratedSecurity = false; 

         CrTables = readDiamondBillReport.Database.Tables; 
         foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in CrTables) 
         { 
          crtableLogoninfo = CrTable.LogOnInfo; 
          crtableLogoninfo.ConnectionInfo = crConnectionInfo; 
          CrTable.ApplyLogOnInfo(crtableLogoninfo); 
         } 

         Sections crSections2 = readDiamondBillReport.ReportDefinition.Sections; 
         // loop through all the sections to find all the report objects 
         foreach (Section crSection in crSections2) 
         { 
          ReportObjects crReportObjects = crSection.ReportObjects; 
          //loop through all the report objects in there to find all subreports 
          foreach (ReportObject crReportObject in crReportObjects) 
          { 
           if (crReportObject.Kind == ReportObjectKind.SubreportObject) 
           { 
            SubreportObject crSubreportObject = (SubreportObject)crReportObject; 
            //open the subreport object and logon as for the general report 
            ReportDocument crSubreportDocument = crSubreportObject.OpenSubreport(crSubreportObject.SubreportName); 

            Tables SubCrTables = crSubreportDocument.Database.Tables; 
            foreach (CrystalDecisions.CrystalReports.Engine.Table SubCrTable in SubCrTables) 
            { 
             crtableLogoninfo = SubCrTable.LogOnInfo; 
             crtableLogoninfo.ConnectionInfo = crConnectionInfo; 
             SubCrTable.ApplyLogOnInfo(crtableLogoninfo); 

            } 
           } 
          } 
         } 

         readDiamondBillReport.Refresh(); 
+0

Aus Neugier haben Sie versucht, das DB-Update des Berichts im Vergleich zu seiner Aktualisierung zu testen? – Ryan

+0

@Ryan: Was bedeutet das Timing der Datenbankaktualisierung? – Marshal

+0

Ich meine Zeit, wie lange es dauert, bis der Code die Datenquellen der Berichte aktualisiert, anstatt den Bericht über 'readDiamondBillReport.Refresh()' zu aktualisieren. Meine Vermutung ist, dass eine große Mehrheit der 10 Sekunden zur Aktualisierung und nicht zum Update geht. – Ryan

Antwort

3

Ich fand schließlich, dass, das Anwenden von Anmeldeinformationen weder das Problem noch das Aktualisieren des Berichts war. Aber es war mein großes Bildobjekt, mit dem ich in Crystal Reports ein Wasserzeichen gesetzt habe.

Ich hatte 10 Berichte, die dieses Bild als Wasserzeichen verwendeten. Ich entfernte das Bild ohne Wasserzeichen und nun folgende Probleme gelöst werden:

  1. Projekt baut sehr sehr schnell. Bisher dauerte es ungefähr 1 Minute, um zu bauen, was nun drastisch auf 8-10 Sekunden reduziert wurde.

  2. Änderungen am Projekt, insbesondere an Berichten, werden viel schneller gespeichert.

  3. Ich habe "Not enough storage is available to complete this operation" nach ein oder zwei Builds bekommen. Ich musste VS neu starten und für jeden Build die Daumen drücken.

  4. Crystal Reports werden schneller auf CrystalReportViewer angezeigt und auch objrpt.PrintToPrinter funktioniert 500 mal schneller.

Ich hoffe, diese Punkte werden anderen Programmierern helfen.

2

Jeder Bericht enthält eine Unterberichtssammlung.

Sie können Anmeldeinformationen auf die Tabellen jedes Unterberichts anwenden, anstatt nach Unterberichten in jedem Abschnitt zu suchen. Hier

ist ein Code

private void showrep(string repName) 
     { 
      rd = new ReportDocument(); 
      rd.Load(pth+"\\"+repName); 
      LogInInfo(); 

      crv.ReportSource = rd; // crv is the reportviewer 
      crv.Show(); 
     } 

     private void LogInInfo() 
     { 
      MyApp.Properties.Settings s = new MyApp.Properties.Settings(); 
      TableLogOnInfo linfo = new TableLogOnInfo(); 
      linfo.ConnectionInfo.DatabaseName = s.dbname; 
      linfo.ConnectionInfo.UserID = s.usr; 
      linfo.ConnectionInfo.Password = s.pw; 
      linfo.ConnectionInfo.ServerName = s.svr; 

      foreach (Table t in rd.Database.Tables) 
      { 
       t.ApplyLogOnInfo(linfo); 
      } 
      foreach (ReportDocument sr in rd.Subreports) 
      { 
       foreach (Table t in sr.Database.Tables) 
       { 
        t.ApplyLogOnInfo(linfo); 
       } 
      } 
     } 

Hoffe, es hilft.

+0

Hier werden nur Tabellen mit Anmeldedaten angewendet. Was ist, wenn wir RecordSeletionFormula und GroupSelectionFormula in Abschnitten haben? Oder unterdrücken oder andere Formeln. Sie sind auch sehr abhängig von Anmeldeinformationen. Daher müssen alle Elemente mit Anmeldeinformationen versehen werden. – Marshal

+2

Ihre Frage hat dies nicht erklärt, und Sie haben auch in Ihrem vorherigen Code nicht dasselbe gemacht. Da jeder Bericht/Unterbericht standardmäßig mit Anmeldeinformationen versehen wurde, sind diese Informationen für alle Abschnitte verfügbar. Recordselection Formeln und Formeln unterdrücken brauchen kaum Logininfo !! Beim Push-Modell-Binding können Sie den Bericht sogar ohne Login-Informationen rendern. Und Berichte, die mit einem XML-Schema erstellt wurden, verfügen über keine Anmeldeinformationen für die Datenbank. Wir geben nur einen Datensatz an sie weiter. – Deb

3

Obwohl Sie Ihre eigene Frage beantwortet haben, werde ich auf einen alternativen Ansatz hinweisen, der mit Crystal Reports verwendet werden kann. In der Regel verwenden Benutzer den Pull-Ansatz, bei dem die Verbindung im Crystal Report festgelegt wird und der Datensatz basierend auf in den Bericht eingebetteten Abfragen "abgerufen" wird.

Es ist jedoch auch möglich, einen "Push" -Ansatz zu verwenden. In diesem Szenario binden Sie Ihre Crystal Report-Datenquelle einfach an ein XSD-Schema und legen den Datensatz im Crystal Report fest. In .NET können Sie das XSD einfach aus Ihrem Datensatz generieren, so dass dieser Ansatz einfach ist. Sie können daher jeden Unterbericht an die gewünschte Tabelle aus dem übergebenen Datensatz binden.

Der Vorteil hier ist, dass die Daten von jedem DBMS (Datenbank-agnostisch) kommen und wenn nötig manipuliert werden können, bevor sie an den Bericht übergeben werden (implementieren Sie benutzerdefinierte Sicherheit, Joins usw.).

Der Vorbehalt, dass Sie diesen Ansatz für Berichte mit großen Datenmengen nicht implementieren würden, da .NET-Datensätze speicherintensiv sein können.

Da Ihr Leistungsproblem jedoch mit einem Bild zusammenhing, hätte diese Vorgehensweise nicht geholfen.

Verwandte Themen