prog_Subito2liv.jpg (18041 byte)

Corso di Visual Basic

 

VB-IT: per tutti gli sviluppatori VB o aspiranti tali

VB-IT è la mailing list italiana interamente dedicata a Visual Basic, VBA (Visual Basic for Application) e VBScript. Se sei uno sviluppatore esperto oppure ti interessa il mondo Visual Basic anche solo per diletto, troverai VB-IT utilissima!
Consigli, suggerimenti, trucchi, soluzioni a problemi comuni e molto altro. Per iscriversi, gratuitamente, a VB-IT è sufficiente inviare un messaggio a
majordomo@infomedia.it e nel body inserire la stringa: subscribe vb-it. Una volta iscritto, esponi i tuoi problemi a vb-it@infomedia.it e aiuta gli altri a risolvere i propri. Sarà anche un modo per instaurare nuovi rapporti di lavoro, collaborazione ed amicizia!

capoletteraQ.jpg (6397 byte)uesto mese il corso dedicato a Visual Basic ha come tema lo sviluppo delle applicazioni in grado di far uso dei database, ovvero di strutture in grado di ospitare grandi quantità di dati in modo particolarmente efficiente.

 

 Un database è una struttura residente su un’unità a disco che si caratterizza per la capacità di contenere ingenti quantità di dati organizzati in record. Ciò che fa la differenza fra un database e un normale file ad accesso casuale è la presenza di un modulo, detto generalmente database engine, che permette di effettuare ricerche e inserimenti all’interno dell’archivio in modo semplice e veloce. Esiste quindi un componente che si fa carico di tutta la gestione dei dati, lasciando al programmatore il solo compito di definire i parametri in base ai quali effettuare le operazioni di ricerca. Visual Basic, fin dalle sue origini, ha sempre annoverato fra i suoi punti di forza la capacità di agevolare al massimo lo sviluppo delle applicazioni in grado di gestire dei database. Questa sua caratteristica è andata evolvendosi nel tempo al punto che oggi è uno degli strumenti più utilizzati nel campo della realizzazione di applicazioni gestionali che accedono ad archivi locali o posti su un sistema remoto.

Le soluzioni dell’esercizio proposto nella scorsa lezione

Prima di affrontare lo studio dei database, è opportuno come sempre effettuare un breve ripasso di ciò che si è appreso nella scorsa lezione. Lo spunto è dato dalla correzione dell’esercizio in essa proposto, che prevede la modifica del programma descritto come esempio, in grado di visualizzare un elenco di siti Internet, per consentirgli di gestire la cancellazione logica e, su richiesta, fisica dei record.
Questi ultimi sono del tipo DatiURL, di cui è di seguito riportata la definizione:

Private Type DatiURL
Indirizzo As String * 100
Descrizione As String * 100
End Type

Per consentire la cancellazione degli elementi, è necessario modificare la struttura aggiungendole un campo booleano, che è utilizzato per contrassegnare i record logicamente rimossi. La definizione del tipo DatiURL diventa pertanto la seguente:

Private Type DatiURL
Indirizzo As String * 100
Descrizione As String * 100
Cancellato As Boolean
End Type

Per consentire la cancellazione del record corrente è necessario modificare la procedura ScriviRecord in modo da tenere conto del nuovo campo.

Sub ScriviRecord(Cancella As Boolean)
Dim Dato As DatiURL
Dato.Indirizzo = txtURL.Text
Dato.Descrizione = txtDescrizione.Text
Dato.Cancellato = Cancella
Put #1, Posizione, Dato
End Sub

Si noti che ora accetta un parametro booleano che stabilisce se il record che deve essere scritto sul disco deve essere cancellato logicamente. Il codice da associare alla pressione del pulsante btnCancella, è pertanto il seguente:

Private Sub btnCancella_Click()
ScriviRecord True
End Sub

È inoltre possibile inserire un pulsante in grado di recuperare tutti gli elementi cancellati. La sua pressione deve semplicemente richiamare la procedura Ripristina, composta da un ciclo in grado di leggere tutti i record presenti in archivio e di riscriverli dopo aver modificato il valore del campo Cancellato.

Private Sub Ripristina()
Dim i As Long
Dim NumElementi As Long
Dim Dato As DatiURL
NumElementi = ContaRecord()
For i = 1 To NumElementi
Get #1, i, Dato
Dato.Cancellato = False
Put #1, i, Dato
Next i
End Sub

La rimozione fisica di tutti gli elementi cancellati può invece avvenire per mezzo della funzione CompattaFile, che provvede a copiare in un nuovo file tutti i record caratterizzati dal contenere il valore False all’interno del campo Cancellato. Dopo essere stato creato, il nuovo file sostituisce quello di partenza.

Private Sub CompattaFile()
Dim Dato As DatiURL
Dim Lunghezza As Long
Dim NumElementi As Long
Dim i As Long
NumElementi = ContaRecord()
Open "temp.dat" For Random As #2 Len = LunghezzaRecord
For i = 1 To NumElementi
Get #1, i, Dato
If Not Dato.Cancellato Then
Put #2, , Dato
End If
Next i
Close #1, #2
Kill "archivio.dat"
Name "temp.dat" As "archivio.dat"
Open "archivio.dat" For Random As #1 Len = LunghezzaRecord
End Sub

Il codice completo del programma sopra descritto è riportato nel Listato 1. La sua lunghezza si sarebbe notevolmente ridotta se fosse stato utilizzato un database in luogo del file ad accesso casuale. Nel seguito di questa lezione si vedrà come è possibile fare ciò.

I tipi di database utilizzabili da Visual Basic

Esistono sul mercato molti sistemi di gestione dei database. Ognuno di essi è caratterizzato da un diverso modo di organizzare le informazioni sul disco. Per questo motivo, i file prodotti con tali strumenti presentano spesso dei formati molto diversi. I prodotti più noti sono Microsoft Access e FoxPro, nonché Borland DBase e Paradox.
Visual Basic è in grado di gestire tutti questi formati, grazie a dei moduli supplementari denominati ISAM (Indexed Sequential Access Method) che possono essere utilizzati dal motore di gestione dei database su richiesta dell’applicazione. Oltre ai formati gestibili per mezzo dei moduli ISAM, Visual Basic è in grado di leggere e scrivere dei dati anche in strutture di diverso tipo, eventualmente poste su server remoti, grazie al supporto per la tecnologia ODBC (Open Database Connectivity). Ciò estende notevolmente il campo di utilizzo dello strumento, facendo sì che esso sia in grado di utilizzare qualunque formato di database per il quale esista un driver ODBC.

La struttura di un database

Le informazioni contenute all’interno di un database, essendo spesso in grande quantità, sono raggruppate in tabelle, al fine di minimizzare lo spreco di spazio sul disco e di agevolare le operazioni di ricerca. Ad esempio, supponendo di voler gestire l’inventario di una libreria, sarà necessario conoscere per ciascun libro almeno il titolo, l’autore, l’editore e lo scaffale che lo contiene. È tuttavia verosimile attendersi che molti editori abbiano pubblicato più di un libro. Se ad ogni opera è dedicato un record e se in ognuno di essi sono presenti anche i dati relativi all’editore, è evidente che le informazioni riguardanti gli editori che hanno pubblicato più di un libro sono inutilmente duplicate. L’ingombro degli archivi non risulta pertanto ottimizzato in relazione ai dati contenuti. Ciò si traduce in uno spreco di spazio sul disco e in una maggior quantità di informazioni da leggere durante l’effettuazione delle operazioni di ricerca. Inoltre, la presenza di più copie dello stesso dato può portare a problemi di inconsistenza dovuti ad errori di inserimento o alla mancata sincronizzazione in caso di modifica. Per evitare ciò, è conveniente suddividere l’archivio in più strutture, dette tabelle, raggruppando fra loro le informazioni dello stesso tipo. Fra le tabelle è possibile stabilire delle relazioni.
Nel caso della libreria, ad esempio, è possibile inserire i dati relativi agli editori in una tabella a parte ed associare ad ognuno di essi un identificatore univoco. Le altre informazioni relative ai libri possono essere contenute in una seconda tabella, costituita da record in cui in luogo dei dati relativi agli editori sono presenti solo i loro identificatori. Ciò fa sì che un’eventuale modifica delle informazioni relative a una casa editrice, dovute ad esempio ad un cambio di indirizzo o di ragione sociale, comporti la variazione del contenuto di un solo record e non metta a repentaglio la consistenza dei dati.

L’oggetto data

La gestione dei database in Visual Basic è resa estremamente semplice da uno speciale controllo: l’oggetto data. Si tratta di un componente che presenta il caratteristico aspetto illustrato nella Figura 1; come è possibile osservare, è composto da 4 pulsanti, su cui sono presenti i simboli tipici dei registratori a nastro, posti alle estremità di un’etichetta testuale.
Tutte le operazioni che devono essere effettuate sull’archivio devono far riferimento all’oggetto data ad esso associato. Per poter utilizzare il suddetto componente, occorre assegnare dei valori ad alcune sue proprietà. In primo luogo è necessario specificare il tipo di database che si prevede di utilizzare. Ciò è possibile agendo, per mezzo dell’apposita finestra, sulla proprietà Connect. Il valore predefinito è Access.
Infatti, il motore di gestione dei database utilizzato da Visual Basic, denominato Jet, prevede come formato nativo quello di Microsoft Access, che ha la caratteristica di incorporare tutte le informazioni all’interno di un file di estensione mdb. Scorrendo la lista che appare nella finestra delle proprietà, è possibile osservare l’elenco degli altri formati supportati per mezzo dei driver ISAM. La lunghezza di questa lista è variabile in base al numero dei moduli installati nel sistema.
Si noti che la decisione di utilizzare un formato diverso da quello standard comporta l’aggiunta al disco di distribuzione del necessario modulo ISAM. Dopo averne definito il tipo, è possibile indicare il nome del database. Ciò è possibile agendo sull’attributo DatabaseName. Si noti che, facendo doppio clic sulla voce nella casella delle proprietà, si provoca l’apertura di una finestra che invita a selezionare un file. Nel caso di archivi contenuti interamente all’interno di un unico file, come quelli in formato Access, esso rappresenta il database da utilizzare. In altri casi, quali ad esempio le strutture di tipo xBase (DBase o FoxPro), in cui ogni tabella è memorizzata sul disco in un file a sé stante caratterizzato dall’estensione dbf, il database è costituito dalla directory che contiene i dati.
Un’altra proprietà a cui è necessario assegnare un valore è denominata RecordSource. Essa deve contenere l’espressione che permette al motore di gestione degli archivi di scegliere la fonte dei dati da visualizzare. Il valore da indicare è il nome della tabella da cui si desidera prelevare le informazioni.

La realizzazione di un programma in grado di accedere a un database

Si supponga di voler realizzare un’applicazione analoga a quella dell’esercizio proposto nella scorsa lezione, in grado di visualizzare le informazioni relative a un elenco di siti Internet. Questa volta, tuttavia, si desidera far uso di un database. L’archivio può essere creato mediante un prodotto come Microsoft Access. Con questo strumento è possibile definire una tabella costituita da record aventi due campi di tipo alfanumerico, denominati Indirizzo e Descrizione. Si supponga di assegnarle il nome TabellaURL e di salvare il database nel file Web.mdb.
Il passo successivo consiste nel creare un form, su cui occorre trascinare dalla casella degli strumenti un oggetto di tipo Data. Ad esso si suppone di assegnare il nome dbArchivio. Si procede poi a scegliere il formato da utilizzare assegnando alla proprietà Connect il valore Access e ad assegnare il corretto valore alla proprietà DatabaseName.
A tal fine si seleziona il file Web.mdb per mezzo dell’apposita opzione presente nella finestra delle proprietà. L’ultimo attributo da impostare riguarda la fonte dei dati.
Essendo il database composto da una sola tabella, la scelta del valore della proprietà RecordSource è pressoché obbligata. La lista posta nella finestra delle proprietà è infatti composta dalla sola voce TabellaURL. Dopo aver assegnato i valori alle proprietà fondamentali dell’oggetto di tipo data, non resta che inserire sul form le caselle testuali che permettono la visualizzazione e la modifica dei dati presenti in archivio. Il loro collegamento al database può essere effettuato senza bisogno di scrivere del codice, in quanto avviene semplicemente impostando le proprietà DataSource e DataField.
La proprietà DataSource permette di indicare l’oggetto di tipo data da cui una textbox deve attingere i valori da visualizzare. Nell’apposita finestra è possibile selezionare l’unico valore proposto, ovvero dbArchivio. La proprietà DataField, invece, permette di indicare il nome del campo da visualizzare. Nel caso dell’esempio, i valori possibili sono Indirizzo e Descrizione.
Senza scrivere alcuna riga di codice, bensì semplicemente seguendo le istruzioni sopra riportate, è possibile realizzare un’applicazione in grado di visualizzare un archivio di siti Internet, caratterizzata dalla possibilità di scorrere i record agendo sui pulsanti posti all’interno del controllo di tipo data.

Il metodo UpdateControls

L’applicazione creata consente anche la modifica dei dati presenti in archivio. Se il contenuto di almeno una delle textbox subisce delle variazioni, la pressione di uno dei pulsanti di cui è dotato il controllo dbArchivio provoca il salvataggio nel database delle informazioni modificate.
Si supponga ora di voler aggiungere all’applicazione un pulsante, a cui si dà il nome btnRipristina, in grado di annullare le eventuali modifiche effettuate accidentalmente. Si tratta in pratica di costringere l’oggetto dbArchivio a rileggere il record corrente e a sovrascrivere le informazioni poste nelle textbox collegate. Ciò è possibile semplicemente invocando il metodo UpdateControls. Il codice da associare al pulsante è il seguente:

Private Sub btnRipristina_Click()
dbArchivio.UpdateControls
End Sub

La proprietà Recordset

L’insieme dei record presenti in archivio è identificato dalla proprietà Recordset. Si tratta in sintesi di un oggetto su cui è possibile invocare dei metodi per aggiungere, togliere o modificare gli elementi posti nella base di dati.

L’aggiunta di un record all’archivio

L’aggiunta di un nuovo record all’archivio richiede l’invocazione del metodo AddNew dell’oggetto Recordset. Supponendo di voler inserire nel form il pulsante btnNuovoRecord, il codice da associare alla sua pressione è il seguente:

Private Sub btnNuovoRecord_Click()
dbArchivio.Recordset.AddNew
End Sub

Dopo aver inserito nelle caselle di testo il contenuto del nuovo record, è necessario trasferirlo nel database. Per fare ciò, occorre eseguire il metodo Update dell’oggetto Recordset. Questa operazione può essere effettuata come risposta alla pressione di un pulsante che si suppone denominato btnAggiorna.

Private Sub btnAggiorna_Click()
dbArchivio.Recordset.Update
End Sub

La cancellazione di un record

Anche per cancellare un record è sufficiente utilizzare un semplice metodo dell’oggetto Recordset. Si tratta del metodo Delete. Volendo inserire nel form un pulsante in grado di rimuovere il record corrente, è necessario scrivere il seguente codice:

Private Sub btnCancella_Click()
dbArchivio.Recordset.Delete
End Sub

Un semplice esercizio

Per esercitarsi sui concetti esposti, si provi a realizzare un programma in grado di gestire una semplice rubrica telefonica.

Conclusioni

L’uso di un database consente il trattamento di cospicue quantità di informazioni in modo molto semplice e veloce. Per questo motivo, la stragrande maggioranza delle applicazioni gestionali ne fa uso. A questo tipo di strutture, data l’importanza che le caratterizza, sarà dedicata anche la prossima lezione. Per agevolarne la comprensione, il lettore è quindi invitato ad esercitarsi sui concetti sopra esposti.

Bibliografia

"Visual Basic 5", McGrawHill, ISBN 88-386-0436-3.