Lezione 10
Funzioni e Moduli
Macro
Analisi del flusso
Esercizi
Lez. 10 (11/12) - PB
Elementi di Programmazione
1
Form e Controlli (13)
– Creiamo una UserForm per scegliere fra tre
tipi di funzioni e quindi, prelevando il valore
dalla cella attiva, si applica a questo la
funzione scelta scrivendo il risultato nella cella
accanto
• Si utilizza una ComboBox
– Si crea l’elenco delle voci in un foglio di lavoro compreso
nel file Excel si dà un nome all’elenco (Inserisci->Nome>crea)
– si mette questo nome nella proprietà RowSource
– Infine si scrive il codice da utilizzare quando l’utente
sceglie (Sub ComboBox1_Change())
Lez. 10 (11/12) - PB
Elementi di Programmazione
2
Form e Controlli (14)
Option Explicit
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value = 0 Then
ActiveCell.Offset(0, 1).Value = Sin(ActiveCell.Value)
Else
If Me.ComboBox1.Value = 1 Then
ActiveCell.Offset(0, 1).Value = Cos(ActiveCell.Value)
Else
If Me.ComboBox1.Value = 2 Then
ActiveCell.Offset(0, 1).Value = Tan(ActiveCell.Value)
End If
End If
End If
Me.ComboBox1.Value = ""
Me.Hide
End Sub
Private Sub UserForm_Click()
Me.ComboBox1.Value = ""
Me.Hide
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
3
Form e Controlli (15)
‘ Inizializzazione della Combo Box all’apertura del form
Private Sub UserForm_Initialize()
With ComboBox1
.AddItem "0"
.AddItem "1"
.AddItem "2"
End With
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
4
Aggiungere funzioni (1)
• E’ possibile aggiungere alle funzioni
predefinite in Excel e richiamabili nel foglio
elettronico delle funzioni scritte dall’utente
– Le nuove funzioni vanno aggiunte in un
modulo dall’editor di VBA:
• Inserisci->Modulo
– Si scrivono le funzioni che compariranno
nell’insieme delle funzioni selezionabili sotto
la voce Definite dall’utente
Lez. 10 (11/12) - PB
Elementi di Programmazione
5
Aggiungere funzioni (2)
– Creare la funzione progGeom che ha come argomento un intervallo di valori e
restituisce True se i valori in esso contenuto sono in progressione geometrica (il
rapporto fra due valori consecutivi è costante), altrimenti False
Option Explicit
Function progGeom(r As Range) As Boolean
Dim x As Range, i As Integer
progGeom = True
If (r.Count > 2) Then
For i = 1 To (r.Count - 3)
If (r.Item(i).Value / r.Item(i + 1).Value _
<> r.Item(i + 1).Value / r.Item(i + 2).Value) Then
progGeom = False
End If
Next
End If
End Function
Lez. 10 (11/12) - PB
Elementi di Programmazione
6
Aggiungere funzioni - Esercizio
– Creare la funzione progArit che ha come argomento un
intervallo di valori e restituisce True se i valori in esso
contenuto sono in progressione aritmetica (la differenza
fra due valori consecutivi è costante), altrimenti False
Lez. 10 (11/12) - PB
Elementi di Programmazione
7
Aggiungere funzioni - Soluzione
–
Creare la funzione progArit che ha come argomento un intervallo di valori e
restituisce True se i valori in esso contenuto sono in progressione aritmetica (la
differenza fra due valori consecutivi è costante), altrimenti False
Function progArit(r As Range) As Boolean
Dim i As Integer
progArit = True
With r
If (.Count > 2) Then
For i = 1 To (r.Count - 3)
If (.Item(i).Value - .Item(i + 1).Value _
<> .Item(i + 1).Value - .Item(i + 2).Value) Then
progArit = False
End If
Next
End If
End With
End Function
Lez. 10 (11/12) - PB
Elementi di Programmazione
8
Registratore di Macro (1)
– Excel fornisce un utile strumento per poter registrare
il codice generato in base alle azioni che compiamo
mentre lavoriamo.
– In questo modo è possibile esaminare il codice
prodotto e quindi regolarsi sui comandi da impiegare
– Per attivare questa funzionalità:
Strumenti -> Macro -> Registra macro
• Viene chiesto un nome da dare alla macro
• Inizia la registrazione che termina schiacciando il tasto STOP
Tasto STOP
Registra dando riferimenti
relativi
• Il codice generato si troverà nella cartella moduli di VBA
Lez. 10 (11/12) - PB
Elementi di Programmazione
9
Registratore di Macro (2)
– Utilizziamo il registratore di macro per
registrare i passi relativi alla creazione di un
grafico a partire dai dati presenti in una
tabella
• Si ha un insieme di valori nel range A2:B6
• Si deve creare un grafico di dispersione
Lez. 10 (11/12) - PB
Elementi di Programmazione
10
Registratore di Macro (3)
Sub Grafico()
Charts.Add
ActiveChart.ChartType = xlXYScatterSmooth
ActiveChart.SetSourceData Source:=Sheets("Foglio3").Range("A2:B6"), PlotBy _
:=xlColumns
ActiveChart.SeriesCollection(1).Name = "=""valori Sperimentali"""
ActiveChart.Location Where:=xlLocationAsObject, Name:="Foglio3"
With ActiveChart
.HasTitle = True
.ChartTitle.Characters.Text = "valori Sperimentali"
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "X"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "Y"
End With
With ActiveChart.Axes(xlCategory)
.HasMajorGridlines = False
.HasMinorGridlines = True
End With
With ActiveChart.Axes(xlValue)
.HasMajorGridlines = True
.HasMinorGridlines = False
End With
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
11
Registratore di Macro (4)
N.B.: le macro possono essere diverse a
seconda dei passi esatti seguiti durante la
“performance”.
Quindi non stupirsi di eventuali differenze…
Lez. 10 (11/12) - PB
Elementi di Programmazione
12
Analisi del flusso - 1
Option Explicit
Sub prova(ByRef a As_
Integer, _
ByVal b As Integer)
a = a * 2
b = b * 2
End Sub
Sub richiama()
Dim x As Integer, _
y As Integer
x = 2
y = 10
call prova (x, y)
End Sub
Lez. 10 (11/12) - PB
richiama()
x
y
0
0
2
0
2
10
2
10
4
10
4
10
4
10
prova()
a
b
(^x)
10
(^x)
10
(^x)
20
tempo
Elementi di Programmazione
13
Analisi del flusso - 2
Sub prova()
Dim v As Integer, q As Integer
v = 10
q = 20
Do While v > 0 And q > 5
v=v-1
q=q-1
Loop
v
10
9
8
q
20
19
18
1
0
11
10
…
…
Range("D1") = v
Range("D2") = q
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
14
Analisi del flusso - 3
Option Explicit
Sub prova()
Dim v As Integer
v=4
Do While True
v=v+1
Range("F1") = v
Loop
v
4
5
6
:
:
32767
Range("D1") = v
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
15
Analisi del flusso - 4
Sub primaProc(v1 As Integer, _
ByVal v2 As Integer)
Dim L As Integer
v1 = v1 * 3
v2 = v2 * 2
L = v1 + v2
End Sub
Sub richiama()
Dim x As Integer, y As Integer
x = 8
y = 100
richiama()
x
y
8
100
8
100
24
100
24
100
24
100
24
100
primaProc()
v1
v2
L
^x
100
0
^x
100
0
^x
200
0
^x
200 224
primaProc x, y
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
16
Analisi del flusso - 5
Option Explicit
Sub uno(a As Double)
Dim b As Double
b = a * 2
a = a - 2
End Sub
Sub richi()
Dim x As Double, a As Double
x = 10
a = 50
call uno (x)
call uno (a)
End Sub
Lez. 10 (11/12) - PB
richi()
x
a
0
0
10
0
10
50
10
50
10
50
8
50
8
50
8
50
8
50
8
48
8
48
Elementi di Programmazione
uno()
a
(^x)
(^x)
(^x)
b
0
20
20
(^arichi) 0
(^arichi) 100
(^arichi) 100
17
Analisi del flusso - 6
Option Explicit
Function raddoppia(A As Double) _
As Double
raddoppia = A * 2
A = A - 2
End Function
Sub rch()
Dim x As Double, y As Double
Dim z As Double, w As Double
x = 10
y = 20
z = 30
Call raddoppia(x)
call raddoppia(y)
w = raddoppia(z)
rch()
x y
0 0
10 20
10 20
10 20
8 20
z
0
30
30
30
30
w
0
0
0
0
0
8
8
8
8
20
20
20
18
30
30
30
30
0
0
0
0
8
8
8
8
18
18
18
18
30
30
30
28
0
0
0
0
End Sub
8 18
Lez. 10 (11/12) - PB
raddoppia()
A
raddoppia
(^x)
0
(^x)
20
(^x)
20
20 <(^y)
0
(^y)
40
(^y)
40
40 <(^z)
0
(^z)
60
(^z)
60
60 <-
28 60
Elementi di Programmazione
18
Esercizi
Lez. 10 (11/12) - PB
Elementi di Programmazione
19
Esercizio 1
• Scrivere la funzione sommaDis() da
aggiungere a quelle definite nel foglio
elettronico in uso in modo che calcoli la
somma algebrica dei numeri contenuti in
un intervallo.
– L’intervallo di celle può essere formato da più
intervalli.
• Il parametro ha quindi un numero variabile di
argomenti quindi è un ParamArray
Lez. 10 (11/12) - PB
Elementi di Programmazione
20
Esercizio 1
Function sommaDis(ParamArray r() As Variant) As Double
Dim i As Integer, y As Variant
sommaDis = 0
For i = LBound(r) To UBound(r)
Indispensabile per gestire
più intervalli di valori
For Each y In r(i)
If (IsNumeric(y)) Then
sommaDis = sommaDis + y
End If
Next
Next
End Function
Lez. 10 (11/12) - PB
Elementi di Programmazione
21
Esercizio 2
• Calcolare in valor medio dell’intervallo di celle
A1:B8 usando la funzione predefinita dei fogli di
lavoro Excel
– Tutte le funzioni contenute nel foglio di lavoro si
possono utilizzare mediante l’oggetto
Application.WorksheetFunction
– I nomi delle funzioni sono quelle usate nella versione
in Inglese
• L’elenco delle funzioni disponibili si può ottenere
– Selezionare la voce Guida di Riferimento a Visual Basic per
Microsoft Excel
– Quindi selezionare Concetti della programmazione
– Quindi Eventi, funzioni di Foglio di lavoro, Forme
– Infine la guida contiene un collegamento a tutte queste funzioni
Lez. 10 (11/12) - PB
Elementi di Programmazione
22
Esercizio 2
Option Explicit
Sub calcola()
Range("D3") = _
Application.WorksheetFunction. _
Average(Range("A1:B8"))
End Sub
L’intervallo è di tipo Range
Lez. 10 (11/12) - PB
Elementi di Programmazione
23
Esercizio 2.1
• Ripetere l’esercizio precedente quando i
valori sono nell’intervallo A1:B8 ed F1:F8
– Appoggiare nella soluzione i valori nella
variabile x
• La variabile sarà di tipo Variant o Double
Lez. 10 (11/12) - PB
Elementi di Programmazione
24
Esercizio 2.1
Option Explicit
Sub calcola()
Dim x As Double
x = _
Application.WorksheetFunction. _
Average(Range("A1:B8", "F1:F8"))
Range("D3") = x
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
25
Esercizio 3
• Leggere il contenuto del file mieiDati.txt contenuto nella
stessa cartella del foglio di lavoro. Questo file contiene
su ogni riga due numeri decimali. Scrivere il contenuto
del file nel foglio di lavoro a partire dalla cella A3 in
questo modo:
– Nella colonna A il primo valore della riga di dati
– Nella colonna B il secondo valore della riga di dati
– Utilizzando le funzione predefinite dal foglio elettronico min e
max calcolare per ogni colonna questi valori e scriverli nelle
righe 1 e 2 del foglio di lavoro.
– Utilizzando la formula ben formata per Excel scritta come stringa
nella cella D1 che ha come variabile _x, applicarla ad ogni
elemento della colonna A a partire da A3 scrivendo il risultato
nella colonna C nella riga corrispondente
Lez. 10 (11/12) - PB
Elementi di Programmazione
26
Esercizio 3 (sol v1)
Option Explicit
Sub scaricaCalcola()
Dim riga As Integer
Dim v1 As Double, v2 As Double
Dim rg As Range, frm As String
Dim frms As String, i As Integer
riga = 2
Open ThisWorkbook.Path & "\" & _
"mieiDati.txt" For Input As #1
Do While Not EOF(1)
riga = riga + 1
Input #1, v1, v2
Cells(riga, 1) = v1
Cells(riga, 2) = v2
Loop
If riga <> 2 Then
Set rg = Range("A3:A" & riga)
Range("A1") = Application.WorksheetFunction.Min(rg)
Range("A2") =
Application.WorksheetFunction.Max(rg)
Set rg = Range("B3:B" & riga)
Range("B1") = Application.WorksheetFunction.Min(rg)
Range("B2") =
Application.WorksheetFunction.Max(rg)
End If
Close #1
frm = Range("D1").Value
For i = 3 To riga
frms = Replace(frm, "_x", CStr(Cells(i, 1).Value))
frms = "=" & Replace(frms, ",", “.")
Cells(i, 3).Formula = frms
Next
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
27
Esercizio 3 (sol v2)
Option Explicit
Option Base 1
Sub esercizio()
Dim v1 As Double, v2 As Double
Dim i As Integer, r As Range
Dim formula As String, fmls As String
Open ThisWorkbook.Path & _
"\mieiDati.txt" For Input As #1
Set r = Range("A3:A" & (i - 1))
Cells(1, 1).Value =
_
Application.WorksheetFunction.Min(r)
Cells(2, 1).Value =
_
Application.WorksheetFunction.Max(r)
Set r = Range("B3:B" & (i - 1))
Cells(1, 2).Value = _
Application.WorksheetFunction.Min(r)
formula = Range("D1")
i = 3
Do While Not EOF(1)
Input #1, v1, v2
Cells(i, 1).Value = v1
Cells(i, 2).Value = v2
Cells(2, 2).Value = _
Application.WorksheetFunction.Max(r)
Close #1
End Sub
fmls = "=" & Replace(formula, _
"_x", _
Replace(CStr(v1), ",", "."))
Cells(i, 3).formula = fmls
i = i + 1
Loop
Lez. 10 (11/12) - PB
Elementi di Programmazione
28
Esercizio 4
• Eliminare dal foglio di lavoro tutti i valori
non numerici contenuti nell’intervallo
A1:C7
– Usare la funzione isnumeric()
Lez. 10 (11/12) - PB
Elementi di Programmazione
29
Esercizio 4
Option Explicit
Sub cancella()
Dim el As Range
For Each el In Range("A1", "C7")
If Not IsNumeric(el.Value) Then
el.Value = ""
End If
Next
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
30
Esercizio 5
• Dato un foglio di lavoro in cui nella
colonna A e nella colonna B ci sono dei
valori numerici, disegnare i grafico di
dispersione della colonna B in funzione
della colonna A
– Non so dove finiscono le due colonne
Lez. 10 (11/12) - PB
Elementi di Programmazione
31
Esercizio 5
Sub Macro2()
'
' Macro2 Macro
' Macro recorded 12/18/2009 by %USERNAME%
'
Ricavato col registratore di macro;
Poi è adattato nella pagina
successiva
'
Charts.Add
ActiveChart.ChartType = xlXYScatterSmooth
ActiveChart.SetSourceData Source:=Sheets("Sheet4").Range("B1:B" & ), PlotBy:= _
xlColumns
ActiveChart.SeriesCollection(1).XValues = "=Sheet4!R1C1:R3C1"
ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet4"
ActiveSheet.Shapes("Chart 1").IncrementLeft 157.5
ActiveSheet.Shapes("Chart 1").IncrementTop -80.25
ActiveChart.PlotArea.Select
Selection.Left = 1
Selection.Top = 16
ActiveChart.ChartArea.Select
ActiveSheet.Shapes("Chart 1").IncrementLeft -135#
ActiveSheet.Shapes("Chart 1").IncrementTop 165.75
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
32
Esercizio 5
Option Explicit
Sub disegna()
Dim riga As Integer
riga = 1
While Not IsEmpty(Cells(riga, 1))
riga = riga + 1
Wend
riga = riga - 1
Punti in cui è stato modificato
If riga = 0 Then
Exit Sub
End If
Charts.Add
ActiveChart.ChartType = xlXYScatterSmooth
ActiveChart.SetSourceData Source:=Sheets("Sheet4").Range("B1:B" & riga), PlotBy:= _
xlColumns
ActiveChart.SeriesCollection(1).XValues = "=Sheet4!R1C1:R" & riga & "C1"
ActiveChart.Location Where:=xlLocationAsObject, Name:="Sheet4"
ActiveChart.ChartArea.Select
End Sub
Lez. 10 (11/12) - PB
Elementi di Programmazione
33
Scarica

Lezione 10 - 05/12/2011