Condividi tramite


Gestione delle eccezioni del modulo di Crystal Report

Quando si esegue Crystal Reports tramite l'applicazione, il modulo di Crystal Report potrebbe provocare eccezioni. Se si verifica un'eccezione, può apparire un messaggio di errore oppure interrompersi l'elaborazione dei report. Alcune cause delle eccezioni sono:

  • Report Engine non è in grado di collegarsi al database. Questa situazione può verificarsi se sono stati specificati per Report Engine parametri relativi alla posizione del database o all'accesso non corretti. L'eccezione può verificarsi anche a seguito di altri errori del database, ad esempio una tabella bloccata da un altro utente, installazione non corretta del modulo del database o perché una tabella risulta danneggiata.
  • Dati non corretti specificati per un parametro. Se un parametro riceve dati non corretti dal codice o dall'input dell'utente, si può provocare l'interruzione dell'esecuzione del report. Ad esempio, un valore stringa passato a un parametro numerico provoca l'arresto del report.
  • Individuazione di un errore in una formula di Crystal Reports. Se non è possibile valutare correttamente una delle formule del report, viene sollevata un'eccezione. Questa situazione può essere provocata da una sintassi errata nella formula o da altri errori nel programma, ad esempio una divisione per zero.
  • Report Engine non è in grado di aprire un report. Questa situazione si verifica se viene fornito un nome o un percorso di file errato, se si seleziona un report non Crystal o se il report è stato danneggiato.

È possibile assegnare al modulo Crystal Report la gestione dell'eccezione e visualizzare l'appropriato messaggio di errore oppure gestirla in modo personalizzato. I vantaggi della gestione delle eccezioni tramite programma sono:

  • È possibile personalizzare il messaggio di errore visualizzato per l'utente. Ad esempio, invece di visualizzare "Accesso non riuscito" se il report non è in grado di collegarsi all'origine dei dati, è possibile visualizzare un messaggio più completo, ad esempio "Impossibile collegarsi al database, parametri di accesso non validi". L'utente può così ricevere informazioni più dettagliate.
  • È possibile scrivere un evento per il file log dell'applicazione. È possibile specificare il messaggio di errore, l'ID dell'errore, l'ora in cui si è verificato e altre informazioni. In questo modo è possibile registrare gli errori e analizzarli in seguito.
  • È possibile gestire l'eccezione tramite codice per consentire la continuazione dell'elaborazione del report. Verificando la tipologia dell'errore, è possibile scrivere il codice appropriato per gestire l'errore e rieseguire il report con le informazioni corrette.

Il modulo di Crystal Report fornisce classi di eccezione che consentono di determinare il tipo di errore generato. Le classi di eccezione sono ereditate dalla classe System.ApplicationException e, inoltre, forniscono la proprietà ErrorID. ErrorID è un tipo enumerato che consente di stabilire il tipo di errore. Le tabelle che seguono mostrano le diverse classi di eccezione e i diversi valori di enumerazione.

Classi di eccezione

Classe di eccezione Descrizione
DataSourceException Ereditata da EngineException. Attivata in caso di errori dell'origine dati.
EngineException Ereditata da System.ApplicationException. Si tratta della classe di eccezioni di base del modulo di Crystal Report. Fornisce la proprietà ErrorID che consente di determinare il tipo di errore.
ExportException Ereditata da EngineException. Attivata se si verifica un errore di esportazione.
FormattingException Ereditata da EngineException. Attivata se si verifica un errore di formattazione del report.
FormulaException Ereditata da EngineException. Attivata se si verifica un errore in un campo formula.
InternalException Ereditata da EngineException. Attivata se si verifica un errore interno al modulo di Crystal Reports.
InvalidArgumentException Ereditata da EngineException. Attivata se si utilizza un argomento non valido.
LoadSaveReportException Ereditata da EngineException. Attivata se si verifica un errore durante l'apertura di un report.
LogOnException Ereditata da DataSourceException. Attivata se si verifica un errore durante il collegamento a un'origine dati.
OutOfLicenseException Ereditata da EngineException. Attivata se viene superato il numero di licenze correnti.
ParameterFieldCurrentValueException Ereditata da ParameterFieldException. Attivata se non è stato impostato il valore corrente del campo di parametro.
ParameterFieldException Ereditata da EngineException. Attivata se si verifica un errore in un campo di parametro.
PrintException Ereditata da EngineException. Attivata se si verifica un errore durante la stampa di un report.
SubreportException Ereditata da EngineException. Attivata se si verifica un problema durante l'apertura di un sottoreport.

Valori di enumerazione EngineExceptionErrorID

ErrorID Descrizione
DataSourceError Si è verificato un errore durante l'accesso all'origine dati.
ExportingFailed Si è verificato un errore durante l'esportazione del report.
IndexOutOfBound È stato tentato l'accesso a un valore non compreso tra i limiti della matrice.
InternalError Si è verificato un errore interno al modulo di Crystal Report.
InvalidArgument Argomento non valido utilizzato per impostare un valore.
InvalidExportOptions I valori delle opzioni di esportazione specificati per Report Engine sono incorretti o vi sono dati mancanti.
InvalidFormula Si è verificato un errore durante l'elaborazione di un campo formula.
InvalidParameterField Si è verificato un errore durante l'elaborazione di un campo di parametro.
InvalidParameterValue Si è verificato un errore a causa di un valore non valido specificato per il valore corrente del campo di parametro.
InvalidPrintOptions I valori delle opzioni di stampa specificati per Report Engine sono incorretti o vi sono dati mancanti.
LoadingReportFailed Si è verificato un errore durante l'apertura di un report.
LogOnFailed Si è verificato un errore durante il collegamento a un'origine dati.
MissingParameterFieldCurrentValue Il campo di parametro non contiene valori correnti.
OpenSubreportFailed Si è verificato un errore durante l'apertura di un sottoreport.
OutOfLicense Si è verificato un errore provocato dal superamento del numero di licenze.
PageFormattingFailed Si è verificato un errore durante la formattazione del report.
PrintingFailed Si è verificato un errore durante la stampa di un report.
SavingReport Si è verificato un errore durante il salvataggio del report.

Gestione delle eccezioni nel codice

La modalità di gestione delle eccezioni differisce leggermente a seconda che si utilizzi l'oggetto Report Document, Windows Forms Viewer o Web Forms Viewer. I controlli dei due visualizzatori contengono un evento HandleException predefinito a cui è possibile aggiungere codice. L'oggetto Report Document richiede la gestione delle eccezioni tramite un'istruzione di tipo "try-catch". Se si passa il report al visualizzatore e si verifica un errore, il visualizzatore cattura l'eccezione.

Gestione delle eccezioni con i controlli del visualizzatore

Se si gestisce l'eccezione con i controlli del visualizzatore, viene utilizzato l'evento HandleException del visualizzatore. In questo evento, è possibile assegnare il parametro ExceptionEventArgs.Exception dell'evento a una classe EngineException. Dopo aver impostato la classe EngineException, è possibile verificare la proprietà ErrorID per determinare il tipo di errore verificato.

Nel seguente esempio viene illustrato in che modo è possibile ignorare il messaggio visualizzato in caso di errore di collegamento con il database o durante l'accesso all'origine dati. Tutti gli altri messaggi di errore vengono visualizzati dal modulo Crystal Report.

[Visual Basic]

Private Sub CrystalReportViewer1_HandleException(ByVal source As Object, _ ByVal e As CrystalDecisions.Windows.Forms.ExceptionEventArgs) Handles CrystalReportViewer1.HandleException
   If TypeOf (e.Exception) Is EngineException Then
      Dim engEx As EngineException
      engEx = e.Exception
      If engEx.ErrorID = EngineExceptionErrorID.DataSourceError Then
         e.Handled = True
         MessageBox.Show _ 
         ("An error has occurred while connecting to the database.")
      ElseIf engEx.ErrorID = EngineExceptionErrorID.LogOnFailed Then
         e.Handled = True
         MessageBox.Show _ 
     ("Incorrect Logon Parameters. Check your user name and password.")
      End If
   End If
End Sub

[C#]

private void crystalReportViewer1_HandleException(object source, CrystalDecisions.Windows.Forms.ExceptionEventArgs e)
{
   if (e.Exception is EngineException)
   {
      EngineException engEx = (EngineException)e.Exception;
      if (engEx.ErrorID == EngineExceptionErrorID.DataSourceError)
      {
         e.Handled = true;
         MessageBox.Show _
         ("An error has occurred while connecting to the database.");
      }
      else if (engEx.ErrorID == EngineExceptionErrorID.LogOnFailed)
      {
         e.Handled = true;
         MessageBox.Show _
    ("Incorrect Logon Parameters. Check your user name and password.");
      }
   }
}

[C++]

void crystalReportViewer1_HandleException (Object* sender, CrystalDecisions::Windows::Forms::ExceptionEventArgs * e)
{
   try
   {
      EngineException* engEx; 
      engEx = __try_cast<EngineException*>(e->Exception);
      if (engEx->ErrorID == EngineExceptionErrorID::DataSourceError)
      {
         e->Handled = true;
         MessageBox::Show ("An error has occurred while connecting to the database.");
      }
      else if (engEx->ErrorID == EngineExceptionErrorID::LogOnFailed)
      {
         e->Handled = true;
         MessageBox::Show ("Incorrect Logon Parameters. Check your user name and password.");
      }
   }
   catch(System::InvalidCastException*)
   {
      // Aggiungere il codice dell'errore.
   }
};

[VJ#]

private void crystalReportViewer1_HandleException(System.Object source, CrystalDecisions.Windows.Forms.ExceptionEventArgs e)
{
   if (e.get_Exception() instanceof EngineException)
   {
      EngineException engEx = (EngineException)e.get_Exception();
      if (engEx.get_ErrorID() == EngineExceptionErrorID.DataSourceError)
      {
         e.set_Handled(true);
         MessageBox.Show
         ("An error has occurred while connecting to the database.");
      }
      else if (engEx.get_ErrorID() == EngineExceptionErrorID.LogOnFailed)
      {
         e.set_Handled(true);
         MessageBox.Show
    ("Incorrect Logon Parameters. Check your user name and password.");
      }
   }
}

Gestione delle eccezioni con l'oggetto ReportDocument

Se si gestisce l'eccezione con l'oggetto ReportDocument, occorre utilizzare un'istruzione di tipo "try-catch", in cui è possibile fare riferimento a una delle classi di eccezioni di Crystal. EngineException è la classe di base che cattura tutte le eccezioni sollevate dal modulo di Crystal Report. È possibile utilizzare le altre classi di eccezione per stabilire il tipo di errore che si è verificato. Catturando tali classi di eccezioni prima della classe EngineException e di ApplicationException, è possibile conoscere il tipo di eccezione sollevato.

Nel seguente esempio viene illustrato in che modo è possibile ignorare il messaggio visualizzato in caso di errore di collegamento con il database o durante l'accesso all'origine dati. Tutte le altre eccezioni visualizzano il messaggio di errore originale.

[Visual Basic]

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _ System.EventArgs) Handles Button1.Click
   Try
      Dim report As New ReportDocument()
      report.Load("c:\sample.rpt")
      report.PrintToPrinter(1, True, 1, 2)
   Catch engEx As LogOnException
      MessageBox.Show _
     ("Incorrect Logon Parameters. Check your user name and password.")
   Catch engEx As DataSourceException
      MessageBox.Show _
      ("An error has occurred while connecting to the database.")
   Catch engEx As EngineException
      MessageBox.Show(engEx.Message)
   End Try
End Sub

[C#]

private void button1_Click(object sender, System.EventArgs e)
{
   try
   {
      ReportDocument report = new ReportDocument();
      report.Load ("c:\\sample.rpt");
      report.PrintToPrinter (1,true,1,2);
   }
   catch (LogOnException engEx)
   {
      MessageBox.Show _
("Incorrect Logon Parameters. Check your user name and password.");
   }
   catch (DataSourceException engEx)
   {
   MessageBox.Show _
("An error has occurred while connecting to the database.");
   }
   catch (EngineException engEx)
   {
      MessageBox.Show (engEx.Message);
   }
}

[C++]

void ButtonClick(Object* sender, System::EventArgs * e)
{
   try
   {
      ReportDocument* report = new ReportDocument();
      report->Load ("c:\\sample.rpt");
      report->PrintToPrinter (1,true,1,2);
   }
   catch (LogOnException* engEx)
   {
      MessageBox::Show("Incorrect Logon Parameters. Check your user name and password.");
   }
   catch (DataSourceException* engEx)
   {
      MessageBox::Show("An error has occurred while connecting to the database.");
   }
   catch (EngineException* engEx)
   {
      MessageBox::Show (engEx->Message);
   }
};

[VJ#]

private void button1_Click(System.Object sender, System.EventArgs e)
{
   try
   {
      ReportDocument report = new ReportDocument();
      report.Load ("c:\\sample.rpt");
      report.PrintToPrinter (1,true,1,2);
   }
   catch (LogOnException engEx)
   {
      MessageBox.Show
("Incorrect Logon Parameters. Check your user name and password.");
   }
   catch (DataSourceException engEx)
   {
   MessageBox.Show
("An error has occurred while connecting to the database.");
   }
   catch (EngineException engEx)
   {
      MessageBox.Show (engEx.get_Message());
   }
}

Vedere anche

Libreria di classi Crystal Reports