3 dicembre 2007

Integrazione SQL Server, Crystal Report e Mail

Ho terminato una applicazione Web che consente la gestione di uno scadenziario per le manutenzioni delle apparecchiature. L'applicazione si basa su pagine ASP con SQL Server come DBMS e Crystal Report per la creazione delle stampe.
On-demand l'applicazione crea dei report di Crystal in formato PDF che vengono girati via web all'utente secondo i parametri di tempo impostabili tramite un comune form.
L'idea che mi è venuta è stata quella di automatizzare questa operazione così da fornire all'utente un report periodico via mail che gli ricordasse le scadenze più immediate.
Senza inventare l'acqua calda ho pensato di sfruttare uno dei report già esistenti, tanto vanno già bene come formato.
Ho creato un DTS all'interno di SQL Server scrivendo una applicazione in VB Script che è in grado di aprire il DB (remoto), creare un'istanza di Crystal Report, tirare su da disco il report desiderato, ed inviarlo all'utente via mail.
Ho pianificato l'esecuzione del DTS all'interno di SQL per ogni primo del mese, così ogni giorno 1 l'utente si trova in posta una mail con l'elenco delle scadenze per quel mese.

Function Main()
'
'DICHIARAZIONE DELLE VARIABILI NECESSARIE
'
Const crEDTDiskFile = 1
Const crEFTPortableDocFormat = 31
Const crEDTEMailMAPI = 2
Const Shortdate = 2

'
'APERTURA DEL DATABASE E DI TUTTI I RECORDSET
'NECESSARI ALL'OPERAZIONE
'

'--------------------------------------------
'Creo un'istanza di Crystal Report
If IsObject(oApp) Then Set oApp = Nothing
Set oApp = CreateObject("CrystalRuntime.Application")

'--------------------------------------------
'Creo un'istanza del Report e lo apro
If IsObject(oRpt) Then Set oRpt = Nothing
Set oRpt = oApp.OpenReport(Path & NomeMod, 1)

'-- INIZIO PARTE INTERESSANTE ------------------------------

oRpt.MorePrintEngineErrorMessages = False
oRpt.EnableParameterPrompting = False

oRsOperatori.Open "SELECT * FROM tbl_Operatori WHERE Op_IDGestore = " & oRsGestori("Srv_IDGestore"), conn

Clausola = "Sr_IDGestore = " & oRsGestori("Srv_IDGestore") & " AND " & DataConfronto & " <= '" & FormatDateTime(Now() + 7, ShortDate ) & "' " Selezione = "SELECT * FROM " & NomeQuery & " WHERE " & Clausola oRs.Open Selezione, conn oRpt.DiscardSavedData Set Database = oRpt.Database Set Tables = Database.Tables Set Table1 = Tables.Item(1) 'solo un report senza sub altrimenti ciclare Table1.SetDataSource oRs, 3 oRpt.ReadRecords If Err.Number <> 0 Then
conn.Close
Set oRpt = Nothing: Set oApp = Nothing: Set oRs = Nothing: Set conn = Nothing
Exit Function
End If

ElencoIndizizziOperatori = ""
While Not oRsOperatori.EOF
If oRsOperatori("Op_Email") <> "" Then
ElencoIndizizziOperatori = ElencoIndizizziOperatori + RTrim(oRsOperatori("Op_Email")) + "; "
End If
oRsOperatori.MoveNext
Wend

'INVIO PER MAIL IL REPORT CHE VIENE GENERATO
oRpt.ExportOptions.FormatType = crEFTPortableDocFormat '31 = PDF
oRpt.ExportOptions.DestinationType = crEDTEMailMAPI ' 2 = MAPI
oRpt.ExportOptions.PDFExportAllPages = True
oRpt.ExportOptions.MailSubject = "PROVA - Scadenziario!"
oRpt.ExportOptions.MailMessage = "Ecco le scadenze per il prossimo periodo"
oRpt.ExportOptions.MailToList = ElencoIndizizziOperatori
oRpt.DisplayProgressDialog = False
oRpt.Export (False)

'-- FINE PARTE INTERESSANTE ----------------------------

'
' CLEANUP DI TUTTI GLI OGGETTI PRIMA DI USCIRE
'

Main = DTSTaskExecResult_Success

End Function

LIMITAZIONI
Per inviare la mail Crystal Report si appoggia a MAPI, quindi è necessario che l'utente che esegue l'applicazione abbia una casella di posta. Questo preclude che l'esecuzione di SQL possa avvenire con un utente generico si sistema, ma obbliga ad eseguirlo con un utente reale. Cosa che già accade comunque se si vuole utilizzare il servizio di mailing all'interno di SQL.

Nessun commento: