Il linguaggio di programmazione Delphi
 

Stampa da DBGrid

Stark 8 Apr 2017 16:22
Sto facendo una proc di stampa da DBGrid e l'ho fatto con QuickReport, ma
non riesco ad allineare correttamente i titoli delle colonne al loro
contenuto, soprattutto quando le colonne e i titoli del DBGrid sono
dichiarati con alignment taCenter.

La larghezza della colonna la determino con l'espressione:
DBGrid.Columns[i].width;

e per determinare la larghezza del Title ho provato con:
DBGrid.Canvas.TextWidth(AGrid.Columns[i].Title.Caption

ma credo di stare usando due unità di misura completamente differenti dati i
risultati. Pensavo che entrambi esprimessero i 'punti'. Qualcuno mi può
chiarire ?
Daniele 11 Apr 2017 10:16
Ciao,

> Sto facendo una proc di stampa da DBGrid e l'ho fatto con QuickReport, ma
> non riesco ad allineare correttamente i titoli delle colonne al loro
> contenuto, soprattutto quando le colonne e i titoli del DBGrid sono
> dichiarati con alignment taCenter.

Premetto che non uso la DBGrid (preferisco fare tutto a mano e usare una
griglia normale) quindi prendi tutto con le dovute cautele.
Inoltre io uso il QR 5.06 su delphi seattle.
Per adattare la larghezza delle colonne al contenuto puoi stravolgere questa
procedura

procedure AdjustColumnWidths(DBGrid: TDBGrid);
var
TotalColumnWidth, ColumnCount, GridClientWidth, Filler, i: Integer;
Old : Integer;
begin
ColumnCount := DBGrid.Columns.Count;
if ColumnCount = 0 then
Exit;
for i := 0 to ColumnCount-1 do
If Not DBGrid.Columns[I].Visible Then ColumnCount:=ColumnCount-1;
// compute total width used by grid columns and vertical lines if any
TotalColumnWidth := 0;
for i := 0 to ColumnCount-1 do
Begin
If DBGrid.Columns[I].Visible Then
TotalColumnWidth := TotalColumnWidth + DBGrid.Columns[i].Width;
End;
if dgColLines in DBGrid.Options then
// include vertical lines in total (one per column)
TotalColumnWidth := TotalColumnWidth + ColumnCount;

// compute grid client width by excluding vertical scroll bar, grid
indicator,
// and grid border
GridClientWidth := DBGrid.Width - GetSystemMetrics(SM_CXVSCROLL);
if dgIndicator in DBGrid.Options then begin
GridClientWidth := GridClientWidth - IndicatorWidth;
if dgColLines in DBGrid.Options then
Dec(GridClientWidth);
end;
if DBGrid.BorderStyle = bsSingle then begin
if DBGrid.Ctl3D then // border is sunken (vertical border is 2 pixels
wide)
GridClientWidth := GridClientWidth - 4
else // border is one-dimensional (vertical border is one pixel wide)
GridClientWidth := GridClientWidth - 2;
end;

// adjust column widths
if TotalColumnWidth < GridClientWidth then begin
Filler := (GridClientWidth - TotalColumnWidth) div ColumnCount;
for i := 0 to ColumnCount-1 do
Begin
If DBGrid.Columns[I].Visible Then
DBGrid.Columns[i].Width := DBGrid.Columns[i].Width + Filler;
End;
end
else if TotalColumnWidth > GridClientWidth then begin
Filler := (TotalColumnWidth - GridClientWidth) div ColumnCount;
if (TotalColumnWidth - GridClientWidth) mod ColumnCount <> 0 then
Inc(Filler);
for i := 0 to ColumnCount-1 do
Begin
If DBGrid.Columns[I].Visible Then
Begin
Old:=DBGrid.Columns[i].Width;
DBGrid.Columns[i].Width := DBGrid.Columns[i].Width - Filler;
If DBGrid.Columns[i].Width<0 Then DBGrid.Columns[i].Width:=Old;
End;
End;
end;
end;

che, onestamente, non mi ricordo dove l'ho trovata (risale a qualche anno
fa).

Per quanto riguarda la stampa, utilizzando la stringgrid, io procedo in
questo senso:
Nel report configuro la grafica e le opportune bande, poi quando devo
stampare il contenuto della griglia utilizzo una qrLoopBand.

Sempre per onesta' intellettuale, devo dirti che i miei report sono report
"elemetari" senza sorta di grouping, calcioli parziali ecc...., inoltre la
dimensione dei db e' veramente minimale (qualche decina di migliao di
record, non milioni)
Il lavoro di preparazione lo svolgo a priori sulla griglia, poi quando
stampo devo solo preoccuparmi di stampare la griglia.
La decisione di utilizzare la stringgrid invece della dbgrid sta nel fatto
che le operazioni di filtraggio, ordinamento ecc ecc sono piu' veloci sulla
prima che non sul db (su cui si deve operare con sql e poi con filter).
Per le mie esigenze va piu' che bene.

Ciao

Daniele
Giacomo Degli Esposti 11 Apr 2017 12:07
Il giorno sabato 8 aprile 2017 16:22:20 UTC+2, Stark ha scritto:
> Sto facendo una proc di stampa da DBGrid e l'ho fatto con QuickReport, ma
> non riesco ad allineare correttamente i titoli delle colonne al loro
> contenuto, soprattutto quando le colonne e i titoli del DBGrid sono
> dichiarati con alignment taCenter.
>
> La larghezza della colonna la determino con l'espressione:
> DBGrid.Columns[i].width;
>
> e per determinare la larghezza del Title ho provato con:
> DBGrid.Canvas.TextWidth(AGrid.Columns[i].Title.Caption
>
> ma credo di stare usando due unità di misura completamente differenti dati i
> risultati. Pensavo che entrambi esprimessero i 'punti'. Qualcuno mi può
> chiarire ?

Che risultati hai ottenuto?

La butto li, tirando a indovinare: la DBGrid ti dice che una colonna
e' larga 80 pixel. A video a video e' circa 2 cm ma quando vai a stampare
la colonna viene larga 3 millimetri?

ciao
Giacomo
Stark 25 Apr 2017 14:32
Ciao Daniele e grazie per il codice. Purtroppo quella procedura la conoscevo
già e non funziona affatto, pur essendo pubblicata sul sito Embarcadero. Non
dimensiona correttamente alla larghezza del contenuto del campo e ha degli
strani comportamenti quando si ridimensiona la finestra. E' interessante che
tu preferisci la stringGrid al DBGrid. Ma perchè trovi più semplice il
filtraggio e l'ordinamento dei campi quando agendo sul dataset un set filter
e un order by bastano allo scopo ?
Comunque, io cercavo di creare una procedura di stampa un pò universale, nel
senso che un bottone Stampa potesse accompagnare un qualsiasi DBGrid con
qualunque contenuto. Evidentemente la cosa deve essere più complicata di
quanto io mi renda conto, se questa cosa non c'è..
Daniele 26 Apr 2017 10:29
Ciao,

> E' interessante che tu preferisci la stringGrid al DBGrid.
> Ma perchè trovi più semplice il filtraggio e l'ordinamento dei campi
> quando agendo sul dataset un set filter e un
> order by bastano allo scopo ?

Il componente che preferisco usare in assoluto, quando si tratta di
stringgrid, e' la stringgrid della TMS.
E' molto ben fatta, veloce e facile da usare.
Utilizzo questo componente quando ho la sola necessita' di leggere i dati.
Ogni volta che si deve fare un'ordinamento (order by) devi sempre rifare la
query (ma forse sbaglio).
Quindi sql per estrarre i dati, grid semplice per leggerli.

Se invece devo anche scrivere sul db, i componenti che utilizzo sono
- la versione db della griglia della TMS
- la griglia della Scalabium
Quest'ultima e' davvero ben fatta e, in alcune circostanze, molto piu'
veloce di quella della tms.
Prova a dare un'occhiata a questa griglia (www.scalabium.com) magari
risolvi.

> Comunque, io cercavo di creare una procedura di stampa un pò universale,
> nel senso che un bottone Stampa potesse accompagnare un qualsiasi DBGrid
> con qualunque contenuto. Evidentemente la cosa deve essere più complicata
> di quanto io mi renda conto, se questa cosa non c'è..

Bhe la stampa e' tua, nel senso che a te spetta il compito di gestirla.
Di per se nella funzione di stampa puoi fare quello che vuoi, anche passare
tutta la griglia o tutto il dataset.
Quello che puo' variare e' la configurazione della griglia (colonne) o il
dataset.
Nel caso tu hai intenzione di fare una procedura universale, devi anche
pensare che i dati che andrai a visualizzare nel tuo report siano sempre in
quell'ordine.

Nelle mie due necessita' (stringgrid e dbstringgrid) ho risolto in questi 2
modi.
1) Nella form di generazione del report, nelle uses indico la unit dove e'
presente la stringgrid.
In questo modo ho l'accesso alla griglia e stampo quello che devo.
2) Dato che uso la versione db della griglia e che questa e' legata ad un
data set, per la stampa leggo direttamente quello e non la griglia.

Onestamente, viste le mie scarse necessita' di stampa, non ho mai avuto
grosse problematiche nei report.
Quindi per poter risolvere il tuo problema dovrebbe risponderti qualcuno con
piu' esperienza di me.

Ciao

Daniele
Stark 26 Apr 2017 15:22
"Daniele" ha scritto nel messaggio news:odploo$sma$1@gioia.aioe.org...

Ciao,

> E' interessante che tu preferisci la stringGrid al DBGrid.
> Ma perchè trovi più semplice il filtraggio e l'ordinamento dei campi
> quando agendo sul dataset un set filter e un
> order by bastano allo scopo ?

Il componente che preferisco usare in assoluto, quando si tratta di
stringgrid, e' la stringgrid della TMS.
E' molto ben fatta, veloce e facile da usare.
Utilizzo questo componente quando ho la sola necessita' di leggere i dati.
Ogni volta che si deve fare un'ordinamento (order by) devi sempre rifare la
query (ma forse sbaglio).
Quindi sql per estrarre i dati, grid semplice per leggerli.

Se invece devo anche scrivere sul db, i componenti che utilizzo sono
- la versione db della griglia della TMS
- la griglia della Scalabium
Quest'ultima e' davvero ben fatta e, in alcune circostanze, molto piu'
veloce di quella della tms.
Prova a dare un'occhiata a questa griglia (www.scalabium.com) magari
risolvi.

> Comunque, io cercavo di creare una procedura di stampa un pò universale,
> nel senso che un bottone Stampa potesse accompagnare un qualsiasi DBGrid
> con qualunque contenuto. Evidentemente la cosa deve essere più complicata
> di quanto io mi renda conto, se questa cosa non c'è..

Bhe la stampa e' tua, nel senso che a te spetta il compito di gestirla.
Di per se nella funzione di stampa puoi fare quello che vuoi, anche passare
tutta la griglia o tutto il dataset.
Quello che puo' variare e' la configurazione della griglia (colonne) o il
dataset.
Nel caso tu hai intenzione di fare una procedura universale, devi anche
pensare che i dati che andrai a visualizzare nel tuo report siano sempre in
quell'ordine.

Nelle mie due necessita' (stringgrid e dbstringgrid) ho risolto in questi 2
modi.
1) Nella form di generazione del report, nelle uses indico la unit dove e'
presente la stringgrid.
In questo modo ho l'accesso alla griglia e stampo quello che devo.
2) Dato che uso la versione db della griglia e che questa e' legata ad un
data set, per la stampa leggo direttamente quello e non la griglia.

Onestamente, viste le mie scarse necessita' di stampa, non ho mai avuto
grosse problematiche nei report.
Quindi per poter risolvere il tuo problema dovrebbe risponderti qualcuno con
piu' esperienza di me.
Ciao
Daniele

Grazie, apprezzo che tu sia disponibile a condividere la tua esperienza. Io
ormai uso Delphi più per hobby che per altro, pur mantenendo qualche
applicazione abbastanza corposa. Invece mi pare che il forum non lo sia
tanto, e oltretutto è scarsamente frequentato. Sarà che non è più il periodo

di Delphi ..
enrico.giudici@gmail.com 26 Apr 2017 15:53
Ciao Stark,

> Grazie, apprezzo che tu sia disponibile a condividere la tua esperienza. Io
> ormai uso Delphi più per hobby che per altro, pur mantenendo qualche
> applicazione abbastanza corposa. Invece mi pare che il forum non lo sia
> tanto, e oltretutto è scarsamente frequentato. Sarà che non è più il
periodo
> di Delphi ..

sinceramente, nel mio caso non ho mai utilizzato un qualcosa che stampasse una
dbgrid in modo "universale", cioè un metodo unico per qualsiasi dbgrid
all'interno dell'applicativo e ti spiego anche i motivi.
Nel mio applicativo l'utente ( mio cognato ) ed i suoi collaboratori non hanno
mai avuto necessità di avere su carta il contenuto di una dbgrid anche perchè
vi sono dei report ah hoc che stampano i relativi dati, è capitato però un
paio di volte che mio cognato volesse al volo su carta alcuni record della
dbgrid, in questo caso ha fatto semplicemente un print-screen della videata.

Ciao da Enrico Giudici c/o Anthelios
Stark 27 Apr 2017 09:53
ha scritto nel messaggio
news:865a5e1d-cc3a-4f1e-93ac-f19da198c780@googlegroups.com...

Ciao Stark,

> Grazie, apprezzo che tu sia disponibile a condividere la tua esperienza.
> Io
> ormai uso Delphi più per hobby che per altro, pur mantenendo qualche
> applicazione abbastanza corposa. Invece mi pare che il forum non lo sia
> tanto, e oltretutto è scarsamente frequentato. Sarà che non è più il
> periodo
> di Delphi ..

sinceramente, nel mio caso non ho mai utilizzato un qualcosa che stampasse
una dbgrid in modo "universale", cioè un metodo unico per qualsiasi dbgrid
all'interno dell'applicativo e ti spiego anche i motivi.
Nel mio applicativo l'utente ( mio cognato ) ed i suoi collaboratori non
hanno mai avuto necessità di avere su carta il contenuto di una dbgrid anche
perchè vi sono dei report ah hoc che stampano i relativi dati, è capitato
però un paio di volte che mio cognato volesse al volo su carta alcuni record
della dbgrid, in questo caso ha fatto semplicemente un print-screen della
videata.
Ciao da Enrico Giudici c/o Anthelios

Ma si, più o meno è proprio questa l'esigenza che volevo coprire. E cioè,
quando una DBGrid è usata per visualizzare un set di dati limitato che a
volte voglio anche conservare su un foglio di carta. Una stampa dello
schermo non va bene perchè magari non comprende tutto. Certo potrei per
ognuno di questi casi sviluppare un report, ma un dbgrid già fronisce di sè
i dati da stampare, le testate, le larghezze, etc. Ecco perchè pensavo ad
una proc generalizzata.
enrico.giudici@gmail.com 27 Apr 2017 11:30
Ciao Stark,

> Ma si, più o meno è proprio questa l'esigenza che volevo coprire. E cioè,
> quando una DBGrid è usata per visualizzare un set di dati limitato che a
> volte voglio anche conservare su un foglio di carta. Una stampa dello
> schermo non va bene perchè magari non comprende tutto. Certo potrei per
> ognuno di questi casi sviluppare un report, ma un dbgrid già fronisce di sè
> i dati da stampare, le testate, le larghezze, etc. Ecco perchè pensavo ad
> una proc generalizzata.

tieni presente che, nel mio caso, le dbgrid utilizzate all'interno
dell'applicativo di mio cognato hanno pochissimi dati, giusto quelli essenziali
per far capire a mio cognato o ai suoi collaboratori le info essenziali, oltre a
questo (opinione personale), mettendo tanti dati nelle dbgrid si ottiene un
peggioramento delle performance sia per recepirle sia nella navigazione. Per mio
cognato non ha senso scorrersi tutto all'interno della dbgrid. Ecco perchè
quando gli occorre il dettaglio utilizza uno o più report costruiti ad hoc.

Ciao da Enrico Giudici c/o Anthelios.
Daniele 28 Apr 2017 13:29
Ciao,
non si tratta di avere filtrato o meno il database (la griglia serve solo
per vedere i dati) ma si tratta di cosa vuoi fare con la griglia.
E' quasi impossibile fare un report universale per *qualsiasi* database o
griglia.
Il perche' e' abbastanza semplice:
Il database puo' avere decine (se non centinaia) di tabelle ognuna con poche
o decine di colonne (campi).
Se poi fai una select con diverse join su chissa' quali tabelle avrai come
risultato un dataset con colonne anche create al volo.

Mi spieghi come puoi fare un report "universale" che puoi chiamare in
chissa' quali punti del tuo programma?
Nel mio caso ho 4 form dove eseguo interrogazioni al database (dove uso
largamente le join) con 4 report differenti, ognuno dedicato al lavoro che
e' richiesto.

Diverso e' gestire il report sulla griglia che invoca il report.
Tu sai cos'hai nella griglia (hai definito tu le colonne) che NON
necessariamente rispecchia tutto il record (record di 100 campi, ma
visualizzati solo 10) e, dato che stai usando una dbgrid, sai che ogni riga
corrisponde ad un record.
A questo punto scorrendo il dataset ( while not Dataset.eof do) nel tuo
report visualizzi i dati che hai bisogno (che non sono necessariamente
quelli esposti nella griglia).

Enrico ti ha suggerito bene, se dopo il lavoro sulla griglia hai pochi
record (righe) e i dati che hai bisogno sono tutti in vista, basta un print
screen.

Dato che usi QuickReport (lo uso anch'io) non riesci ad usare il componente
TQrGridReport che permette un link ad un dbgrid (io, come gia' detto, non lo
uso).

Ciao

Daniele

Links
Giochi online
Dizionario sinonimi
Leggi e codici
Ricette
Testi
Webmatica
Hosting gratis
   
 

Il linguaggio di programmazione Delphi | Tutti i gruppi | it.comp.lang.delphi | Notizie e discussioni delphi | Delphi Mobile | Servizio di consultazione news.