Crystal Report® & VFP®

 

© Articolo di: Franco Felosi - Brescia 11 Luglio 2002 - Riproduzione vietata

Livello: Avanzato
File allegato: crystal-vfp.pdf

<parte1><parte2><parte3>

In parecchi ambienti di sviluppo una delle "parti" meno curate è quella che riguarda il report dei dati gestiti.
Pur essendo meglio di molti altri ambienti anche Visual FoxPro "zoppica" in fase di presentazione dati.
Per supplire a queste mancanze sono stati sviluppati tools che si occupano esclusivamente della generazione di report, fra questi un prodotto che merita la nostra attenzione, visto anche il notevole successo commerciale, è Crystal Report che può vantare un mercato di cinque milioni di copie ed una discreta integrazione con diffusi linguaggi ed ambienti di sviluppo.
Crystal ha "Technology Partners" del calibro di: Microsoft, IBM, Sap, Baan, Informix …. Spesso questi partners integrano versioni di Crystal Report (con funzionalità ridotte) nei loro prodotti.

Le funzioni di base di Crystal Report si possono riassumere in:

· Accesso a dati di qualsiasi tabella o database
· Eventuale elaborazione (filtri, calcoli, raggruppamenti, ordinamenti ….)
· Presentazione dei dati in base al layout definito dallo sviluppatore
· Stampa, esportazione, conversione o invio elettronico dei dati mostrati

Le possibilità d'elaborazione si estendono grazie a:

· Più di 200 di funzioni (ben documentate in inglese)
· Possibilità di utilizzare strutture di controllo
· Formattazione condizionale del testo
· Creazione di relazioni "al volo" fra tabelle del data environment del report
· Possibilità di distribuire report autosufficienti in forma eseguibile

Risorse richieste
L'investimento economico è di € 680 / 850 (listino full) in base alla versione (professional o developer)
L'investimento in termini di tempo, viste le potenzialità del prodotto, è notevole, si può quantificare in un paio di mesi per essere in grado di realizzare ed integrare con l'applicazione Visual FoxPro report di livello medio. In 15 / 20 giorni si riesce a mettere una persona senza conoscenze specifiche di VFP in grado di provvedere al mantenimento (modifiche al layout richieste dall'utente finale) dei report.

Attualmente è commercializzata la versione 8.5 in lingua inglese e la versione 8.0 in italiano, non esiste versione dimostrativa ma c'è la possibilità di recuperare documentazione e partecipare a "seminari virtuali" in linea sul sito web del produttore.

Non è richiesta alcuna licenza aggiuntiva per distribuire report, librerie e componenti necessari in runtime.

Documentazione / supporto


Il prodotto è discretamente documentato sia in forma elettronica sia con un manuale cartaceo.
Su internet si trova molta documentazione (esempi compresi), ovviamente il rapporto fra Visual FoxPro e Visual Basic 1/50 ed è quasi completamente in inglese ma con un po' di pazienza ….

Crystal Report e Visual FoxPro

Per quel che riguarda gli sviluppatori FoxPro l'integrazione fra form e report è abbastanza agevole e può avvenire utilizzando librerie (dll) o controlli activex.

In base alla mia esperienza ed alla documentazione trovata la soluzione migliore consiste nell'utilizzo del controllo activex Crystl32.OCX.

Si può standardizzare la procedura di creazione del report operando in questo modo:

· Utilizzando l'applicativo o la finestra comandi "creare" l'ambiente dati
· Realizzare il report utilizzando Crystal
· Realizzare l'integrazione fra il form ed il controllo activex

Spesso il report lavora su una copia dei dati (ottenuta con query od altro) localizzata in una cartella locale.
Esempi:
Report semplice (una sola tabella libera)

La tabella ARTI.DBF (archivio articoli) ha la seguente struttura:

Field Type Width Dec Significato
ID Integer 4   id articolo
CODE Character 20   Codice articolo
DESC Character 43   Descrizione
UMAR Character 3   Unità di misura
GRUM Character 3   Gruppo merceologico
CATE Character 3   Categoria
FAMG Character 7   Famiglia
MARC Character 20   Marca
SERI Character 20   Serie

Si vuole realizzare un report con: CODICE, DESCRIZIONE e FAMIGLIA.

Da finestra comandi creiamo una tabella temporanea in formato fox 2.6 con:
copy to c:\windows\temp\articoli fields code,desc,grum,cate,marc,famg fox2x,

questa tabella serve esclusivamente in fase di sviluppo o modifica report e, volutamente, ha dei campi in più rispetto a quelli necessari per il primo report.

Utilizzando il wizard "Esperto report" scegliamo: report standard, file di database e localizziamo la tabella c:\windows\temp\articoli, con aggiungi la inseriamo nell'ambiente dati del report e con successivo selezioniamo i campi da aggiungere.

Con Prog. Report lasciamo il wizard e lavoriamo in modo visuale sul report posizionando campi e testo ed aggiungendo eventuali elementi grafici.

Ogni report è composto di cinque sezioni base (è possibile aggiungerne a volontà) ogni sezione può essere omessa, nascosta e formattata (il tutto anche condizionato da formule tipo "ometti se …")

Con F5 otteniamo l'anteprima e, direttamente da anteprima possiamo utilizzare i menù per cambiare formato, allineamento, visualizzare i dati ….

Con il menù inserisci è possibile aggiungere campi, testo, formule, oggetti ed elementi grafici.

Potremmo impostare ordinamenti e raggruppamenti, ma, in questa fase, tralasciamo questa possibilità.

Possiamo, invece, inserire fin da subito campi "speciali" tipo nome del file, data ed ora di stampa, numero pagina, pagina x di y ….., nome dell'autore, commenti ….

Soddisfatti del risultato salviamo il report (nel nostro esempio: c:\windows\temp\report1) con l'avvertenza di togliere il check a "salva dati con il report" del menù "file".

N.B. Il report creato è autosufficiente, con l'apposito tools può essere compilato e installato come .exe, il tools provvede a creare la struttura di distribuzione con tanto di "setup.exe" per l'installazione sulla stazione dell'utente finale.

Funzionerà su qualsiasi macchina dove esiste il file: c:\windows\temp\articoli.dbf (in formato fox 2.x) indipendentemente dal fatto che siano installati Crystal o Visual FoxPro.

Per integrare il report nella nostra applicazione:

Creiamo un nuovo form.

Aggiungiamo l'activex Crystl32.OCX assegnandoli come name crw1.

Per abitudine, metto sempre tre textbox e tre pulsanti per permettere di: scegliere la stampante, scegliere il file report, cambiare il titolo predefinito del report.

Si aggiunge al form la proprietà prnset da utilizzarsi come controlsource di Text1 e la proprietà creport da utilizzare come controlsource di Text2.

Nell'init del form aggiungiamo questo codice

* imposta stampante predefinita
set printer to default
* rileva nome, driver e porta stampante
declare integer GetProfileString in win32api;
               string csection,;
               string centry,;
               string cdefault,;
               string @cretval,;
               integer nretlen   
cdefault=""
cretval=space(255)
nretlen=len(cretval)
nretlen=getprofilestring("windows","device","x",@cretval,nretlen)
thisform.prnset=left(cretval,nretlen)
release cretval,nretlen,cdefault,csection,centry

Nota: il codice precedente serve per ottenere una "stringa" che riporti, separati da virgola, nome, driver e porta stampante.
Per mostrare correttamente la finestra anteprima Crystal utilizza la stampante di destinazione che è, appunto, definita da questi tre parametri.


thisform.creport = (pathname report) c:\windows\temp\report1 && stabilisco il "nome" del report da usare

Nel click del primo pulsante (scegli stampante) mettiamo:
cprinter=""
cprinter=getprinter() && funzione fox per scelta stampante
if !empty(cprinter)then
               declare integer GetProfileString in win32api;
                              string csection,;
                              string centry,;
                              string cdefault,;
                              string @cretval,;
                              integer nretlen
               cdefault=""
               cretval=space(255)
               nretlen=len(cretval)
               nretlen=getprofilestring("devices",cprinter,"",@cretval,nretlen)
               Thisform.text1.value=cprinter+","+left(cretval,nretlen)
               release cretval,nretlen,cdefault,cprinter,csection,centry
endif

Con il click del secondo pulsante (seleziona report) attivo, di solito, un controllo CommonDialog che permette di scegliere report alternativi.

A questo proposito ho "standardizzato" il procedimento assegnando ad ogni form un nome (esempio: SA030) e filtrando il Commondialog in modo che mi mostri solo i file con estensione .rpt il cui nome inizia con il nome del form (esempio: SA030-1 elenco sintetico, SA030-2 elenco completo …..)

Nel terzo textbox l'utente può immettere il titolo da assegnare al report.

Click del pulsante "Anteprima"


* "genero" un nome di file temporaneo univoco con funzioni tipo:
mtb="C:\WINDOWS\TEMP\"+SUBSTR(SYS(2015), 3, 10)+".TMP" && anche se c'è di meglio
use arti in 0 noupdate && apro il file dati
select arti
* copio i record nel file temporaneo che utilizzerò per la stampa
copy to (mtb) fields code,desc,grum,cate,marc,famg fox2x && volutamente utilizzo formato Fox 2.x
* chiudo tutte le tabelle
close table
* inizio procedura di stampa
with thisform.crw1
        .reportfilename = thisform.Text2.value && stabilisco il nome del file report
        .reporttitle = thisform.Text3.value && utilizzo text3 come titolo report
        * con quest'istruzione imposto la "sorgente dati" della prima (ed unica) tabella nel report
        .datafiles(0) = (mtb)
        * per sicurezza forzo un refresh dei dati (se per sbaglio avessi salvato il report con i dati)
        .discardsaveddata = 1
        * rilevo dalla proprietà del form nome,porta e driver stampante
        .printername=left(thisform.prnset,at(",",thisform.prnset,1)-1)
        .printerport=right(thisform.prnset,len(thisform.prnset)-at(",",thisform.prnset,2))
        .printerdriver=substr(thisform.prnset,at(",",thisform.prnset,1)+1,;
        -at(",",thisform.prnset,1)+(at(",",thisform.prnset,2)-1))
        * imposto il titolo della finestra anteprima
        .windowtitle = "Anteprima di stampa "+.reportfilename
        * stabilisco che l'utente non possa esportare il report
        .WindowShowExportBtn = 0
        * decido (anche se è di default) che la destinazione è "finestra anteprima"
        .destination = 0
        * lancio il report
        .action = 1
endwith

Ovviamente subclassando ed utilizzando funzioni utente si può ottenere un codice più elegante ed efficiente.

<SEGUE>

 

© Articolo di: Franco Felosi - Brescia 11 Luglio 2002 - Riproduzione vietata

© FoxPro e Visual FoxPro sono un marchi registrati da Microsoft Corporation
© Crystal Report è un marchio di proprietà SEAGATE TECNOLOGY LLC

 



Data: 13/07/2002
webmaster@foxitaly.com

 

dal 22 Giugno 1999