Lez. 6 (10/11) - PBElementi di Programmazione1 Lezione 6 Parametri Facoltativi Matrici Matrici di parametri
Lez. 6 (10/11) - PBElementi di Programmazione2 Parametri facoltativi In VB è possibile passare ad una routine una serie di parametri facoltativi (optional parameter) –Si fa precedere dalla parola chiave Optional ByRef o ByVal se presenti altrimenti Optional precede il nome del parametro I parametri Optional devono essere gli ultimi –Si dichiara il parametro di tipo Variant Strettamente parlando il parametro potrebbe essere di qualsiasi tipo ma se è di tipo Variant è possibile usare la funzione IsMissing(nomeParametro) che restituisce True se il parametro è stato passato alla funzione
Lez. 6 (10/11) - PBElementi di Programmazione3 Parametri facoltativi –Quando si richiama la routine i parametri facoltativi possono essere omessi Usando la notazione posizionale si mette la virgola (, ) per i parametri che non si vogliono fornire quando si debbono dare dei valori ai parametri successivi a quello da saltare usando la notazione := per indicare solo i parametri necessari
Lez. 6 (10/11) - PBElementi di Programmazione4 Parametri facoltativi E buona norma dare un valore prefissato per i parametri facoltativi : usando la funzione IsMissing() per stabilire se il parametro è presente e quindi dando il valore in caso non lo sia usando la notazione: Optional nomeParametro = valoreDefault oppure Optional nomeParametro As Tipo = valoreDefault
Lez. 6 (10/11) - PBElementi di Programmazione5 Esempio Option Explicit Function facoltativi(x As Integer, _ Optional ByVal y = 2, _ Optional k As Variant) If IsMissing(k) Then k = 3 facoltativi = x + y + k End Function Sub richiama() MsgBox (facoltativi(8)) MsgBox (facoltativi(8, 7)) MsgBox (facoltativi(8,, 100)) End Sub
Lez. 6 (10/11) - PBElementi di Programmazione6 Errata Corrige dellEsempio Durante la lezione dell8/11, nellesempio appena sopra riportato era stato per errore indicato: Optional k As Integer) Invece di: Optional k As Variant)
Lez. 6 (10/11) - PBElementi di Programmazione7 Vettori e matrici Sono gruppi di variabili dello stesso tipo nelle quali si fa riferimento agli elementi mediante un indice: –possono avere una (vettori) o più dimensioni (matrici) Si userà matrice per indicare entrambi i casi –la dimensione può essere fissa o dinamica –gli indici partono da 0: Si può fare in modo che gli indici partano sempre da 1, come le celle di Excel, scrivendo allinizio del modulo fuori da tutte le routine: Option Base 1 si può modificare il punto di partenza e di arrivo
Lez. 6 (10/11) - PBElementi di Programmazione8 Una matrice monodimensionale Dim v(n) 0 12n v v(2)
Lez. 6 (10/11) - PBElementi di Programmazione9 Option Explicit Sub prv() Dim v(3) As Integer, i As Integer Dim a1 As Integer, a2 As Integer Dim a3 As Integer For i = 0 To 3 v(i) = InputBox("dammi intero " & i & ": ") Range("B" & (i + 1)).Value = v(i) v(i) = v(i) * 2 Range("C" & (i + 1)).Value = v(i) Next End Sub Esempio
Lez. 6 (10/11) - PBElementi di Programmazione10 Matrici Il singolo elemento di una matrice è una variabile del tipo con cui è formata la matrice –Nelle matrici di tipo Variant possono essere presenti sia elementi di tipo numerico che di tipo stringa Le matrici son passate solo per riferimento ( ByRef ) ad una routine Le matrici NON POSSONO essere –Assegnate in blocco –Confrontate in blocco
Lez. 6 (10/11) - PBElementi di Programmazione11 Matrici Le matrici NON POSSONO essere –Assegnate in blocco –Confrontate in blocco
Lez. 6 (10/11) - PBElementi di Programmazione12 Matrici statiche La dichiarazione avviene specificando il numero di elementi di ogni dimensione: Dim nomeMatrice(dim1,...,dimN) As Tipo –Se si cerca di accedere ad un elemento oltre le dimensioni viene generato un errore di esecuzione –Le variabili di tipo numerico sono inizializzate a 0, quelle di tipo Variant ad Empty Ci si riferisce ad un elemento attraverso le sue coordinate: nomeMatrice(coord1,...,coordN)
Lez. 6 (10/11) - PBElementi di Programmazione13 Dim matri(3,2)
Lez. 6 (10/11) - PBElementi di Programmazione14 Option Explicit Sub provaVettore() Dim vet(3) As Double, matr(4, 3) As Double Dim i, j As Integer For i = 0 To vet(i) = Rnd Next For i = 0 To For j = 0 To matr(i, j) = Rnd Next Range("A1").Value = "vettore" For i = 0 To Cells(1, i + 2).Value = vet(i) Next Range("A3").Value = "matrice" For i = 0 To For j = 0 To Cells(3 + j, i + 2).Value = matr(i, j) Next End Sub
Lez. 6 (10/11) - PBElementi di Programmazione15 Esempio Scrivere un sub in VBA che –carica un matrice 2x3 di double di nome Mt –somma tutti gli elementi contenuti nella matrice la prima coordinata indica le righe, la seconda le colonne Mt 0 (0,0) (0,1) (0,2) (1,0) (1,1) (1,2) Option Explicit Sub matrix() Dim Mt(2, 3) As Double Dim som As Double Dim i As Integer Dim j As Integer som = 0 For i = 0 To 1 For j = 0 To 2 Mt(i, j) =_ InputBox("valore (" &_ i & "," & j & "): ") som = som + Mt(i, j) Next Cells(1, 1) = som End Sub
Lez. 6 (10/11) - PBElementi di Programmazione16 Matrici statiche In VB è possibile indicare esplicitamente lintervallo di variazione degli indici: Dim nmMatr (da1 To a1,..., daN To aN) E possibile conoscere quali sono i valori degli indici minimo e massimo di una matrice grazie a LBound(NomeMatrice, dimensione) UBound(NomeMatrice, dimensione) –Se non specificato dimensione vale 1 –E meglio usare i valori di queste funzioni per gestire le matrici
Lez. 6 (10/11) - PBElementi di Programmazione17 Sub provaVettore() Dim vet(3) As Double, matr(4, 3) As Double, i As Integer, j As Integer For i = LBound(vet) To UBound(vet) vet(i) = Rnd Next For i = LBound(matr, 1) To UBound(matr, 1) For j = LBound(matr, 2) To UBound(matr, 2) matr(i, j) = Rnd Next Range("A1").Value = "vettore" For i = LBound(vet) To UBound(vet) Cells(1, i + 2).Value = vet(i) Next Range("A3").Value = "matrice" For i = LBound(matr, 1) To UBound(matr, 1) For j = LBound(matr, 2) To UBound(matr, 2) Cells(3 + j, i + 2).Value = matr(i, j) Next End Sub
Lez. 6 (10/11) - PBElementi di Programmazione18 Matrici statiche Sub provaIndici() Dim Vet(5 To 9) As Double Dim i As Integer For i = LBound(Vet) To UBound(Vet) Vet(i) = i * 10 Next For i = LBound(Vet) To UBound(Vet) Cells(6, i + 2).Value = Vet(i) Next End Sub
Lez. 6 (10/11) - PBElementi di Programmazione19 Esempio Scrivere una funzione che legge il contenuto delle celle da A1 ad A5 e lo memorizza in un vettore lo raddoppia e lo scrive nelle celle da B7 in poi
Lez. 6 (10/11) - PBElementi di Programmazione20 Option Explicit Option Base 1 Sub matri() Dim celle(5) As Double, i As Integer For i = LBound(celle) To UBound(celle) celle(i) = Cells(i, 1).Value Next For i = LBound(celle) To UBound(celle) Cells(i + 6, 2).Value = celle(i) * 2 Next End Sub
Lez. 6 (10/11) - PBElementi di Programmazione21 Matrici dinamiche Le matrici dinamiche possono cambiare la loro dimensione durante lesecuzione Dim nmMatrDin() As Tipo –Prima delluso la matrice va dimensionata: ReDim nmMatrDim(dim1,..., dimN) Una matrice può essere ridimensionata più volte durante lesecuzione –Ogni ridimensionamento fa perdere il contenuto precedente a meno di usare lopzione Preserve. Dimi può essere lestremo superiore oppure un intervallo (valoreIniziale To ValoreFinale)
Lez. 6 (10/11) - PBElementi di Programmazione22 Matrici dinamiche Sub matrDin() Dim nD() As Double Dim i, j As Integer ReDim nD(8) For i = LBound(nD) To UBound(nD) nD(i) = i Cells(1, i + 1).Value = nD(i) Next ReDim nD(4, 8 To 13) For i = LBound(nD, 1) To UBound(nD, 1) For j = LBound(nD, 2) To UBound(nD, 2) nD(i, j) = i * j Cells(3 + i, j + 1) = nD(i, j) Next End Sub Modifica estremo superiore prima dimensione Modifica estremo Inferiore e superiore della seconda dimensione
Lez. 6 (10/11) - PBElementi di Programmazione23 Option Explicit Option Base 1 Sub allunga() Dim vt() As Double, i As Integer Dim vDim As Integer, j As Integer ReDim vt(4) For i = LBound(vt) To UBound(vt) vt(i) = Rnd: Cells(1, i) = vt(i) Next vDim = UBound(vt): ReDim vt(8, 2) For i = LBound(vt) To UBound(vt) For j = LBound(vt, 2) To UBound(vt, 2) vt(i, j) = Rnd Next: Next For i = LBound(vt) To UBound(vt) For j = LBound(vt, 2) To UBound(vt, 2) Cells(2 + i, j) = vt(i, j) Next: Next End Sub
Lez. 6 (10/11) - PBElementi di Programmazione24 Matrici Dinamiche Luso di ReDim con lopzione Preserve impedisce la modifica: –Delle dimensioni della matrice eccetto lultima In un vettore a due dimensioni posso modificare solo la seconda In un vettore ad una dimensione posso modificare la dimensione –Del numero delle dimensioni –Del tipo della matrice Il tipo della matrice è modificabile quando non si usa Preserve e solo se il tipo è Variant
Lez. 6 (10/11) - PBElementi di Programmazione25 Matrici Dinamiche Option Base 1 Sub matrDinPre() Dim nD() As Double Dim i, j As Integer ReDim nD(8) For i = LBound(nD) To UBound(nD) nD(i) = i Cells(2, i + 1).Value = nD(i) Next ReDim Preserve nD(12) For i = LBound(nD) To UBound(nD) nD(i) = i * 1000 Cells(3, i + 1) = nD(i) Next End Sub
Lez. 6 (10/11) - PBElementi di Programmazione26 Matrici Le matrici devono essere passate per riferimento ad una routine Sub carica(v() As Double) Dim i As Integer For i = LBound(v) To UBound(v) v(i) = InputBox("dammi un valore") Next End Sub Sub stampaFoglio(v() As Double, cx As Integer, cy As Integer) Dim i As Integer For i = LBound(v) To UBound(v) Cells(cx, cy + i) = v(i) Next End Sub Sub x() Dim vt(5) As Double, vq() As Double Call carica(vt): Call stampaFoglio(vt, 1, 1) End Sub
Lez. 6 (10/11) - PBElementi di Programmazione27 Matrici di Parametri In VB è possibile richiamare con un numero di parametri non fissato a priori usando le matrici di parametri –Il parametro è preceduto dalla parola chiave ParamArray ed è di tipo Variant –è sempre lultimo elemento di una lista di parametri
Lez. 6 (10/11) - PBElementi di Programmazione28 Matrici di Parametri Option Explicit: Option Base 1 Function argoVar(uno As Integer, _ ParamArray vari() As Variant) Dim i As Integer, s As String s = "" For i = LBound(vari) To UBound(vari) s = s & i & " " & vari(i) & vbNewLine Next MsgBox ("uno vale " & uno & vbNewLine & s) argoVar = UBound(vari) End Function Sub usaArgVar() Dim uno As Integer, due As Integer uno = argoVar(8, "wer", 890, 34.78) due = argoVar(800, 0.78, "casa") MsgBox ("-> " & uno & vbNewLine & " --> " & due) End Sub
Lez. 6 (10/11) - PBElementi di Programmazione29 Riferirsi ad intervalli di celle Per le routine può essere necessario riferirsi a blocchi di celle di un foglio di lavoro –Per avere una interazione corretta basta ricordare: Un intervallo di celle è SEMPRE una matrice bidimensionale Una singola cella non è una matrice –Il predicato IsArray(variabile) restituisce True se la variabile è una matrice Il parametro che indica lintervallo va passato come Variant e va poi assegnato ad una variabile locale di tipo Variant
Lez. 6 (10/11) - PBElementi di Programmazione30 Riferirsi ad intervalli di celle Function interv(inte As Variant) As Double Dim X As Variant Dim i As Integer, j As Integer X = inte interv = 0 If IsArray(X) Then For i = LBound(X) To UBound(X) For j = LBound(X, 2) To UBound(X, 2) if IsNumeric(X(i,j)) Then interv = interv + X(i, j) EndIf Next End If End Function Sub total() Range("A10").Value = interv(Range("a1:d5")) End Sub