Capitolo 29 Grafici

 

29.1 Tipi Di Grafico

 

In questo Capitolo studieremo come costruire grafici. Per eseguire l’Esercizio prepariamo una nuova Cartella, la C:\GRIGLIE_ADO\Esercizio_26. L’esercizio sviluppato e’ presente come al solito nella Cartella Soluzione.

 

Per l’Esercizio e’  necessario aggiungere due Componenti:

 

l’Oggetto MSChart della Microsoft e

l’Oggetto CSXGraphTrial della Chestysoft

 

L’utility CsxGraph puo’ essere scaricata gratuitamente da internet dal sito della casa che lo produce. Il sito per il download e’:

 

http://www.chestysoft.com/dllregsvr/default.asp

 

Si scarica un eseguibile che crea e registra l’OCX, Dopo di che l’OCX e’ disponibile tra i Componenti del Progetto.

 

Inoltre, dato che opereremo,   oltre che con Oggetti ADO e DAO, anche con Oggetti Excel,  occorre prevederne i rispettivi Riferimenti nel Progetto:

 

 

 

 

E’ importante precisare che con gli strumenti sopra descritti potremo preparare due tipologie di grafico, con risultati piu’ o meno soddisfacenti a seconda dello strumento utilizzato, come preciseremo di volta in volta.:

 

a-   Grafici di tipo Matematico/Scientifico, in cui i valori su entrambe le ascisse sono posizionati in modo proporzionale al loro valore. Servono per rappresentare con verosimiglianza l’andamento di fenomeni naturali/matematici, come ad esempio il comportamento della pressione di un gas contenuto in un recipiente chiuso al variare della temperatura oppure la rappresentazione grafica di una funzione, per esempio X = Y 2.

 

b-   Grafici di tipo Marketing in cui solo le etichette sull’asse delle Y (ordinate) sono poste in modo proporzionale al loro valore, mentre quelle sulle X (ascisse) sono semplicemente poste a distanza regolare una dall’altra. Grafici di questo tipo servono per rappresentare visivamente l’andamento di fenomeni commerciali, come le vendite/ incassi mese per mese o l’andamento di una azione o ancora il costo/rendimento di ciascun reparto di una azienda.

 

 

29.2 Grafici con Excel (Foglio Esistente)

 

I grafici con Excel sono quelli che realizzano al meglio i grafici di tipo Scientifico e che permettono anche una buona visualizzazione di quelli di tipo Marketing.

Studieremo due tipi di grafico Excel, il primo utilizzando un Foglio esistente e preparato in anticipo ed il secondo che crea direttamente un nuovo Foglio contenente il grafico.

 

Per il primo tipo il Form di lancio ha questo aspetto:

 

 

 

 

L’esercizio si propone di tracciare una curva definita da tre punti sull’asse X e tre corrispondenti punti sull’asse  Y. Resta sottinteso che il numero di punti puo’ essere aumentato a piacere. Per la loro gestione  e’ quindi conveniente assegnare sempre lo stesso nome  a tutte le caselle di testo che li identificano e giocare poi con la proprieta’ indice: ad esempio txtXX(0), txtXX(1), etc.

 

Vogliamo poi assicurarci la possibilita’ di poter inserire in queste caselle TextBox delle X dati di qualunque tipo cioe’  dati tipo Data, dati tipo Testo, dati tipo Numero.

 

Il grafico dovra’ essere tracciato in un Foglio Excel preesistente in cui avremo preparato il tipo opportuno di grafico tra i molti messi a disposizione da Excel.  In particolare noi prepareremo due fogli: uno destinato ospitare i  grafici generati da dati tipo Numero e tipo Data, l’altro i grafici tipo Testo. La necessita’ di distinguere deriva dal fatto che per il primo foglio occorre preparare un grafico tipo “DISPERSIONE” (scattering) mentre per il secondo il grafico sara’ tipo “LINEE”.

 

E’ ovvio che potremo anche scegliere altri tipi, a barre, ad area, a torta etc pero’ qui vogliamo concentrarci sulla realizzazione di grafici di tipo Scientifico che sono possibili solo con grafici a linea.

 

Apriamo quindi Excel  con un nuovo foglio che salveremo con nome

 

“C:\GRIGLIE_ADO\ARCHIVIODATI\MAG.MIA\GRAFNUME.XLS”

 

ed inseriamo tre coppie di valori a caso che servono solo a definire l’area da cui tracciare il grafico come da figura seguente:

 

 

 

In modo analogo creiamo un altro foglio che salveremo con nome

 

“C:\GRIGLIE_ADO\ARCHIVIODATI\MAG.MIA\GRAFTEXT.XLS”

 

Su questo foglio pero’ i valori delle celle A1, A2, A3 saranno di tipo test, ad esempio “A”, “B”, “C” e il tipo  di grafico sara’ a “LINEE”.

 

 

Dopo questo lavoro preliminare possiamo ora scrivere la Routine che realizza il grafico, la “CMDSHOW_CLICK”. Data la sua importanza, la illustriamo frammento per frammento

 

Si inizia con un frammento che si occupa di individuare la tipologia dei dati che l’Utente ha inserito nelle TextBox delle X (variabile “tipografo”):

 

'Dichiarazioni

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

Dim excel_app As Excel.Application

Dim excel_sheet As Worksheet

 

definisce tipografo -->numero, testo, data

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

tipografo = "numero"

If Not IsNumeric(txtXX(0)) Then

 

'data/testo

On Error GoTo testo

date_parts = Split(CDate(txtXX(0)), "/")

day_part = date_parts(0)

month_part = date_parts(1)

year_part = date_parts(2)

myrdata = (day_part & "-" & Mid$(MonthName(month_part), 1, 3) & "-" & year_part)

tipografo = "data"

GoTo avanti

 

testo:

tipografo = "testo"

On Error GoTo errori

avanti:

 

End If   'isnumeric

 

In pratica si analizza “TXTXX(0)” e si determina se il dato contenuto e’ di tipo “NUMERO”, “DATA”, “TESTO”. Questo e’ fondamentale per decidere quale foglio Excel aprire:

 

' Create the Excel application.

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

Set excel_app = CreateObject("Excel.Application")

pathexcel = excel_app.Path

 

' Comment this line to make Excel notvisible.

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

‘excel_app.Visible = True

 

' Open the Excel spreadsheet.

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

If tipografo = "testo" Then

excel_app.Workbooks.Open FileName:=txtEXCTEXT.Text

Else

excel_app.Workbooks.Open FileName:=txtEXCNUME.Text

End If

 

' Check for later versions.

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

If Val(excel_app.Application.Version) >= 8 Then

Set excel_sheet = excel_app.ActiveSheet

Else

Set excel_sheet = excel_app

End If

 

La variabile “PATHEXCEL” contiene la definizione del percorso di “EXCEL.EXE” nel computer, percorso che puo’ essere diverso per ogni macchina.

 

Il Foglio Excel viene mantenuto non visibile durante il processo in cui si inseriscono  i dati forniti dall’utente nelle TextBox. Contemporaneamente si formattano le celle:

 

 

' Valori delle X

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

For r = 1 To 3

 

Select Case tipografo

 

Case "data"

'---

excel_sheet.Cells(r, 1).NumberFormat = "dd-mmm-yy"

excel_sheet.Cells(r, 1) = CDate(txtXX(r - 1))

 

Case "numero"

'---

excel_sheet.Cells(r, 1).NumberFormat = "### ##0.00;;#"

excel_sheet.Cells(r, 1) = virvalore(txtXX(r - 1))

 

Case "testo"

'---

excel_sheet.Cells(r, 1).NumberFormat = ""

excel_sheet.Cells(r, 1) = txtXX(r - 1)

 

End Select

 

'valori delle Y

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

excel_sheet.Cells(r, 2).NumberFormat = "### ##0.00;;#"

excel_sheet.Cells(r, 2) = virvalore(txtYY(r - 1))

'---

Next r

 

La Routine termina con la chiusura degli Oggetti Excel per  eliminare ogni traccia di Excel dal Task Manager. Di seguito si puo’ passare alla riapertura di una nuova istanza di Excel con il grafico interessato

 

'seleziona 1a cella

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

excel_sheet.Cells(1, 1).Select

 

'chiude Fogli con/senza salvare

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

excel_app.ActiveWorkbook.Close True

 

'chiude Excel.

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

excel_app.Workbooks.Close

excel_app.Quit

Set excel_sheet = Nothing

Set excel_app = Nothing

                          

'riapre Excel

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

If tipografo = "testo" Then

exe$ = pathexcel & "\EXCEL.EXE" & Space(1) & txtEXCTEXT

Else

exe$ = pathexcel & "\EXCEL.EXE" & Space(1) & txtEXCNUME

End If

 

AA = Shell(exe$, 1)

 

Exit Sub

 

errori:

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

titolo = "Attenzione !"

Messaggio = "Dati incongruenti  !"

Stile = vbOKOnly + vbExclamation ' Definisce pulsanti.

Risposta = MsgBox(Messaggio, Stile, titolo)

 

End Sub 

 

Se ora si lancia il Progetto si nota che:

-        in caso che i  dati sulle ascisse siano di tipo “NUMERO” e “DATA”, si ottiene un grafico di tipo scientifico,

-        in caso invece che si inseriscano dei valori “TESTO”, questi vengono trattati come etichette a distanza uguale tra loro.

 

  

29.3 Grafici con Excel (Foglio Creato)

 

Esiste anche un’altra possibilita’ di preparare un grafico in Excel,  cioe’ la creazione di un Foglio e di un Grafico completamente ex-novo. Qui non si necessita quindi della preparazione preliminare dei fogli come visto sopra. 

 

La Routine e una rielaborazione di un’idea di Internet, VBHelper, ed e’ decisamente molto interessante anche se presenta l’inconveniente di girare solo una volta (istruzione End).

Infatti, se nell’esempio precedente il foglio Excel esisteva fisicamente e quindi poteva essere chiuso da programma e poi riaperto con sessione esterna, qui il foglio e’ solo creato in memoria e non puo’ essere chiuso dato che deve essere mostrato.

La chiusura di Excel va fatta a mano dopo aver salvato oppure no il grafico creato.

 

Per questo Esercizio prepareremo una serie un po’ piu’ numerosa di dati, diciamo 15, che collocheremo anche qui in una serie di TextBox.

 

 

 

Naturalmente nelle TextBox si possono immettere i dati che si vogliono: noi supponiamo ad esempio di voler plottare un grafico che porta sulle ascisse i valori dei gradi di un cerchio, diciamo da 1° a circa 200° , intervallati di 15° (o, 15, 39, …) e sulle ordinate i valori della funzione Sin(X).

 

Per immettere rapidamente i dati X ed Y useremo questa routine:

 

Private Sub cmdCARICA_Click()

 

'carica gradi (intervallo di 15°) e seni

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

For i = 0 To 14

'---

'gradi-->radianti

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

pigreco = 4 * Atn(1)

alfagra1 = 15 * i

alfarad1 = (alfagra1 * (2 * pigreco)) / 360   'radianti

 

txtVALX(i).Text = Format(alfagra1, "###.0")

txtVALY1(i).Text = Format(Sin(alfarad1), "###.0000")

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

'---

Next i

 

End Sub

 

Ed ecco come si presentano le TextBox con i dati:

 

 

A  questo punto possiamo definire il Titolo desiderato per l’intero grafico ed i titoli da mettere sull’asse X ed Y rispettivamente. Dopodiche’ possiamo lanciare la Routine di creazione Grafico

 

La routine contiene varie parti comuni a quanto visto sopra che servono a decidere il tipo di grafico da creare. La differenza e’ che qui la istruzione “excel_app.Visible = True” e’ attiva.

 

Private Sub cmdCREA_GRAF_Click()

 

'Dichiarazioni

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

Dim excel_app As Excel.Application

Dim excel_sheet As Worksheet

Dim new_chart As Chart

Dim new_book As Workbook

 

'definisce tipografo

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

tipografo = "numero"

If Not IsNumeric(txtXX(0)) Then

 

'data/testo

On Error GoTo testo

date_parts = Split(CDate(txtXX(0)), "/")

day_part = date_parts(0)

month_part = date_parts(1)

year_part = date_parts(2)

myrdata = (day_part & "-" & Mid$(MonthName(month_part), 1, 3) & "-" & year_part)

tipografo = "data"

GoTo avanti

 

testo:

tipografo = "testo"

On Error GoTo errori

avanti:

 

End If   'isnumeric

 

' Create the Excel application.

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

Set excel_app = CreateObject("Excel.Application")

pathexcel = excel_app.Path

 

' Comment this line to make Excel notvisible.

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

excel_app.Visible = True

 

' Create a new spreadsheet.

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

Set new_book = excel_app.Workbooks.Add()

Set excel_sheet = new_book.Sheets(1)

  

' Valori date delle X

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

For r = 1 To 3

 

Select Case tipografo

 

Case "data"

'---

excel_sheet.Cells(r, 1).NumberFormat = "dd-mmm-yy"

excel_sheet.Cells(r, 1) = CDate(txtXX(r - 1))

 

Case "numero"

'---

excel_sheet.Cells(r, 1).NumberFormat = "### ##0.00;;#"

excel_sheet.Cells(r, 1) = virvalore(txtXX(r - 1))

 

Case "testo"

'---

excel_sheet.Cells(r, 1).NumberFormat = ""

excel_sheet.Cells(r, 1) = txtXX(r - 1)

 

End Select

 

'valori delle Y

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

excel_sheet.Cells(r, 2).NumberFormat = "### ##0.00;;#"

excel_sheet.Cells(r, 2) = virvalore(txtYY(r - 1))

'---

Next r

 

Seguono le istruzioni relative alla creazione del grafico:

 

'crea grafico

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

Set new_chart = Charts.Add()

With new_chart

If (tipografo = "numero") Or (tipografo = "data") Then

.ChartType = xlXYScatterLines

Else

.ChartType = xlLineMarkers

End If

.SetSourceData Source:=excel_sheet.Range("A1:B" & Format$(r - 1)), PlotBy:=xlColumns

.Location Where:=xlLocationAsObject, Name:=excel_sheet.Name

End With

 

 'posizione e dimensioni grafico

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

excel_sheet.Shapes(excel_sheet.Shapes.Count).Top = 10

excel_sheet.Shapes(excel_sheet.Shapes.Count).Left = 100

excel_sheet.Shapes(excel_sheet.Shapes.Count).Width = 600

excel_sheet.Shapes(excel_sheet.Shapes.Count).Height = 200

 

'intestazioni grafico

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

ActiveChart.ChartArea.Select

With ActiveChart

.HasTitle = True

.ChartTitle.Characters.Text = txtTITOLO

.Axes(xlCategory, xlPrimary).HasTitle = True

.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = txtLABELX

.Axes(xlValue, xlPrimary).HasTitle = True

.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = txtLABELY

End With

 

' Select the first cell.

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

excel_sheet.Cells(1, 1).Select

 

'chiude Fogli con/senza salvare

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

'excel_app.ActiveWorkbook.Close True

 

'chiude Excel.

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

‘excel_app.Workbooks.Close

‘excel_app.Quit

'Set new_book = Nothing

'Set excel_sheet = Nothing

'Set new_chart = Nothing

'Set excel_app = Nothing

 

End

 

Exit Sub

errori:

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

titolo = "Attenzione !"

Messaggio = "Dati incongruenti  !"

Stile = vbOKOnly + vbExclamation ' Definisce pulsanti.

Risposta = MsgBox(Messaggio, Stile, titolo)

 

End Sub

 

Si noti che Erxcel NON e’ stto chiuso. Vediamo allora come si presenta il grafico:

 

 

 

 

29.4 Grafici con MSCHART

 

MSChart e’ un OCX presente nel pacchetto Visual Basic che va aggiunto tra i Componenti del Progetto (MSCHRT20.OCX). I grafici con questo Oggetto realizzano  grafici di tipo Scientifico quasi accettabili e grafici di tipo Marketing molto buoni.

 

Il Form per i grafici MSChart ha questo aspetto:

 

 

 

Anche qui sono presenti le TextBox del paragrafo precedente. La Routine di inserimento dati in MSChart si basa sulla dichiarazione e costruzione di una “ARRAY” e nell’assegnazione di questa Array alla proprieta’  “CHARTDATA”. Nel nostro caso si trattera’ di una Array a tre valori su due colonne.

 

Anche qui svilupperemo l’Esercizio tracciando un grafico tipo curva. Questo tipo non e’ spettacolare come altri disponibili, previsti appositamente per il Marketing, ma noi siamo piu’ interessati ad esplorare le possibilita’ di realizzare grafici di tipo Scientifico, dando per scontati gli altri.

 

Anche qui sono previsti due tipi di linee “NORMALE 2D” e “SCATTERING”. Per decidere quale usate e’ necessario come al solito determinare il tipo di dato inserito dall’Utente nelle TextBox, cioe’ “NUMERO”, “DATA”, “TESTO”.

 

La Routine e’ la seguente:

 

Private Sub cmdGRALINEA_Click()

 

'crea grafico

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

creaGRALINEA

 

'definisce tipografo

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

tipografo = "numero"

If Not IsNumeric(txtXX(0)) Then

 

'data/testo

On Error GoTo testo

date_parts = Split(CDate(txtXX(0)), "/")

day_part = date_parts(0)

month_part = date_parts(1)

year_part = date_parts(2)

myrdata = (day_part & "-" & Mid$(MonthName(month_part), 1, 3) & "-" & year_part)

tipografo = "data"

GoTo avanti

 

testo:

tipografo = "testo"

On Error GoTo errori

avanti:

 

End If   'isnumeric

 

'tipo grafico

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

If tipografo = "numero" Then

MSChart1.ChartType = VtChChartType2dXY             'XY 2D

End If

 

'crea array

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

Dim arrVALORI(1 To 3, 1 To 2)

 

For i = 1 To 3

arrVALORI(i, 1) = txtXX(i - 1)

arrVALORI(i, 2) = txtYY(i - 1)

Next i

 

'assegna array

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

MSChart1.ChartData = arrVALORI

 

Exit Sub

errori:

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

titolo = "Attenzione !"

Messaggio = "Dati incongruenti  !"

Stile = vbOKOnly + vbExclamation ' Definisce pulsanti.

Risposta = MsgBox(Messaggio, Stile, titolo)

 

End Sub

 

Si comincia con la Subroutine “CREAGRALINEA” che vedremo subito sotto e che imposta le caratteristiche di un grafico MSChart a linee normali.

Nel caso di dati delle X di tipo “NUMERO” si cambia il tipo di grafico a “SCATTER” (dispersione) per realizzarne uno di tipo Scientifico.

Le  “DATE”  vengono invece trattate dal MSChart come etichette, contrariamente a quanto visto perr Excel.

 

Dopo la definizione della variabile “tipografo”, si passa alla dichiarazione e riempimento della Array “ARRVALORI” . La array riempita viene quindi assegnata alla Proprieta’ “CHARTDATA” del grafico.

 

Vediamo ora la Routine di creazione grafico. Le varie componenti sono presentate con sottotitoli e tutti i valori possibili delle Proprieta’ sono esplicitati e possono essere scelti a convenienza:

 

Sub creaGRALINEA()

 

' Tipo di Grafico

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

With MSChart1

 

'.chartType = VtChChartType3dBar               'Barre 3D

'.chartType = VtChChartType2dBar               'Barre 2D

'.ChartType = VtChChartType3dLine              'Linee 3D

.ChartType = VtChChartType2dLine               'Linee 2D

'.chartType = VtChChartType3dArea              'Area 3D

'.chartType = VtChChartType2dArea              'Area 2D

'.ChartType = VtChChartType3dStep             'Istogramma 3D

'.chartType = VtChChartType2dStep              'Istogramma 2D

'.chartType = VtChChartType3dCombination   'Combinazione 3D

'.chartType = VtChChartType2dCombination   'Combinazione 2D

'.chartType = VtChChartType2dPie                 'Torta 2D

'.ChartType = VtChChartType2dXY                 'XY 2D

 

End With

 

 'Titolo e Leggende

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

With MSChart1

 

.Title = "Titolo"

.FootnoteText = Space(50) & "Footnote"

.ShowLegend = True

'.Legend.Location.LocationType = VtChLocationTypeTop

'.Legend.Location.LocationType = VtChLocationTypeTopRight

.Legend.Location.LocationType = VtChLocationTypeRight

.Legend.VtFont.Style = VtFontStyleItalic

'.Legend.VtFont.Style = VtFontStyleBold

.Plot.SeriesCollection(1).LegendText = "Leggenda 1"

'.Plot.SeriesCollection(2).LegendText = "Leggenda 2"

 

End With

 

'finiture

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

With MSChart1

 

'colore dati grafici a barra 2D e 3D

'.Plot.SeriesCollection(1).Pen.VtColor. _

'         Set red, green, blue

 

'colore dati altri tipi di grafico

.Plot.SeriesCollection(1).DataPoints(-1).Brush.FillColor. _

         Set 0, 0, 250

 

'Applica il colore azzurro allo sfondo

.Plot.Backdrop.Fill.Style = VtFillStyleBrush

.Plot.Backdrop.Fill.Brush.FillColor.Set 100, 255, 200

 

'Aggiunge un bordo.

.Plot.Backdrop.Frame.Style = VtFrameStyleThickInner

'VtFrameStyleSingleLine  Lo sfondo è incluso in una linea singola.

'VtFrameStyleDoubleLine  Lo sfondo è incluso tra due linee di uguale spessore.

'VtFrameStyleThickInner  Lo sfondo è incluso tra una linea interna spessa e una linea esterna sottile.

'VtFrameStyleThickOuter  Lo sfondo è incluso tra una linea interna sottile e una linea esterna spessa.

 

'Imposta lo stile di ombreggiatura.

.Plot.Backdrop.Shadow.Style = VtShadowStyleDrop

'VtShadowStyleNull   Nessuna ombreggiatura.

'VtShadowStyleDrop   Ombreggiatura.

 

'Applica il colore giallo alle pareti del grafico non torta

.Plot.Wall.Brush.Style = VtBrushStyleSolid

.Plot.Wall.Brush.FillColor.Set 255, 255, 0

'VtBrushStyleNull    Nessun pennello (lo sfondo è trasparente)

'VtBrushStyleSolid   Pennello in tinta unita

'VtBrushStylePattern Pennello con motivo a bitmap

'VtBrushStyleHatched Pennello tratteggiato

 

'altezza e colore della base grafici 3d

'.Plot.PlotBase.BaseHeight = 800

'.Plot.PlotBase.Brush.Style = VtBrushStyleSolid

'.Plot.PlotBase.Brush.FillColor.Set 255, 0, 0

 

 'markers

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

.Plot.SeriesCollection(1).DataPoints(-1).Marker.Visible = True

 

End With

 

'scala per grafico non torta

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

MSChart1.Plot.Axis(VtChAxisIdY).AxisScale.Type = VtChScaleTypeLinear

'VtChScaleTypeLinear I valori del grafico vengono tracciati in scala lineare,

'dal minimo al massimo valore di intervallo del grafico.

'VtChScaleTypeLogarithmic    I valori del grafico vengono tracciati in base a una scala logaritmica

'specifica impostata con l'argomento logBase di questa funzione.

'VtChScaleTypePercent    I valori del grafico vengono tracciati in scala lineare

'in base alle percentuali dei valori di intervallo del grafico.

 

End Sub

 

L’Esercizio prevede anche un bottone per la realizzazione di un grafico tipo torta, adatto naturalmente ad esigenze di Marketing. Qui non e’ necessario determinare il tipo di dati delle X perche’ essi vengono tutti trattati come etichette. La Routine “CREAGRATORTA” e’ identica all precedente ove pero’ si e’ cambiato la posizione degli apostrofi di commento e si e’ scelto il grafico tipo torta. Il risultato e’ deludente.

 

Private Sub cmdGRATORTA_Click()

 

'crea grafico

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

creaGRATORTA

 

'crea array

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

Dim arrVALORI(1 To 3, 1 To 2)

 

For i = 1 To 3

arrVALORI(i, 1) = txtXX(i - 1)

arrVALORI(i, 2) = txtYY(i - 1)

Next i

 

'assegna array

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

MSChart1.ChartData = arrVALORI

 

End Sub

 

Vediamo ora altre possibilita’ di utilizzo del MSChart. Per prima cosa realizziamo un grafico prelevando i dati da un DataBase, per esempio il

 

C:\GRIGLIE_ADO\ARCHIVIODATI\MAGFILE.MDB , Tabella ARTFILE

 

Anche qui serve una Array per la quale occorre decidere il numero di righe e di colonne. In ogni riga, prenderanno posto i dati dei Records, ad esempio 20. Il numero di colonne specifica quanti dati vogliamo mostrare per ogni record,  ad esempio 2, nome e costo base netto oppure 3 se si vuole anche lo stock, etc. La Routine di riempimento e’ la seguente:

 

'crea array

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

Dim arrARTICOLI(1 To 20, 1 To 2)

Dim i As Integer

For i = 1 To 20

 

arrARTICOLI(i, 1) = Rs!artnome

arrARTICOLI(i, 2) = Rs!cosbanetto * 10

 

Rs.MoveNext

Next i

 

La colonna 1 rappresenta sempre la base, cioe’ i dati in ascissa e le altre colonne danno luogo ad una o piu’ curve, cioe’ set di dati.

 

Ecco la Routine completa:

 

Private Sub cmdGRAMDB_Click()

 

'Dichiarazioni

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

Dim Rs As New ADODB.Recordset

Dim Cn As ADODB.Connection

Set Cn = New ADODB.Connection

pathmdb = txtACCESSFILE

 

'apre Cnessione

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

Cn.CursorLocation = adUseClient

Cn.Open "data Provider=Microsoft.Jet.OLEDB.4.0;Provider=MSDataShape.1;" & _

            "Data Source=" & pathmdb

 

'apre il Recordset

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

SelezART = "Select * from ARTFILE ORDER BY ARTCODI"

Rs.Open "" & SelezART & "", Cn, adOpenStatic, adLockOptimistic

 

'crea array

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

Dim arrARTICOLI(1 To 20, 1 To 2)

Dim i As Integer

For i = 1 To 20

 

arrARTICOLI(i, 1) = Rs!artnome

arrARTICOLI(i, 2) = Rs!cosbanetto * 10

 

Rs.MoveNext

Next i

  

'definisce tipografo

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

tipografo = "numero"

If Not IsNumeric(arrARTICOLI(1, 1)) Then

 

'data/testo

On Error GoTo testo

date_parts = Split(CDate(arrARTICOLI(1, 1)), "/")

day_part = date_parts(0)

month_part = date_parts(1)

year_part = date_parts(2)

myrdata = (day_part & "-" & Mid$(MonthName(month_part), 1, 3) & "-" & year_part)

tipografo = "data"

GoTo avanti

 

testo:

tipografo = "testo"

avanti:

 

End If   'isnumeric

 

'tipo grafico

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

creaGRALINEA

If tipografo = "numero" Then

MSChart1.ChartType = VtChChartType2dXY             'XY 2D

Else

MSChart1.ChartType = VtChChartType3dBar           'Barre 3D

End If

 

'assegna array

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

MSChart1.ChartData = arrARTICOLI

 

End Sub

 

Per finire vediamo come utilizzare l’MSChart per realizzare un grafico prelevando i dati da un foglio Excel.

 

Scegliamo per esempio il

 

C:\GRIGLIE_ADO\ARCHIVIODATI\MAG.MIA\GRAFTEXT.XLS

 

Qui determiniamo il numero di righe dell’Array “ARREXCE” contando il numero di righe del foglio con la Proprieta’ “CURRENTREGION” e poi riempiamo la prima colonna dell’Array con i dati della colonna “A” del foglio Excel e la seconda colonna con i dati della colonna “B”

Se nel foglio Excel ci fossero altre colonnee occorre aumentare la dichiarazione dellArray “ARREXCE” e ogni nuova colonna determina un nuovo set di dati e quindi una nuova curva nel grafico.

 

Ecco allora la Routine completa:

 

Private Sub cmdGRAEXC_Click()

'Dichiarazioni

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

Dim excel_app As Object

Dim excel_sheet As Object

pathexc = txtEXCFILE

 

' Create the Excel application.

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

Set excel_app = CreateObject("Excel.Application")

 

' Comment this line to make Excel notvisible.

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

'excel_app.Visible = True

 

' Open the Excel spreadsheet.

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

excel_app.Workbooks.Open FileName:=pathexc

' Check for later versions.

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

If Val(excel_app.Application.Version) >= 8 Then

Set excel_sheet = excel_app.ActiveSheet

Else

Set excel_sheet = excel_app

End If

 

'crea array excel

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

Set arrExce = excel_app.Worksheets(1).Range("A1").CurrentRegion

intRows = arrExce.Rows.Count

       

'popola  array per MSChart

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

Dim i As Integer

ReDim arrVALORI(1 To intRows, 1 To 2)

For i = 1 To intRows

arrVALORI(i, 1) = CStr(arrExce.Range("A" & i).Value)

arrVALORI(i, 2) = virvalore(arrExce.Range("B" & i).Value)

Next i

 

'chiude Excel

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

excel_app.Workbooks.Close

excel_app.Quit

Set excel_sheet = Nothing

Set excel_app = Nothing

 

'tipo grafico

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

creaGRALINEA

MSChart1.ChartType = VtChChartType3dBar           'Barre 3D

 

'assegna array

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

MSChart1.ChartData = arrVALORI

 

End Sub

 

 

29.5 Grafici con csxGraph (Numerici da Tabella)

 

Lo csxGraph e’ un OCX scaricabile da internet come sopra descritto, che va aggiunto tra i Componenti del Progetto. I grafici con questo Oggetto realizzano  grafici di tipo Scientifico  e grafici di tipo Marketing piuttosto buoni.

 

Supponiamo ad esempio di voler plottare un grafico che porta sulle ascisse i valori dei gradi di un cerchio, diciamo da 1° a circa 200° e sulle ordinate i valori della funzione Sin(X).

 

Al solo scopo didattico prepariamo allora un Form con una collezione di 15 Caselle di testo indicizzate a nome VALX(i) (con indice da 0 a 14)  ed altrettante VALY1(i) e VALY2(i).

 

 

Nella collezione VALX(i) metteremo i gradi, pero’ intervallati di 15° l’una dall’altro (0, 15, 30…), e nella collezione VALY1 i rispettivi seni.

Per fare questo ci serviremo del bottone “Carica Dati” con le seguenti istruzioni:

 

'carica gradi (intervallo di 15°) e seni

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

For i = 0 To 14

'---

'gradi-->radianti

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

pigreco = 4 * Atn(1)

alfagra1 = 15 * i

alfarad1 = (alfagra1 * (2 * pigreco)) / 360   'radianti

 

txtVALX(i).Text = Format(alfagra1, "###.0")

txtVALY1(i).Text = Format(Sin(alfarad1), "###.0000")

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

'---

Next i

 

Se pero’ ora plottiamo queste due serie di valori (con istruzioni che vedremo piu’ sotto) il risultato e’ deludente:

 

 

Il fenomeno dipende dal fatto che la serie di dati Y e’ di una scala di valori molto piu’ piccola della serie X. Per correggere la cosa conviene moltiplicare la serie Y per esempio per 50 volte ed ottenere cosi’ una nuova serie la cui scala di grandezza e’ simile a quella delle X (almeno il 25% della scala delle X.

 

Questo si realizza riempiendo la collezione VALY2(i) con le istruzioni:

 

'applica incremento

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

For i = 0 To 14

'---

txtVALY2(i).Text = Format(50 * virvalore(txtVALY1(i)), "###.00")

'---

Next i

 

A questo punto plotteremo VALX(i) contro VALY2(i) ed il risultato e’ soddisfacente:

 

  

 

Vediamo allora come si realizza un grafico partendo dalle due serie di dati, X e Y (bottone “Grafico Dati”).

Si inserisce un Oggetto Grafico CSX (Draw) e gli si da il nome “Chart”.

Si comincia ora con una serie di istruzioni che inizializzano il grafico:

 

With Chart

'Inizializza

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

.ClearData

.ShowGrid = True

.AxisTextFont.Bold = True

.GridColor = vbGreen

.PlotAreaColor = vbWhite  '&HEEEEEE - grigio, VBWhite,VBRed, VBBlue, VBYellow,                VBGreen,VBMagenta, VBCyan

.ShowPlotBorder = False

.ShowNumbers = True

 

'Tipo Grafico

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

.GraphType = 3     '0 - Pie Chart, 1 - Vertical Bar Chart, 2 - Horizontal Bar Chart, _

                    3 - Line Graph, 4 - Vertical Stacked Bar Chart, 5 - Horizontal Stacked Bar Chart.

 

'linea

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

.LineWidth = 3

.PointSize = 8

.PointStyle = 2 '0 - none, 1 - dot, 2 - circle, 3 - diagonal cross, 4 - vertical cross.

 

'Titolo

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

.Title = "Grafico di Prova"

.TitleColor = vbBlue

.TitleX = 300

.TitleY = 50

.TitleFont.Name = "Arial"

.TitleFont.Size = 20

.TitleFont.Bold = True

 

'Testo Supplettivo

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

.AddLineGraphText "Seno di X", 130, 55, 45 'rispetto a valori di X e Y , angolo

 

Le istruzioni sono spesso intuitive, comunque le istruzioni dettagliate per il loro utilizzo possono essere trovate nel PDF fornito dalla Chestysoft ed accessibile dal menu’ principale di questo Esercizio.

 

Si passa ora al cuore della procedura, cioe’ il caricamento dei dati:

 

'Aggiunge punti

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

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

For i = 0 To 14

'---

X = virvalore(txtVALX(i))

Y = virvalore(txtVALY2(i))

'----

.AddPoint X, Y, vbRed, "  Sin(X)  "

.AddLineGraphText "(" & X & " - " & Y / 50 & ")", X + 5, Y, 5

'---

Next i

 

L’istruzione principale e’ la:

 

    .AddPoint X, Y, vbRed, "  Sin(X)  "

 

in accordo con le istruzioni, linea rossa e Leggenda: “Sin(X)”:

 

AddPoint (X As Double, Y As Double, Colour As OLE_COLOR, LineName As String) - This
command adds a point to be plotted on a line graph. X and Y are the coordinates of the point, which
must be numeric values. Colour is the colour of the line. LineName is the string that will be displayed if
a legend is used. When the graph is plotted all the points that are the same colour will be joined by
straight lines going from point to point in the order they were added.
A separate call to AddPoint must be made for each point on the graph.

 

L’altra istruzione ( o pacchetto) e’:

 

.AddLineGraphText "(" & X & " - " & Y / 50 & ")", X + 5, Y, 5

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

Essa serve ad aggiungere accanto a ciascuno dei 15 punti plottati il loro valore (X,Y). In particolare si noti che il valore di Y viene diviso per lo stesso moltiplicatore introdotto per creare VALY2(i), cioe’ 50.

 

Vedremo sotto come correggere la anomalia venutasi a creare proprio in seguito di questa moltiplicazione per 50 dei valori delle Y plottati: Infatti, ed e’ logico, i riferimenti che compaiono sull’asse delle Y sono giustamente riferiti ai valori delle Y moltiplicate.

 

 

Per ora pero’ trascuriamo i valori di tacca Y ed occupiamoci delle dimensioni del grafico. In particolare occorre che tutti i punti X ed Y siano visibili. Questo si ottiene variando i parametri MaxX e MaxY.

 

'Asse X

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

.MaxX = Chart.Width + 150

.XAxisNegative = 100

'.XGrad = 5

'.XTop = 255

.XMarkSize = 7

 

'Asse Y

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

.MaxY = Chart.Height - 250

.YAxisNegative = 100

.YGrad = 5

.YTop = 60

.YMarkSize = 7

 

'Origine

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

.OriginX = (Chart.Width / 2) - 300

.OriginY = (Chart.Height / 2) + 100

'.XOffset = -5

 

 I valori sopra indicati sono stati ottenuti con vari tentativi per ottimizzare l’aspetto del grafico.

Passiamo ora a  correggere  la situazione dei valori di tacca sull’asse Y. Per fare questo  occorre sostituire i riferimenti  con Labels opportune:

 

'label sulle Y

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

.ClearAxisLabels

.UseYAxisLabels = True

.AddYValue 10, "0.2"

.AddYValue 20, "0.4"

.AddYValue 30, "0.6"

.AddYValue 40, "0.8"

.AddYValue 50, "1.0"

.AddYValue 60, "1.2"

 

Si hanno poi le istruzioni seguenti che riguardano la Leggenda e la sua posizione:

 

'Leggenda

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

.LegendColor = vbBlack

.LegendX = 700

.LegendY = 200

 

Si passa ora a definire il testo sotto l’asse X (orizzontale) e a sinistra dell’asse Y (verticale). Se si vuole si possono usare le istruzioni XaxisText e YaxisText ma spesso e’ necessario usare la AddText che posiziona l’etichetta dove si vuole e con l’angolatura che si vuole:

 

'Testo Assi

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

'.AxisTextColor = vbRed

'.XAxisText = "Testo Asse X"

'.YAxisText = "Testo Asse Y"

.Decimals = -1           'numero di decimali sugli assi

 

'Testo Manuale Assi

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

.AddText "Gradi", 500, 500, 0

.AddText "Seno Trigonometrico", 50, 300, 90

.TextColor = vbRed

.TextFont.Name = "Arial"

.TextFont.Bold = True

.TextFont.Size = 10

 

L’ultima parte della procedura lancia il grafico e nasconde la scritta “Trial” della Chestysoft con un Frame all’uopo inserito nella parte alta del grafico.

 

'Lancio

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

.DrawGraph

End With

Frame1.ZOrder 0

 

Per terminare questa parte di esercizio occorre ancora segnalare che nella realta’ non e’ certo necessario creare le collezioni VAX(i) e VALY(i). E’ molto piu’ pratico ricorrere a una o due array. Nel caso specifico avremo nel “Carica dati”:

 

'carica array

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

For i = 0 To 14

'gradi-->radianti

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

pigreco = 4 * Atn(1)

alfagra1 = 15 * i

alfarad1 = (alfagra1 * (2 * pigreco)) / 360   'radianti

 

VALX(i) = alfagra1

VALY(i) = Round(Sin(alfarad1), 2)

 

Next i

'---

 

Ove le arrays sono state definite nella zona “Dichiarazioni” del form.

 

Dim VALX(20)

Dim VALY(20)

 

In questo caso le istruzioni di caricamento dei dati per il grafico diventano:

 

 

'Aggiunge punti

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

For i = 0 To 14

'---

'da array

'---

fattore = 50

X = VALX(i)

Y = VALY(i)

'----

.AddPoint X, Y * fattore, vbRed, "  Sin(X)"

.AddLineGraphText "(" & X & " - " & Y & ")", X + 5, Y * fattore, 10

'---

Next I

 

Si e’ qui introdotta la variabile “fattore” che contiene l’incremento da dare alla serie di valori Y per renderli congruenti con la  serie X. Questa variabile viene determinata con alcuni tentativi osservando ogni volta se si riescono a rendere visibili tutti i punti delle due serie.

 

Meglio usare valori del tipo 2, 5, 10, 20, 50, 100 etc per rendere poi facile la scrittura delle label Y come sopra indicato.

Viceversa se si hanno valori della serie Y  molto piu’ grandi della serie X, il valore da dare a “fattore” e’ del tipo 0.1,  0.2,  0.5,  0.01,  0.02, 0.05 etc.

 

 

 

29.6 Grafici con csxGraph (Numerici da MDB)

 

Vogliamo ora ampliare gli esempi di utilizzo del csxGraph vedendo come prelevare i dati da un MDB. Per esempio, a scopo solo didattico ovviamente, partiamo dalla Tabella “ARTFILE” e cerchiamo di realizzare un grafico in cui in ascissa abbiamo i codici degli articoli (1, 2, 3…) ed in ordinate i relativi valori di stock.

 

Per leggere i valori della Tabella occorre, al solito, aprire un recordset:

 

'Dichiarazioni

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

Dim Rs As New ADODB.Recordset

Dim Cn As ADODB.Connection

Set Cn = New ADODB.Connection

pathmdb = txtACCESSFILE

 

'apre Sessione

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

Cn.CursorLocation = adUseClient

Cn.Open "data Provider=Microsoft.Jet.OLEDB.4.0;Provider=MSDataShape.1;" & _

            "Data Source=" & pathmdb

 

'apre il Recordset

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

SelezART = "Select * from ARTFILE ORDER BY ARTCODI"

Rs.Open "" & SelezART & "", Cn, adOpenStatic, adLockOptimistic

 

Le altre istruzioni del grafico sono le solite, mentre per la creazione punti avremo:

 

 

'Aggiunge punti

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

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

'---

Do While Not Rs.EOF

fattore = 0.1

'---

X = Rs!ARTCODI

Y = CStr(Rs("STOCK") & "")            'evita i campi Null

 

If Len(Trim(Y)) <> 0 Then

.AddPoint X, Val(Y) * fattore, vbRed, "  Stock  "

.AddLineGraphText "(" & X & " - " & Y * 10 & ")", X + 1, Val(Y) * fattore, 10

End If

'---

Rs.MoveNext

Loop.Bold = False

'---

Rs.MoveNext

Loop

 

Qui i valori degli Stock (fino a 250) sono molto alti rispetto ai valori dei Codici (fino a 50 circa), per cui si usa un “fattore” pari a 0.1 (cioe’ si plottano valori di Stock divisi per 10) ottenendo cosi’ un avvicinamento delle scale di grandezza dei due assi.

 

Si noti che anche i valori Y delle etichette di .AddLineGraphText  vanno moltiplicati per lo stesso fattore onde essere mostrate correttamente mostrati come coppia (X, Y) accanto ad ogni punto.

 

Per il valore di MaxX si e’ usato qui un valore piuttosto alto, al fine di “stirare” l’asse X e

permettere di mostrare i valori 1,2,3…..  invece che 10, 20, 30…

 

'Asse X

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

.MaxX = Chart.Width + 3000

.XAxisNegative = 50

'.XGrad = 5

'.XTop = 255

.XMarkSize = 7

 

Anche qui, come operazione inversa all’utilizzo del “fattore”,  si rende necessaria la operazione di aggiustamento dei riferimenti sull’asse Y con le seguenti label:

  

'label sulle Y

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

.ClearAxisLabels

.UseYAxisLabels = True

.AddYValue 10, "100"

.AddYValue 20, "200"

.AddYValue 30, "300"

.AddYValue 40, "400"

.AddYValue 50, "500"

.AddYValue 60, "600"

 

Per quanro riguarda le labels dell’asse X scriveremo:

 

'label sulle X

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

.XValuesVertical = False

 

Quanto sopra rende indispensabile usare le istruzioni di testo Manuale Assi, dato che Xaxis Text cade ampiamente fuori dal grafico e quindi non si vede.

 

'Testo Manuale Assi

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

.AddText "Codice", 500, 600, 0

.AddText "Stock", 50, 300, 90

.TextColor = vbRed

.TextFont.Name = "Arial"

.TextFont.Bold = True

.TextFont.Size = 10

 

Ecco il risultato:

 

 

 

 

29.7 Grafici con csxGraph (Numerici da Excel)

 

Esaminiamo ora il foglio Excel “CSXNUME collocato in Cartella Soluzione (App.Path):

 

 

 

Ci proponiamo di plottare i valori della colonna “A” sull’asse delle X e i valori della colonna “B”  sull’asse delle Y.

 

Si inizia con le istruzioni gia’ viste in precedenza per caricare l’Excel Sheet:

 

'Carica da Foglio Excel

'==========================================================

'Dichiarazioni

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

Dim excel_app As Object

Dim excel_sheet As Object

pathexce = App.Path & "\" & txtEXCFILE.Text

 

' Create the Excel application.

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

Set excel_app = CreateObject("Excel.Application")

 

' Comment this line to make Excel notvisible.

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

'excel_app.Visible = True

 

' Open the Excel spreadsheet.

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

excel_app.Workbooks.Open FileName:=pathexce

 

' Check for later versions.

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

If Val(excel_app.Application.Version) >= 8 Then

Set excel_sheet = excel_app.ActiveSheet

Else

Set excel_sheet = excel_app

End If

 

'calcola numero di Rows

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

Set arrExce = excel_app.Worksheets(1).Range("A1").CurrentRegion

intRows = arrExce.Rows.Count

'==========================================================

 

 Seguono le solite istruzioni di inizializzazione del grafico e poi si procede al caricamento dei punti (in questo esempio solo 3):

 

 

'Aggiunge punti

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

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

For i = 1 To 3

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

fattore = 0.5

X = excel_sheet.Cells(i, 1)

Y = excel_sheet.Cells(i, 2)

'----

If Len(Trim(Y)) <> 0 Then

.AddPoint X, Y * fattore, vbRed, "  Excel  "

.AddLineGraphText "(" & X & " - " & Y & ")", X + 1, Y * fattore, 10

End If

'---

Next i

 

Dopo qualche tentativo si trova che il “fattore” giusto per avere tutti i punti visibili e’ “0.5”.

 

Anche qui si aggiustano i valori di MaxX e MaxY  ed i valori degli intervalli tacca.

 

'Asse X

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

.MaxX = Chart.Width

.XAxisNegative = 200

'.XGrad = 5

'.XTop = 255

.XMarkSize = 7

 

 'Asse Y

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

.MaxY = Chart.Height - 150

.YAxisNegative = 50

.YGrad = 5

'.YTop = 60

.YMarkSize = 7

 

'Origine

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

.OriginX = (Chart.Width / 2) - 350

.OriginY = (Chart.Height / 2) + 200

'.XOffset = -5

 

Si passa quindi alla definizione delle label sulle X e sulle Y

 

'label sulle X

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

.XValuesVertical = True

 

'label sulle Y

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

.ClearAxisLabels

.UseYAxisLabels = True

.AddYValue 10, "20"

.AddYValue 20, "40"

.AddYValue 30, "60"

.AddYValue 40, "80"

.AddYValue 50, "100"

 

Si danno le ultime definizioni e si lancia il grafico:

 

'Leggenda

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

.LegendColor = vbBlack

.LegendX = 700

.LegendY = 200

 

'Testo Assi

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

'.AxisTextColor = vbRed

'.XAxisText = "Titolo X"

'.YAxisText = "Titolo Y"

'.Decimals = -1           'numero di decimali sugli assi

 

'Testo Manuale Assi

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

.AddText "Titolo X", 500, 600, 0

.AddText "Titolo Y", 50, 300, 90

.TextColor = vbRed

.TextFont.Name = "Arial"

.TextFont.Bold = True

.TextFont.Size = 10

 

'Lancio

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

.DrawGraph

End With

Frame1.ZOrder 0

 

Alla fine si chiude il Foglio Excel:

 

'chiude Excel

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

excel_app.Workbooks.Close

excel_app.Quit

Set excel_sheet = Nothing

Set excel_app = Nothing

 

Ecco il grafico:

 

 

 

 

29.8 Grafici con csxGraph (Text sulle X da Tabella)

 

Vogliamo ora studiare il caso generico in cui si vogliano plottare dei valori Text sull’asse delle X e dei valori numerici sull’asse delle Y.

 

Si disponga ad esempio della seguente serie:

 

Incassi:

Gennaio            10

Febbraio            20

Marzo               18

Aprile               17

Maggio             16

Giugno             50

 

Purtroppo ai fini del garfico anche i valori delle X devono essere numerici, salvo provvedere poi alla sostituzione delle etichette.  Plotteremo allora 1, 2, 3, 4, 5, 6 sull’asse X.

 

Inoltre il range delle Y (10-50) e’ molto maggiore del range delle X (1-6) per cui useremo un “fattore” minore do zero, precisamente “0.1”  per rendere visibili tutti i valori.

Come al solito in questa fase si ignorano i valori di tacca di Y.

 

 

'Aggiunge punti

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

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

fattore = 0.1

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

X = 1

Y = 10

.AddPoint X, Y * fattore, vbRed, "  Incasso  "

.AddLineGraphText "(" & "Gennaio" & " - " & Y & ")", X, Y * fattore, 10

'---

X = 2

Y = 20

.AddPoint X, Y * fattore, vbRed, "  Incasso  "

.AddLineGraphText "(" & "Febbraio" & " - " & Y & ")", X, Y * fattore, 10

'---

X = 3

Y = 18

.AddPoint X, Y * fattore, vbRed, "  Incasso  "

.AddLineGraphText "(" & "Marzo" & " - " & Y & ")", X, Y * fattore, 10

'---

X = 4

Y = 17

.AddPoint X, Y * fattore, vbRed, "  Incasso  "

.AddLineGraphText "(" & "Aprile" & " - " & Y & ")", X, Y * fattore, 10

'---

X = 5

Y = 16

.AddPoint X, Y * fattore, vbRed, "  Incasso  "

.AddLineGraphText "(" & "Maggio" & " - " & Y & ")", X, Y * fattore, 10

'---

X = 6

Y = 50

.AddPoint X, Y * fattore, vbRed, "  Incasso  "

.AddLineGraphText "(" & "Giugno" & " - " & Y & ")", X, Y * fattore, 10

 

Si definiscono ora i valori di MaxX e MaxY:

 

'Asse X

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

.MaxX = Chart.Width - 200

.XGrad = 1

'.XTop = 255

.XMarkSize = 7

  

'Asse Y

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

.MaxY = Chart.Height - 100

.YAxisNegative = 50

.YGrad = 1

'.YTop = 60

.YMarkSize = 7

 

'Origine

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

.OriginX = (Chart.Width / 2) - 350

.OriginY = (Chart.Height / 2) + 200

'.XOffset = -5

 

Si passa di seguito alle labels sulle X e sulle Y:

 

'labels sulle Y

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

.ClearAxisLabels

.UseYAxisLabels = True

.AddYValue 1, "10"

.AddYValue 2, "20"

.AddYValue 3, "30"

.AddYValue 4, "40"

 

'label sulle X

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

'.ClearAxisLabels

.UseXAxisLabels = True

.XValuesVertical = True

.AddXValue 1, "Gennaio"

.AddXValue 2, "Febbraio"

.AddXValue 3, "Marzo"

.AddXValue 4, "Aprile"

.AddXValue 5, "Maggio"

.AddXValue 6, "Giugno":

 

 

 

 

29.9 Grafici con csxGraph (Text sulle X da ARTFILE)

 

Vediamo ora in altro esempio di come posizionare dati di tipo Text sull’asse delle X. In particolare vogliamo mostrare i valori dei Codici degli Articoli sull’asse Y e i nomi dei corrispondenti Articoli sull’asse X.

 

Le istruzioni di apertura Recordset ed inizializzazione grafico sono le stesse gia’ viste. Concentriamoci sul frammento di caricamento punti:

 

'Aggiunge punti

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

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

'---

Do While Not Rs.EOF

fattore = 1

'---

X = Rs!ARTCODI

Y = Rs!ARTCODI

'----

If Len(Trim(Y)) <> 0 Then

'----

.AddPoint X, X * fattore, vbRed, "  Nome Articolo  "

End If

'---

Rs.MoveNext

Loop

 

Anche qui, come nell’esempio precedente, si procede artificialmente a plottare dei valori numerici sull’asse X. Il “fattore” usato e’ qui “1”.

 

I valori numerici sulle Y vanno bene. Invece bisogna sostituire quelli del’asse X.

 

 

'label sulle X

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

.ClearAxisLabels

.UseXAxisLabels = True

For i = 1 To Rs.RecordCount - 3

'Find

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

kriterio = "ARTCODI = " & i & " "

Rs.MoveFirst

Rs.Find kriterio

.AddXValue i, Left(Rs!artnome, 20)

Next i

 

 

 

 

 

29.10 Grafici con csxGraph (Date sulle X da EXCEL)

 

Vediamo ora in altro esempio di come posizionare dati sull’asse delle X, questa volta di tipo data.

 

Partiamo da un set  di dati, per esempio quelli presenti in GAS.XLS, presente nella Cartella della Soluzione (App.Path).

 

 

 

Vogliamo plottare i dati dell’anno 1996 , cioe’ righe da 7 a 13, mettendo sulle X i valori delle Date (Colonna A) e sulle Y le due serie di dati “Miles” (colonna B) e “Gallons” (Colonna C) per realizzare un grafico con due curve.

 

Le istruzioni per l’apertura e chiusura del Foglio Excel nonche’  quelle per l’inizializzazione del grafico sono le stesse viste prima. Vediamo solo il caricamento dei punti:

 

 

'Aggiunge punti

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

.LineGraphTextFont.Name = "Arial"

.LineGraphTextFont.Size = 8

.LineGraphTextFont.Bold = False

 

For i = 7 To 13

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

'primo set

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

fattore1 = 0.01

X = CDate(excel_sheet.Cells(i, 1))

Y1 = excel_sheet.Cells(i, 2)

.AddPoint X, Y1 * fattore1, vbRed, "  Miglia  "

.AddLineGraphText "(" & X & " - " & Y1 & ")", X + 1, Y1 * fattore1, 30

 

'secodo set

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

fattore2 = 0.2

Y2 = excel_sheet.Cells(i, 3)

.AddPoint X, Y2 * fattore2, vbBlue, "  Gasoline "

.AddLineGraphText "(" & X & " - " & Y2 & ")", X + 1, Y2 * fattore2, 30

'---

Next i

 

Il “fattore” per la prima curva e’ 0.01 e quello per la seconda e’ 0.2.

 

Ed ecco le istruzioni per le labels:

 

 

label sulle X

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

.UseXAxisDates = True

.XOffset = CLng(CDate("07/01/96"))

.XTop = CLng(CDate("30/03/96"))

.DateTimeFormat = 1             '0 - date/time, 1 - date, 2 - time.

.DateFormatString = "dd-mmm-yy"

.XValuesVertical = True

 

'label sulle Y

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

'.ClearAxisLabels

.UseYAxisLabels = True

.AddYValue 0.5, "50 M - 2.5 Gas"

.AddYValue 1, "100 M - 5 Gas"

.AddYValue 2, "200 M - 10 Gas"

.AddYValue 3, "300 M - 15 Gas"

 

 Come si vede, e’ stao necessario individuare il range di date entro il quale si mostrera’ il grafico.

 

Ecco il grafico:

 

 

 

 

29.11 Grafici con csxGraph (Text sulle Y da ARTFILE)

 

Passiamo ora ad un esercizio simile a quello visto sopra, in cui pero’ i dati di tipo Text  sono posizionati sull’asse Y. In particolare vogliamo mostrare i valori dei Codici degli Articoli sull’asse X e i nomi dei corrispondenti Articoli sull’asse Y.

 

Le istruzioni di apertura Recordset, inizializzazione grafico e caricamento punti sono le stesse gia’ viste. Sono diversi solo i frammenti delle label:

 

'label sulle X

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

.XValuesVertical = False

 

'label sulle Y

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

.ClearAxisLabels

.UseYAxisLabels = True

 

For i = 1 To Rs.RecordCount - 3

'Find

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

kriterio = "ARTCODI = " & i & " "

Rs.MoveFirst

Rs.Find kriterio

.AddYValue i, Left(Rs!artnome, 20)

Next i

 

Ecco il grafico:

 

 

 

 

29.12 Grafici senza OCX

 

Esiste anche la possibilita’ di tracciare un grafico senza utilizzare OCX, usando l’istruzione “Controls.Add”.

 

Si prepari un Form “GRAFICO1”n come da figura:

 

 

La Routine “CMDCARICA” serve a riempire i dati da porre sull’asse X (gradi da - 60 a +150 con intervallo di 15 °) nonche’ i corrispondenti Sen(X) nelle TextBox “TXTVALY1” ed il Cos(X) nelle TextBox “TXTVALY2”. Queste ultime due sono moltiplicate per un “FATTORE” per renderne i valori dello stesso ordine di grandezza dei valori sulle X.

 

La variabile “FATTORE” viene individuata dividendo il piu’ grande valore sulle X per il piu’ grande sulle Y:

 

Private Sub cmdCARICA_Click()

 

'carica gradi (intervallo di 15°) e seni

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

For i = 0 To 14

'---

'gradi-->radianti

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

pigreco = 4 * Atn(1)

alfagra1 = -60 + (15 * i)

alfarad1 = (alfagra1 * (2 * pigreco)) / 360   'radianti

 

txtVALX(i).Text = alfagra1

txtVALY1(i).Text = Sin(alfarad1)

txtVALY2(i).Text = Cos(alfarad1)

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

'---

Next i

 

'trova i maxi

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

maxix = 0

For i = 0 To 14

If Abs(virvalore(txtVALX(i))) > maxix Then

maxix = Abs(virvalore(txtVALX(i)))

End If

Next

 

maxiy = 0

For i = 0 To 14

If Abs(virvalore(txtVALY1(i))) > maxiy Then

maxiy = Abs(virvalore(txtVALY1(i)))

End If

Next

 

fattore = maxix / maxiy

 

'applica incremento

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

For i = 0 To 14

'---

txtVALY1(i).Text = Format(fattore * virvalore(txtVALY1(i)), "###.00")

txtVALY2(i).Text = Format(fattore * virvalore(txtVALY2(i)), "###.00")

'---

Next i

 

End Sub

 

 Si prepari poi un Form “GRAFICO2" coma da figura:

 

 

Vediamo ora in dettaglio la Routine “SHOWGRAFICO1”.

 

Si inizia individuando le variabili “RAPPX” e “RAPPY”.  Queste due variabili si basano sulla variabile “UTILIZZO”  che definisce quale percento del Form deve essere utilizzato per il grafico (nel nostro caso 90%) e sono i fattori per cui vanno moltiplicati i valori per farli rientrare nel Form.

 

Sub ShowGrafico1()

 

'dichiarazioni

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

numdati = 14

Me.Height = 9600

Me.Width = 18000

 

'trova valori maximi

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

maxix = 0

For i = 0 To numdati

If Abs(Val((Grafico1.txtVALX(i))) > maxix) Then

maxix = Abs(Val(Grafico1.txtVALX(i)))

End If

Next

 

maxiy = 0

For i = 0 To numdati

If Abs(Val((Grafico1.txtVALY1(i)))) > maxiy Then

maxiy = Abs(Val(Grafico1.txtVALY1(i)))

End If

Next

 

'rapporti tra dati maximi e gli assi

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

dispx = (Me.Width - LineAsseY.X1)

dispy = (Me.Height - LineAsseX.Y1)

utilizzo = 0.9

 

If maxix <> 0 Then

rappx = (utilizzo * dispx) / maxix

Else

rappx = (utilizzo * dispx)

End If

 

If maxiy <> 0 Then

rappy = (utilizzo * dispy) / maxiy

Else

rappy = (utilizzo * dispy)

End If

 

Si passa quindi ad un ciclo sui 15 punti creando con l’istruzione “Controls.Add”  un cerchietto per ogni punto che viene posizionato in modo proporzionale al suo valore Y. Le coordinate del punto vengono memorizzate nelle array “COORDX(i)” e “COORDY(i).

 

'ciclo

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

For i = 0 To numdati

If (Grafico1.txtVALX(i) <> "") And (Grafico1.txtVALY1(i) <> "") Then

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

nomeshape = "Shape" & i

nomelabel = "Label" & i

nomelabel2 = "Label2" & i

nomelabel3 = "Label3" & i

 

'Crea Shape punto

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

On Error Resume Next

Me.Controls.Remove nomeshape

On Error GoTo 0

Set Shape1 = Controls.Add("VB.Shape", nomeshape, Me)

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

With Shape1

'.Shape = 0    'rectangle

'.Shape =1     'square

.Shape = 3      'circle

 

.Height = 100

.Width = 100

 

.Left = LineAsseY.X1 + (Val(Grafico1.txtVALX(i)) * rappx)

.Top = Me.Height - dispy - Val(Grafico1.txtVALY1(i)) * rappy

.Visible = True

.BorderWidth = 3

.BorderColor = vbBlack

 

End With

 

'memorizza

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

coordx(i) = Shape1.Left

coordy(i) = Shape1.Top

 

Si passa quindi alla creazione delle etichette dei valori, a patto che la CheckBox in “GRAFICO1” sia positiva, altrimenti si passa al tracciamento della linea di congiunzione dei due ultimi punti, senza etichetta.

 

Ecco le istruzioni per mostrare le coppie valori tra parentesi:

 

'Etichette

'==============================================================

If Grafico1.Check1.Value = 0 Then

'Coppie parentesi no

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

Shape1.Height = 0

Shape1.Width = 0

GoTo collegamento

End If

 

'Coppie parentesi si

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

On Error Resume Next

Me.Controls.Remove nomelabel

On Error GoTo 0

Set Label1 = Controls.Add("VB.Label", nomelabel, Me)

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

With Label1

.Left = Shape1.Left + 200

.Top = Shape1.Top - 200

.Width = 1300

LabelX = Format(Grafico1.txtVALX(i), "### ###.00")

LabelY = Format(Val(Grafico1.txtVALY1(i)) / fattore, "### ###.00")

.Caption = "(" & LabelX & " - " & LabelY & ")"

.Visible = True

End With

 

Ed ecco le label per l’asse X dove vengono ripresi gli stessi valori X dei punti:

 

'etichette asse X

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

On Error Resume Next

Me.Controls.Remove nomelabel2

On Error GoTo 0

Set Label2 = Controls.Add("VB.Label", nomelabel2, Me)

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

With Label2

.Left = Shape1.Left

.Top = LineAsseX.Y1 + 100

.Caption = Format(Grafico1.txtVALX(i), "### ###.0")

.Width = 350

.Visible = True

End With

 

Stessa cosa per l’asse Y:

 

 

'etichette asse Y

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

On Error Resume Next

Me.Controls.Remove nomelabel3

On Error GoTo 0

Set Label3 = Controls.Add("VB.Label", nomelabel3, Me)

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

With Label3

.Left = LineAsseY.X1 - 500

.Top = coordy(i) - 80

.Caption = Format(Val(Grafico1.txtVALY1(i)) / fattore, "### ###.00") & Space(1) & "------"

.Width = 900

.Height = 200

.Visible = True

End With

 

Ed ecco la creazione della linea di collegamento tra gli ultimi due punti e la continuazione del ciclo:

 

collegamento:

'==============================================================

'Linea collegamento punti

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

If (i > 0) Then

DrawWidth = 3

Line (coordx(i), coordy(i))-(coordx(i - 1), coordy(i - 1)), vbBlack

End If  'i

'==============================================================

 

'fine ciclo

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

End If

Next i

 

Si passa ora ad un ciclo che traccia una griglia di assi orizzontali e verticali per facilitare le interpolazioni:

 

'griglia verticali parallele asse Y

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

primax = (LineAsseY.X1) - 7700

 

For i = 100 To 180

nomeline = "Line" & i

 

On Error Resume Next

Me.Controls.Remove nomeline

On Error GoTo 0

Set Line1 = Controls.Add("VB.Line", nomeline, Me)

 

With Line1

.BorderColor = vbBlack

.BorderStyle = 3   'dot

.Y1 = 0

.Y2 = Me.Height

.X1 = primax + (i - 100) * (7000 / virvalore(Grafico1.txtGRID))

.X2 = .X1

.Visible = True

End With

 

Next i

 

'griglia orizzontali parallele asse X

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

primay = (LineAsseX.Y1) - 4900

For i = 200 To 300

nomeline = "Line" & i

On Error Resume Next

Me.Controls.Remove nomeline

On Error GoTo 0

Set Line1 = Controls.Add("VB.Line", nomeline, Me)

 

With Line1

.BorderColor = vbBlack

.BorderStyle = 3   'dot

.X1 = 0

.X2 = Me.Width

.Y1 = primay + (i - 200) * (7000 / virvalore(Grafico1.txtGRID))

.Y2 = .Y1

.Visible = True

End With

Next i

 

La spaziatura della griglia puo’ essere regolata cambiando in “GRAFICO1”  il valore di “TXTGRID”. Comunque la posizione dei punti e la linea restano gli stessi.

 

Resta solo di creare una etichetta per l’asse X e l’asse Y. Quest’ultima sara’ in verticale per cui useremo una routine vista in un Esercizio precedente:

 

'titolo asse Y

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

Dim TextToDraw  As String

Dim Adestra     As Integer

Dim Inbasso     As Integer

Dim Angle       As Double

Dim Colore      As ColorConstants

 

'Must use a TrueType font, otherwise the text won't be rotated.

Font.Name = "Times New Roman"

Font.Bold = True

Font.Size = 12

TextToDraw = "Sin(X)/ Cos(X)"

Adestra = 550

Inbasso = 260

Angle = 90

Colore = &HC000&    'verde

  

'crea effetto 3D

DrawText hdc, TextToDraw, Adestra, Inbasso, Angle, rgb(0, 0, 0)

 

'scrive label

DrawText hdc, TextToDraw, Adestra - 1, Inbasso, Angle, Colore

 

'titolo asse X

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

'Must use a TrueType font, otherwise the text won't be rotated.

Font.Name = "Times New Roman"

Font.Bold = True

Font.Size = 12

TextToDraw = " Gradi "

Adestra = 950

Inbasso = 470

Angle = 0

Colore = &HFF&          'rosso

 

'crea effetto 3D

DrawText hdc, TextToDraw, Adestra, Inbasso, Angle, rgb(0, 0, 0)

 

'scrive label

DrawText hdc, TextToDraw, Adestra - 1, Inbasso, Angle, Colore

 

'ritorna al font del Form

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

Font.Name = "MS sans Serif"

Font.Bold = True

Font.Size = 8

 

Ecco il grafico che si ottiene:

 

 

 In modo analogo si puo’ lanciare anche la seconda serie di valori (i coseni):

 

 

 

 

 

Fine del Capitolo 29 - Grafici