Se ci serve un Database...
...possiamo fare 2 cose: aprirlo o crearlo
La differenza sostanziale sta nel fatto che se il file esiste lo apriamo, altrimenti lo creiamo
Ad esempio aprire il file "MioDb.Mdb" richiede
Dim MioDatabase As Database
Set MioDatabase=DbEngine.WorkSpaces(0).OpenDatabase("MioDb.Mdb")
o la forma abbreviata
Dim MioDatabase As Database
Set MioDatabase=OpenDatabase("MioDb.Mdb")
Cosa significhi tutto questo codice lo capiremo adesso
La struttura di Jet ci aiuta sempre
Il motore Jet è fortemente OO(Object Oriented) nel senso che la sua struttura è orientata agli oggetti, il che ci obbligherà a memorizzare qualche informazione sugli oggetti che compongono Jet
In seguito poi saremo addirittura facilitati da questa scelta di Microsoft
Il primo oggetto che rappresenta l'istanza di Jet in esecuzione è anche uno di quelli meno usati e prende il nome di
DbEngine
Questo oggetto ha sulle spalle tutta la gerarchia di Jet Engine, ma è anche uno di quegli oggetti che lavorano nell'ombra, tanto è che nonostante le due versioni del codice riportato sopra siano equivalenti di solito vedrete sempre la seconda o al limite l'indicazione del solo WorkSpace
Ma anche lui ha diritto al suo momento di gloria, che arriva sempre nei momenti difficili, come quando usate RepairDatabase()
DBEngine.RepairDatabase "MioDb.Mdb"
Questo metodo tenta di ripristinare un Database danneggiato di nome MioDb.Mdb
Questo metodo si usa però solo di rado, un metodo più usato è CompactDatabase()
DBEngine.CompactDatabase "MioDb.Mdb", "MioNuovoDb.Mdb"
Questo metodo compatta il file "MioDb.Mdb" e lo copia in "MioNuovoDb.Mdb", per ottenere "MioDb.Mdb" compattato è necessario usare anche
Kill "MioDb.Mdb"
FileCopy "MioNuovoDb.Mdb","MioDb.Mdb"
Compattare un Database permette di eliminare fisicamente i record eliminati che vengono marcati da Jet con un segnaposto, ma questo è un metodo di Recordset
Un altro metodo di DbEngine utile in ambienti multiutente è CreateWorkSpace()
Dim MyWorkSpace As WorkSpace
Set MyWorkSpace = CreateWorkspace("NuovoWorkSpace", "Enrico", "JetEngine")
Il WorkSpace è un ambiente di transazioni per un utente, ove con transazioni si intende qualsiasi processo che faccia uso delle funzionalità di Jet Engine
Il nostro codice crea un WorkSpace chiamato NuovoWorkSpace il cui utente è Enrico con password JetEngine
Siamo quasi alla fine di questa trattazione di DbEngine, ma mancano ancora due metodi, Idle() e RegisterDatabase(), oggi però ci soffermeremo su Idle()
DBEngine.Idle
Supponiamo che dopo un pò di tempo che elaborate dati notiate un rallentamento nel sistema, provate a chiamare Idle() e dovreste notare un miglioramento dell'esecuzione perchè Idle() permette a Jet di completare alcune operazioni interne
Dim JetVersion As String, NumVersion As String, NumRelease As String
Dim DotLocation As Integer
JetVersion = DBEngine.Version
DotLocation = InStr(JetVersion, ".")
NumVersion = Left$(JetVersion, DotLocation - 1)
NumRelease = Right$(JetVersion, Len(JetVersion) - DotLocation)
Debug.Print "Versione di Jet:" & NumVersion & "." & NumRelase
Prima di iniziare la disamina sui Database vorrei spiegare questo pezzo di codice che reperisce Versione e Aggiornamento di Jet Engine tramite DbEngine.Version il quale restitiusce una stringa del tipo Version.Relase(5.21 indica la Versione 5, Aggiornamento 21) e lo stampa nella finestra Debug
DbEngine.WorkSpaces(0).Databases(0).OpenRecordset("Varie"), ovvero?
Ovvero apri la Tabella Varie dell'elemento 0 dell'insieme Databases, dell'elemento 0 dell'insieme WorkSpaces dell'oggetto DbEngine, so che è un pò difficile, ma andiamo con ordine e capiremo tutto
Nella gerarchia di Jet Database discende da WorkSpace che discende da DbEngine, ma Jet prevede che tutti gli oggetti, all'infuori di DbEngine, abbiano anche un insieme che ne contiene tutte le istanze, così DbEngine.WorkSpace prevede l'insieme DbEngine.WorkSpaces che conterrà tutti i WorkSpace
Quindi DbEngine.WorkSpace.Database prevede DbEngine.WorkSpaces(ind).Databases
Ma di solito gli insiemi non ci saranno troppo utili, pertanto questa trattazione sugli insiemi sarà ripresa poche volte
Set oggettodb = areadilavoro.OpenDatabase(nomedb[, esclusivo[, solalettura[, fonte]]])
Questa è la sintassi completa di WorkSpace.OpenDatabase(), metodo che ritorna un oggetto di tipo Database
Di solito però non tutti gli elementi della sintassi sono utili, noi comunque passiamoli in rassegna
nomedb
E' il nostro Database, questo può essere un nome di file o un DSN ODBC, in tal caso dobbiamo specificare tutti i parametri
esclusivo
Utile solo in ambienti multiutenti, dice a Jet che vogliamo impedire ad altri utenti l'accesso al DB
solalettura
Dice a Jet che vogliamo aprire il Database in sola lettura, ovvero solo per leggere dati
fonte
Indica la stringa di connessione ODBC, se lo si usa bisogna specificare anche esclusivo e solalettura
Un esempio potrebbe essere questo:
Set MyDb = MyWorkSpace.OpenDatabase("", True, False, "ODBC;")
Questo permetterà all'utente di scegliere tra tutti i DSN ODBC in una finestra di dialogo visualizzata da ODBC
Per i più pignoli riporto qui la sintassi del parametro Fonte con un DSN ODBC
"ODBC;
UID=utente; PWD=password;
DSN=nomefontedati
LOGINTIMEOUT=secondi"
che potrebbe generare qualcosa come
"ODBC;
UID=Enrico; PWD=JetEngine;
DSN=MioDatabase;
LOGINTIMEOUT=50"
cioè, l'utente Enrico con password JetEngine richiede di apire MioDatabase con LoginTimeout di 50 secondi
Tornando a VB possiamo ora passare al metodo successivo: CreateDatabase(), se ricordate lo accennammo all'inizio dell'articolo e dicemmo che ci sarebbe servito nel caso il Database non fosse esistito, adesso poniamo che noi abbiamo bisogno di un database di nome "miofirst.mdb", il file manca, come crearlo?
Set MioDb = CreateDatabase ("miofirst.mdb", dbLangGeneral)
Ovvero assegna a MioDb il file miofirst.mdb che deve usare l'ordinamento generico, valido per l'Italiano e per altre lingue quali Inglese, Tedesco, Francese, Portoghese e Spagnolo
il che vuol dire che nella maggioranza dei casi useremo dbLangGeneral, ma esistono altre costanti che potete cercare nella guida di VB
Ma questo non esaurisce le operazioni da compiere nel nostro esempio, prima però vorrei discutere su un metodo importante, CreateRelation()
Set MyRelation = MyDb.CreateRelation("MiaRelazione", "Impiegati", "CassaIntegrati")
Questo metodo crea una relazione tra Impiegati e CassaIntegrati, ma c'è ancora qualcosa da fare, decidere quali campi saranno coinvolti nella relazione
Set MyField = MyRelation.CreateField("CodiceImpiegato")
MyField.ForeignName = "CodiceCassaIntegrato"
MyRelation.Fields.Append MyField
che mette in relazione Impiegati.CodiceImpiegato con CassaIntegrati.CodiceCassaIntegrato e infine aggiunge a MyRelation.Fields che è un insieme di oggetti di tipo Field, cioè campo
Comunque ci manca ancora una cosa per completare la nostra Relation, cioè
MyDb.Relations.Append MyRelation
che inserisce nell'insieme Relations di MyDb la nostra Relation
Questo argomento ci sposta verso l'argomento Field, ma questo sarà argomento del prossimo articolo, adesso vorrei trattare un altro metodo interessante di Database MakeReplica() il quale crea Repliche di un Database, ma questo richiede una modifica al Database, cioè questa:
MyDb.Replicable=True
che rende il Database replicabile, ma attenti, non provate dopo a scrivere
MyDb.Replicable=False
perchè questo genererebbe un errore di Run Time, una volta che Replicable è True non può più diventare False
Una volta settato Replicable è però possibile usare MakeReplica() per copiare un DB
MyDb.MakeReplica("A:\back10marzo1998.mdb")
potrebbe essere usato per creare la copia di Backup del 10 marzo 1998 del Database MyDb, l'utilità è chiara, poter creare copie identiche di un Database senza bisogno di FileCopy e quindi della determinazione del nome di file che in applicazioni come Data Manager, ove il DB non è determinato dal programma, può richiedere la dichiarazioni di ulteriori variabili, come nell'esempio che segue
Dim DatabaseName As String
...
CommonDialog1.ShowOpen
DatabaseName=CommonDialog1.filename
Set MyDb=OpenDatabase(DatabaseName)
...
Public Sub SaveCopy()
Dim DbNew As String
CommonDialog1.ShowOpen
DbNew=CommonDialog1.filename
Set MyDb=Nothing 'Sempre meglio chiudere
FileCopy DatabaseName, DbNew
Set MyDb=OpenDatabase(DatabaseName) 'Ora possiamo riaprire
End Sub
che imposta DatabaseName con il nome del Database così che la chiamata di SaveCopy possa funzionare, un elemento di rilievo sono i commenti di SaveCopy() che dicono
'Sempre meglio chiudere
nel senso che prima di queste transazioni è sempre meglio chiudere il Database per evitare problemi
poi dopo
'Ora possiamo riaprire
perchè adesso Jet può riprendere il controllo del DB, e questo è forse il punto di forza di MakeReplica() di Jet rispetto alla nostra SaveCopy(), MakeReplica() non deve chiudere il DB e questo ci fa risparmiare notevole tempo, pertanto ecco la stessa versione del codice con MakeReplica()
CommonDialog1.ShowOpen
Set MyDb=OpenDatabase(CommonDialog1.filename)
MyDb.Replicable=True
...
Public Sub SaveCopy()
Dim DbNew As String
CommonDialog1.ShowOpen
DbNew=CommonDialog1.filename
MyDb.MakeReplica(DbNew) 'Qui non dobbiamo chiudere nè fare altro
End Sub
come si può notare il codice è più breve e quindi anche più veloce
Per questa volta abbiamo comunque concluso la nostra esplorazione di Jet