PRINCIPALE > SOFTWARE E STRUMENTI DI PROGRAMMAZIONE

Eseguire una ricerca veloce nell' archivio delle risorse di Visual Basic Italia®: 

Preso dall'archivio...

Premere il pulsante sotto per accedere direttamente ad un articolo o ad un esempio preso in modo casuale dall'archivio.



Ultimo e-book pubblicato:

"INTRODUZIONE AI CSS"

Lo scopo del CSS language è quello di controllare lo stile dei vari elementi che concorrono a formare un
documento HTML.
Si può operare in tre modi collegamento ad un foglio di stile esterno;definizione degli stili all'inizio
del documento utilizzo della proprietà style all'interno di un Tag HTML (embedded style). Questo e-book introduttivo
servirà per apprendere tali nozioni fondametali dei fogli di stile.

Prezzo: € 0.0.
Presentazione:
REAL SOFTWARE RILASCIA LA VERSIONE 5.0 di REALbasic per Windows






Gorizia, 5 maggio 2003 - Active, distributore in esclusiva di REALSoftware, Austin, Tx, annuncia la disponibilità di REALbasic 5.0 per Windows, uno strumento per lo sviluppo semplice da usare che permette agli utenti Windows di tutti i livelli di creare applicazioni personalizzate e di compilarle sia per la piattaforma Windows che per quella Macintosh.
[>>]

http://www.active-software.com

 

Contatti. Utilizzare l'email generica per domande relative al sito:
Porre domande relative al sito
oppure scrivere ad un responsabile di area.
Responsabile del sito: >Andrea Martelli
Responsabile area "Corso di VB":
> Giorgio Abraini

Lezioni di Database (a cura di Paolo Malesci): Creazione di oggetti DAO e modifiche a strutture esistenti


Questa lezione, consultata da 24427 utenti, è stata giudicata di ottimi contenuti , con un'esposizione perfettamente comprensibile e con un livello di approfondimento ottimo da 84 votanti.


Metodi di DbEngine

Come prima cosa esaminiamo due metodi applicabili all'oggetto DbEngine e che eseguono operazioni del Menù Access Strumenti / Utilità Database, e precisamente la Compattazione di un Database (ovvero l'eliminazione fisica dei record cancellati) ed il Ripristino di un Database danneggiato.
Come in Access il Database non deve essere già aperto. La sintassi è la seguente:

DbEngine.CompactDatabase databasedacompattare, nuovodatabase
DbEngine.RepairDatabase database

Ovviamente l'utilizzo in una applicazione deve prevedere copie di sicurezza e, nel primo caso, che il nuovo database sostituisca l'originario se l'operazione ha esito positivo; pertanto avremo un codice come il seguente:

(CompactDatabase):

Screen.MousePointer = 11
DBEngine.CompactDatabase App.Path + "\Rubrica.mdb", App.Path + "\RubricaNew.mdb"
If Len(Dir(App.Path + "\Rubrica.bak")) > 0 Then
Kill App.Path + "\Rubrica.bak"
End If
Name App.Path + "\Rubrica.mdb" As App.Path + "\Rubrica.bak"
Name App.Path + "\RubricaNew.mdb" As App.Path + "\Rubrica.mdb"
Screen.MousePointer = 0
RCode = MsgBox("Il Database originario è sato salvato come Rubrica.bak", _ vbOKOnly, "ATTENZIONE")

(RepairDatabase):

Screen.MousePointer = 11
RCode = MsgBox("Il Database originario viene salvato come Rubrica.bak", _ vbOKOnly, "ATTENZIONE")
FileCopy App.Path + "\Rubrica.mdb", App.Path + "\Rubrica.bak"
DBEngine.RepairDatabase App.Path + "\Rubrica.mdb"
Screen.MousePointer = 0

Tra le proprietà di DbEngine esaminiamo DefaultType; può assumere i valori dbUseJet o dbUseODBC e ci permette di specificare di che tipo saranno gli oggetti Workspace creati, se per MS Jet o per fonti esterne ODBC.
Per quanto riguarda i metodi, oltre ai due precedenti, è fondamentale CreateWorkspace: l'oggetto Workspace infatti definisce una sessione per un utente e contiene le collection Connections, Databases, Groups e Users; tuttavia per semplici applicazioni che non coinvolgano gruppi di lavoro o utenti con diversi livelli di accesso useremo tale metodo in una forma più semplice, ovvero quella che crea il Workspace di default di MS Jet:

Set oggettoworkspace = DBEngine.Workspaces(0)

Anzichè trattare sistematicamente la creazione degli oggetti esamineremo un esempio pratico, ovvero la creazione a programma di un Database con Table e Query.

Un esempio

Partiamo da un problema concreto: abbiamo scritto una Applicazione di Gestione dati per un cliente ed è già in funzione (ovvero il Db non è vuoto).
Si presenta l'esigenza di modificarlo aggiungendo un campo nuovo e non possiamo eseguire l'operazione con Access presso il cliente; facciamo allora un programma che effettua tale operazione.
Per motivi ovvii di sicurezza non operiamo direttamente sul Db originario ma ne creiamo uno nuovo e poi lo aggiorniamo con i dati dell'originario.
Se tutto è andato bene facciamo 2 rename e l'operazione è completata.
Come esempio (banale) vogliamo aggiungere a Rubrica.mdb l'indirizzo del sito Web e, visto che lo modifichiamo, anche la Query di selezione per anagrafico (Cognome+Nome).

Nelle dichiarazioni:

Dim wksPredef As Workspace
Dim dbsRubrica As Database
Dim tdfRubrica As TableDef
Dim qdfRubrica As QueryDef
Dim rsRubrica As Recordset
Dim dbsRubricaOld As Database
Dim rsRubricaOld As Recordset
Dim Campo As Field

Nel corpo del programma: creiamo il Database

' se esiste già lo cancella perché altrimenti
' il metodo CreateDatabase darebbe errore

If Len(Dir(App.Path & "\Rubrica1.mdb")) > 0 Then
Kill App.Path & "\Rubrica1.mdb"
End If

' apre il Workspace default di MS Jet
Set wksPredef = DBEngine.Workspaces(0)

' Crea un nuovo oggetto Database, lo salva su disco e lo apre come Database 'corrente
Set dbsRubrica = wksPredef.CreateDatabase(App.Path & "\Rubrica1.mdb", _ dbLangGeneral)

Abbiamo creato Rubrica1.mdb ma è un database vuoto; adesso dobbiamo creare la Table "Rubrica".

' Crea un nuovo oggetto TableDef.
Set tdfRubrica = dbsRubrica.CreateTableDef("Rubrica")

' Crea i campi e li accoda al nuovo oggetto TableDef.
' Questa operazione deve essere eseguita prima di accodare l'oggetto TableDef
' all'insieme TableDefs di Rubrica1.mdb.

With tdfRubrica
Set Campo = .CreateField("Cognome", dbText, 30)
Campo.Required = True 'il default è NO
.Fields.Append Campo
Set Campo = .CreateField("Nome", dbText, 20)
Campo.AllowZeroLength = True 'il default è NO
.Fields.Append Campo
Set Campo = .CreateField("Indirizzo", dbText, 30)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("CAP", dbText, 5)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("Città", dbText, 30)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("Prov", dbText, 3)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("TelefonoC", dbText, 12)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("TelefonoU", dbText, 15)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("Telefonino", dbText, 12)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("Fax", dbText, 15)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("EMail", dbText, 30)
Campo.AllowZeroLength = True
.Fields.Append Campo
Set Campo = .CreateField("Web", dbText, 30)
Campo.AllowZeroLength = True
.Fields.Append Campo
End With

' accoda il nuovo oggetto all'insieme TableDefs
dbsRubrica.TableDefs.Append tdfRubrica
Label1.Caption = "Creazione di Rubrica1.mdb effettuata"
Label1.Visible = True

' chiude il Database
dbsRubrica.Close

Alcuni commenti: innanzitutto le note sulla creazione di un oggetto TableDef ed il suo successivo accodamento all'insieme TableDefs; non è automatico come la creazione di un oggetto Database ed il suo accodamento all'insieme Databases. Inoltre per poterlo accodare deve essere già stato definito l'insieme base Fields, necessario per l'esistenza stessa dell'oggetto Table.
L'istruzione di creazione/accodamento degli oggetti Field avrebbe potuto essere scritta:

.Fields.Append .CreateField("nomecampo", tipocampo, lunghezza)

ma in tal caso le proprietà del campo sarebbero state quelle di default ed in particolare Richiesto = No e Consenti lunghezza zero = NO.
Un metodo più sofisticato (e da seguire) sarebbe stato quello di aprire il database Rubrica.mdb e quindi la Table Rubrica ed utilizzare un loop For sugli oggetti Field di Rubrica creando un oggetto Field della table Rubrica di Rubrica1.mdb per ogni oggetto Field della table Rubrica di Rubrica.mdb con lo stesso Name, Type, Size, Required ed AllowZeroLength con un codice del tipo seguente (rsRubricaOld è la Table Rubrica di Rubrica.mdb) nel blocco With:

For I = 0 To rsRubricaOld.Fields.Count - 1
Set Campo = .CreateField(rsRubricaOld.Fields(I).Name, _
rsRubricaOld.Fields(I).Type, rsRubricaOld.Fields(I).Size)
Campo.Required = rsRubricaOld.Fields(I).Required
Campo.AllowZeroLength = rsRubricaOld.Fields(I).AllowZeroLength
.Fields.Append Campo
Next I
Set Campo = .CreateField("Web", dbText, 30)
Campo.AllowZeroLength = True
.Fields.Append Campo

La ragione per cui non lo abbiamo utilizzato è la minore immediatezza, ma è più sicuro (non possiamo sbagliare le proprietà dei campi) e quindi da usare sempre.
La creazione di una Query è invece molto più semplice: il metodo .CreateQueryDef accoda automaticamente la query all'insieme QueryDefs del database se il nome della query non è una stringa nulla:

' Crea un nuovo oggetto QueryDef.
Set qdfRubrica = dbsRubrica.CreateQueryDef("Alfabetico", MySQL)

dove in MySQL abbiamo precedentemente messo la stringa SQL voluta non perché era necessario ma per una migliore leggibilità del programma; possiamo infatti scrivere anche:

Set qdfRubrica = dbsRubrica.CreateQueryDef("Alfabetico", "SELECT Cognome, Nome, _ Telefono, TelefonoU, Cognome & " & Chr$(34) & " " & Chr$(34) & " & Nome AS _ Anagraf FROM Rubrica ORDER BY Anagraf")

ma poi potremmo anche non capirci più nulla.
A questo punto non ci rimane che vedere come si crea un Indice ed abbiamo visto tutto quello che ci serve per creare un database od aggiungere nuovi oggetti ad un database esistente, perché il metodo è lo stesso; l'unica avvertenza è che i metodi di creazione degli oggetti DAO danno un e
rrore di run-time se l'oggetto che si vuole creare esiste già.

Set dbsRubrica = OpenDatabase(App.Path & "\Rubrica1.mdb")
Set tdfRubrica = dbsRubrica!Rubrica

With tdfRubrica
' Crea il primo oggetto Index, crea e accoda gli oggetti Field all'oggetto Index ' e accoda l'oggetto Index all'insieme Indexes dell'oggetto TableDef.
Set idxNome = .CreateIndex
With idxNome
.Name = "Rubrica"
.Fields.Append .CreateField("Cognome")
.Fields.Append .CreateField("Nome")
End With
.Indexes.Append idxNome
.Indexes.Refresh
End With

dbsRubrica.Close

Non ci resta altro che aprire entrambi i database ed entrambe le Table Rubrica ed inserire in una i records presenti nell'altra, ma ormai siete diventati bravi e la parte del programma relativa la capite da soli senza bisogno di commentarla.
Ovviamente daremo una struttura logica al programma, con bottoni di comando da abilitare in cascata e Label che segnalano il compimento delle varie fasi; il programma completo si chiama CreaDAO e tutti i files di progetto sono contenuti in CreaDAO.zip (Download - 3Kb); non è stata inclusa la parte relativa al rename di Rubrica.mdb->Rubrica.bak e Rubrica1.mdb->Rubrica.mdb perché si presuppone che prima di farlo un programmatore voglia controllare che il programma sia andato bene ! (altrimenti è meglio che si metta a vendere bruciate: guadagnerà di più e combinerà meno casini).


Approfondimenti

» "DAO Object Model: The Definitive Reference" di Helen Feddema capitolo 2: "DBEngine Object"
» "Data Access Object Reference" introduzione al "DBEngine Object"