TUTORIAL - Introduzione Al Visual Basic

download TUTORIAL - Introduzione Al Visual Basic

of 39

Transcript of TUTORIAL - Introduzione Al Visual Basic

INTRODUZIONE A MICROSOFT VISUAL BASICMicrosoft Visual Basic 6.0

Microsoft Visual Basic uno strumento di sviluppo della famiglia Microsoft Visual Studio che permette di realizzare in modo rapido ed immediato (RAD: Rapid Application Development) applicazioni altamente integrate con l'insieme di sistemi operativi Windows di Microsoft. Il prodotto distribuito in tre versioni principali: Learning Edition Professional Edition Enterprise Edition

La differenza fonamentale tra le tre versioni non riguarda la sintassi del linguaggio di programmazione ma gli strumenti sviluppo disponibili. La versione Learning infatti pu essere vista come una versione di base orientata agli studenti o agli hobbisti che vogliono iniziare a conoscere il VB. E' ottima per imparare ma inevitabilmente finirete per sentire la necessit degli strumenti presenti nelle versioni maggiori se inizierete ad usare con continuit questo strumento. La versione Professional infatti include strumenti indispensabili per la creazione di applicazione client/server e per Internet. La versione Enterprise infine la scelta corretta per gruppi di sviluppatori che necessitano di tutti gli strumenti per monitorare e migliorare le prestazioni e l'efficienza del loro codice. Ovviamente i prezzi dei tre prodotti cambiano in funzione delle caratteristiche, quindi si passa dalle circa 200 mila Lire (109$) della versione Learning, al milione abbondante (549$) della edizione Professional per finire con circa 3 milioni (1299$) della versione Enterprise. Se la vostra intenzione solo quella di valutare il prodotto vi consiglio la versione Learning in quanto contiene anche un manuale di "avviamento" alla programmazione su cd-rom. Se avete intenzione di sviluppare delle applicazioni professionali per vi ocnviene comprare direttamente la versione Professional. Un consiglio che mi sento di darvi: usate la versione Inglese. Il VB un linguaggio molto simile all'inglese, non sono 3 voci di men in italiano che ci semplificano la vita, l'inglese dobbiamo conoscerlo comunque per poter utilizzare il VB. Spesso le versioni nazionalizzate hanno problemi/bug specifici che nelle versioni inglesi e/o internazionali non sono presenti. I fix spesso escono prima nella versione inglese e poi nelle versioni nazionalizzate, quindi se avete il VB italiano vi tocca aspettare. Se volete prima o poi certificarvi come Microsoft Certified Professional non tutti gli esami esistono in italiano. Quelli sul VB sono tutti in inglese quindi se voi imparate ad usare il VB in italiano rischiate poi di non sapere le risposte alle domande relative all'interfaccia utente.

Cosa possiamo fare ?

In questa prima "puntata" intendo dare solo una panoramica veloce delle possibilit offerte dal VB. Con le versioni Professional/Enterprise possiamo realizzare le seguenti tipologie fondamentali di applicazione:

Standard EXE: sono i classici programmi eseguibili, pensati per le postazioni desktop ActiveX EXE: sono applicazioni eseguibili che espongono ulteriori informazioni per essere raggiungibili anche da altri programmi/computer

ActiveX DLL: sono librerie COM (Component Object Model) ... vedremo bene di cosa si tratta nella seconda met del tutorial

ActiveX Control: sono dei controlli grafici che possiamo inserire nelle nostre applicazioni o in pagine Web ActiveX Documents: sono dei particolari documenti visualizzabili in container (Contenitore di Office, Internet Explorer, ecc.) AddIn: sono programmi che servono a noi programmatori per automatizzare determinati compiti durante lo sviluppo delle nostre applicazioni DHTML Application: sono applicazioni Web basate sul Dynamic HTML

IIS Application: sono applicazioni Internet particolari che permettono di inviare ai client Web (Explorer, Netscape, ecc.) pagine HTML pure anche se generate dinamicamente sul server

Kit di sopravvivenza

Prima di buttarci a capofitto nello sviluppo VB mi permetto di consigliarvi alcuni strumenti che potete pensare come una sorta di kit di sopravvivenza. Questi sono: Programmare Microsoft Visual Basic 6.0 - Francesco Balena (Microsoft Press - Mondadori Informatica) Microsoft Access 97/2000 - non un libro ma il software in quanto tale. Microsoft Windows NT Option Pack o il Personal Web Server di Windows 9x

Il libro di Francesco Balena un comodo supporto allo sviluppo di tutti i giorni. I software sono praticamente indispensabili per poter lavorare e di conseguenza saranno fondamentali anche per alcune delle realizzazione che svolgeremo nella seconda parte di questo tutorial.

INTERFACCIA UTENTE E PROGRAMMAZIONE GUIDATA DAGLI EVENTIAvviamo il VB

Se mandiamo in esecuzione il nostro Microsoft Visual Basic 6.0 ci troviamo all'interno dell'ambiente di sviluppo. Tramite questa interfaccia possiamo creare tutte le nostre applicazioni e i nostri componenti. La prima schermata che ci si presenta quella che ci permette di scegliere il tipo di applicazione che stiamo iniziando a creare (Standard EXE, ActiveX EXE, ActiveX DLL, ecc.). In questa primo caso ci occuperemo di un applicativo desktop tradizionale e quindi chiederemo al VB di creare un modello di progetto Standard EXE. Questa scelta comporta il fatto che il VB crei un nuovo progetto e vi inserisca automaticamete le informazioni necessarie a gestire la visualizzazione di una finestra. Tradotto in pratica questo determina la creazione di un progetto di applicazione inizialmente costituita da una sola form.

La prima Form

Selezionato il tipo di progetto quindi ci troviamo nell'ambiente di sviluppo VB e sullo schermo del nostro PC avremo la possibilit di disegnare la nostra interfaccia utente tramite il mouse e la casella degli strumenti, di default alla sinistra della finestra. Un approccio classico allo sviluppo di applicazioni desktop VB quindi il disegno dell'interfaccia utente. Pensiamo di voler inserire un pulsante nella nostra form. Non dovremo fare altro che selezionare nella casella degli strumenti lo strumento CommandButton e poi disegnarne la forma sulla form affinch il pulsante venga aggiunto all'interfaccia grafica della stessa. Se a questo punto volessimo eseguire (tasto F5 = Esegui) il nostro programma - che non far assolutamente nulla - vedremmo che comunque il programma gi in grado di funzionare ed infatti la sua esecuzione comporta la visualizzazione di una finestra con lo stesso aspetto della form da noi definita. Questo ci permette di concludere che le applicazioni desktop per essere realizzate in termini di interfaccia grafica possono non richiedere alcun elemento di codice. In relt vedremo nel prosieguo di questo tutorial che molto spesso l'interfaccia grafica viene caricata o quantomento gestita dal codice e quindi nelle applicazioni concrete non baster mai definire soltanto l'aspetto grafico degli oggetti. Se premiamo il tasto F4 (= Visuallizza Propriet) possiamo accedere ad una finestrella come quella riportata in figura, che ci permette di definire la maggior parte delle informazioni relative ai nostri oggetti disegnati sullo schermo. Ad esempio generalmente ci sono le propriet per selezionare il colore di sfondo dell'oggetto, il colore in primo piano, ecc. Una buona regola di comportamento, attuabile tramite l'utilizzo di questa finestra di propriet, assegnare al progetto, alle form ed ai controlli dei nomi (propriet (Name) nel pannellino) sensati, meglio se nel rispetto della notazione ungarica.

La programmazione ad eventi

Definita l'interfaccia utente del mio programma devo pensare a scrivere il codice che la gestisca. L'idea alla base di questo modo di ragionare che, definito un elemento nell'interfaccia utente

di un applicazione, posso codificare la procedura da fargli eseguire quando questo elemento viene premuto con il mouse, piuttosto che quando il mouse gli passa sopra senza premerlo. Il bello di questi programmi che l'utente finale delle nostre applicazioni di solito libero di premere un tasto piuttosto che un altro, di muovere il mouse sopra un controllo piuttosto che un altro. Quindi si potrebbe verificare potenzialmente qualsiasi delle casistiche accennate. Questa idea di applicazione che risponde alle richieste ed alle azioni dell'utente, richiamando determinate procedure senza un ordine di esecuzione prestabilito, ci porta ad avere programmi che saranno costituiti da piccoli blocchi di codice, che gestiranno le singole situazioni che si possono verificare (click del mouse, movimenti del mouse, altro...). Quindi si parla di programmazione guidata dagli eventi (Event-Driven) perch tutto ci che si verifica dovuto ad eventi associati ad elementi della nostra interfaccia grafica.

Gestiamo il click di un pulsante

Chiarito il concetto di programmazione guidata dagli eventi vediamo come gestire un semplice evento. Inseriamo un pulsante di comando all'interno della nostra interfaccia utente e chiamiamolo cmdButton tramite la finestra delle propriet (F4). Facendo doppio click sull'oggetto appena definito comparir una finestra che ci permette di scrivere del codice associato all'evento predefinito dell'oggetto. Si parla di evento predefinito perch un oggetto pu essere in grado di gestire diversi eventi (click, doppio click, mousemove, mouseover, ecc.). Nel caso del pulsante di comando ci troveremo all'interno della procedura di gestione dell'evento Click e quindi ci si presenter una schermata simile a quella nella seguente.

Osserviamo che ci troviamo in un modulo di codice associato ad una form ed all'interno di questo troviamo della sintassi VB (che nelle prossime lezioni approfondiremo) che ci definisce una procedura cmdButton_Click, la quale scatter ogni volta che il nostro utente far click con il mouse sul pulsante cmdButton. Per verificare il funzionamento di questa logica ad eventi abbiamo inserito un'istruzione MsgBox "Hai fatto click sul pulsante cmdButton !" che altro non fa che aprire sullo schermo una finestrella di messaggio che riporter come messaggio appunto la dicitura che le forniamo come argomento. Eseguendo (F5) il nostro progetto possiamo renderci conto del fatto che ora, contrariamente al progetto privo di codice in esecuzione, la nostra applicazione ogni volta che viene premuto il pulsante di comando eseguir questa riga di codice e visualizzer il messaggio sullo schermo.

COSTRUTTI FONDAMENTALI DEL LINGUAGGIO VISUAL BASICAree di codice

In Microsoft Visual Basic possiamo avere diversi file e moduli di codice all'interno di un unico progetto di applicazione. Nei moduli di codice di Microsoft Visual Basic abbiamo diverse aree che possiamo localizzare selezionandole nelle caselle a discesa che troviamo nella parte alta dei moduli di codice stessi. Queste aree sono: (Generale) - (Dichiarazioni) => in questa dovremo inserire informazioni di interesse per tutto il modulo di codice. Nome_Oggetto - Procedura Evento => in queste aree dovremo caricare il codice relativo a singole procedure evento (per es. Command1_Click). (Generale) - Procedura Generica => in queste aree avremo il codice relativo alle procedure e funzioni da noi definite (ne parleremo tra poco).

All'interno di queste aree dovremo inserire del codice di programmazione nel rispetto della sintassi del linguaggio ed appoggiandoci ai costrutti che vedremo in questa lezione.

Le Variabili

Anche in Microsoft Visual Basic 6.0 come in qualsiasi linguaggio di programmazione possibile dichiarare delle variabili. Le variabili sono un'area di memoria dove possibile salvare delle informazioni per riutilizzarle in seguito. Le parole chiave per dichiarare delle variabili in Microsoft Visual Basic sono: Dim NomeVariabile As Tipo Public NomeVariabile As Tipo Private NomeVariabile As Tipo Static NomeVariabile As Tipo Vi sono diverse parole chiave a seconda dello spazio di azione (visibilit) che vogliamo assegnare alle variabili che dichiariamo. In realt in Microsoft Visual Basic possibile lavorare senza dichiarare le variabili, ma il fatto che un linguaggio offra questa possibilit non significa che noi dobbiamo per forza sfruttarla. Lavorare senza dichiarare le variabili che si utilizzano una pessima abitudine. Dal momento che lo scopo di questo tutorial imparare a programmare bene in Microsoft Visual Basic, per noi le variabili saranno sempre da dichiarare. Per essere sicuri di non sbagliare possiamo attivare un'opzione che ci costringe a dichiarare le variabili. Dal men Strumenti->Opzioni selezionare il primo pannello ed attivare "Richiedi la dichiarazione delle variabili". A questo punto vediamo cosa significano le parole chiave elencate precedentemente: Dim significa che stiamo dimensionando una variabile che avr uno spazio di azione pari a quello della sezione in cui dichiariamo la variabile. Questo significa che se useremo Dim all'interno di una procedura (un blocco di codice che pu essere richiamato pi volte) allora la variabile che dichiareremo sar valida soltanto all'interno di quella procedura, soltanto nel momento in cui la procedura in esecuzione. Di solito la parola chiave Dim si usa proprio in questo caso. Public e Private invece si usano di solito nel dichiarare variabili nella parte che prima abbiamo definito come (Generale) - (Dichiarazioni). Qualora si voglia avere le variabili visibili dagli altri moduli di codice del progetto si user Public altrimenti Private per avere le variabili visibili solo all'interno del modulo in cui le abbiamo definite. Torneremo pi avanti nel Tutorial a parlare di queste cose (sviluppo di componenti). La parola chiave Static infine dimensiona una variabile all'interno di una procedura in modo tale che la stessa mantenga il suo valore tra diverse esecuzioni della procedura.

Tutte e quattro le parole chiave richiedono un nome (conviene dare nomi sensati alle variabili) ed un tipo subito dopo la parola chiave As. Per tipo si intende la tipologia di valori che la variabile pu assumere. I tipi di dati pi comuni definiti da Microsoft Visual Basic sono: Tipo di Dato Boolean Byte Currency Date (Time) Double Prefisso bln byt cur dtm dbl Valore Ammesso True/False 0-255 da -922,337,203,685,477.5808 a 922,337,203,685,477.5807. Data (64 bit) da 1.79769313486231E308 a -4.94065645841247E-324 per valori negativi; da 4.94065645841247E-324 a 1.79769313486232E308 per valori positivi. da -32,768 a 32,767 da -2,147,483,648 a 2,147,483,647 Un variabile Oggetto da -3.402823E38 a -1.401298E-45 per valori negativi; da 1.401298E-45 a 3.402823E38 per valori positivi Sequenze di caratteri a lunghezza fissa da 0 a 63K caratteri o a lunghezza variabile da 0 a 2 billioni di caratteri. Tipi definiti dall'utente Valore Variant (16/22 Byte)

Integer Long Object Single

int lng obj sng

String

str

User-defined type Variant

udt vnt

Possiamo anche definire dei nostri tipi di dati personalizzati, cos come possiamo definire delle matrici di dati. Anche di questo parleremo pi avanti nel corso del Tutorial. Quando le variabili vengono inizializzate, le variabili numeriche sono inizializzate a 0, le stringhe a lunghezza variabile sono inizializzate ad una stringa vuota (""), e le stringhe a lunghezza fissa sono riempite con caratteri ASCII zero. Le variabili Variant sono inizializzate al valore Empty. Ciascun elemento di un tipo definito dall'utente viene inizializzato come se fosse un elemento isolato dal resto del tipo definito dall'utente.

Operatori Logici

Anche in Microsoft Visual Basic 6.0 ci sono una serie di operatori logici per valutare e relazionare espressioni. Tra questi i pi importanti sono: NOT OR AND XOR Negazione Disgiunzione Congiunzione Esclusione

Costrutti Condizionali

Tra i costrutti condizionali presenti in Microsoft Visual Basic 6.0 i pi importanti sono: If ... Then ... Else ... End If Select Case ... End Select Il primo costrutto permette di valutare diverse condizioni e di eseguire del codice al verificarsi della prima condizione che risulti vera. Al verificarsi di una condizione le condizioni seguenti saranno ignorate, se all'interno dello stesso blocco condizionale. I costrutti If possono essere annidati. If condizione Then [istruzioni] [ElseIf condizione-ennesima Then [istruzioni alternative]] ... [Else [istruzioni da eseguire in tutti i casi non previsti]] End If Il secondo costrutto invece permette di valutare diverse situazioni in funzione di un'unica espressione. Risulta comodo quando vi sono espressioni uniche che possono assumere diversi valori a seconda del momento. In questi casi il costrutto permette di svolgere blocchi di istruzioni piuttosto che altri in funzione del valore assunto dall'espressione valutata. Select Case espressione da valutare [Case lista di valori possibili separati da virgole [istruzioni]] ... [Case Else [istruzioni da eseguire in qualsiasi caso non previsto]] End Select Il costrutto Select Case ... End Select da preferirsi, in termini di prestazioni, al costrutto If ... Then ... End If laddove sia possibile applicarli indistintamente.

Costrutti Iterativi

I costrutti iterativi sono quelli che permettono di eseguire pi volte uno stesso blocco di istruzioni. In Microsoft Visual Basic 6.0 abbiamo diverse modalit di costruzione di costrutti iterativi. I pi utilizzati sono i costrutti For ... Next e Do ... Loop . Vediamo come funziona il primo: For Contatore = Inizio To Fine [Step Passo] [istruzioni] Next [Contatore] Il che equivale a dire che si vuole ripetere N volte un blocco di istruzioni, per N che varia da Inizio a Fine spostandosi ogni volta di un valore pari al Passo. C' anche la possibilit di abbandonare l'iterazione prima della fine tramite l'istruzione Exit For. Il costrutto Do ... Loop invece ripete un blocco di istruzioni finch non diventa vera una determinata condizione. Do {While | Until [condizione]} [istruzioni]

Loop {While | Until [condizione]} Se si indica la condizione all'inizio del ciclo (Do), qualora la condizione non sia verificata nemmeno all'inizio del ciclo stesso, non vi sar alcuna esecuzione di istruzione. Se invece la verifica della condizione viene posta alla fine del ciclo (Loop) allora comunque le istruzioni all'interno del ciclo saranno eseguite almeno una volta. Qualora si utilizzi la parola chiave While il ciclo sar ripetuto finch la condizione rimane vera, altrimenti nel caso della parola chiave Until l'iterazione si svolger finch la condizione rimane falsa e si fermer non appena la condizione diventa vera. Come nel caso precedente possibile uscire immediatamente da un ciclo di questo tipo tramite l'istruzione Exit Do.

Dichiarazione di Procedure e Funzioni

Entreremo meglio nel dettaglio della dichiarazione di procedure e funzioni nelle prossime lezioni del Tutorial su Microsoft Visual Basic 6.0 . In questo momento ci che conta capire come sia possibile costruire isole di codice richiamabili pi volte dalle nostre procedure evento per poter svolgere compiti ripetitivi. Per fare questo ci appoggeremo alla dichiarazione di subroutine (blocchi di istruzioni che svolgono una determinata attivit e non restituiscono alcun valore a chi le ha invocate) e funzioni (procedure che restituiscono un particolare valore a chi le invoca). La sintassi da usare : [{Public | Private}] Sub NomeProcedura ([argomenti]) [istruzioni] End Sub [{Public | Private}] Function NomeFunzione ([argomenti]) As TipoRestituito [istruzioni] End Function Come si intuisce dalle dichiarazioni, la parola chiave Sub identifica la dichiarazione di una subroutine (non restituisce valori) e la parola chiave Function indica la dichiarazione di una funzione (restituisce una variabile di tipo TipoRestituito). Come argomenti vanno passate delle variabili (capiremo meglio pi avanti con che modalit) che permettano alle nostre subroutine e funzioni di lavorare su dei dati in ingresso. Queste variabili saranno caratterizzate da un tipo di dato.

La nostra prima Funzione

Concludiamo quindi questa lunga puntata con un esempio di funzione che restituisce un valore dopo avere eseguito un ciclo nel quale si valutano delle espressioni. Public Function ContaNumeroInteroLungo() As Long 'Questa funzione conta casualmente per 5 secondi 'a partire da quando viene chiamata, 'quindi restituisce il valore contato. Dim lngValoreContato As Long Dim vntInizioConteggio As Variant vntInizioConteggio = Timer Do While (Timer - vntInizioConteggio) 2147483645 Then Exit Do End If Loop 'Restituisco al chiamante il valore contato ContaNumeroInteroLungo = lngValoreContato End Function

LA NOSTRA PRIMA FORM: LA FINESTRA DI BENVENUTOLa Form di benvenuto All'interno di un progetto Microsoft Visual Basic possiamo inserire diversi elementi, tra questi vi sono le Form che sono il principale strumento per la realizzazione di una interfaccia grafica. La Form l'equivalente di una qualsiasi finestra di Windows. Il tipico approccio allo sviluppo di applicazioni desktop (destinate all'utente finale) orientato agli eventi in Microsoft Visual Basic prevede la realizzazione della parte di interfaccia grafica e l'associazione agli elementi disegnati di procedure evento (vedi Lezione 2). In questa puntata ci concentreremo sugli elementi grafici che generalmente si inseriscono in una finestra di benvenuto. Controlli predefiniti All'interno di Microsoft Visual Basic abbiamo una serie di controlli sempre disponibili di seguito riepilogati.

Puntatore: serve per selezionare i controlli nella form. Picture: permette di inserire elementi grafici nelle form, pu contenere altri controlli al suo interno (si dice controllo contenitore). Label: serve per inserire etichette di testo nella form.

TextBox: consente di ricevere informazioni testuali dall'utente della nostra applicazione. Frame: un altro controllo contenitore che permette di delimitare l'area che contiene con un titolo ed un riquadro tridimensionale. CommandButton: si utilizzano per inserire pulsanti clickabili nelle finestre. CheckBox: forniscono caselle di selezione dove l'utente pu abilitare o meno valori, permettono di rappresentare informazioni binarie (Vero/Falso). Spesso si inseriscono in controlli contenitore per raggrupparli. OptionButton: si utilizzano per porre all'utente domande a risposta multipla, di cui una sola per volta pu essere vera. Spesso si inseriscono in controlli contenitore per raggrupparli. ComboBox: la classica casella a discesa tipica delle interfacce grafiche di oggi. Permette di fornire all'utente un elenco di valori che si espande solo quando l'utente preme la freccia di espansione. Fornisce diversi stili di interazione con l'utente. ListBox: la versione senza pulsante a discesa ma con barre di scorrimento del controllo precedente. HScrollBar, VScrollBar: consentono di disegnare barre di scorrimento orizzontali (HScrollBar) e verticali (VScrollBar). Generalmente si utilizzano per scorrere il contenuto di controlli contenitore. Timer: ci permette di svolgere determinate attivit ripetutamente (ogni N millisecondi) oppure dopo un certo momento da quando decidiamo di eseguirle (eventi asincroni). DriveListBox, DirListBox, FileListBox: consentono di creare elementi grafici di selezione del disco, della cartella e dei file dal file system dell'utente finale della nostra applicazione. Si possono utilizzare per costruire finestre di apertura/salvataggio files su disco. Conviene per appoggiarsi agli strumenti forniti dal sistema operativo (Common Dialog) al fine di avere un'interfaccia consistente con il sistema in cui la nostra applicazione viene eseguita. Shape: permette di disegnare forme varie (cerchi, quadrati, ecc.) sulla Form. Line: permette di disegnare linee sulla Form. Image: si utilizza per caricare nel documento file grafici. Contrariamente al controllo Picture non si tratta di un controllo contenitore. Data Control: consente di collegare alcuni dei controlli precedenti ad una fonte dati, noi useremo la versione OLEDB del Data Control e non questa che si appoggia ad una tecnologia di accesso ai dati (DAO = Data Access Objects) ormai in disuso. OLE Control: permette di collegare (OLE = Object Linking and Embeding) documenti da OLE server esterni (Word, Excel, ecc.), ultimamente poco utilizzato.

Disegnamo la Form di benvenuto All'interno di Microsoft Visual Basic creiamo quindi un progetto di tipo Standard EXE nuovo. Selezioniamo la Form che viene creata automaticamente (Form1) e gestiamone prima di tutto l'aspetto grafico.

Una delle prime attivit che conviene svolgere rinominare il progetto (tasto destro del mouse su Project1 -> Project1 Properties e quindi assegnare un valore sensato alla propriet Project Name nel nostro caso useremo Biblio_VBIUG). Quindi una buona regola dare un nome ragionevole anche alle form che si utilizzano. Assegnamo nome frmSplash alla nostra finestra iniziale di benvenuto (tasto destro del mouse su Form1 -> Properties, quindi assegnare il valore alla propriet (Name) ). La rappresentazione del nostro progetto diventer quindi la seguente.

A questo punto siamo pronti per disegnare il contenuto della nostra finestra di benvenuto. Per prima cosa caratterizzimo l'aspetto grafico della finestra stessa. Dalle propriet della form configuriamo la finestra come di seguito indicato: Caption = Vuoto ( il titolo della finestra e di solito le finestre di benvenuto non hanno titolo). BorderStyle = 1 - Fixed Single (corrisponde ad un bordo sottile e non ridimensionabile). ControlBox = False (nasconde il men di sistema e l'icona della finestra in alto a sinistra). StartUpPosition = 2 - CenterScreen (fa in modo che la finestra si apra esattamente al centro dello schermo corrente).

Selezioniamo dalla casella degli strumenti il controllo Frame e tracciamo un riquadro nella finestra della dimensione che pi ci aggrada. Anche di questo controllo svuotiamo la propriet Caption in modo tale che non abbia alcun titolo e si presenti solo come un riquadro. Selezioniamo il Frame appena creato e disegnamo al suo interno un controllo Image, diamo a questo ultimo nome imgSplashLogo (propriet (Name) ). Per caricare un'immagine nel controllo appena disegnato selezioniamo la propriet Picture e facciamo doppio click sulla stessa per scegliere un file grafico dal disco fisso (nel percorso "C:\Program Files\Microsoft Visual Studio\Common\Graphics" o simile, a seconda di dove stato installato Visual Basic, troverete diverse immagini gi pronte. Nella sotto cartella Icons\Writing selezioniamo il file BOOKS05.ICO). Il controllo immagine appena disegnato si ridimensioner per contenere secondo le giuste proporzioni l'immagine appena assegnatagli. Per fare in modo che l'immagine sia "stirabile" e si possa quindi ingrandire impostate a True la propriet Stretch e quindi stirate il controllo fino alla dimensione desiderata. Avremo una frmSplash simile alla seguente:

Inseriamo a questo punto un paio di etichette di testo (Label) per rappresentare le informazioni sul prodotto (nome, versione, produttore) e una linea che separi queste informazioni dalle informazioni sul Copyright. Sono sufficienti quattro controlli Label cos configurati: 1. (Name) = lblCompany Autosize = True Caption = "Visual Basic - Italian User Group" Font = Verdana, 12, Regular 2. (Name) = lblProductName Autosize = True Caption = "Archivio Biblioteca" Font = Verdana, 14, Bold 3. (Name) = lblProductVersion Autosize = True

Caption = "1.0" Font = Verdana, 14, Regular 4. (Name) = lblCopyRight Autosize = True Caption = "(C) VBIUG Tutorials - 2001" Font = Verdana, 10, Italic Inseriamo anche una riga (controllo Line) che divida le informazioni. Il risultato sar simile al seguente:

Se provate ad eseguire questo progetto (F5) vi renderete subito conto che manca qualcosa di fondamentale ... un modo per fermare la finestra di benvenuto e continuare con la normale esecuzione del programma. Per fare questo utilizzeremo due diversi strumenti: Un controllo Timer Una procedura evento

Il controllo Timer possiamo inserirlo dove vogliamo nella form, si tratta infatti di un controllo invisibile in fase di esecuzione e quindi non roviner l'aspetto grafico della nostra finestra. Assegnamogli le seguenti propriet: (Name) = tmrUnload Interval = 3000 (cio 3 secondi, si tratta di millesimi di secondo) Enabled = True (vogliamo che scatti!)

A questo punto facciamo doppio click sul controllo Timer appena configurato. Ci troveremo nella finestra del codice associato alla procedura evento tmrUnload_Timer(). Scriviamo il seguente codice: Public Sub tmrUnload_Timer() 'Questa procedura scarica la finestra di benvenuto e passa il controllo alla normale esecuzione del programma Unload frmSplash End Sub L'istruzione Unload frmSplash equivale a comunicare al VB che vogliamo scaricare la finestra frmSplash dalla memoria e quindi vogliamo anche nasconderla. In questo modo, dopo 3 secondi dal caricamento della nostra finestra di benvenuto il Timer scatter e la scaricher

dalla memoria. Salviamo prima di chiudere Ricordiamoci di salvare il progetto prima di chiuderlo e confermiamo i nomi che abbiamo associato agli oggetti creati sino a qui (Biblio_VBIUG per il progetto, frmSpalsh per la finestra di benvenuto).

LA MASCHERA PRINCIPALE DI UN PROGETTO: MENU' E BARRE DEI PULSANTI

Applicazioni SDI e MDI Le interfacce utente dei software possono essere raggruppate in due grandi categorie: Single Document Interface (SDI): applicazioni basate su un'unica finestra, che per ogni documento richiedono una nuova istanza di programma (ad es. Notepad). Multiple Document Interface (MDI): applicazioni che gestiscono pi documenti all'interno di un'unica istanza (ad es. Microsoft Word 9x).

Per creare applicazioni SDI sufficiente costruire dall'IDE di Microsoft Visual Basic l'interfaccia grafica ed associare ai controlli inseriti nella form delle procedure evento (Lezione 2, Lezione 3 e Lezione 4). Lo sviluppo di applicazioni MDI richiede invece generalmente uno sforzo maggiore per gestire barre dei pulsanti, barre dei men contestuali al documento visualizzato e gestione degli eventi di caricamento e scaricamento dei documenti. Per questo motivo ci occuperemo in questa lezione dello sviluppo di interfacce MDI, in quanto i concetti appresi saranno applicabili nello stesso modo anche alle applicazioni SDI seppur in un contesto semplificato. Creare una finestra MDI principale I progetti basati su interfaccia MDI richiedono che sia inserita all'interno del progetto una form "speciale" di tipo MDIForm che si comporter da "contenitore" per tutte le altre form di visualizzazione dei documenti. Per fare questo apriamo il progetto Biblio_VBIUG e dalla finestra di progetto (CTRL+R) premiamo il tasto destro del mouse sul progetto e scegliamo la voce Inserisci -> MDI Form come illustrato in figura.

Ogni progetto pu contenere una sola finestra di tipo MDI che sar il contenitore di tutte le altre finestre di documento, che si diranno MDIChild. Tutte le form tradizionali (non MDI) proprio per questo hanno tra le loro propriet la voce MDIChild che se impostata a True permette di inserirle all'interno della MDIForm contenitore. Per impostare l'aspetto grafico della MDI Form in modo tale che presenti una barra dei pulsanti ed una barra di stato occorre aggiungere al progetto dei riferimenti a controlli esterni. Si prema il tasto destro del mouse sulla casella degli strumenti e si selezioni la voce Componenti o si scelga la voce di men Progetto -> Componenti. Si cerchi e si selezioni "Microsoft Windows Common Controls 6.0" (MSCOMCTL.OCX).

Questo componente OCX fornisce alcuni controlli utili per disegnare interfacce utente con il tipico aspetto delle applicazioni Windows. Premendo il pulsante Chiudi appariranno nella casella degli strumenti dei nuovi controlli (come rappresentato in figura).

Quelli evidenziati in rosso sono gli strumenti che servono a noi per realizzare la nostra interfaccia utente. Selezionare e trascinare la Barra Pulsanti sulla MDI Form appena inserita. Fare altrettanto con la Barra di Stato e con la Lista di Immagini. Assegnare i seguenti nomi agli elementi: ToolBar: barra dei pulsanti StatusBar: barra di stato imgList: lista di immagini frmMain: MDIForm

Premere il tasto destro del mouse sul controllo imgList e scegliere la voce di men "Propriet". Selezionare una dimensione 16x16 per le immagini e visualizzare il pannello "Immagini", dal quale possibile caricare una lista di file grafici che dovranno corrispondere alle immagini dei nostri pulsanti. Caricare una ad una le immagini dei pulsanti da inserire ed assegnare a ciascuna immagine una Chiave. Usare le seguenti immagini (dal percorso su disco "\Program Files\Microsoft Visual Studio\Common\Graphics\Bitmaps\ OffCtlBr\Large\Color\): NEW.BMP => Chiave: New OPEN.BMP => Chiave: Open SAVE.BMP => Chiave: Save

Premere OK per salvare. Premere ora il tasto destro del mouse sulla barra dei pulsanti e selezionare la voce di men "Propriet". Assegnare il valore imgList alla propriet "ImageList". Sar ora possibile creare i pulsanti della barra bottoni associandovi le immagini precedentemente inserite. Dal pannello "Bottoni" inserire tramite il tasto "Inserisci Bottone" i pulsanti valorizzando le seguenti propriet: Chiave: la chiave che useremo per riconoscere i bottoni da codice (usare New, Open e Save rispettivamente). ToolTipText: il testo di aiuto che verr visualizzato al passaggio del mouse sui bottoni (opzionale ma utile). Immagine: indica la chiave dell'immagine associata a ciascun bottone (usare le tre chiavi inserite per le immagini nella lista New, Open e Save).

A questo punto la nostra barra pulsanti pronta dal punto di vista grafico. Occorre quindi creare la barra dei menu. Premere il tasto destro del mouse su un'area libera della MDI Form e scegliere la voce "Men Editor". Dalla finestra che compare caricare le voci di men necessarie considerando che: Caption: il testo che verr visualizzato nella voce di men. Per avere la prima lettera di un men sottolineata usare la & (e commerciale) prima della lettera da sottolineare. Per inserire uno spazio (riga) tra diverse voci di men usare come caption il segno meno (-). Nome: il nome che verr utilizzato da codice per riferirsi alla voce Le freccette (vedi figura) servono per gestire la posizione delle voci di men le une

rispetto alle altre.

Rimane ora da configurare la barra di stato. Per farlo sufficiente premere un'ultima volta il tasto destro del mouse sulla barra di stato disegnata nella MDI Form e scegliere "Propriet". Dal pannello "Pannelli" caricare i pannelli necessari tenendo presente che: Chiave: ci servir, ancora una volta, per valorizzare da codice i pannelli in termini di contenuto Stile: ci permette di scegliere se il pannello deve visualizzare del testo, lo stato dei pulsanti Ins, CapsLock, BlocNum oppure informazioni su data e ora (Kana per le tastiere giapponesi, a noi non serve) Allineamento: permette di impostare l'allineamento a destra, sinistra o centrato del testo mostrato AutoSize: permette di indicare alla statusbar quali pannelli si devono dimensionare automaticamente. Di solito si usa per il pannello all'estrema sinistra che contiene le informazioni di stato testuali scegliendo il valore sbrSpring che corrisponde ad occupare tutto lo spazio a disposizione, lasciato quindi libero dagli altri pannelli.

Inseriamo 4 pannelli con le seguenti caratteristiche: Chiave: Chiave: Chiave: Chiave: Status - Stile: sbrText - AutoSize: sbrSpring - Allineamento: sinistra Ins - Stile: sbrIns - AutoSize: sbrNoAutoSize - Allineamento: centrato Date - Stile: sbrDate - AutoSize: sbrNoAutoSize - Allineamento: centrato Time - Stile: sbrTime - AutoSize: sbrNoAutoSize - Allineamento: centrato

Diamo infine un titolo alla finestra MDI Form tramite la propriet Caption, usiamo il valore "Archivio Biblioteca - VBIUG". A questo punto abbiamo costruito una finestra principale che si presenter in modo simile alla figura seguente.

Rimane da gestire il codice associato agli eventi che il nostro utente pu scatenare usando tale interfaccia. Associazione del codice all'interfaccia Il codice da associare alla nostra interfaccia sar comune tanto ai men quanto ai pulsanti. E' allora consigliabile creare delle procedure (Sub o Function) a livello di modulo Form o all'interno di un modulo di codice BAS (Progetto -> Inserisci Modulo) al fine di richiamare le stesse da diversi punti del programma (men e bottoni per esempio). Inseriamo quindi un modulo BAS e definiamo 4 procedure al suo interno, come segue: Public Sub Main() 'Questa procedura si occupa dell'avviamento del programma frmSplash.Show vbModal frmMain.Show End Sub Public Sub NewFile() 'Questa la procedura che gestir la creazione di un nuovo file End Sub Public Sub OpenFile() 'Questa la procedura che gestir l'apertura di un file End Sub Public Sub SaveFile() 'Questa la procedura che gestir il salvataggio di un file End Sub Public Sub Quit() 'Questa la procedura che gestisce la chiusura del programma End End Sub Per associare queste procedure ai pulsanti ed alle voci di men basta selezionare dalla

modalit di design le voci di menu. Comparir il codice di ciascuna voce nel quale si dovr scrivere il nome della procedura da richiamare. Per i pulsanti si dovr invece fare doppio click sulla barra dei pulsanti e all'interno del codice della procedura evento che si presenter(Private Sub ToolBar_ButtonClick) riportare un costrutto Select Case basato sulla chiave del parametro Button che viene passato ByVal alla procedura evento. Il codice della procedura evento della barra pulsanti della nostra MDI Form sar simile a quanto riportato nella figura seguente.

Ultime operazioni prima di chiudere Dalla finestra delle propriet del nostro progetto configuriamo come oggetto di avvio la procedura Sub Main anzich la form frmSplash. Chiamiamo il modulo di codice BAS creato modMain e salviamolo. Salviamo la MDI Form con nome frmMain.

MASCHERE DI SECONDO LIVELLOForm secondarie Nella puntata precedente abbiamo visto come sia possibile realizzare una finestra principale in grado di contenere una serie di finestre secondarie, una barra dei menu ed una barra dei pulsanti. Ora ci occuperemo della creazione delle finestre secondarie da inserire all'interno della form MDIForm principale. Innanzitutto occorre dire che una form secondaria si dice MDIChild, cio figlia, proprio per indicare che potr vivere solo all'interno di una form MDIForm principale. Contrariamente alle MDIForm principali che sono diverse dalle form normali, le form MDIChild sono finestre canoniche (form) che hanno la propriet MDIChild impostata a True. Inseriamo quindi nel nostro progetto Biblio_VBIUG una nuova Form e nella finestra delle propriet assegnamo alla propriet MDIChild il valore True. Diamole quindi nome (Name) frmChild e impostiamo il suo titolo (Caption) con il valore "Documento". Al suo interno per ora non carichiamo alcun oggetto. Vedremo nelle prossime lezioni come gestire tramite controlli grafici l'accesso ai dati. Per ora occupiamoci dell'interazione tra la nostra MDIForm e la frmChild.

Visualizzare le form MDIChild Per mostrare una form MDIChild sufficiente richiamare il metodo Show cos come accade per le form tradizionali. Proviamo quindi a scrivere nella Sub NewFile() il codice che mostra la nostra finestra MDIChild. Public Sub NewFile() 'Questa la procedura che gestir la creazione di un nuovo file frmChild.Show End Sub Proviamo ad eseguire il nostro programma. Qual il problema che si evidenzia subito ? Se premiamo pi volte il tasto "File->Nuovo" la finestra si apre solo la prima volta e non viene creata una nuova finestra per ogni pressione del tasto o scelta della voce di men corrispondente. Questo corretto se ci pensiamo perch noi stiamo chiedendo, ad ogni esecuzione della procedura, di mostrare la frmChild. Se frmChild gi visibile non succeder nulla. Potremmo a questo punto pensare di dover creare N copie della nostra frmChild (ne facciamo 10 ? 20 ? quante ?) per averle pronte da visualizzare, ma questo non sarebbe un buon modo di lavorare, non possiamo vincolare il nostro utente finale ad aprire un numero massimo di finestre Child in funzione di quante secondo noi dovevano essere aperte. Allora quale pu essere la soluzione al problema ? Istanze multiple di una form Quando noi creiamo una form all'interno di Visual Basic dall'interfaccia grafica del VB quello che facciamo in realt creare un "modello" di form e non una form unica. Se provate a scrivere dentro ad una qualsiasi finestra di codice del nostro programma Biblio_VBIUG un'istruzione come la seguente: Dim objForm As New frmChild

vedrete che da VB non avrete alcun errore, anzi potrete fare riferimento a tutte le caratteristiche di frmChild, compresi i controlli eventualmente inseriti al suo interno, tramite la variabile objForm. Attenzione per che quella che utilizzerete non sar la frmChild che avete disegnato voi, ma una copia identica della stessa. Cosa significa questo ? Significa che le form che noi costruiamo in VB sono "modelli" di form, si chiamano in realt classi e di queste possiamo crearne diverse copie fra loro uguali come caratteristiche e comportamento (label, textbox, pulsanti, codice delle procedure evento) ma diverse come valore delle singole propriet (la Caption, la posizione, ecc.). Allora proviamo a scrivere il codice seguente nella procedura NewFile: Public Sub NewFile() 'Questa la procedura che gestir la creazione di un nuovo file Dim frmNewChild As frmChild Set frmNewChild = New frmChild nlDocumenti = nlDocumenti + 1 frmNewChild.Caption = "Documento " & nlDocumenti frmNewChild.Show End Sub Ogni volta che la procedura verr richiamata otterremo la creazione di una nuova copia della frmChild che avr titolo diverso dalle copie precedenti in virt della variabile globale (definita come Private nlDocumenti As Long in modMain.BAS). Il risultato sar simile a quello rappresentato in figura.

Ora rimangono ancora alcune questioni da risolvere: 1) come facciamo a distinguere tra loro le finestre MDIChild ?

2) come facciamo a gestire le MDIChild con codice univoco all'interno della MDIForm principale ? Scaricare una Form MDI Child Ciascuna form MDIChild sar individuabile tramite la propriet ActiveForm delle MDIForm principale. Nel nostro caso quindi scrivere: MsgBox frmMain.ActiveForm.Caption corrisponder a visualizzare in una MsgBox il titolo della MDIChild attiva in questo momento. In alternativa ciascuna MDIChild al suo interno potr fare riferimento a se stessa tramite la parola chiave Me. Infatti se provate ad inserire nella frmChild un CommandButton con il codice seguente: MsgBox frmChild.Caption fornir un risultato forse inaspettato, ma corretto: avrete sempre il titolo della frmChild cos come l'avete definita dall'IDE del VB. Se invece scrivete nel codice della procedura evento click del CommandButton: MsgBox Me.Caption otterete ogni volta il titolo della frmChild corrente. Poter individuare una MDIChild fra tante fondamentale sia per poter gestire correttamente il diverso contenuto delle MDIChild sia per poterne gestire la corretta chiusura/scaricamento. Pensate di voler aggiungere una voce di men "Chiudi" che permetta di scaricare la MDIChild corrente. Un primo modo di lavorare aggiungere una voce di men alla frmMain e associare ad essa il seguente codice: Unload frmMain.ActiveForm In alternativa potete associare dei men particolari a ciascuna MDIChild tenendo presente che quando una MDIChild ha un men associato, questo sovrascriver il men della MDIForm principale ogni qualvolta la Child sar la finestra attiva. Questo significa che in un progetto con una MDIForm e due MDIChild, di cui una senza men e l'altra con un men personalizzato, ogni volta che la MDIChild senza men sar la MDIChild attiva avremo in alto il men della MDIForm, mentre quando sar attiva la MDIChild dotata di men avremo in alto il men di questa ultima al posto di quello della MIDForm. Allora per renderci conto di questo inseriamo nella frmChild un men uguale a quello della frmMain ma con in pi la voce "Chiudi" prima di "Esci" e associamole il seguente codice: Private Sub mnuClose_Click() Unload Me End Sub Il risultato sar proprio quello voluto: ogni volta che sceglieremo il men "Chiudi" la sola MDIChild corrente si chiuder. Durante la chiusura di una MDIChild o della MDIForm principale potremmo avere l'esigenza di gestire il salvataggio dei dati contenuti. Pensate a cosa accade quando chiudete Microsoft Word senza aver salvato il documento corrente. Il programma vi chiede se volete salvare o meno i dati, oppure se volete annullare la chiusura del programma. La stessa situazione possiamo gestirla anche noi con il codice delle procedure evento Form_Unload e Form_QueryUnload delle MDIChild. Ogni volta che la MDIForm viene chiusa prima di chiudersi e scaricare con se le MDIChild che contiene succede quanto segue:

1) Tutte le MDIChild vengono "pre-allertate" della chiusura tramite l'evento Form_QueryUnload e se anche una sola di queste imposta l'argomento Cancel = True nel codice della procedura evento, l'intero processo di Unload viene sospeso e tutte le form (MDIForm e MDIChild) rimangono caricate 2) Se nessuna MDIChild ha detto Cancel = True nell'evento Form_QueryUnload allora la MDIForm richiama per ciascuna MDIChild l'evento Form_Unload e scarica la MDIChild. Se anche una sola delle MDIChild imposta Cancel = True a questo punto il processo di Unload si ferma comunque, ma le MDIChild che avevano gi ricevuto l'evento Form_Unload senza dire Cancel = True, ormai sono gi state scaricate.

Per provare questo comportamento nel codice del nostro progetto, che potete scaricare in versione aggiornata, trovate un esempio concreto. Gestire le form MDIChild dalla MDIForm Cosa manca ancora al nostro progetto, dal punto di vista dell'interfaccia utente, che gli altri programmi MDI hanno ? La possibilit di gestire le finestre con il classico men "Finestre" che permette di posizionare e richiamare le MDIChild. Questa ultima funzionalit assolutamente banale e si ottiene semplicemente aggiungendo al men della MDIForm o delle MDIChild (non dimenticate che i men delle MDIChild vincono su quello della MDIForm !) una voce di men che abbia l'attributo WindowList selezionato. Questo ci permetter di avere l'elenco delle MDIChild caricate, separato con una linea dal resto delle voci di quel men (vedi le figure).

Noi dovremo aggiungere a mano le voci di men per allineare le MDIChild. Il codice da associare alle singole voci di men si basa sul metodo Arrange proprio di ciascuna MDIForm che permette di gestire l'allineamento delle MDIChild. Per i pi curiosi stata inserita anche una procedura che "scorre" tutte le MDIChild per ridurle ad icona basandosi sulla parola chiave Forms che corrisponde alla collezione di tutte le form caricate (Loaded) nel progetto corrente.

Tra queste a noi interessano solo quelle di tipo frmChild (TypeOf objForm Is frmChild). Ecco il codice caricato nella nostra frmChild: Private Sub mnuTileHorizontally_Click() frmMain.Arrange vbTileHorizontal End Sub Private Sub mnuTileVertically_Click() frmMain.Arrange vbTileVertical End Sub Private Sub mnuCascade_Click() frmMain.Arrange vbCascade End Sub Private Sub mnuIconize_Click() Dim objForm As Form For Each objForm In Forms If TypeOf objForm Is frmChild Then objForm.WindowState = vbMinimized End If Next End Sub

ACCESSO AI DATI CON OLEDB E I CONTROLLI NATIVI DEL VISUAL BASICI Controlli Nativi Microsoft Visual Basic da sempre un linguaggio orientato alla produzione rapida di applicazioni dotate di interfaccia utente. In particolare le applicazioni di accesso ai dati sono tra le pi tipiche realizzazioni Visual Basic grazie alla presenza di controlli di accesso ai dati e di visualizzazione degli stessi dall'utilizzo immediato.

Tra questi controlli possiamo per esempio considerare: Microsoft Microsoft Microsoft Microsoft ADO Data Control 6.0 DataGrid Control 6.0 DataList Control 6.0 DataRepeater Control 6.0

E' sufficiente quindi da un qualsiasi progetto VBP selezionare tramite la voce di men Progetto>Componenti i precedenti controlli per poter scrivere (o il pi delle volte disegnare con il mouse) le nostre applicazioni di accesso ai dati. Una form MDIChild di accesso ai Dati Iniziamo quindi con il disegnare il nostro database dei libri per la nostra biblioteca. Il database preveder le seguenti tabelle: tab_Libri tab_Iscritti tab_Prestiti tab_Prenotazioni tab_StoricoPrestiti

e pensiamo alla realizzazione di una form MDIChild per consultare la lista dei libri tramite una griglia. Inseriamo nel nostro progetto della biblioteca una form e impostiamo a True la sua propriet MDIChild. Assegnamo alla form il nome frmLibri e il titolo (caption) "Anagrafica Libri" e salviamola. Aggiungiamo al progetto i controlli: - Microsoft ADO Data Control 6.0 - Microsoft DataGrid Control 6.0 ed inseriamoli nella form MDIChild come nell'immagine seguente.

Assegnamo alla DataGrid il nome grdLibri e all'ADO Data Control il nome datLibri. Iniziamo quindi a configurare l'ADO Data Control indicandogli quale sia il database Access 2000 da cui deve leggere i dati e quale tabella vogliamo leggere. Configurazione di ADODC Per fare questo premiamo il tasto destro del mouse sul controllo e scegliamo la voce di men "Propiet ADODC".

Nella finestra di propriet che viene visualizzata possiamo indicare all'ADODC la stringa di connessione al database in diversi modi, scegliamo "Usa Stringa di Connessione" (la terza opzione) e configuriamo graficamente la connessione alla base dati.

Scegliamo come Provider "Microsoft Jet 4.0 OLE DB Provider" per indicare all'ADODC che vogliamo utilizzare il Jet Engine di Access 2000 (4.0), selezioniamo quindi il file di database MDB e abilitiamo il salvataggio delle informazioni di sicurezza, come nell'immagine seguente e - dopo aver eventualmente testato positivamente la connessione - premiamo il tasto "OK".

A questo punto spostiamoci nella sezione relativa alla sorgente dati (terzo pannello di configurazione dell'ADODC) e indichiamo che vogliamo accedere ad una tabella di dati (adCmdTable) di nome tab_Libri, come nella seguente immagine.

Premiamo OK e salviamo nuovamente la form. Configurazione della Data Grid A questo punto dobbiamo indicare alla Data Grid che il suo contenuto deve essere letto dall'ADODC appena configurato. Ottenere questo assolutamente banale, sufficiente selezionare la Data Grid e dalla finestra delle sue propriet selezioniamo nella proprit DataSource l'ADODC appena configurato, come da immagine.

Se a questo punto modifichiamo i men della nostra MDIForm affinch vi sia una voce per visualizzare la frmLibri potremo osservare che la nostra form gi pronta per l'uso. Volendo potremmo personalizzare l'aspetto delle colonne di dati rappresentate nella griglia entrando nelle proprit della Data Grid o, ancor meglio, selezionando una ad una le colonne di nostre interesse nella tabella di dati. E' infatti completamente inutile recuperare un'intera tabella da un database per poi sfruttarne solo alcune colonne, conviene richiedere direttamente al motore di database le sole colonne di nostro interesse.

Data Binding a singolo campo Se volessimo poi rappresentare all'interno di una singola form dati non in forma tabellare (griglia) ma tramite diversi controlli, per esempio TextBox, ComboBox, Option Button, ecc. dovremo considerare le seguenti propriet di configurazione: DataSource: il controllo ADODC da cui leggere i dati DataField: il campo della tabella o selezione dati correntemente ottenuta tramite l'ADODC che si vuole visualizzare nel controllo DataFormat: si tratta di informazioni sulla formattazione a schermo del dato da visualizzare (data, valuta, numero, ecc.)

Impostando queste propriet per ciascuno dei controlli da visualizzare nella form (vedi immagine 8) possibile costruire delle maschere che visualizzino un singolo record e che si possono poi scorrere tramite i tasti cursore dell'ADODC come nel caso della nostra form di visualizzazione degli utenti iscritti nell'anagrafica della BiblioVBIUG.

GESTIRE GLI EVENTI NEI COMPONENTICosa sono gli eventi ?

I componenti che realizziamo con Microsoft Visual Basic ci permettono di esporre dei metodi che le applicazioni client COM utilizzano per demandare ai nostri componenti lo svolgimento di alcuni compiti. Le chiamate a questi metodi sono per chiamate sincrone (vedremo la prossima volta che possiamo fare anche altrimenti) e quindi dal momento in cui chiamiamo il metodo a quando l'elaborazione dello stesso si conclude il nostro client non pu fare altro che aspettare. Questo oltre a non essere molto elegante non nemmeno molto comodo. Se pensiamo alla normale programmazione guidata dagli eventi (Click su un CommandButton), gli oggetti nelle nostre Form possono informarci di cio' che sta accadendo. Queste informazioni, che possono essere pensate come delle notifiche, non sono altro che eventi che gli oggetti da noi utilizzati (in questo esempio il CommandButton) ci inviano quando necessario. Anche i componenti che realizziamo autonomamente possono avere questo comportamento. Per farlo dobbiamo inserire nell'implementazione del nostro componente le informazioni necessarie a far s che questo possa esporre degli eventi e possa farli scattare.

Come si definiscono

Per definire un evento in una classe dobbiamo utilizzare la parola chiave Event e precisamente dobbiamo esporre un evento pubblico che sia caratterizzato da un nome e da eventuali parametri, come segue: Public Event Notifica(ByVal sMessaggio As String) Quello appena definito un evento di nome Notifica che passer al chiamante (il client COM) un parametro di tipo stringa per valore. Se vogliamo notificare ad un client COM delle informazioni senza la necessit di ricevere dallo stesso delle "risposte" possiamo appoggiarci a costrutti di questo tipo, dove i parametri passati insieme all'evento sono forniti al client ByVal. Se invece vogliamo permettere al client COM di fornirci delle informazioni in risposta all'evento

- per esempio vogliamo permettere al chiamante di interrompere un'elaborazione eccessivamente lunga nel tempo - allora possiamo utilizzare parametri ByRef tramite una definizione come quella in figura.

A questo punto quando sul client COM scatter il nostro evento (da noi opportunamente generato) potremo valutare se il client vuole fermare o meno l'elaborazione controllando il valore del parametro passatogli per riferimento. In ogni caso per definire un evento, avendolo quindi a disposizione nell'interfaccia della sua classe, sufficiente definirlo con la dichiarazione Public Event.

Ok cos definito! Ma come faccio a far scattare un evento ?

All'interno del codice della nostra classe sar sufficiente ricorrere all'istruzione RaiseEvent per far scattare un evento. Per esempio nel nostro caso possiamo pensare di inserire nella procedura di elaborazione la seguente riga di codice: RaiseEvent Notifica("Sto lavorando") Questo comporter dal lato del client lo scattare dell'evento Notifica qualora la variabile oggetto che conterr l'istanza delle nostra classe sia stata definita ad eventi, come segue: Private WithEvents objMiaClasse As clsMiaClasse Nella figura seguente illustrato il caso in esame.

Nel caso degli eventi che passano parametri per riferimento, dal codice del client baster cambiare tali valori per far s che il componente COM possa rendersene conto e possa agire di conseguenza. Per esempio per bFerma = True potremmmo decidere di eseguire l'istruzione Exit Do per terminare un ciclo di elaborazione.

SVILUPPO DI COMPONENTI COM ASINCRONI

Il concetto di asincronicit

Per componente asincrono si intende un componente che sia in grado di lavorare mentre anche il chiamante (client COM) pu svolgere delle altre attivit. Pensiamo a Microsoft Word ed al correttore ortografico automatico. Mentre noi digitiamo i nostri testi il correttore ortografico controlla la correttezza delle informazioni da noi digitate, pero' questo non comporta per ogni parola l'interruzione della nostra attivit di battitura testo. Oppure pensiamo al controllo WebBrowser che in grado di scaricare una pagina web - mentre noi da codice facciamo altro - e ci avvisa con un evento della conclusione dello scaricamento delle pagina web richiesta.

L'idea alla base dei componenti asincroni

In Microsoft Visual Basic non esiste alcun attributo da impostare per far s che un componente sia asincrono. Per ottenere questo risultato dobbiamo lavorare via codice ed appoggiarci a qualche strumento fornito internamente al VB. L'idea alla base dei metodi asincroni nei componenti quella di far tornare il pi velocemente possibile il controllo al client COM e poi eseguire il codice della procedura autonomamente, notificando la conclusione dei lavori al client con un normale evento VB. Per ottenere questo risultato dobbiamo appoggiarci ai timer in modo tale che possiamo dire al sistema: appena viene chiamato il metodo attiva un timer e restituisci il controllo al chiamante; poi allo scattare del timer verr eseguito il vero lavoro del metodo, il quale alla sua conclusione scatener un evento di notifica. In VB, vedremo meglio poi, conviene appoggiarsi a finestre di codice che contengono l'oggetto timer.

Un metodo asincrono in pratica

Se vogliamo concretizzare queste idee con del codice possiamo pensare ad una classe simile alla seguente: Private frmTimer As FormTimer Public Event NotificaEsecuzione(ByVal sStatus As String) Public Sub EseguiAsync([Parametri]) Set frmTimer = New FormTimer frmTimer.tmrAsync.Enabled = True frmTimer.tmrAsync.Interval = 100 End Sub In questa procedura si fa riferimento ad una classe FormTimer che dovr corrispondere ad una form definita nel nostro progetto e che conterr un controllo timer di nome tmrAsync. Il codice della form sar simile al seguente: Private Sub tmrAsync_Timer() tmrAsync.Enabled = False EseguiLavoroVero([Parametri]) End Sub La procedura EseguiLavoroVero potr essere collocata in un modulo di codice .BAS oppure se vogliamo che scateni degli eventi dovr essere nella classe che ha attivato il timer.

In questo secondo caso dovremo passare alla form un riferimento alla classe che l'ha chiamata e lavorare con una procedura di CallBack. Nel secondo caso la procedura - definita nella classe - avr un aspetto simile al seguente: Public Sub EseguiLavoroVero([Parametri]) Set frmTimer = Nothing [... codice da eseguire ...] RaiseEvent NotificaEsecuzione("Ho finito !") End Sub La form dovr presentare una propriet assegnabile per impostare un riferimento alla classe chiamante e quindi dovr poi richiamare la procedura che svolge il lavoro non per nome ma come metodo della classe chiamante, nella forma RiferimentoAllaClasse.EseguiLavoroVero([Parametri]).

Considerazioni sui Timer

Ritengo importante notare che nel caso precedentemente esposto dobbiamo appoggiarci al controllo Timer del VB. Utilizzando le API di Windows si posso sfruttare i metodi SetTimer e KillTimer. La soluzione delle API di sistema ci permetterebbe di evitare di avere delle form all'interno del nostro componente. Tuttavia la funzione SetTimer richiede l'indirizzo di una funzione di callback che deve risiedere in un modulo .BAS . Questo comporta qualche problema nel caso in cui i nostri oggetti siano all'interno di un componente COM che utilizza un Poll di Thread perch potremmo trovarci a condividere variabili a livello di modulo senza volerlo. Quindi, bench sembri pi elegante l'utilizzo dei timer tramite API di sistema, conviene appoggiarsi ai controlli timer delle form.

ACCESSO AI DATI DA CODICE TRAMITE ACTIVEX DATA OBJECTSUniversal Data Access

ActiveX Data Objects (da qui in poi ADO) sar lo strumento che useremo in Microsoft Visual Basic 6.0 per accedere le basi di dati. Alla base di questo strumento c' il concetto che qualsiasi insieme di informazioni (relazionali o meno) pu e deve essere acceduto nello stesso identico modo. Questa idea ha dato vita a quello che si chiama Universal Data Access (http://www.microsoft.com/data/default.htm) e che si basa appunto sull'idea che sia possibile avere un unico strumento per accedere qualsiasi tipo di informazione. Per ottenere questo risultato sono stati create dei livelli software che ci separano dall'accesso ai dati diretto e che sono rappresentati nella Figura seguente.

In sostanza vi sono tre livelli software che sono: Data Providers: a questo livello si trovano gli insiemi di informazioni, relazionali o meno (SQL Server, Oracle, Exchange, Active Directory, ecc.). Service Components: a questo livello invece troviamo gli strumenti software che virtualizzano l'accesso ai dati preoccupandosi di creare dei cursori per conto nostro sulle basi di dati che vogliamo interrogare. Si basano su OLEDB e forniscono funzionalit di ricerca e raggruppamento di dati. Data Consumers: a questo ultimo livello ci siamo noi con le nostre applicazioni che utilizzano ADO per comunicare con i Service Components, per arrivare quindi ai Data Providers parlando un'unica lingua.

In questa lezione ci occuperemo delle regole di utilizzo di ADO per colloquiare correttamente con i Service Components e quindi avere accesso ai dati, tra loro anche diversi, parlando un'unica lingua. Le regole che vedremo saranno applicabili a data base Access, SQL Server, Oracle, ecc. con la sola differenza che dovremo, in ciascuno dei casi, comunicare ad ADO quale sia il Data Provider con il quale vogliamo parlare.

Modello ad Oggetti ADO

ADO nella sua implementazione pi semplice, escluse le classi pi recenti (dalla versione 2.5 in poi), si basa su tre classi fondamentali: ADODB.Connection: gli oggetti di tipo Connection sono quelli che ci permettono di accedere ad un Data Provider piuttosto che ad un altro. Sono gli oggetti Connection che devono sapere il nome (OLEDB Provider) del Data Provider che vogliamo utilizzare. ADODB.Recordset: gli oggetti di tipo Recordset sono invece insiemi di righe, tabelle quindi, che ci forniscono la strada di accesso ai singoli record negli insiemi di dati che

stiamo accedendo. ADODB.Command: gli oggetti di tipo Command infine sono degli strumenti molto comodi per svolgere delle interrogazioni, eseguire delle stringhe di comando SQL e delle chiamate a stored procedure e query definite all'interno dei nostri insiemi di dati.

L'aspetto interessante del modello ad oggetti di ADO che ciascuna classe pu vivere indipendentemente dalle altre. Per chi tra voi ha gi utilizzati altri modelli ad oggetti per l'accesso ai dati questo risulter evidente nel momento in cui andremo ad utilizzare questo strumento concretamente. In Data Access Object (DAO) o in Remote Data Objects (RDO) eravamo costretti ad istanziare ed utilizzare in un ben preciso ordine gli oggetti a nostra disposizione. Con ADO potremo creare oggetti di tipo Recordset senza aver creato precedentemente degli oggetti di tipo Connection verso la basi di dati che vorremo utilizzare. Vediamo quindi come utilizzare questo strumento.

ADODB.Connection

Si tratta della classe che ci permette di aprire delle connessioni verso le basi di dati che vogliamo utilizzare. Tra le sue propriet principali troviamo: ConnectionString: identifica la stringa di connessione verso l'insieme di dati che si vuole accedere. Pu essere costruita utilizzando dei files UDL (Microsoft Data Link) oppure fornendone esplicitamente il valore come stringa. Provider: corrisponde al nome dell'OLEDB Provider che si vuole utilizzare per accedere all'insieme di dati. Alcuni esempi sono: Microsoft.Jet.OLEDB.4.0 - SQLOLEDB.1 MSDAORA.1 rispettivamente per Access 2000, SQL Server, Oracle. Ve ne sono molti altri.

I metodi significativi invece sono: Open: apre una connessione precedentemente fornita nella propriet ConnectionString oppure apre una ConnectionString fornita come argomento al metodo stesso (si veda l'esempio pi avanti nella lezione). Durante la chiamata al metodo Open possibile fornire oltre alla stringa di connessione le credenziali per l'autenticazione dell'utente (userid e password). Close: questo metodo conclude una connessione precedentemente aperta verso una base dati. Execute: esegue un blocco di istruzioni SQL. Tramite questo metodo possibile avere in risposta un insieme di record (un Recordset quindi) da utilizzare per scorrere il risultato della interrogazione/istruzione SQL. BeginTrans: avvia una transazione sulla connessione correntemente attiva. CommitTrans: chiude e conferma le attivit svolte durante una transazione. RollbackTrans: chiude e annulla le attivit svolte durante una transazione.

Ecco un esempio di codice Microsoft Visual Basic 6.0 che utilizza l'oggetto Connection per aprire una connessione verso un data base Access ed esegue un aggiornamento sulla tabella degli Utenti: 'Dimensiono ed istanzio le variabili di accesso ai dati Dim cnAccess As ADODB.Connection Set cnAccess = New ADODB.Connection 'Apro la connessione verso Access (attenzione alle 4 virgolette sulla 'password che corrispondono a 2 virgolette nella stringa)

cnAccess.Open "Provider=Microsoft.Jet.OLEDB.4.0;Password="""";" & _ "Data Source=Database.mdb;Persist Security Info=True" 'Aggiorno con un'istruzione SQL dei record nella tabella Utenti cnAccess.Execute "UPDATE Utenti SET Attivo = -1 WHERE Attivo = 0" 'Chiudo la connessione cnAccess.Close 'Scarico dalla memoria gli oggetti Set cnAccess = Nothing Oppure per accedere un data base SQL Server possiamo utilizzare il seguente codice: Dim cnSQLServer As ADODB.Connection Set cnSQLServer = New ADODB.Connection 'Qui vi l'unica DIFFERENZA con il codice precedente: 'la stringa di connessione ! cnSQLServer.Open "Provider=SQLOLEDB.1;Password="""";" & _ "Persist Security Info=True;User ID=sa;Initial Catalog=Utenti;" & _ "Data Source=(local)" cnSQLServer.Execute "UPDATE Utenti SET Attivo = -1 WHERE Attivo = 0" cnSQLServer.Close Set cnAccess = Nothing Gi tramite questi due esempi possibile notare che, a parte la stringa di connessione, il nostro comportamento nei confronti di Access o di SQL Server rimasto analogo. Questa considerazione, con basi di dati dotate di strutture normali, cos vera che potremo spostare i nostri insiemi di informazioni tra motori diversi preoccupandoci solo di aggiornare le stringhe di connessione OLEDB da utilizzare, senza dover rivedere ogni volta il nostro codice sorgente quindi, ma agendo solo su un parametro (o su di un file UDL) che contiene la stringa di connessione da noi scelta.

ADODB.Recordset

Gli oggetti di tipo Recordset sono insiemi di record che ci forniscono il vero e proprio accesso alle informazioni nel data base. Tramite gli oggetti Recordset possiamo accedere i singoli record di una tabella di dati, sfogliandoli e modificandoli, piuttosto che aggiungendone di nuovi. Vedremo nel corso della lezione e del tutorial in generale che non si deve assumere per questo motivo che l'oggetto Recordset sia sempre lo strumento pi corretto da utilizzare per accedere i dati in lettura/scrittura. In particolare grazie alle ultime versioni dei motori di data base e di ADO conviene infatti utilizzare altri strumenti per l'accesso in scrittura sui data base, limitando l'uso degli oggetti di tipo Recordset alla visualizzazione ed allo scambio di dati. Le propriet fondamentali degli oggetti di tipo Recordset sono: CursorLocation: indica al Recordset dove deve risiedere il cursore, cio dove devono stare i record mentre vengono sfogliati. I valori possibili sono adUseClient (stanno nella memoria del client) o adUseServer (stanno sul server). Un recordset lato client impiega pi tempo ad arrivare sul client (perch deve essere trasferito per intero dal server al client) ma quando stato trasferito completamente allegerisce il server in quanto non

richiede pi ulteriori attivit sul server stesso. Eventualmente sar necessario fare degli aggiornamenti asincroni (UpdateBatch) sul server una volta che si sia finito di utilizzare i dati sul client. LockType: indica il tipo di lock cio di bloccaggio sui record quando si accedono i dati in lettura/scrittura. Le configurazioni possibili sono adLockReadOnly (sola lettura), adLockPessimistic (il record o la pagina di record viene bloccata non appena si accede un qualsiasi campo in modifica), adLockOptimistic (il record o la pagina di record vengono bloccati solo al momento del salvataggio delle modifiche, potrebbero esservi dei conflitti se pi utenti hanno iniziato a modificare i dati), adLockBatchOptimistic (si usa nel caso di cursori disconnessi lato client ... ne parleremo pi avanti nel tutorial). CursorType: permette di decidere che tipo di notifiche vogliamo avere dall'esterno sulle modifiche apportate ai nostri dati cos come ci permette di stabilire in quali direzioni vogliamo sfogliare i dati (si veda la tabella seguente per maggiori dettagli). I valori possibili sono: -adOpenForwardOnly: permette di scorrere i dati solo in avanti un record alla volta, dal primo all'ultimo e non vede le modifiche apportate dall'esterno ai record che scorre. -adOpenKeyset: permette di scorrere i dati in avanti ed indietro e vede le modifiche apportate dall'esterno ai soli record che scorre (non si accorge se ne vengono aggiunti o modificati altri). -adOpenDynamic: permette di scorrere avanti ed indietro i record e si accorge di qualsiasi tipo di modifica sui record. -adOpenStatic: si tratta di una copia dei dati presenti sul server che si pu scorrere in qualsiasi direzione ma che non si accorger mai di modifiche apportate sul server ai dati che contiene. Direzione Modifiche Esterne adOpenForwardOnly adOpenKeyset adOpenDynamic adOpenStatic Solo Avanti Avanti/Indietro Avanti/Indietro Avanti/Indietro Non le vede Solo sui propri record Su tutti i record Non le vede

AbsolutePosition: indica la posizione corrente, cio il numero del record corrente. RecordCount: indica il numero complessivo di record (vale solo in alcuni casi). ActiveConnection: identifica un riferimento all'oggetto Connection utilizzato dal Recordset per ottenere i dati. Sort: permette di ordinare i dati contenuti nel Recordset. Filter: permette di filtrare i dati contenuti nel Recordset. BOF: ci informa del fatto che siamo arrivati all'inizio del Recordset e non ci sono pi record da scorrere qualora dovessimo ancora andare indietro nel Recordset (vale True/False). EOF: ci informa del fatto che siamo arrivati alla fine del Recordset e non ci sono pi record da scorrere qualora dovessimo ancora andare avanti nel Recordset (vale True/False). Fields: si tratta di una propriet di tipo collezione che fornisce accesso ai singoli campi del record corrente. E' la propriet di default di un Recordset. Per accedere il campo [Nome] del record corrente di un Recordset di nome rsData si puo' quindi scrivere: rsData.Fields("Nome").Value oppure in modo equivalente si pu scrivere: rsData("Nome")

I metodi significativi invece sono: Open: vuole un massimo di 5 argomenti che sono la sorgente da aprire (una stringa SQL, un oggetto Command, una tabella, ecc.), la connessione da utilizzare (pu essere un oggetto Connection o una ConnectionString scritta esplicitamente, oppure nulla), il tipo di cursore (CursorType) ed il tipo di lock (LockType) ed infine delle opzioni. Sono tutti argomenti opzionali che dobbiamo fornire o meno a seconda di come stiamo utilizzando l'oggetto Recordset. Close: chiude un Recordset precedentemente aperto. AddNew: aggiunge un nuovo record al Recordset, qualora la modalit di accesso lo permetta. Delete: cancella un record dal Recordset, qualora la modalit di accesso lo permetta. Update: aggiorna un record modificato, qualora la modalit di accesso lo permetta. Si verifica in automatico quando si modifica un record e poi ci si sposta su di un altro. MoveFirst: si sposta in testa al Recordset (appena dopo BOF). MoveLast: si sposta in fondo al Recordset (appena prima di EOF). MoveNext: si sposta avanti di un record nel Recordset. MovePrevious: si sposta indietro di un record nel Recordset.

Ecco un esempio di codice che apre un Recordset ed aggiorna tutti i record al suo interno, quindi aggiunge un nuovo record e cancella il primo record. 'Dimensiono ed istanzio le variabili oggetto di accesso ai dati Dim cnSQLServer As ADODB.Connection Dim rsData As ADODB.Recordset Set cnSQLServer = New ADODB.Connection Set rsData = New ADODB.Recordset 'Apro la connessione verso il motore di data base cnSQLServer.Open "Provider=SQLOLEDB.1;Password="""";" & _ "Persist Security Info=True;User ID=sa;Initial Catalog=Utenti;" & _ "Data Source=(local)" 'Richiedo al server la lista di tutti gli utenti Set rsData = cnSQLServer.Execute("SELECT * FROM Utenti") 'Scorro con un ciclo tutti gli utenti 'finch non arrivo ad EOF = True, cio alla fine Do While Not rsData.EOF 'ed imposto il campo Attivo a -1 rsData("Attivo") = -1 rsData.MoveNext Loop 'Aggiungo un nuovo record e lo valorizzo rsData.AddNew rsData("Nome") = "Paolo" rsData("Attivo") = -1 rsData.Update 'Mi sposto in testa alla tabella e cancello il primo record rsData.MoveFirst rsData.Delete adAffectCurrent 'Chiudo il Recordset e la Connection rsData.Close

cnSQLServer.Close 'Scarico completamente dalla memoria gli 'oggetti Recordset e Connection Set rsData = Nothing Set cnAccess = Nothing

ADODB.Command

Gli oggetti di tipo Command permettono di richiamare delle stored procedure, piuttosto che di eseguire delle istruzioni o dei comandi SQL, eventualmente che restituiscono un insieme di righe (Recordset) che saranno eseguiti dal server di dati. Le propriet fondamentali sono: ActiveConnection: indica un riferimento all'oggetto Connection tramite il quale si vuole eseguire il comando. Pu essere un oggetto di tipo Connection oppure una Connection String scritta esplicitamente. CommandText: stringa SQL contenente le istruzioni da eseguire o il nome della stored procedure che si vuole mandare in esecuzione. CommandType: comunica al server il tipo di istruzione SQL che si sta richiedendo di eseguite (adCmdStoredProc=stored procedure; adCmdText=stringa SQL; ecc.). CommandTimeout: indica un tempo massimo di attesa per l'esecuzione della query. Prepared: informa il motore di data base, qualora sia in grado di recepire l'informazione, che il piano di esecuzione della stringa SQL deve essere mantenuto in memoria per successive esecuzioni. Parameters: identifica la collezione dei parametri di una stored procedure o di una stringa SQL parametrica.

I metodi interessanti sono: Execute: esegue il codice SQL richiesto ed eventualmente restituisce un Recordset come valore di ritorno. CreateParameter: crea un oggetto di tipo Parametro che possibile aggiungere alla collezione dei parametri Parameters.Append [...] .

Ecco un esempio di codice SQL che apre una connessione verso SQL server ed esegue una stringa SQL tramite un Command. 'Dimensiono ed istanzio le variabili oggetto di accesso ai dati Dim cnSQLServer As ADODB.Connection Dim cmdData As ADODB.Command Dim rsData As ADODB.Recordset Set cnSQLServer = New ADODB.Connection Set cmdData = New ADODB.Command Set rsData = New ADODB.Recordset 'Apro la connessione verso il motore di data base cnSQLServer.Open "Provider=SQLOLEDB.1;Password="""";" & _ "Persist Security Info=True;User ID=sa;Initial Catalog=Utenti;" & _ "Data Source=(local)" 'Configuro il Command e richiedo al 'server la lista di tutti gli utenti With cmdData

Set .ActiveConnection = cnSQLServer .CommandText = "SELECT * FROM Utenti" .CommandType = adCmdText .Prepared = True Set rsData = .Execute End With '***************************************** 'Qui potrei scorrere i dati ... come prima '***************************************** 'Chiudo il Recordset e la Connection rsData.Close cnSQLServer.Close 'Scarico completamente dalla memoria gli 'oggetti Recordset, Command e Connection Set rsData = Nothing Set cmdData = Nothing Set cnAccess = Nothing

Regole di sopravvivenza

Quando si lavora con ADO e si accedono basi di dati conviene tenere presenti alcune regole: E' possibili utilizzare il pool di connessioni fornito da OLEDB ed quindi inutile mantenere connessioni aperte durante tutta l'esecuzione del programma. Conviene aprire e chiudere le connessioni (mordi e fuggi) man mano servono. I parametri di una stored procedure possono essere forniti alla stessa tramite il metodo Refresh della collezione Parameters di un oggetto Command, ma molto pi efficiente creare a mano (CreateParameter) i parametri e poi aggiungerli (Parameters.Append) alla collezione dei parametri. I Recordset con cursori adOpenDynamic sono comodi ma sono molto dispendiosi. I Recordset non dovrebbero essere utilizzati per fare aggiornamenti massicci sui dati. Conviene invece creare delle stored procedure che saranno decisamente migliori in termini di rapidit ed efficienza di esecuzione. I Recordset dovrebbero essere utilizzati per scorrere i dati e passarli tra diversi livelli software (magari come recordset disconnessi XML ... ne parleremo ...) e non per aggiornamenti massivi sui dati.

Per maggiori informazioni vedere: http://www.visualbasic.it