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());
}
}