Corso di

Visual Basic

(Parte 2)

di Maurizio Crespi

La seconda parte del corso introduttivo alla programmazione in Visual Basic si pone come scopo di insegnare l'uso della struttura di controllo If e delle proprie varianti.

Dopo aver studiato come si creano delle semplici applicazioni ed aver preso confidenza con i tipi di dati fondamentali, è ora giunto il momento di occuparsi delle strutture di controllo, mediante le quali si possono scrivere dei programmi in grado di comportarsi in modo diverso a seconda dei valori assunti dai dati da elaborare.

 

Le soluzioni degli esercizi proposti nella prima parte

Prima di affrontare nuovi argomenti, è bene rivedere ciò che è stato oggetto di studio nella scorsa puntata. Lo spunto è offerto dalla correzione degli esercizi in essa proposti.

Il primo esercizio

Il primo esercizio prevede la creazione di un programma in grado di simulare il funzionamento di un interruttore mediante due pulsanti, riportanti rispettivamente le scritte "ON" e "OFF" e un'etichetta di testo, nella quale devono essere visualizzate in alternativa le indicazioni "Acceso" e "Spento".

La prima fase consiste nel creare un nuovo progetto e nell'inserire all'interno del form principale i tre elementi grafici. Si provvede poi, per mezzo dell'apposita finestra, ad assegnare ad essi i valori della proprietà Caption, affinché sui pulsanti appaiano le scritte "ON" e "OFF". L'interfaccia appare come nella Figura 1.

È buona norma assegnare anche dei nomi agli oggetti. Ciò comporta l'impostazione per ognuno di essi della proprietà Name. Si supponga di utilizzare i nomi btnON, btnOFF, per i pulsanti e lblValore per l'etichetta testuale.

L'ultimo passo consiste nello scrivere il codice da associare alla pressione dei bottoni. Essi devono semplicemente variare il testo visualizzato dalla label, ovvero modificare la sua proprietà Caption. Dopo aver premuto due volte il tasto sinistro del mouse sul pulsante btnON ed aver quindi aperto la finestra che ospita il codice di risposta all'evento Click, è necessario scrivere quanto segue:

Private Sub btnON_Click()

lblValore.Caption = "Acceso"

End Sub

Si noti che l'indicazione Private, il cui significato sarà analizzato in uno dei prossimi numeri, deve essere omessa sulle versioni di Visual Basic precedenti la 4.0. In modo perfettamente analogo si può completare l'applicazione associando al pulsante btnOFF la procedura:

Private Sub btnOFF_Click()

lblValore.Caption = "Spento"

End Sub

Il secondo esercizio

Nel secondo esercizio è richiesta la modifica del funzionamento di un programma che simula un cronografo. L'interfaccia si compone di un pulsante di azzeramento e di una label che visualizza il numero dei secondi trascorsi. Si desidera fare in modo che l'indicazione del tempo sia rappresentata nel formato HH:MM:SS.

Il conteggio avviene per mezzo di un timer regolato, mediante l'impostazione della proprietà Interval al valore 1000, in modo da generare un evento ogni secondo. La procedura da modificare è pertanto quella che gestisce gli eventi Timer da esso prodotti. Devono essere eseguite delle divisioni successive per determinare il numero delle ore, dei minuti e dei secondi. Il codice diventa pertanto il seguente:

Private Sub Timer1_Timer()

Dim Ore, Minuti, Secondi, Resto As Integer

Dim StringaOre, StringaMinuti, StringaSecondi,

Tempo As String

NumSecondi = NumSecondi + 1

Ore = Int(NumSecondi / 3600)

Resto = NumSecondi - (Ore * 3600)

Minuti = Int(Resto / 60)

Secondi = Resto - (Minuti * 60)

StringaOre = Str$(Ore)

StringaMinuti = Str$(Minuti)

StringaSecondi = Str$(Secondi)

Tempo = StringaOre + ":"

Tempo = Tempo + StringaMinuti + ":"

Tempo = Tempo + StringaSecondi

lblMessaggio.Caption = Tempo

End Sub

Si noti che, per estrarre la parte intera del risultato di ogni divisione, si è fatto ripetutamente uso della funzione Int.

Il numero delle ore è calcolato dividendo per 3600 il totale dei secondi, contenuto nella variabile globale NumSecondi. Il resto è poi diviso per 60 al fine di quantificare i minuti. Questa operazione genera un nuovo resto, che rappresenta il numero di secondi. I valori ottenuti sono successivamente trasformati in sequenze alfanumeriche e copiati nella variabile Tempo, anch'essa di tipo String, avendo cura di interporre fra di loro il carattere ":". Si noti che, per concatenare le stringhe, si fa uso dell'operatore di addizione "+". Il valore della variabile Tempo è infine visualizzato per mezzo della label.

 

La struttura If

Avviando l'applicazione sopra descritta, è possibile osservare che il contenuto dell'etichetta non è esattamente espresso nel formato HH:MM:SS. Infatti, l'indicazione appare come in Figura 2, ossia i valori indicanti il numero di ore, minuti e secondi non sono obbligatoriamente composti da due cifre. Si supponga di voler modificare il programma affinché provveda ad anteporre uno zero non significativo al contenuto delle variabili StringaOre, StringaMinuti e StringaSecondi ogniqualvolta esse risultino composte da una sola cifra. L'applicazione, in questo caso, deve essere in grado di riconoscere una condizione, nella fattispecie la presenza di un valore inferiore a dieci e di intervenire anteponendo uno zero solo quando essa è verificata. A differenza degli esempi fino ad ora esaminati, il flusso delle istruzioni all'interno della procedura non è più rigidamente definito, ma può variare in base al verificarsi di alcune condizioni. Il programma deve pertanto essere in grado di prendere delle decisioni. Come la quasi totalità dei linguaggi di programmazione, Visual Basic prevede a tal fine la struttura If, caratterizzata dalla seguente sintassi:

If <condizione> Then

<istruzioni da eseguire se la condizione è vera>

[Else

<istruzioni da eseguire se la condizione è falsa>]

End If

La condizione può essere rappresentata da pressoché qualsiasi espressione booleana. Si ricorda che un'espressione è così detta se può assumere solo due valori distinti, cioè vero o falso. Se essa è verificata, l'interprete esegue il blocco di istruzioni indicato fra le parole chiave Then e Else. In caso contrario, è eseguito il secondo gruppo di comandi. Si noti che quest'ultimo può anche essere assente. In tal caso, la parola chiave Else non va utilizzata e non è eseguito alcun codice in caso di mancata verifica della condizione.

La frase End If delimita la struttura. Tutte le istruzioni che la seguono sono eseguite in modo indipendente dal valore dell'espressione booleana. La procedura da associare all'evento Timer può essere pertanto modificata come indicato:

Private Sub Timer1_Timer()

Dim Ore, Minuti, Secondi, Resto As Integer

Dim StringaOre, StringaMinuti, StringaSecondi,

Tempo As String

NumSecondi = NumSecondi + 1

Ore = Int(NumSecondi / 3600)

Resto = NumSecondi - (Ore * 60)

Minuti = Int(Resto / 60)

Secondi = Resto - (Minuti * 60)

If Ore < 10 Then

StringaOre = "0" & Ore

Else

StringaOre = Str$(Ore)

End If

If Minuti < 10 Then

StringaMinuti = "0" & Minuti

Else

StringaMinuti = Str$(Minuti)

End If

If Secondi < 10 Then

StringaSecondi = "0" & Secondi

Else

StringaSecondi = Str$(Secondi)

End If

Tempo = StringaOre + ":"

Tempo = Tempo + StringaMinuti + ":"

Tempo = Tempo + StringaSecondi

lblMessaggio.Caption = Tempo

End Sub

Essa si differenzia dalla precedente per l'introduzione di tre strutture di controllo pressoché analoghe. Si osservi ad esempio la prima; la condizione è vera se la variabile Ore contiene un numero inferiore a dieci. In questo caso, alla variabile StringaOre è associato un testo composto dal carattere "0" e dal valore contenuto nella variabile Ore. Si noti che in questo caso non si è fatto uso della funzione Str$. Quando un dato numerico è assegnato ad una variabile di tipo stringa, infatti, la conversione di formato è eseguita automaticamente, a condizione che il codice utilizzato non possa generare delle ambiguità. È per questo motivo che la concatenazione delle stringhe è stata effettuata mediante il simbolo "&", anziché con l'operatore di addizione che, essendo applicabile anche ai valori numerici, avrebbe reso l'interprete incapace di dedurre le reali intenzioni del programmatore. Il carattere "&" può essere utilizzato esclusivamente per unire due stringhe alfanumeriche e quindi pone al riparo da ogni dubbio.

 

La funzione Val

Nel seguito di questa trattazione si farà uso delle caselle di testo (textbox). Esse risultano estremamente simili alle label, ma si differenziano da esse in quanto rendono possibile la modifica del proprio contenuto all'utente finale. Sono pertanto utilizzate ogniqualvolta si presenti la necessità di richiedere un dato alfanumerico all'utilizzatore del programma. Per verificare o modificare il loro contenuto è necessario accedere alla proprietà Text, che è sempre di tipo String. La sua conversione in una valore numerico, quando possibile, può essere effettuata per mezzo della funzione Val, la cui sintassi è:

<var1> = Val(<var2>)

dove var1 è di tipo numerico e var2 rappresenta una stringa. Occorre notare che la funzione esegue una scansione del testo fornitole come parametro a partire dal carattere posto all'estrema sinistra. Il controllo termina quando è incontrato un elemento non numerico. Pertanto, la condizione

Val("1234") = Val("1234abc")

è verificata. Inoltre, è vera anche la condizione:

Val("abcde") = 0

Facendo tesoro di ciò che è stato appena appreso, si provi a realizzare una semplice applicazione in grado di visualizzare in una label il valore assoluto di un numero posto in una casella di testo, senza far uso della funzione Abs. Il calcolo può essere eseguito in corrispondenza della pressione di un pulsante.

 

Le strutture If nidificate

Si supponga di voler realizzare un programma in grado di calcolare il valore massimo fra due numeri forniti in ingresso mediante delle caselle di testo e di visualizzare il risultato in una label. L'interfaccia è rappresentata nella Figura 3. Si supponga di assegnare i nomi txtPrimoValore e txtSecondoValore alle textbox. La procedura da associare come risposta alla pressione del pulsante di calcolo è la seguente:

Private Sub btCalcola_Click()

Dim Valore1, Valore2 As Double

Dim Risultato As String

Valore1 = Val(txtPrimoValore.Text)

Valore2 = Val(txtSecondoValore.Text)

If Valore1 > Valore2 Then

Risultato = "Valore massimo: " & Valore1

Else

If Valore1 < Valore2 Then

Risultato = "Valore massimo: " & Valore2

Else

Risultato = "I valori sono uguali"

End If

End If

lblMessaggio.Caption = Risultato

End Sub

Dopo aver copiato i dati in ingresso in variabili numeriche, l'applicazione procede al confronto fra i valori. Dapprima il programma verifica se prevale il contenuto della variabile Valore1 rispetto a quello di Valore2. Se la condizione è verificata, il massimo è copiato nella variabile Risultato, che costituisce il testo da visualizzare per mezzo della label lblMessaggio. Altrimenti, è eseguito l'altro blocco della struttura If, ovvero è verificata la prevalenza del secondo valore rispetto al primo. In caso negativo, è segnalata l'uguaglianza dei dati in ingresso. È possibile osservare che è stata posta una struttura If all'interno di un'altra. L'annidamento di più blocchi di programma è una pratica molto comune quando si fa uso di linguaggi moderni come Visual Basic. Si noti che se fosse stato necessario eseguire il confronto fra un numero più elevato di valori, l'uso di strutture nidificate avrebbe influenzato negativamente la leggibilità del programma. Per ridurre tali effetti negativi è possibile utilizzare la parola chiave ElseIf, che permette di mantenere un'organizzazione a due livelli anche in presenza di un numero elevato di confronti. Ecco come si presenta la procedura modificata:

Private Sub btCalcola_Click()

Dim Valore1, Valore2 As Double

Dim Risultato As String

Valore1 = Val(txtPrimoValore.Text)

Valore2 = Val(txtSecondoValore.Text)

If Valore1 > Valore2 Then

Risultato = "Valore massimo: " & Valore1

ElseIf Valore1 < Valore2 Then

Risultato = "Valore massimo: " & Valore2

Else

Risultato = "I valori sono uguali"

End If

lblMessaggio.Caption = Risultato

End Sub

L'uso delle parole riservate ElseIf permette di aumentare a piacimento il numero di condizioni da controllare all'interno della stessa struttura. Se nessuna di esse risulta verificata, allora è eseguito il codice specificato dopo la parola chiave Else. Per verificarne l'utilità, si provi a realizzare un'applicazione in grado di visualizzare un messaggio indicante se il dato inserito in una textbox rappresenta il nome di uno dei giorni della settimana.

 

Conclusioni

Le strutture di controllo, oggetto di questa trattazione, danno alle applicazioni la flessibilità necessaria per svolgere operazioni non banali. Per questo motivo, la loro conoscenza è di importanza fondamentale. Al lettore è pertanto rivolto l'invito ad esercitarsi nell'uso di tali costrutti. Buon lavoro, dunque!

(c) 1998 Edizioni Infomedia srl