Author Topic: VBA- Lezione 1 - Come iniziare a scrivere una funzione  (Read 18591 times)

0 Members and 1 Guest are viewing this topic.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
VBA- Lezione 1 - Come iniziare a scrivere una funzione
« on: 28 April , 2012, 20:15:14 PM »
Accolgo l'invito di zax ed inizio a scrivere qualcosa per coloro che non hanno idea di come fare per scrivere piccoli programmini utilizzando l'ambiente excel e che tuttavia aiutati a superare il primo gradino potrebbero essere in grado di percorrere l'intera scala.
In questo primo esercizio mi propongo di illustrare l'ambiente di programmazione VBA, cioè come accedervi, creare moduli di programmazione e inserire del codice e prenderò come esempio quello di scrivere una semplice funzione personalizzata che ricevendo come input un tensore dello stato piano di tensione mi restituisca le tensioni principali e la giacitura del piano principale.

« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #1 on: 28 April , 2012, 20:50:00 PM »
Sia dato il tensore di uno stato piano di tensione attraverso i suoi tre termini sigma.x, sigma.y e tau.xy

ricordiamo che le espressioni per determinare le tensioni principali, la giacitura del piano su cui giace sigma.1 e la tensione tangenziale massima sono quelle riassunte nell'immagine che segue.



Uploaded with ImageShack.us

L'immagine è tratta da un documento trovato in rete.

Abbiamo tutto, adesso occorre tradurlo in codice.


Intanto vediamo che occorrerà dare in input almeno tre dati e cioè
sigma.x
sigma.y
tau.xy

Quindi la struttura della  funzione dovrebbe essere qualcosa di simile:

tensioni_principali(sigmax, sigmay, tauxy)

Ma occorre che la sintassi sia rispettosa delle regole imposte dal linguaggio interprete. Ogni funzione deve essere preceduta dalla parola chiave Function ed oad gni parametro definito nella struttura deve essere attribuito un tipo. Per i tipi di variabili vedere per esteso l'help on line di VBA, per quello che ci riguarda sappiamo che le tensioni possono essere qualsiasi numero reale positivo o negativo. Infine se vogliamo che la funzione personalizzata poi appaia nell'elenco delle funzioni presenti in excel dobbiamo inserire la clausola Public.
Il tipo di dato che rappresenterà l'input sarà quindi un Double.
altri tipi di dati sono Byte, Boolean, Integer, Long, Currency, Single, Double, Variant, Object ed infine un tipo definito dall'utente. Ognuno di questi tipi occupa un ben determinato spazio di memoria (in byte), per esempio il tipo Byte occupa un solo byte cioe 8 bit ed è utile per memorizzarvi un numero positivo compreso tra 0 e 255, mentre il tipo double occupa 8 byte (64 bit) ed è ottimo per memorizzarvi un qualsiasi numero compreso tra 1.79769313486231E308 e -4,94065645841247E-324 per i valori negativi, tra 4,94065645841247E-324 e 1,797693134862325E308 per i valori positivi.
LA conoscenza di queste informazioni risulta importante quando si compongono programmi le cui variabili impegano quantitativi enormi di memoria. In questi casi occorrerà avere molta cura a non sprecare spazio e quindi definire il giusto tipo al giusto dato per evitare per esempio, di impegnare 64 bit per un dato che ne occupa solo 1. Gli altri 63 resteranno vuoti ed inutilizzabili.

....
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #2 on: 28 April , 2012, 21:31:27 PM »
Una funzione personalizzata restituisce un solo valore (oppure per avere piu valori si deve far ricorso alle matrici, ma questo per adesso laciamolo perdere), quindi accetta come input tutta una serei di valori numerici e/o non ed alla fine ci da un solo valore.
Quindi occorre definire anche il tipo del valore restituito.

DA quanto detto allora la definizione della funzione deve essere una cosa del genere:

public Function Tensioni_Principali(sigmax as double, sigmay as double, tauxy as double) as double

in cui proprio la frase finale "as double" definisce il tipo restituito dalla funzione

.....
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #3 on: 28 April , 2012, 21:37:30 PM »
Ma resta ancora una cosa da definire, legata al fatto che la funzione ci restituisce sempre un solo valore mentre noi vogliamo che possa restituirci, a nostro piacimento, o la sigma1 o la sigma2 o la giacitura o infine la taumax.
Io ho risolto questa cosa inserendo in input un ulteriore parametro che sta ad indicare cosa voglio che la funzione mi restituisca. La prima volta chiamai questo parametro col nome "flag" (bandiera) e da allora non l'ho piu cambiato. IL parametro flag è pertanto un intero che asumerà il seguente ruolo:
se a flag do 1 la funzione mi deve restituire sigma1
se a flag do 2 la funzione mi deve restituire sigma2
se a flag do 3 la funzione mi deve restituire taumax
se a flag do 4 la funzione mi deve restituire alfa

Detto questo abbiamo la definizione della funzione come segue:
public Function Tensioni_Principali(sigmax as double, sigmay as double, tauxy as double, flag ad integer) as Variant

Noterete che ho cambiato il tipo del dato restituito dalla funzione da Double a Variant. Prossimamente vi spiego il motivo.

alla prossima


« Last Edit: 30 April , 2012, 10:34:45 AM by afazio »
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #4 on: 28 April , 2012, 21:55:25 PM »
Adesso che abbiamo quasi tutto chiaro, accediamo in ambiente programmazione VBA

Per accedervi abbiamo due vie, la prima è raffigurata nella immagine che segue:



Uploaded with ImageShack.us

mentre la seconda consiste nel far visualizzare anche la barra degli strumenti di VBA ed accedere all'ambiente di VBA mediante pressioen del tasto "Visual Basic Editor" come raffigurato nelle due immagini che seguono.



Uploaded with ImageShack.us



Uploaded with ImageShack.us


LA seconda via è da preferire poiche la barra degli strumenti ci mette a portata di mano altre funzioni come quella che ci mette a disposizione gli strumenti di controllo (questi non sono altro che vari controlli come i box di spunta, le caselle combinate, gli spin, pulsanti, caselle di testo ed altro da poter distribuire sul foglio a piacimento ed attibuire a ciascuno di essi una procedura qualsiasi a nostra scelta), ci consente di passare dalla modalita di progettazione alla modalita utente (utile nel caso in cui stiamo utilizzando gli strumenti di controllo e vogliamo progettare le azioni che excel dovra eseguire alla loro pressione).
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #5 on: 28 April , 2012, 22:23:09 PM »
Entrati in ambiente VBA ci troveremo una cosa simile alla seguente:



Uploaded with ImageShack.us

a sinistra appaiono tutti i progetti attualmente caricati, tra cui il progetto del nostro foglio vuoto (che nell'esempio dell'immagine si chiama "Cartel1")
Gli altri progetti dipendono da quello che voi avete caricato allo start di excel.

Se per esempio avete piu di un file excel aperto vi apparira una cosa simile alla seguente:



Uploaded with ImageShack.us

Occorre pertanto fare attenzione a dove scriviamo il codice dato che spesso il nome dei fogli il nome dei moduli ecc ecc sono gli stessi per tutti i files (a meno che non ci si prende cura di dare nomi diversi a ciscun foglio di ciascun file ed a ciascun modulo di ciascun progetto). Nel caso in esempio io avevo aperto il file eq_grado3 e taglio03.
Noterete che il progetto eq_grado3 e taglio03 possiedono oltre ai fogli che compongono il file anche una cartelletta sotto la voce "moduli" denominata "modulo1" mentre il progetto "Cartel2" non ha questa cartelletta.

Questo significa che nel caso del nostro bravo foglio vuoto potremmo scrivere il codice solo nello spazio virtuale dedicato ai singoli fogli ed in quello dedicato all'intero WorkBook mentre non abbiamo cartellette dove scriver codice comune a tutto il file.
Per prima cosa occorre inserire un nuovo modulo (ed anche quando ve ne fosse uno gia presente è preferibile inserirne uno dedicato al ptogetto che abbiamo intensione di sviluppare). Per inserire un nuovo modulo, selezionamo la voce relativa al nostro bel foglio, click col destro e selezioniamo la voce "Inserisci ---> Modulo". Una volta inserito il modulo rinominiamolo in TensioniPrincipali



Uploaded with ImageShack.us

Vi state chiedendo come fare a rinominarlo?
« Last Edit: 28 April , 2012, 22:32:17 PM by afazio »
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #6 on: 28 April , 2012, 22:59:12 PM »
Anche il modulo, come per i fogli, le celle, i pulsanti ecc ecc , in VBA è un oggetto.
Un oggetto altro non è che un contenitore di una serie di cosette ed è caratterizzato dal possedere delle spcifiche proprietà.
 Nel caso del modulo esso ha come unica proprietà il NOME mentre è destinato a contenere del codice.

L'oggetto in generale è:
definito da una serie di proprietà come per esempio il nome, il colore le coordinate di posizionamento all'interno di un form, il testo contenuto, la visibilità o meno, il colore dello sfondo, la presenza o meno di bordi e cosi via dicendo. Ovviamente non tutti gli oggetti hanno le stesse proprietà cosi per esempio se è lecito attribuire il colore verdeacqua come sfondo ad una cella, non è possibile attribuire il valore "zax" ad check-box il cui valore puo essere solo vero o falso.
OLtre ad essere caratterizzato dalle proprietà un oggetto è anche intercettore di un evento e contenitore del codice da eseguire all'occorrenza dell'evento intercettato.
Gli eventi pososno essere i piu svariati ma i piu comprensibili sono per esempio:
- evento clik del mouse
- evento doppio clik
- evento di passaggio del mouse sopra un qualcosa
- evento del cambio del contenuto
- evento timer (cioe il trascorrere del tempo segnato da clock del PC)
- evento apertura di un file
- evento di ativazione di un foglio diverso
e cosi via
Non tutti gli oggetti possono essere intercettori di qualsiasi tipo di evento. Certamente i bottoni che noi distribuiamo sul nostro foglio sono intercettori dell'evento clik del mouse (che viene chiamato con On_click), le celle intercettano anche l'evento di cambiamento del loro valore (evento On_Change), mentre il file intero "WorkBook"  è intercettore dell'evento di chiusra o di aperturadel file (on_open On_close). In ogni caso, se non è stato scritto alcun codice che gestisce quell'evento, che esegue cioe delle operazioni a seguito intercettazione dell'evento, quell'evento viene praticamente dimenticato.
In una normale sessione di lavoro con excel si verificano decine di migliaia di eventi che vengono sistematicamente ignorati.

Viasualizziamo pertanto il gestore delle proprietà che ci puo tornare utile. Certamente per rinominare la cartelletta del modulo:


Uploaded with ImageShack.us

A questo punto per cambiare il nome al modulo basta cambiare la proprietà "name" che appare nella finestra delle proprietà (ovviamente dopo aver selezionato il modulo al quale intendiamo camabiare Nome).


« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #7 on: 28 April , 2012, 23:24:47 PM »
Penso che per adesso sia sufficiente quanto ho accennato di carattere generale sull'ambiente e sul concetto di oggetto e che sia piu utile passare direttamente a scrivere il codice che mi ero ripromesso di fare.

Rinominata la cartelletta dove metteremo il codice facciamo doppio clik su di essa e si aprirà nella parte a destra los pazio dove noi potremo scrivere il nostro codice.

Dato che gia abbiamo chiaro quel deve essere la forma della nostra funzione, scriviamo quanto segue:

Public Function TensioniPrincipali(sigmax As Double, sigmay As Double, tauxy As Double, flag As Integer) As Variant

vedremo che alla pressione del tasto enter, se non abbiamo commesso errori di sintassi, l'ambiente aggiungerà in automatico il rigo

End Function


e tutto ciò che scriveremo tra la definizione della funzione ed il rigo di fine, fara parte della funzione.

Abbiamo i contenitori della variabili in ingresso, abbiamo anche il contenitore di quella in uscita (che e' la funzione stessa col suo nome), ci mancano i contenitori delle variabili intemedie, cioe quelle dove depositeremo sigma1 sigma2, taumax ed alfa

occorre definirle e definirne anche il tipo di dato

scriviamo quindi:
Dim sigma1 As Double
Dim sigma2 As Double
Dim taumax As Double
Dim alfa As Double
la parola chiave Dim serve appunto a dire all'interprete di predisporre uno spazio di memoria lungo 8 byte da chiamare col nome sigma1 e cosi via dicendo

una pausa: non vorrei essere oggetto di critiche da parte di qualche programmatore serio a causa di queste mie spiegazioni terra terra (anche perche non saprei darle piu approfondite) ma lo scopo di queste righe è semplicemente quella che zax ha chiamato "primo gradino". Quindi non rompete la minkia con critiche puriste. saranno invece accettate discussioni e/o correzioni ai concetti che esprimo ma espressi ancora terra terra.
A questo punto non ci resta che snocciolare nelel righe che seguono le formule che della prima immagine che ho postato.

Una sola nota: vogliamo che l'angolo sia restituito in gradi e non in radianti, quindi ci serve il pigreco. Potremmo decidere di affibbiargli tout court il valore approssimato di 3.14 oppure farlo calcolare a VBA. In questo secondo caso ci serve il contenitore di pigreco

Dim Pi as double

mentre per il calcolo del valore di pigreco possiamo ricorrere all'arcotangente di 1
cha sappiamo esserer pari a 45° cioe a pigreco/4
basta moltiplicarlo per 4 ed avremo Pigreco

Pi= 4*Atn(1)
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline quattropassi

  • Esperto del forum
  • ***
  • Posts: 226
  • Karma: 49
  • Neo - Laureato
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #8 on: 29 April , 2012, 00:07:23 AM »
Innanzitutto grazie.
Poi una piccola nota circa un "metodo" del VBA: Application.Volatile.
Può essere utile sapere cosa fa e il peso che ha.

Spiegarlo qui magari non è necessario, comunque per conoscerne la portata basta spulciare la guida del VBA di Excel.
Ecco, ,questa, anche se è marchiata Micros. , è una buona cosa ;) e per usarla è facile:
mentre scrivi il codice selezioni la tua cosa strana (es. proprio il "metodo" Application.Volatile) e batti F1.
La guida ti dirà, per esempio, che:

Code: [Select]
Contrassegna una funzione definita dall'utente come volatile. Una funzione volatile deve essere ricalcolata ogni volta che vengono eseguiti dei calcoli in qualsiasi cella del foglio di lavoro. Una funzione non volatile verrà ricalcolata soltanto quando vengono modificate le variabili di input. Questo metodo ha effetto soltanto all'interno di una funzione definita dall'utente per calcolare una cella di un foglio di lavoro.
e spesso e volentieri ti fornirà degli utili esempi:
Code: [Select]
Esempio
Questo esempio contrassegna come volatile la funzione definita dell'utente "My_Func". La funzione verrà ricalcolata ogni volta che vengono eseguiti dei calcoli in qualsiasi cella del foglio di lavoro in cui viene utilizzata la funzione.

Function My_Func()
    Application.Volatile
    '
    '    Remainder of the function
    ">
End Function


E chiedo scusa se ho "insozzato" questo 3D  :doh:
ma penso che serva per capire con quale intensità e quando avvenga il ricalcolo di una funzione costruita dell'utente (in gergo UDF User Defined Function).
 :ciau:
* Se ci scambiamo un dollaro, ognuno rimane con un dollaro.
* Se ci scambiano un'informazione, ognuno rimane con due informazioni.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #9 on: 29 April , 2012, 09:20:56 AM »
L'Help On LIne

Si puo accedere all'Help on line di VBA attraverso il "?" del menu presente in ambiente programmazione. Sono presenti tre voci. Sotto la voce "Documentazione di Microsoft Visual Basic" troverete i dettagli relativi ai tipi di dati, alle costanti, alle operazioni che è possibile far eseguire, alle funzioni che è possibile utilizzare, l'elenco dlle proprieta e dove si applicano, le istruzioni, i costrutti logici e cosi via.



Uploaded with ImageShack.us

Altra via di accesso all'Help è la pressione del tasto F1 con la particolarita che se la pressione avviene dopo aver selezionato una parola chiave del codice, viene mostrata la pagina dell'Help che illustra le caratteristiche di quel comando o istruzione oltre alla corretta sintassi.
Se per esempio selezioniamo la parola Dim e premiamo F1 appare la pagina dell'help relativa alla istruzione dim, Se facciamo la stessa cosa selezionando la parola sigma1 non accade nulla dato che sigma1 non è una parola chiave o istruzione di VBA.



Uploaded with ImageShack.us

Dalla pagina specifica dell'help possiamo visualizzare esempi di applicazione di quella particolare istruzione oppure altre pagine di argomenti correlati alla parola di cui abbiamo chiesto help.
Il codice di esempio riportato nell'help si puo copiare cosi com'è ed incollare nel nostro codice, risparmiando parecchia fatica. Se è il caso poi si puo modificare a nostro piacimento.
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #10 on: 29 April , 2012, 09:51:46 AM »
Accennato l'Help on line (che ci tornerà utile spesse volte, specie all'inizio quando ancora non conosciamo i comandi o i costrutti, ma anche piu' in la quando VBA insiste a mostrarci un errore di sintassi e saremo costretti a rivedere se serve una viroila al posto del punto e virgola e cose cosi), scriviamo finalmente le formule per il calcolo della tensioni principali.
L'unica istruzione che ci servirebbe conoscere è la radice quadrata mentre l'istruzione per l'arcotangente la abbiamo già utilizzata e quindi nota. L'elevamento a potenza si esegue con il simbolo "^".

scriviamo quindi:


siGma1 = 0.5 * (siGmax + siGmay) + Sqr((0.5 * (siGmax - siGmay)) ^ 2 + taUxy ^ 2)
siGma2 = 0.5 * (siGmax + siGmay) - Sqr((0.5 * (siGmax - siGmay)) ^ 2 + taUxy ^ 2)
taUmax = 0.5 * (siGma1 - siGma2)

alFa = 0.5 * Atn(2 * taUxy / (siGmax - siGmay)) * 180 / Pi


alcune note:
1- nella definizione delle variabili ho appositamente cambiato una lettera da minuscola in maiuscola questo per rendermi immediatamente conto se ho commesso un errore nella digitazione del nome della variabile all'interno della formula. VBA tiene fermo il nome attribuito in sede di definizione della variabile e quando nel corpo del codice incontra un nome uguale (a meno del case delle lettere che lo compongono) lo trasforma automaticamente in quello definito. Cosi se per esempio ho definito una variabile col nome afaZio e nel corpo del codice scrivo afazio (o anche aFaZio), VBA lo trasforma in afaZio mentre se scrivo erroneamente afazo VBA, non riconsocendo questo nome lo lascia cosi com'è. In questo modo basta scrivere tutte le variabili in minuscolo, notare quindi se VBA lo trasforma. Nel caso in cui non lo trasforma vuol dire che ho digitato malamente ed apporto immediatamente la correzione.
Vi consiglio di non prendere alla leggera questi suggerimenti e di non sottovalutare la possibilita di commettere un banale errore di digitazione. Posso solo dirvi che in qualche occasione ho passato notti insonni alla ricerca di cosa non faceva funzionare il codice, magari esaminado approfonditamente il flusso e la logica, riscrivendo in maniera diversa parti del codice per poi scoprire che tutto era dovuto ad un banale errore di digitazione di una variabile. Non essendo stata definita quella variabile, VBA gli attribuiva un valore nullo. Altro consiglio è quello di definire sempre le variabili e non sfruttare la possibilita che VBA offre di non definirle.
2- abbiamo calcolato tutti quanti i dati che ci necessitano ma ancora non abbiamo attribuito alcun valore alla funzione. Se terminassimo qui il nostro codice, questa funzione non restituirebbe proprio nulla poiche il contenitore della funzione (vi ricordo che il contenitore altro non è che il gruppo di cellette di memoria a cui è stato dato il nome "TensioniPrincipali") è vuoto. QUesto codice cosi come è non ha ancora attribuito nessun valore a TensioniPrincipali.
3 - esiste un conflitto che è dato dal fatto che il nome della cartelletta dove abbiamo scritto il codice è uguale al nome che abbiamo dato alla funzione. Questo crea difficoltà in ambiente excel non facendo apparire la nostra nuova funzione nell'elenco delle funzioni disponibili. Per risolvere questo conflitto o rinominiamo la funzione con nome diverso oppure rinominiamo la cartelletta. Io ho rinominato la cartelletta in "tension".
« Last Edit: 29 April , 2012, 10:01:23 AM by afazio »
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #11 on: 29 April , 2012, 10:49:45 AM »
Commentare il codice.
Qualsiasi programmatore e qualsiasi testo che parla di programmazione consigliano sempre di commentare il codice. Questo per renderlo leggibile e magiormente comprensibili agli altri ma cosa ben piu importante per renderlo comprensibile a se stessi. Infatti capita sempre anche al piu' esperto dei programmatori di non riuscire a rimettere mani al proprio codice dopo qualche mese di inattivita al fine di estenderlo correggerlo o miglioaralo.
In VBA un commento si aggiunge semplicemente iniziando il rigo contenente il commento col segno di apice " ' "
Un commento puo' anche essere inserito in coda ad una istruzione ma sempre precedendolo col segno di apice.

Inseriamo pertanto i seguenti commenti:

Code: [Select]

' questa funzione calcola le tensioni principali per uno stato piano di tensione
' dato il tensore piano attraverso le sue componenti.
' UM. congruenti
' angolo restituito in DEG
' parametro flag:
' flag = 1 restituisce sigma1
' flag = 2 restituisce sigma2
' flag = 3 restituisce taumax
' flag = 4 restituisce alfa


Nella immagine che segue riporto il risultato di quanto fatto fino ad adesso.



Uploaded with ImageShack.us

Noterete:
- ho cambiato il nome della cartelletta del codice per evitare il conflitto di nomi
- ho messo una lettera maiuscola in ciascun nome delle variabili definite
- ho scritto la definizione della funzione su più righe per renderla più leggibile.
- ho inserito commenti sullo scopo della funzione e sull'uso del parametro flag
- ho inserito qualche commento in coda alle definizioni delle variabili

Per spezzare un rigo in piu righe occorre inserire il segno "_" prima di andare a capo.

Adeso rimane da inserire la parte del codice che attribuisce al contenitore "TensioniPrincipali" quello che vogliamo che la funzione ci restituisca attraverso il parametro flag.
Per fare questo abbiamo diversi modi che vedremo alla prossima
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #12 on: 29 April , 2012, 14:33:23 PM »
IL primo modo è quello di fare ricorso alla struttura

if ..... then .....
posta su ubico rigo (cioè unica istruzione

o anche la struttura

if ...... then
......
......
.....
end if

che si sviluppa su piu righe e quindi da la possibilita di inserire formule e altro all'interno della struttura

Per sapere come funzione basta digitare if sul modulo del codice e posizionandosi col cursore accanto all'IF premere F1

Code: [Select]
If...Then...Else
     

Consente l'esecuzione condizionale di un gruppo di istruzioni in base al valore di un'espressione.

Sintassi

If condizione Then [istruzioni] [Else istruzionielse]

In alternativa, è possibile utilizzare la seguente sintassi a blocchi:

If condizione Then
[istruzioni]

[ElseIf condizione-n Then
[istruzionielseif] ...

[Else
[istruzionielse]]

End If

La sintassi dell’istruzione If...Then...Else è composta dalle seguenti parti

Parte Descrizione
condizione Obbligatoria. Uno o più dei due tipi di espressione indicati di seguito:
  Un’espressione numerica o un’espressione stringa che può dare come risultato True o False. Se condizione è Null, viene considerata come False.
  Un’espressione nella forma TypeOf nomeoggetto Is tipooggetto. L’argomento nomeoggetto è qualsiasi riferimento di oggetto e tipooggetto è qualsiasi tipo di oggetto valido. L'espressione dà come risultato True se nomeoggetto è del tipo di oggetto specificato da tipooggetto; in caso contrario il risultato è False.
istruzioni Facoltativa nella sintassi a blocchi; Obbligatoria nella sintassi a riga singola, che non prevede una proposizione Else. Una o più istruzioni separate da due punti, eseguite se la valutazione di condizione dà come risultato True.
condizione-n Facoltativa. Come condizione.
istruzionielseif Facoltativa. Una o più istruzioni eseguite se la valutazione della condizione-n associata dà come risultato True.
istruzionielse Facoltativa. Una o più istruzioni eseguite se la valutazione di nessuna espressione condizione o condizione-n precedente dà come risultato True.



Osservazioni

La forma su una sola riga (prima sintassi) è utile per eseguire brevi e semplici test. La forma a blocco (seconda sintassi) consente una maggiore strutturazione e flessibilità rispetto alla forma su una sola riga e in genere facilita la lettura, il controllo e il debug.

Nota   La sintassi su una sola riga consente di eseguire istruzioni multiple come risultato di una decisione If...Then. Le istruzioni devono comunque essere incluse nella stessa riga e separate da due punti come nell'istruzione di seguito riportata:

If A > 10 Then A = A + 1 : B = B + A : C = C + B

Un'istruzione If in forma di blocco deve essere la prima istruzione di una riga. Le parti Else, ElseIf e End If dell’istruzione possono essere precedute soltanto da un numero di riga o da un’etichetta di riga. Il blocco If deve terminare con un’istruzione End If.

Per determinare se un'istruzione è un blocco If, esaminare gli elementi successivi alla parola chiave Then. Se dopo tale parola chiave e sulla stessa riga non vi sono altri elementi a eccezione di un commento, l'istruzione viene considerata un'istruzione If su una sola riga.

Le proposizioni Else e ElseIf sono entrambe facoltative. Un blocco If può contenere un numero qualsiasi di proposizioni ElseIf, nessuna delle quali deve tuttavia apparire dopo una proposizione Else. Le istruzioni If a blocchi possono essere nidificate, ovvero inserite una all’interno dell’altra.

Nell'esecuzione di un blocco If (seconda sintassi) viene analizzata condizione. Se condizione è True, verranno eseguite le istruzioni successive a Then. Se condizione è False, verranno valutate singolarmente le condizioni ElseIf eventualmente presenti. Quando viene individuata una condizione True, vengono eseguite le istruzioni immediatamente successive all'istruzione Then associata. Se nessuna delle condizioni ElseIf risulta True (o in assenza di proposizioni ElseIf), verranno eseguite le istruzioni che seguono l'istruzione Else. Dopo l'esecuzione delle istruzioni che seguono Then o Else, verrà eseguita l'istruzione che segue EndIf.

Suggerimento   L’istruzione Select Case può risultare più utile per la valutazione di un'espressione singola che include diverse azioni possibili. La proposizione TypeOf nomeoggetto Is tipooggetto non può essere tuttavia utilizzata con l'istruzione Select Case.

Nota   La proposizione TypeOf non può essere utilizzata con tipi di dati diversi da Object, quali Long, Integer e così via.

nel nostro caso scriveremmo:


if flag=1 then TensioniPrincipali=sigma1
if flag=2 then TensioniPrincipali=sigma2
if flag=3 then TensioniPrincipali=taumax
if flag=4 then TensioniPrincipali=alfa


funziona. Ma cosa accade se diamo a flag il valore 0 o il valore 5? Semplicemente accade che il contenitore resta vuoto e la funzione non ci restituisce proprio nulla
Se volessimo prevedere questa possibilita e dare un qualche segnale che l'input ricevato dalla funzione non è corretto, possiamo pensare di riempire il contenitore TensioniPrincipali con la stringa "NB" prima di eseguire il gruppo degli if.
il codice sarebbe:

Code: [Select]
TensioniPrincipali="NB"
if flag=1 then TensioniPrincipali=sigma1
if flag=2 then TensioniPrincipali=sigma2
if flag=3 then TensioniPrincipali=taumax
if flag=4 then TensioniPrincipali=alfa

Questo spiega il motivo per cui ho scelto di attribuire il tipo Variant alla funzione e cioè perfare in modo che essa possa contenere sia un valore di tipo numerico che un valore di tipo stringa che è proprio la caratteristica del tipo Variant.
Il variant praticamente non definisce alcun tipo particolare ma assume il tipo che necessita alla bisogna.

Se diamo un valore decimale la funzione va in errore poichè abbiamo definito flag come un intero.
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #13 on: 29 April , 2012, 14:57:16 PM »
Altro modo per completare il codice è quello di fare ricorso al costrutto Select Case.
Al solito, scrivere la parola Select Case e col cursore posizionato accanto alla parola premere F1. Apparirà la pagina dell'Help che spiega tutto sul costrutto:

Code: [Select]
Istruzione Select Case
     

Esegue uno dei vari blocchi di istruzioni sulla base del valore di un’espressione.

Sintassi

Select Case espressioneprova
[Case elencoespressioni-n
[istruzioni-n]] ...
[Case Else
[istruzionielse]]

End Select

La sintassi dell'istruzione Select Case è composta dalle seguenti parti:

Parte  Descrizione
espressioneprova Obbligatoria. Qualsiasi espressione numerica o espressione stringa.
elencoespressioni-n Obbligatoria in presenza di Case. Elenco delimitato in una delle seguenti forme: espressione, espressione To espressione, oppure Is operatoreconfronto espressione. La parola chiave To specifica un intervallo di valori. Se si utilizza la parola chiave To il valore minore deve apparire prima di To. Utilizzare la parola chiave Is con gli operatori di confronto (a esclusione di Is e Like) per specificare un intervallo di valori. Se non viene indicata, la parola chiave Is verrà inserita automaticamente.
istruzioni-n Facoltativa. Una o più istruzioni eseguite se espressioneprova corrisponde a una qualsiasi parte di elencoespressioni-n.
istruzionielse Facoltativa. Una o più istruzioni eseguite se espressioneprova non corrisponde a nessun elemento della proposizione Case.



Osservazioni

Se espressioneprova corrisponde all'espressione elencoespressioni, associata a una proposizione Case, le istruzioni che seguono tale proposizione Case verranno eseguite fino alla proposizione Case successiva. L'ultimo blocco di istruzioni verrà eseguito fino a End Select. Il controllo passerà quindi all'istruzione successiva a End Select. Se espressioneprova corrisponde a un'espressione elencoespressioni in più di una proposizione Case, verranno eseguite solo le istruzioni che seguono la prima corrispondenza.

La proposizione Case Else viene utilizzata per indicare le istruzionielse da eseguire se non viene trovata corrispondenza tra espressioneprova e elencoespressioni in una delle altre selezioni Case. Sebbene non sia obbligatorio, è consigliabile includere un'istruzione Case Else in un blocco Select Case per gestire valori di espressioneprova non previsti. Se nessuna elencoespressioni Case corrisponde a espressioneprova e non è stata specificata un'istruzione Case Else, verrà eseguita l'istruzione successiva a End Select.

In ciascuna proposizione Case, è possibile utilizzare più espressioni o intervalli. La riga di seguito riportata è, ad esempio, valida:

Case 1 To 4, 7 To 9, 11, 13, Is > MaxNumber

Nota   Si noti che l'operatore di confronto Is e la parola chiave Is utilizzata nell'istruzione Select Case sono elementi diversi.

È inoltre possibile specificare intervalli e più di un'espressione per le stringhe di caratteri. In questo esempio, Case consente di confrontare le stringhe che corrispondono esattamente a everything, le stringhe comprese tra nuts e soup in ordine alfabetico e il valore corrente di TestItem:

Case "everything", "nuts" To "soup", TestItem

Le istruzioni Select Case possono essere nidificate. A ciascuna istruzione Select Case nidificata deve corrispondere un'istruzione End Select.

Studiarlo bene poiche offre parecchie possibilita di selezione dei casi. E' un costrutto molto potente a mio parere piu' del costrutto If ... then.... else.


se volessimo fare ricorso a questo modo, scriveremmo:

Code: [Select]

select case flag

case 1
    TensioniPrincipali=sigma1
case 2
    TensioniPrincipali=sigma2
case 3
    TensioniPrincipali=taumax
case 4
    TensioniPrincipali=alfa
case else
    TensioniPrincipali="NB"

End Select

con questo è tutto.
Torniamo in ambiente excel, salviamo il foglio di lavoro.
Da questo momento in poi ogni volta che apriremo questo foglio, avremo a disposizione  una nuova funzione che apparira nell'elenco delle funziondi excel sotto la voce "funzioni definite dall'utente" col nome "TensioniPrincipali".

Alla prossima parlerò dell'utilizzo della funzione
« Last Edit: 29 April , 2012, 15:24:37 PM by afazio »
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline afazio

  • Veterano del forum
  • ****
  • Posts: 663
  • Karma: 273
  • dovizio mi delizio
    • CI si vede al Bar
Re: VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #14 on: 29 April , 2012, 15:50:23 PM »
Abbiamo completato il codice e se non abbiamo commesso errori dovremmo avere una cosa simile alla figura che segue:


Uploaded with ImageShack.us

La funzione puo essere utilizzata da altra funzione o da una qualsiasi altra procedura oppure richiamata direttamente su una cella del foglio di lavoro. Vediamo questa seconda opportunità

Posizioniamoci in una qualsiasi cella e inseriamo una funzione



Uploaded with ImageShack.us
apparira il form di inserimento di una funzione, selezioniamo quelle definite dall'utente e scegliamo infine la nostra bellissima funzione

A questo punto appare le finestra standard con la richiesta di inserimento dei vari parametri in ingresso della funzione.



Uploaded with ImageShack.us

qui potremo decidere di inserire direttamente i valori numerici dei parametri (se li conosciamo) oppure farli leggere da altre celle del foglio di lavoro. Tutto identicamente a qualsiasi altra funzione incorporata di excel.
Notate che il valore restituito dalla funzione è fornito in anteprima nel form di completamento dei dati di input e noterete che se date a flag il valore 2 o 3 o 4, questo anteprima varia.

ciao
« Ogni qualvolta una teoria ti sembra essere l’unica possibile, prendilo come un segno che non hai capito né la teoria né il problema che si intendeva risolvere. »
K.P.

Offline ing.Max

  • Nonno del forum
  • *****
  • Posts: 1116
  • Karma: 88
VBA- Lezione 1 - Come iniziare a scrivere una funzione
« Reply #15 on: 01 May , 2012, 00:32:57 AM »
Grazie Afazio, il topic è veramente interessante e istruttivo. Studierò anche se forse non arriverò mai a produrre qualcosa!
"La conoscenza non occupa spazio"

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24