Gestione dell'informazione aziendale
Prima parte, lezione 1 - 23/09
In questa lezione si sviluppa un esempio con Access: si crea un “Database Nuovo”: i dati che andremo ad utilizzare saranno in forma tabellare; ogni riga corrisponderà ad una specifica anagrafica. Visual Basic sarà lo strumento che ci permetterà di automatizzare alcune funzionalità che andremo ad implementare: è una macro di esecuzione. Per andare a scrivere il codice dovremo inserire un “nuovo modulo”.
La “finestra immediata” che viene posta in basso è un ambiente in cui vengono eseguite le funzioni come ad esempio “?2+3”, restituendo il risultato dell’operazione o della subroutine. La “finestra delle variabili locali” ci permette di controllare come le variabili create si stanno modificando nel corso dell’esecuzione del programma.
Uno dei vantaggi di VBA è che è un software estremamente strutturato mentre altri tipi di linguaggio permettono di arrivare ad un medesimo risultato con più percorsi; inoltre il sistema di debug è anch’esso molto strutturato, ossia ne permette l’esecuzione del codice che è stato scritto: è solo in questo istante che verranno individuati gli errori di funzioni (logiche) o di scrittura che non permettono la corretta esecuzione del programma.
I primi elementi che andiamo a descrivere sono le variabili: al loro interno assegneremo dei valori che potranno essere modificati, letti, stampati eccetera. Una generica variabile, ad esempio, è il “nome” di uno studente e un’altra variabile è quella per il “cognome”.
Tipologie di variabili
- Predefinite/Standard: sono comuni a più sistemi di linguaggio
- Numeriche
- È un numero intero corto (ordine delle migliaia): Integer
- Numeri più grossi interi: Long
- Numeri con le virgole: Single
- Numeri con le virgole più precisi: Double
- Numeri da 0 a 256: Byte
- Non Numeriche
- Testo: String
- 0 oppure 1 per rispettivamente Vero o Falso: Boolean
- Accoglie una data: Date
- Valore monetario: Currency
- Variant: può contenere più forme: si predispone uno spazio di memoria e successivamente verrà indicata in modo più preciso la tipologia della variabile. Se nella compilazione non viene indicata la tipologia della variabile di default viene assegnata la tipologia variant.
- Numeriche
- Para-standard: definite ma in ogni caso modificate dall’utente, ridimensionate a seconda delle esigenze: tra questi Enum, Object, Type che non consentono l’assegnazione diretta.
- Personalizzate: sono variabili che devono essere create da zero. //In questo modo ho tipizzato A come una variabile che conterrà solo numeri interi. Dim A As Integer se non dichiarassi la tipologia di variabile di default verrebbe a crearsi una Variant.
Le variabili para-standard o personalizzate che non possono essere riempite per assegnazione diretta vengono create all’interno di un sotto-contenitore, quindi non nel modulo ma in un suo sotto-contenitore: una funzione oppure una procedura subroutine. Quando si parla di routine parliamo di una procedura iterativa che viene ripetuta nello stesso modo e ordine più volte.
Funzioni vs Procedure
Entriamo ora nel merito di questa differenza che sussiste tra una funzione e una procedura:
- Una funzione è un’operazione che riceve un certo numero di dati in input e elabora un valore di output.
- Una procedura è una serie di istruzioni che possono essere richiamate all’interno di una funzione.
La differenza tra una Function e una Sub è che la prima restituisce un risultato singolo (come in analisi matematica) mentre la seconda, accettando qualsiasi valore di input, non restituisce nessun valore come risultato ma esegue solamente il codice che è stato scritto.
Affinché le procedure o le variabili possano essere utilizzate dal compilatore, dobbiamo assegnare a queste un grado di accesso: la posso utilizzare ovunque e in qualsiasi modulo presente nel database. Public è visibile al solo codice presente nel medesimo modulo e non nelle altre sezioni. Private.
Esempi di codice
Esempio di prova delle variabili, stampa delle variabili, operazioni sulle variabili:
Public Sub Prova_Variabili()
‘Implicitamente, nel momento in cui creo una funzione, sto creando una variabile che servirà per accogliere il risultato del processo
Dim Val As Integer, Val2 As Integer ‘Ho creato due variabili
Val = 10
Debug.Print(Val) ‘Stampo il valore “10”
Val = Val + 3
Debug.Print(Val) ‘Stampo il valore “13”
Val2 = Val ‘Copio il valore
Debug.Print(Val2) ‘Stampo Val2
Val2 = Val2 + 3 ‘Modifico solo Val2 e non Val
Debug.Print(Val2) ‘Stampo Val2
End Sub
Quando si battezzano i nomi delle variabili devono essere pressoché semplici ma chiare. Una variabile scritta all’interno di una Sub ha vita sino alla fine del processo di routine. Se devo avere una variabile che durerà per l’intero modulo allora dovrò crearla al di fuori dello spazio della routine, come ad esempio all’inizio della compilazione. In quest'ultimo caso, la variabile morirà solo al termine dell’esecuzione del programma e non della singola routine.
Creata la variabile posso infatti assegnare un valore (numerico in questo caso) oppure effettuarne delle modifiche al valore già assegnato. Quando si effettuano operazioni di assegnamento o copiatura di un valore ad un’altra variabile bisogna sincerarsi che vengano effettuate le corrette operazioni: nel nostro caso avviene un assegnamento di valore. Per testarlo posso eseguirlo: per farlo uso la finestra immediata scrivendo: Call Prova_Variabili.
//Stampo a video per richiamare una Sub scrivo Call //Per richiamare una Function scrivo ?
Esempio: predisposizione dello spazio per una variabile che non viene utilizzata:
Public Sub Prova_Variabili()
Dim Val As Integer, Val2 As Integer //Ho creato due variabili
Val = 10.5
End Sub
Se battezzo una variabile ma poi non la uso di default, in questo caso, si assegna Val2 = 0 oppure una stringa non avrà valori all’interno o una data avrà la prima data storicamente utile. Un altro aspetto importante riguarda la forzatura di assegnazione; per capire meglio, supponendo di assegnare alla variabile di tipo intero Val = 10.5 sto effettuando un errore perché il programma si aspetta un valore intero: Forzando l’assegnazione però questa viene comunque effettuata: questo particolare aspetto prende il nome di TypeForcing e in parole povere si verifica quando si passa da un valore non propriamente corrispondente alla tipologia di variabile che vorrei utilizzare, in questo caso da Integer a Double.
Per forzare il TypeCasting e quindi convertire il dato che sto forzando, uso la funzione C_ _ _ dove di seguito riporto a quale tipo di variabile voglio convertire. Ad esempio: S = CStg(Quando si sbaglia ad assegnare un valore ad una variabile si ha l’effetto OverFlow, ossia quando si supera il volume disponibile (in termini di memoria) del contenitore creato.
Esempio: proviamo ora a scrivere una funzione che quindi restituirà un risultato:
- Come procedura:
Public Sub HW(Name As String, Surname As String)
Dim S as String ‘Creo una stringa
S = Name & “ ” + Surname & “ ”
‘Popolo la stringa e opportunamente metto gli spazi: sto concatenando gli input
Debug.Print(“S”)
Debug.Print(Len(S)) ‘Stampo la lunghezza della stringa comprensiva di spazi
‘La funzione predefinita Len conta il numero di caratteri di una stringa
End Sub
- Come function:
Public Function H_W(Name As String) As String
H_W = “Hello “ & Name
End Function
In questo secondo caso, a differenza della procedura, la finestra immediata restituirà un risultato senza che io abbia scritto il debug.print proprio perché è natura della Function restituire un risultato una volta che viene chiamata la funzione stessa, cosa che non accade nel caso della procedura nella quale devo opportunamente inserire nel codice una richiesta di stampa a video di una o più variabili.
Lezione 2 - 24/09
Procedure e funzioni
Riprendiamo l’ultimo argomento svolto nella lezione precedente: le funzioni e i procedimenti sono molto simili come si è visto; sono un insieme di istruzioni che messe nel contenitore possono essere richiamate ad ogni ciclo. In poche parole:
- Una procedura esegue set di istruzioni ma non ritorna nulla.
- Una funzione ritorna un valore, in casi particolari più valori.
Vediamo un esempio pratico che restituisce come valore un numero random tra 1 e 6: in questo esempio, la funzione è senza input; prima di iniziare a scrivere proviamo nell’immediata una funzione predefinita ?rnd() che è in grado di restituire un numero compreso tra 0 e 1; sfrutteremo proprio questa predefinita per creare il nostro esempio:
Public Function Dice() As Integer
Dice = Rnd()
‘Se lo eseguissi il risultato sarebbe solo 0 o 1
‘Per ottenerne uno tra [0;6] moltiplico per 6 e traslo di uno poiché il valore zero non è compreso nella richiesta dell’esercizio
Dice = Rnd() * 6 + 1
End Function
Esempio due: elevare un numero ad una potenza chiedendo come input la base e l’esponente
Public Function Power(Val As Long, Exp As Integer) As Long
Power = Val ^ Exp ‘Assegno a power l’operazione da fare
End Function
‘Nell’immediata per provare posso mettere come input ?Power(4,2) = 16
Esempio tre: radice quadrata
Public Function Radn(Val As Long, n As Integer) As Double
Radn = Val ^ (1/n)
End Function
Inserisco ora un parametro opzionale: voglio fare solo le radici quadrate quindi fisso il secondo parametro, ossia n, con valori pari a 2.
Public Function Radn(Val As Long, Optional n As Integer = 2) As Double
Radn = Val ^ (1/n)
End Function
Inserisco un altro parametro opzionale: voglio troncare il numero dopo un tot di decimali
Public Function Radn(Val As Long, Optional n As Integer, Optional n_digit = -1) As Double
Radn = Val ^ (1/n)
End Function
Se mettessi a n_digit = -1 questo non avrebbe senso perché per arrotondare dovrei mettere un valore positivo. Esiste però già una funzione che può essere richiamata che arrotonda alle cifre che vogliamo:
?Round() come input chiede il valore da arrotondare e il numero di cifre dopo la quale troncare.
La posso quindi sfruttare all’interno della funzione, andando ad inserire l’arrotondamento tramite il parametro opzionale n_digit
Public Function Radn(Val As Long, Optional n As Integer, Optional n_digit = -1) As Double
Radn = Val ^ (1/n)
Radn = Round(Radn,n_digit)
End Function
Se l’utente non indica n_digit non arrotondo il risultato mentre se viene indicata allora gli devo chiedere a quale cifra decimale fare l’arrotondamento. Dovremo utilizzare la condizione logica IF e IF ELSE
Public Function Radn(Val As Long, Optional n As Integer, Optional n_digit= -1) As Double
If n_digit <= -1 Then
Radn = Val ^ (1/n)
Else If n_digit >=0 Then
Radn = Round(Val ^ (1/n),n_digit)
End If
End Function
Notiamo però che la procedura di calcolo viene svolta in due momenti distinti: per andare ad ottimizzare il codice potrei pensare di calcolare l’operazione in un unico step e solo successivamente richiamare la condizione di IF e IF ELSE stampando il valore come richiesto dall’utente.
Public Function Radn(Val As Long, Optional n As Integer, Optional n_digit= -1) As Double
Radn = Val ^ (1/n)
If n_digit>=0 Then Radn = Round(Radn,n_digit)
‘Di default il valore n_digit è impostato su -1
End Function
Esempio quattro: ottenere il resto di una divisione
Public Function Re(Val As Long, Optional D As Integer = 2) As Integer
Dim Div_Int As Integer
Div_Int = Val\D
Re = Val - Div_Int * D
End Function
Esempio cinque: valutare se un numero è divisibile per un altro numero. Questa funzione deve restituire un boolean quindi un vero=1 oppure un falso=0. Per svolgere questo esempio sfrutto l’esempio quattro che è già stato svolto.
Public Function Is_Div(Val As Long, Optional D As Integer = 2) As Boolean
If D <=0 Then
Is_Div = False
Exit Function
‘Cioè se il denominatore è negativo o zero di default restituisco falso
End If
If Re(Val,D) = 0 Then
Is_Div = True
Else
Is_Dev = False
End If
End Function
Visibilità delle variabili
Una variabile Locale è definita all’interno di una funzione o di una procedura: è una variabile di appoggio che nasce e muore all’interno della procedura e che quindi viene eliminata dalla memoria alla fine del ciclo. Un esempio che usa questo tipo di variabile è:
Dim L_Var As Integer L_Var = L_Var + 1 P_Var = P_Var + 1 //Richiamo la var globale successiva Debug.Print (CStr(L_Var) & “ ” & CStr(P_Var))
Qual è la cosa interessante? È che se continuo a lanciare il debug, il valore che incrementa è solo quello globale perché quella locale viene creata ed eliminata a fine ciclo mentre quella globale rimane viva anche quando il ciclo è stato eseguito.
Una variabile Globale viene definita all’esterno di una funzione e quindi la sua visibilità è estesa a tutte le procedure o funzioni. Qualsiasi istruzione quindi può utilizzare questa variabile andando a sovrascrivere ogni volta il suo contenuto. Un esempio che usa questo tipo di variabile è:
Public P_Var As Integer
_____________________________________
Public Sub Usa_P_Var()
…
End Sub
Trasferimento del contenuto di una variabile
Altro breve argomento riguarda il trasferimento del contenuto di una variabile ad un’altra variabile: per riferimento o per valore.
- Per riferimento, in pratica, sto dicendo di modificare il valore contenuto in un certo indirizzo, ossia all’interno della variabile. Il compilatore userà direttamente quell’indirizzo di memoria e il suo valore viene cambiato ad ogni iterazione. Di default le variabili vengono passate per riferimento.
- Per valore invece non dico al compilatore dove si trova quella variabile ma gli trasferisco solo il valore che gli è stato attribuito e alla variabile nativa non viene cambiato il suo valore.
Esempio di sintassi: trasferimento per valore e per riferimento
Public Sub S_ByVal(ByVal n As Integer)
‘Ossia questa variabile n viene passata per valore
Public Sub S_ByVal(ByRef n As Integer)
‘Ossia questa variabile n viene passata per riferimento (è di default)
Esempio pratico: passaggio per valore e per riferimento
Public Function Quadrato1(Val As Long) As Long
Quadrato1 = Val ^ 2
End Function
Public Function Quadrato2(Val As Long) As Long
Quadrato2 = Val ^ 2
End Function
Public Sub Foo()
Dim A As Long, B As Long, C As Long
A = 10
B = Quadrato1(A) ‘Per riferimento: non c’è assegnamento a Val
C = Quadrato2(A) ‘Per valore: uso Val ma non lo modifico
Debug.Print(A)
Debug.Print(B)
Debug.Print(A)
Debug.Print(C)
Debug.Print(A)
Altro esempio pratico: passaggio per valore e per riferimento
Private Function Do_Change(N As Integer) As Integer
N = N + 2 ‘Funzione che modifica la variabile per riferimento: default!
Do_Change = N * 10
End Function
_________________________________________________________________________________
Private Function Do_Not_Change(ByVal M As Integer) As Integer
M = M + 2 ‘Funzione che non modifica la variabile per valore
Do_Not_Change = M * 10
End Function
_________________________________________________________________________________
Public Sub Reference_Exemple(I As Integer, J As Integer)
Debug.Print CStr(I) & “ ” & CStr(J)
I = Do_Change(I)
J = Do_Not_Change(J)
Debug.Print CStr(I) & “ ” & CStr(J)
End Sub
Cosa succede? In entrambi i casi ho effettuato una assegnazione: nel primo caso però non modifica il dato di input mentre nel secondo caso si.
Funzioni predefinite operanti su stringhe
Vediamo le funzioni più comuni operanti sulle stringhe: Len, Mid, Left, Right, Instr, Trim, Ucase, Lcase.
Public Function Char(S As String, Optional pos As Integer = 1) As String
‘Restituirà il carattere in posizione pos della stringa S
Char = Mid(S, pos, 1)
End Function
Char: la funzione restituisce il carattere della cella della stringa. Pos
- Len: ?Len(“pippo”) = lunghezza = 5
- Mid: ?Mid(“pippo”,1,2) = tronca parte della stringa = ip
- Left: ?Left(“pippo”,2) = sottostringa che parte da sinistra (ossia dall’inizio) = pi
- Right: ?Right(“pippo”,3) = sottostringa a partire da destra (ossia dalla fine) = ppo
- InStr: ?InStr(“1,”abcdefghi”,”cde”) = se un carattere è contenuto in una stringa di partenza = 3 (in corrispondenza del terzo carattere, restituisce il punto in cui comincia la sottostringa cercata)
- Trim: ?Trim(“ ”) = toglie spazi prima o
- Ucase: ?Ucase() = tutto maiuscolo
- Lcase: ?Lcase() = tutto minuscolo
Lezione 3 - 27/09
Proseguiamo con un altro argomento: i cicli. Vedremo le due forme più frequenti che sono il ciclo FOR e il ciclo WHILE: entrambi permettono di eseguire un certo numero di volte una serie di istruzioni in maniera uguale ogni volta che viene eseguita; il ciclo WHILE ne permette di eseguire un numero di volte dipendente da una certa condizione mentre il ciclo FOR per un numero infinito di volte.
Due esempi sull’ultimo argomento della lezione scorsa
Esempio uno sulle stringhe: funzione che restituisce TRUE se Val è divisibile per un secondo valore n
Public Function Divisibile(Val As Long, Optional n As Integer = 2) As Boolean
Dim Div_Int As Long
Dim Resto As Long
//Calcoliamo il resto di val/n
Div_Int = Val\n
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Appunti lezioni di Gestione dell'informazione aziendale
-
Organizzazione aziendale - Appunti
-
Appunti di Economia aziendale - Prof Magnani
-
Gestione aziendale - Appunti relativi alla strategia aziendale