Capitolo 15.  Le Stampe

                                                                                                                                                                                                                                                

Nota 1: Nel Paragrafo 11.15 abbiamo, senza rimpianti,  preso commiato da VB.NET per cui in questo Capitolo e seguenti studieremo solo procedure relative al VB6.

Comunque, per chi volesse fari male, avvertiamo che nel Capitolo 40 di quest'Opera viene affrontato anche il problema della stampa sotto VB.NET: auguri.

 

Nota 2: Le stampe studiate in questo Capitolo sono basate sull'uso degli oggetti Data Report. Nel Capitolo 23 di quest'Opera viene presentato anche un altro metodo, basato solo su istruzioni SQL, capace di realizzare stampe di tipo complesso che non sono possibili con i Data Reports.

 

15.1 I Form ArtREP1 e ARTREP2

In questo Capitolo studieremo l’uso dell’oggetto ADO DataReport.

Come e' noto, questo oggetto puo' essere mosso (DataSource) da due possibili motori:

 

- Un oggetto Data Environment.

- un RecordSet

 

Noi, per ogni Report seguiremo questo metodo:

1- Useremo il DataEnvironment per studiare la struttura del Report e quindi la formulazione di una SQL.

2- Dopodiche' prepareremo un Report SENZA DataEnvironment usando questa SQL come la RecordSource di un RecordSet, avendo cosi' liberta' di apportare le opportune le necessarie modifiche per includere filtri ed altre condizioni desiderate che non possono essere specificati nel Data Environment

 

Prepariamo allora una nuova Cartella con i soliti metodi  e diamole nome “ESERCIZIO_15_ADO”.

 

Le operazioni di stampa si effettuano con l’utilizzo di due Form.

Il primo serve a definire tutte le possibilta’ di stampa che vogliamo realizzare ed il secondo a definire i parametri specifici del Report  che si vuole fare e quindi a lanciare le istruzioni vere e proprie di stampa.

 

Prepariamo il  primo Form a cui daremo nome “ARTREP1”  e che avra’ questo aspetto:

 

 

Come cedremo, ciascuna Opzione definisce un Flag “FLAREPART”, dichiarato Global nel Modulo1 che servira’ ad indirizzare le operazioni vere e proprie di stampa che sono scritte nel successivo Form.

 

Il secono Form, "ARTREP2, e’ il cuore del sistema e presenta questo aspetto:

 

 

La Label “LBLCRES1”  serve ad indicare il tipo di stampa ed e' definita in “ARTREP1”

 

La Label “LBLCRES2”  e le TextBox “TXTSELE3” e “TXTSELE4” vengono rese visibili solo se la stampa prescelta richiede di definire un intervallo di date entro cui si vogliono selezionare i Records da stampare.

 

Le TextBox “TXTSELE1” e TXTSELE2” vengono rese visibili solo se il tipo di stampa richiede di indicare alcuni parametri specifici, per esempio il Codice Articolo da stampare se in “ARTREP1” si e’ scelto l’ Opzione “Un Codice Articolo” (secco).

 

Il Bottone di Help lancia diversi Form di Help a seconda della stampa richiesta, per esempio l’Help degli Articoli per la stampa sopra citata  oppure l’Help dei Produttori per l’Opzione “Un Produttore”.

 

Il Bottone “OK”, a nome “CMDPRINT” lancia la stampa vera e propria dopo aver controllato che i dati forniti siano congruenti.

 

 

15.2 Report di una Tabella senza Raggruppamenti

Il primo Report che studieremo e' una lista semplice di tutti gli articoli in ordine di ARTCODI.

 

Segueno il metodo sopra accennato, inseriamo nel Progetto un Data Environment dal Menu' Progetto. Nota: Se questa possibilita' non appare nella tendina occorre scegliere "Componenti" , selezioanare la linguetta "Finestre di Progettazione" e spuntare qui sia il Data Environment che il Data Report.

 

Inserito il DataEnvironment1, procediamo a collegarlo al nostro Database: con taso destro del Mouse battiamo su Connection1/Properties e scegliamo come Provider OLEDB il "Microsoft Jet 4.0 OLEDB Provider"

 

 

Battiamo OK e scegliamo il "MAGFILE" di "ARCHIVIODATI"

 

 

 

Nota: in prima battuta colleghiamoci al database in "ARCHIVIODATI". Se per qualche ragione dobbiamo cambiare la collocazione del Database collegato, per esempio "PATHMIA" o altro, ricordiamo che l'istruzione e' la seguente:

'ENVIRO1

'---------------------

ENVIRO1.MIOFILE.ConnectionString = "Provider=Microsoft.Jet.OLEDB.3.51;" & _

            "Persist Security Info=False;Data Source=" & pathmia

 

Confermiamo con OK e con tasto destro del mouse su "Connection1" aggiungiamo un Command e modifichiamone le Properties come da figura:

 

 

Possiamo ora aggiungere un nuovo DataReport1 ed impostarne:

- la Proprieta' "DataSource" a "DataEnvironment1" 

- la Proprieta' "DataMember" a "ARTFILE".

 

Ora,co tasto destro del mouse sul DataReport, possiamo scegiele scegliere "Retrieve Structure". Il DataReport organizzera' la sua gerarchia in base al DataEnvironment1.

 

Poniamo le proprieta' "GridX" e "GridY" uguale a 5 per disporre di un reticolato piu' fine e, con il DataEnvironment aperto:

 

 

Trasportiamo ora col mouse alcuni campi su DataReport1:

 

 

Ora aggiungiamo sel Form "ARTREP1" un bottone provvisorio con la seguente semplice istruzione:

 

Private Sub Command1_Click()
DataReport1.Show
End Sub

 

Lanciamo il Progetto, salviamo il Datareport1 e il DataEnvironment1 ed otterremo questa finesta:

 

 

 

Alla fine di questo lavoro abbiamo trovato e testato la formulazione della SQL e la struttura del Report. Siamo allora pronti ad affrontare il programma di stampa vero e proprio, cioe' la preparazione di un Report SENZA DataEnvironment.

 

Per prima cosa scriviamo le istruzioni del primo bottone di Opzione, per cui assegnamo il valore “21” al flag “FLAREPART”.:

 

Private Sub optart21_Click()

 

flarepart = 21

 

Artrep2.lblcres1.Caption = "Per Codice"

Artrep2.txtsele1.Visible = False

Artrep2.txtsele2.Visible = False

 

Artrep2.lblcres2.Caption = "Data Aggiornamento da a"

Artrep2.lblcres2.Visible = True

Artrep2.txtsele3.Visible = True

Artrep2.txtsele4.Visible = True

Artrep2.txtsele3 = "01/01/00"

Artrep2.txtsele4 = Date

 

Artrep2.cmdhlp1.Visible = False

Artrep2.Show

Artrep1.Enabled = False

 

End Sub

 

In particolare si nota che le "TXTSELE3" e "TXTSELE4" di "ARTREP2" vengono impostate come visibili dato che vogliamo stampare si tutti gli Articoli per' solo quelli aggiornati in un cero intervallo di date: una scelta di chiara impronta didattica che ci da la scusa di studiare come si applicano i filtri Data.

 

Vediamo allora il frammento di “CMDPRINT” relativo a questo tipo di stampa che e’ lanciata per valore “21” del flag “FLAREPART”.

 

Case 21
'Listato semplice
'-----------------------------------
titolo1 = "AL/A-Lista Articoli per Codice"
titolo2 = "Data Aggiornamento dal" & txtsele3 & " Al " & txtsele4
titolo3 = "Stampata il: " & Date

filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"
filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTFILE where " & filtro3 & " and " & filtro4 & " "
SQL = SQL & "ORDER BY ARTCODI"

GoTo ARTREPO1

 

Come si vede viene definita una  definizione “SQL” basata sulla SQL del DataEnvironment.

 

In particolare qui, abbiamo introdotto un filtro di intervallo di date. Inoltre,  per rendere l’esempio  un po’ piu’ interessante, abbiamo introdotto anche la possibilita’ di definire un campo (fittizio) che non esiste nella Tabella “ARTFILE” ma che noi vogliamo comunque stampare. Si tratto di “VALORE” inteso come prodotto di “COSBANETTO” e di “STOCK”.

 

Si passa poi ad una etichetta ARTREPO1 che definisce le opzioni di stampa di un DataReport preparato apposta per questa stampa: “ARTREPO1” (stesso nome per semplicita’).

 

 ARTREPO1:

'------------------------------------

'Recordset

'------------------------------------

Rs.Open SelezRepo, Cn, adOpenStatic, adLockOptimistic

Set ARTREPO1.DataSource = Rs

 

''aspetto

'---------------------

With ARTREPO1

.Caption = titolo1

'.Orientation = vbPRORLandscape

.Top = 100

.Left = 200

.Height = 8000

.Width = 14500

.LeftMargin = 700

.TopMargin = 700

.BottomMargin = 700

.Sections(2).Controls("Label1").Caption = titolo1

.Sections(2).Controls("Label2").Caption = titolo2

.Sections(2).Controls("Label3").Caption = titolo3

End With

 

'Preview  report

'---------------------

ARTREPO1.Show vbModal

GoTo fine

 

Come si vede si apre un Recordset ADO a nome “RS”  (che deve essere dichiarato Global in Modulo1) e che e'  basato su una  variable “SELEZREPO”  (Global in Modulo1) e lo si pone come “DATASOURCE” di ARTREPO1.

 

NOTA: La proprieta’ “ORIENTATION” del  DataReport e’ disponibile SOLO se si e’ installato il “Service Pack 5” oppure 6 del Visual Basic.

 

Inoltre, se si lavora con Windows 10, questa proprieta' non e' disponibile comunque, anche dopo aver passato il Pack.

Per risolvere il problema occorre impostare manualmente a "Landscape" la proprieta' orientamento della "Stampante di Default", passando per la "Gestione Dispiositivi" di Windows.

 

In ogni caso non sipuo' superare un valore di 14 000 per la Width del Data Report, pena ricevere il messaggio:" Larghezza del report maggiore della larghezza della pagina".

 

 Vediamo allora l’aspetto del DataReport “ARTREPO1”:

  

 

 

 Questo Report si ottiene chiedendo l’inserimento di un nuovo DataReport dal Menu’  Progetto e modificandone il nome in “ARTREPO1”.

 

Per il Report complessivo le Proprieta' "DATASOURCE" e "DATAMEMBER" sono Blank.

 

Nella Sezione 1 (Dettaglio) si inseriscono tante  TextBox (tasto destro del Mouse) quanti sono i campi che si vogliono stampare e si definisce per ciascuna TestBox solo e solamente la Proprieta’  “DATAFIELD” assegnandole il nome esatto del Campo (Field) della Tabella da stampare, nonche’ eventualmente  il nome dei nuovi campi virtuali creati nella “SQL” di cui sopra, nel nostro caso "VALORE".

Le Proprieta' "DATAMEMBER Vanno poste Blank (NB: nel DataReport1 erano poste ad "ARTFILE).

 

Nella sezione 2 (Intestazione di Pagina) si inseriscono tre Labels che serviranno a scrivere il titolo der Report (tipo di Report ed eventualmente, come nel nostro caso,  l’intervallo di date, etc,) . La Caption di queste tre Labels sono definite nella Routine “CMDPRINT” (vedi sopra) come contenuto delle variabili  “TITOLO1”, “TITOLO2” e “TITOLO2” che a loro volta vanno definite per ogni opzione di stampa.

 

Per finire con la Sezione 2, si inserisce ancora una Label che verra’ estesa per tutta la larghezza de Report ed in cui si scriveranno i Titoli delle Colonne che si e’ deciso di stampare. (in alternativa, naturalmente, piu' labels).

 

Ecco un esempio di stampa in cui abboamo imposto di vedere solo i Records aggiornati nel anno 2008:

 

 

Il Report e’ lanciato in modalita’  “VBMODAL” il  che significa che  fino a che non viene chiuso viene impedito ogni altro intervento dell’utente.

 

 

15.3 Report di ua Tabella con Un Raggruppamento

Proponiamoci ora di stampare un Report in cui i nostri Articoli sono raggruppati, diciamo,  per Produttore. Vogliamo inoltre che siano stampati solo i Records la cui data di aggiornamento e’ compresa in un intervallo dato.

 

Ripartiamo con i nostri DataEnvironment e RadaReport di lavoro, (che solo a questo servono nel Progetto).

 

In Proprieta' di Environment1, linguetta "Grouping", spuntiamo ed aggiungiamo i due campi per cui vogliamo fare il raggruppamento:

 

 

Andiamo ora a DataReport1. Con taso destro facciamo un "Clear Structure" quindi impostiamo le Proprieta' DataSource e dataEnvironment:

 

 

Ora, con taso destro facciamo un "Retrive Structure" ed inseriamo alcuni campi rispettando naturalmente la gerarchia di dataEnvironment1:

 

 

 

Lanciamo ora il Progetto e col solito bottone provvisorio procediamo ad uno Show del DataReport1:

 

 

 

Come si vede, vengono elencati prima i Record con Produttore "Blank" e poi gruppo per gruppo, i vari Produttori presenti nella Tabella "ARTFILE".

 

Abbiamo quasi finito la fase preparatoria: ci serve solo la formulazione della SQL: questa si ottiene battendo con taso destro sull'Environment, 

Grouping, Hyerarchy Info:

 

 

Abbiamo tutto: possiamo passare a preparare il Report senza DataEnvironment:

 

Inseriamo queste istruzioni nella secona Opzione del Form "ARTREP1":

 

Private Sub optart22_Click()

flarepart = 22

Artrep2.lblcres1.Caption = "Per Produttore"
Artrep2.txtsele1.Visible = False
Artrep2.txtsele2.Visible = False

Artrep2.lblcres2.Caption = "Data Aggiornamento da a"
Artrep2.lblcres2.Visible = True
Artrep2.txtsele3.Visible = True
Artrep2.txtsele4.Visible = True
Artrep2.txtsele3 = "01/01/" & Year(Now)
Artrep2.txtsele4 = Date

Artrep2.cmdhlp1.Visible = False
Artrep2.Show
Artrep1.Enabled = False

End Sub

 

Ed  in "ARTREP2":

 

Case 22

'-----------------------------------

titolo1 = "AL/B-Lista Articoli per Produttore"

titolo2 = "Data Aggiornamento dal" & txtsele3 & " Al " & txtsele4

titolo3 = "Stampata il: " & Date

 

filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"

filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

 

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTFILE where  " & filtro3 & " and " & filtro4 & " "

SQL = SQL & "ORDER BY PROCOGN,PRONOME,ARTCODI"

 

SelezRepo = "SHAPE {" & SQL & "}  AS ARTFILE "

SelezRepo = SelezRepo & "COMPUTE ARTFILE BY PROCOGN,PRONOME"

 

GoTo ARTREPO2

 

Qui la “SQL” e’ un po’ piu’ complicata perche’ bisogna definire, oltre ai due  filtri di Data, il metodo “SHAPE/COMPUTE” del linguaggio SQL per gestire il raggruppamento.

 

Non diamo qui l’Etichetta “ARTREPO2” perche’ e’ simile a quella gia’ vista prima.

 

Diamo invece una immagine del Datareport “ARTREPO2”:

 

 

 

Come si vede si e’ dovuto inserire un nuovo gruppo (tasto destro)  per tener conto del raggruppamento su base Produttore.

 

Per il Report complessivo le Proprieta' "DATASOURCE" e "DATAMEMBER" sono Blank.

 

Nella Sezione 6  (Intestazione di Gruppo) si inseriscono le TextBox dei Campi di Raggruppamento, nel nostro caso “PROCOGN” e “PRONOME” definendo solo la Proprieta' "DATAFIELD" con il nome del campo della Tabella, lasciando in bianco la Proprieta' "DATAMEMBER".

 

Nella Sezione 1 (Dettaglio) si inseriscono le TextBox che si vogliono e si definisce per ciascuna:

- La Proprieta’  “DATAFIELD” assegnandole il nome esatto del Campo (Field) della Tabella da stampare, nonche’ il nome del nuovo campo creato nella “SQL” di cui sopra.

- La Proprieta’  “DATAMEMBER” col nome della Tabella “ARTFILE”.

 

Ed ecco la stampa che si ottiene: dapprima gli Articoli con Produttore Blank e poi gli altri, ripartiti per Produttore, nell’intervallo di date specificato.

 

 

 

Nota: Per chi e' esperto in linguaggio SQL possiamo fornire una formulazione alternativa della SQL:

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTFILE where  " & filtro3 & " and " & filtro4 & " "

SQL = SQL & "ORDER BY TIPO,ARTCODI"

 

SelezRepo = "SHAPE {SELECT  TIPO FROM ARTFILE GROUP BY TIPO} "

SelezRepo = SelezRepo & "APPEND ({ " & SQL & " "

SelezRepo = SelezRepo & "} as ARTFILE RELATE TIPO TO TIPO)"

 

 

15.4 Report di una Tabella con un Raggruppamento (Due Tabelle)

Nell'esempio precedente,raggruppamento per Produttori,  vengono listati solo i Produttori che compaiono nella Tabella "ARTFILE".

 

In un'altra situazione puo' servire un elenco su base campo di raggruppamento in cui vengono listati tutti i gruppi di una Tabella  del database, indipendentemente che ci siano Articoli di quel gruppo oppure no.

Per esempio possiamo richiedere una stampa di tutti i "Tipi" della Tabella "TIPFILE".

 

In questo caso la DataEnvironment1 inizia con un Command "TIPFILE" ordinato per "TIPCODI" a cui va aggiunto un Child Command "ARTFILE":

 

 

Qui, nella linguetta Relation aggiungeremo la seguente Relazione TIPFILE--->ARTFILE:

 

 

Passiamo ora al nostro DataReport1 ed impostiamone le Proprieta':

 

 

Ora apriamolo e facciamo il solito "Retrieve Structure" ed aggiungiamo alcuni campi rispettando la gerarchia di DataEnvironment1:

 

 

 

Lanciamo il Report ed otteniamo:

 

 

Come desiderato, si elencano tutti i Tipi e, per quelli che hanno Articoli, questi compaiono raggruppati.

Vediamo allora la Hyerarchy Info:

 

 

Abbiamo tutti gli elementi per preparare il report ARTREPO3.

Inseriamo queste istruzioni nella secona Opzione del Form "ARTREP1":

 

Private Sub optart23_Click()

flarepart = 23
Artrep2.lblcres1.Caption = "Per Tipo"
Artrep2.txtsele1.Visible = False
Artrep2.txtsele2.Visible = False

Artrep2.lblcres2.Caption = "Data Aggiornamento da a"
Artrep2.lblcres2.Visible = True
Artrep2.txtsele3.Visible = True
Artrep2.txtsele4.Visible = True
Artrep2.txtsele3 = "01/01/" & Year(Now)
Artrep2.txtsele4 = Date

Artrep2.cmdhlp1.Visible = False
Artrep2.Show
Artrep1.Enabled = False

End Sub

 

Ed  nel Form  "ARTREP2":

 

Case 23
'Listato con un gruppo e intervallo di date - Base TIPFILE
'-----------------------------------
titolo1 = "AL/C-Lista Articoli per Tipo"
titolo2 = "Data Aggiornamento dal" & txtsele3 & " Al " & txtsele4
titolo3 = "Stampata il: " & Date

filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"
filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTFILE where " & filtro3 & " and " & filtro4 & " "
SQL = SQL & "ORDER BY ARTCODI"

SelezRepo = "SHAPE {SELECT * FROM TIPFILE ORDER BY TIPCODI} AS TIPFILE "
SelezRepo = SelezRepo & "APPEND ({ " & SQL & " "
SelezRepo = SelezRepo & "} as ARTFILE RELATE TIPCODI TO TIPO) AS ARTFILE"

GoTo ARTREPO3

 

Aggiungiamo ora un nuovo DataReport e diamogli nome "ARTREPO3".

 

 

Anche qui, come prima, si e’ dovuto inserire un nuovo gruppo (tasto destro)  per tener conto del raggruppamento su base Tipo.

 

Per il Report complessivo le Proprieta' "DATASOURCE" e "DATAMEMBER" sono Blank.

 

Nella Sezione 6  (Intestazione di Gruppo) si inseriscono le TextBox dei Campi di Raggruppamento, nel nostro caso “TIPCODI” definendo solo la Proprieta' "DATAFIELD" con il nome del campo della Tabella, lasciando in bianco la Proprieta' "DATAMEMBER".

 

Nella Sezione 1 (Dettaglio) si inseriscono le TextBox che si vogliono e si definisce per ciascuna:

- La Proprieta’  “DATAFIELD” assegnandole il nome esatto del Campo (Field) della Tabella da stampare, nonche’ il nome del nuovo campo creato nella “SQL” di cui sopra.

- La Proprieta’  “DATAMEMBER” col nome della Tabella “ARTFILE”.

 

Ed ecco la stampa che si ottiene:

 

 

Comanda il Tipo (TPFILE) e per ciascun Tipo sono elencati i relativi Articoli. Il Tipo compare comunque, sia che ci siano Articoli che no, dapprima gli Articoli con Produttore Blank e poi gli altri, ripartiti per Produttore, nell’intervallo di date specificato.

 

 

15.5 Report di Una Tabella con Due Raggruppamenti

 

Proponiamoci  di stampare un Report in cui i nostri Articoli sono raggruppati per Produttore e all’interno di ogni Produttore, per Tipo. Chiediamo inoltre che siano stampati solo i Records la cui data di aggiornamento e’ compresa in un intervallo dato.

 

Prepariamo allora questo un DataEnvironment che preveda la Tabella "ARTFILE" ordinata per "ARTCODI" e raggruppata come segue:

 

 

 

Prepariamo il Datareport1 con le seguenti Proprieta':

 

 

 

e riempiamo alcuni campi:

 

 

e lanciamo una stampa col solito bottone provvisorio:

 

 

Come si vede, ogni colta che cambia uno dei tre parametri di raggruppamento "PROCOGN"," PRONOME", "TIPO", si crea un nuovo gruppo.

 

Ecco allora la Hyerarchy Info:

 

 

Passiamo quindi alla preparazione del Report "ARTREPO5":

 

Nel Form "ARTREP1":

 

Case 24

'-----------------------------------

titolo1 = "AL/D-Lista Articoli per Produttore/Tipo"

titolo2 = "Data Aggiornamento dal" & txtsele3 & " Al " & txtsele4

titolo3 = "Stampata il: " & Date

 

filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"

filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

 

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTFILE where  " & filtro3 & " and " & filtro4 & " "

SQL = SQL & "ORDER BY ARTCODI"

 

SelezRepo = "SHAPE {" & SQL & "}  AS ARTFILE "

SelezRepo = SelezRepo & "COMPUTE ARTFILE BY PROCOGN,PRONOME,TIPO"

 

GoTo ARTREPO4

 

Ed ecco il “ARTREPO4”:

 

 

Anche qui per il Report complessivo le Proprieta' "DATASOURCE" e "DATAMEMBER" sono Blank.

 

Nella Sezione 6  (Intestazione di Gruppo) si inseriscono le TextBox dei Campi di Raggruppamento, nel nostro caso "PROCOGN", "PRONOME" e “TIPCODI” definendo solo la Proprieta' "DATAFIELD" con il nome del campo della Tabella, lasciando in bianco la Proprieta' "DATAMEMBER".

 

Nella Sezione 1 (Dettaglio) si inseriscono le TextBox che si vogliono e si definisce per ciascuna:

- La Proprieta’  “DATAFIELD” assegnandole il nome esatto del Campo (Field) della Tabella da stampare, nonche’ il nome del nuovo campo creato nella “SQL” di cui sopra.

- La Proprieta’  “DATAMEMBER” col nome della Tabella “ARTFILE”.

 

Ecco allora l’aspetto del Report:

 

 

 

 

15.6 Report di Una Tabella con Tre Raggruppamenti

Se si vuole un Report con tre gradini occorre fare uso di  due Tabelle.

 

Proponiamoci  di stampare un Report in cui i nostri Articoli sono raggruppati per Tipo e all’interno di ogni Tipo per  Produttore. Chiediamo inoltre che siano stampati solo i Recirds la cui data di aggiornamento e’ compresa in un intervallo dato.

 

Il DataEnvirinment prevede una Tabella "TIPFILE" ordinata per "TIPCODI" a cui viene aggiunto un Child Command per una Tabella "ARTFILE" ordinata per "ARTCODI" e contenente una relazione con "TIPFILE":

 

nonche' un Raggruppamento:

 

 

 

Per il Datareport1 (DataSource=DataEnvironment1, DataMember=TIPFILE) dopo retrieving della struttura, si possono aggiungere campi come da esempio:

 

 

 

Lanciando il Report si ottiene:

 

 

Visto che il Report e' quello che cercavamo, Tipo dopo Tipo e per ciascun Tipo i vari Produttori, annotaiamo la Hyerarchic Info:

 

 

Siamo pronti per il Report "ARTREP5".

 

Ecco l’Opzione “25” nel Form "ARTREP2":

 

Case 25

'-----------------------------------

'Listato con tre gruppi in scala - Spezza ogni cambio primo e ogni cambio secondo gruppo
'anche records Tipo blank
titolo1 = "AL/E-Lista Articoli per Tipo/Produttore (TIPFILE)"

titolo2 = "Data Aggiornamento dal" & txtsele3 & " Al " & txtsele4

titolo3 = "Stampata il: " & Date

 

filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"

filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

 

SQL1 = "SELECT * FROM TIPFILE ORDER BY TIPCODI"

 

SQL2 = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTFILE where  " & filtro3 & " and " & filtro4 & " "

SQL2 = SQL2 & "ORDER BY ARTCODI"

 

SelezRepo = "SHAPE { " & SQL1 & " }  AS TIPFILE "

SelezRepo = SelezRepo & "APPEND (( SHAPE { " & SQL2 & " }  AS ARTFILE "

SelezRepo = SelezRepo & "COMPUTE ARTFILE BY TIPO,PROCOGN,PRONOME) AS ARTFILE_Grouping "

SelezRepo = SelezRepo & "RELATE TIPCODI TO TIPO) AS ARTFILE_Grouping"

 

GoTo ARTREPO5

 

Il DataReport “ARTREPO5” ha questo aspetto:

 

 

Per il Report complessivo le Proprieta' "DATASOURCE" e "DATAMEMBER" sono Blank.

 

Nella Sezione 8  (Intestazione di Gruppo) si inseriscono le TextBox dei Campi di Raggruppamento, nel nostro caso “TIPCODI” definendo solo la Proprieta' "DATAFIELD" con il nome del campo della Tabella, lasciando in bianco la Proprieta' "DATAMEMBER".

 

Nella Sezione 6  (Intestazione di Gruppo) si inseriscono le TextBox dei Campi di Raggruppamento, nel nostro caso “PROCOGN” e "PRONOME" definendo:

- La Proprieta' "DATAFIELD" con il nome del campo della Tabella ("PROCOGN" e "PRONOME").

- La Proprieta’  “DATAMEMBER” con il nome di raggruppamento usato per la SelezRepo: "ARTFILE_Grouping".

 

Nella Sezione 1 (Dettaglio) si inseriscono le TextBox che si vogliono e si definisce per ciascuna:

- La Proprieta’  “DATAFIELD” assegnandole il nome esatto del Campo (Field) della Tabella da stampare, nonche’ il nome del nuovo campo creato nella “SQL” di cui sopra.

- La Proprieta’  “DATAMEMBER” col nome della Tabella “ARTFILE”.

 

Ed ecco la corrispondente stampa:

 

 

 

15.7 Report di una Tabella con Tre Raggruppamenti senza Salti

 

Il Report visto sopra e’ effettivamente a tre gradini ma comporta un importante inconveniente. Vengono elencati tutti i Tipi , sia che esistano Articoli di quel Tipo sia che no,

 

Questo a volte puo’ essere interessante ma talvolta no.

 

Vediamo allora un metodo per mantenere i tre gradini del Report ma eliminate i Tipi a cui non corrisponde nessun Articolo.

Dato che la Tabella “TIPFILE non ci sta bene, dobbiamo crearcene un’altra che contenga solo i Tipi per cui esistono effettivamente uno o piu’ Articoli.

 

Chiamiamo questa nuova Tabella “TIPTEMP” con metodo gia’ studiato sopra (copia di “TIPFILE” rinominata) e collochiamola nel DataBase “MIOFILE” collocato in Cartella “MAG.MIA”

 

A questo punto il nuovo DataReport che prepareremo (ARTREPO6) dovra’ essere connesso a “MIOFILE” e non piu’ a “MAGFILE” come e’ stato il caso finora.

 

I DataReport non accettano dati da due diversi DataBase e non accettano neanche la istruzione “JOIN” del linguaggio SQL, pertanto non resta altro che spostare anche “ARTFILE” in “MIOFILE” riempiendo la Tabella “ARTTEMP” gia’ vista in precedenza con tutti e solo i Records da stampare, cioe’ quelli dell’intervallo di data indicato dall’utente.

 

Dobbiamo quindi preparare una Routine che crei queste due Tabelle “TEMP”. Eccola:

 

Sub MakeTemp()

'svuota ARTTEMP/TIPTEMP
'------------------------
ARTQ1 = "delete from ARTTEMP"
CnMia.Execute ARTQ1
DoEvents

TIPQ1 = "delete from TIPTEMP"
CnMia.Execute TIPQ1
DoEvents

'apre ARTFILE
'---------------------------
filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"
filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

'filtro3 = "DATAGG>= '" & txtsele3 & "'"
'filtro4 = "DATAGG<= '" & txtsele4 & "' "

SQL = "SELECT * FROM ARTFILE where " & filtro3 & " and " & filtro4 & " "
SQL = SQL & "ORDER BY ARTCODI"

art22.Open "" & SQL & "", Cn, adOpenStatic, adLockOptimistic

'apre TIPTEMP
'---------------------------
SQL = "SELECT * from TIPTEMP order by TIPCODI"
TIPtmp22.Open "" & SQL & "", CnMia, adOpenStatic, adLockOptimistic

'apre ARTTEMP
'---------------------------
SQL = "SELECT * from ARTTEMP"
ARTtmp22.Open "" & SQL & "", CnMia, adOpenStatic, adLockOptimistic

'ciclo su ARTFILE
'----------------------------
Do While Not art22.EOF

'aggiunge in ARTTEMP
'---------------
ARTtmp22.AddNew
For f = 0 To ARTtmp22.Fields.Count - 1
ARTtmp22.Fields(f) = art22.Fields(f)
Next f
ARTtmp22.Update
'---------------

'aggiunge in TIPTEMP
'---------------
kriterio = "TIPCODI = '" & art22!tipo & "' "
If Not TIPtmp22.EOF Then
TIPtmp22.MoveFirst
End If
TIPtmp22.Find kriterio

If TIPtmp22.EOF Then
TIPtmp22.AddNew
TIPtmp22!TIPCODI = art22!tipo
TIPtmp22.Update
End If
'--------------------------
art22.MoveNext
Loop

'chiude
'-------------------
ARTtmp22.Close
TIPtmp22.Close
art22.Close

End Sub
 

 

Una vota in possesso delle due Tabelle possiamo scrivere l’Opzione “26” che e’ identica all 25 con la differenza che al posto delle Tabelle “FILE” vengono invocate le Tabelle “TEMP” e non esiste il filtro di date poiche' questo e' stato gia' definito in "MAKETEMP"

 

Case 26
'Listato con tre gruppi in scala - Spezza ogni cambio primo e ogni cambio secondo gruppo
'nessun record blank (File TEMP)
'-----------------------------------
titolo1 = "AL/F-Lista Articoli per Tipo/Produttore (TIPTEMP)"
titolo2 = "Data Aggiornamento dal" & txtsele3 & " Al " & txtsele4
titolo3 = "Stampata il: " & Date

MakeTemp

SQL1 = "SELECT * FROM TIPTEMP ORDER BY TIPCODI"

SQL2 = "SELECT *, (COSBANETTO*STOCK) As VALORE FROM ARTTEMP "
SQL2 = SQL2 & "ORDER BY ARTCODI"

SelezRepo = "SHAPE { " & SQL1 & " } AS TIPTEMP "
SelezRepo = SelezRepo & "APPEND (( SHAPE { " & SQL2 & " } AS ARTTEMP "
SelezRepo = SelezRepo & "COMPUTE ARTTEMP BY TIPO,PROCOGN,PRONOME) AS ARTTEMP_Grouping "
SelezRepo = SelezRepo & "RELATE TIPCODI TO TIPO) AS ARTTEMP_Grouping"

GoTo ARTREPO6

 

Anche l’Etichetta “ARTREPO6” e’ diversa dalle altre perche’ si connette al “MIOFILE” tramite la Connessione “CNMIA”  dichiarata  anch’essa, come la  “CN”, nel “APRIPROGETTO”.

 

ARTREPO6:

'------------------------------------

'Recordset

'------------------------------------

Rs.Open SelezRepo, CnMia, adOpenStatic, adLockOptimistic

Set ARTREPO6.DataSource = Rs

 

 Il DataReport "ARTREPO6" e' identico a "ARTREPO5" tranne che i riferimenti ad "ARTFILE_Grouping" vanno sostituiti con "ARTTEMP_Grouping".

 

Ecco una stampa in cui non compaiono Tipi per cui non ci sono Articoli:

 

 

 

15.8 Report di Estrazione di Un Record

Se si desidera estrarre solo un Codice di Articolo bisogna indicare quale nel “ARTREP2”

( “TXTSELE1”) e poi si usa l’Opzione “11”

 

Case 11

'-----------------------------------

titolo1 = "AR/A-Lista Articoli per il Codice: " & txtsele1

titolo2 = "Stampata il: " & Date

titolo3 = ""

 

filtro1 = "ARTCODI= " & txtsele1 & ""

 

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE  FROM ARTFILE where  " & filtro1 & " "

SQL = SQL & "ORDER BY ARTCODI"

 

SelezRepo = SQL

GoTo ARTREPO1

 

Si recupera il gia’ esaminato “ARTREPO1” cambiandogli solo la query SQL.

 

 

15.9 Report di Estrazione di Un Gruppo di Record

 

Se si vogliono estrarre tutti i Record di un certo Produttore senza intervallo di Date, si usa l’Opzione !12”

 

Case 12

'-----------------------------------

titolo1 = "AR/B-Lista Articoli per il Produttore: " & txtsele1

titolo2 = "Stampata il: " & Date

titolo3 = ""

 

filtro1 = "PROCOGN= '" & txtsele1 & "'"

filtro2 = "PRONOME= '" & txtsele2 & "'"

 

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE  FROM ARTFILE where  " & filtro1 & "  and " & filtro2 & " "

SQL = SQL & "ORDER BY ARTCODI"

 

SelezRepo = SQL

GoTo ARTREPO1

 

Analogamente con l’Opzione “13” si possono estrarre gli Articoli di un certo Tipo ma con intervallo di Data.

 

Case 13

'-----------------------------------

titolo1 = "AR/C-Lista Articoli per il Tipo: " & txtsele1

titolo2 = "Stampata il: " & Date

titolo3 = ""

 

filtro1 = "TIPO= '" & txtsele1 & "'"

filtro3 = "DATAGG>= CDate('" & txtsele3 & "' )"

filtro4 = "DATAGG<= CDate('" & txtsele4 & "' )"

 

SQL = "SELECT *, (COSBANETTO*STOCK) As VALORE  FROM ARTFILE where  " & filtro1 & "  and " & filtro3 & " and " & filtro4 & " "

SQL = SQL & "ORDER BY ARTCODI"

 

SelezRepo = SQL

GoTo ARTREPO1

 

 

15.10 L’Help di Estrazione

 

Nel Form “ARTREP2” e’ presente un bottone di Help che permette di selezionare :

 

-        Il Codice che si vuole estrarre.

-        Il Produttore che si vuole estrarre

-        Il Tipo che si vuole estrarre.

 

A seconda del valore di “FLAREPART” il bottone chiama l’Help degli Articoli (Codice) oppure dei Produttori. Volendo, si puo’ aggiungere l’Help dei Tipi.

 

Le routoines “CMDTAKE” di questi Help sono simili a quelle gia’ studiate in precedenza.

 

Per ogni Help si definisce un Flag, per esempio per i Produttori Il Flag “FLAHLPPRO” (Global nel Modulo1) che risulta necessario  nel caso che l’Help “PROHLP1! venga chiamato da punti diversi del Progetto. Ogni volta apparirà sempre lo stesso “PROHLP1” ma occorre un Flag per decidere poi le azioni dei “CMDTAKE” e “CMDABANDON”.  Ad es.

 

Private Sub cmdtake_Click()

 

SELECT Case flahlppro

Case 1

Artsk2.Enabled = True

Artsk2.txtprocogn = pro12!procogn

Artsk2.txtpronome = pro12!PRONOME

 

Case 2

Artrep2.Enabled = True

Artrep2.txtsele1 = pro12!procogn

Artrep2.txtsele2 = pro12!PRONOME

 

End SELECT

 

Unload Prohlp1

pro12.Close

End Sub

 

Come si vede, se il Flag e’ 1 si lavora su “ARTSK2” mentre se e’ 2 si lavora su “ARTREP2”.

 

 

 

 

Fine del Capitolo15. Le Stampe