Esiste il metodo Edit che entra in modalità Editing per il record corrente, ma che richiede sempre Update per aggiornare i dati
Ad esempio poniamo che l'Editore "Diemme" sia diventato "Dielle", come registrare la modifica?
Dim Editori As RecordSet
Set Editori=MyDb.OpenRecordSet("Editori")
Do Until Editori.Eof
If Editori("Nome")="Diemme" Then
BeginTrans
Editori.Edit
Editori("Nome")="Dielle"
Editori.Update
CommitTrans
End If
Loop
Editori.Close
Metodi avanzati per le tabelle
Questo codice cerca l'editore Diemme in tutta la tabella e quando lo trova lo sostituisce con Dielle, tutto questo sempre incluso in una Transazione, ma a proposito di transazioni, poniamo che ad un certo punto vogliamo annullare delle modifiche
Come fare?
Dim Editori As RecordSet
Set Editori=MyDb.OpenRecordSet("Editori")
Do Until Editori.Eof
If Editori("Nome")="Diemme" Then
BeginTrans
Editori.Edit
Editori("Nome")="Dielle"
If Annullo Then
RollBack
Else
Editori.Update
CommitTrans
End If
End If
Loop
Editori.Close
Dove Annullo è una qualsiasi condizione che vogliamo esaminare, ovvio che nel caso stessimo eseguendo Editori.Update quando è mancata la corrente RollBack non può più fare niente, in qual caso solo RepairDatabase() o una copia di backup potranno qualcosa
Bisogna poi sapere che anche CancelUpdate() permette di annullare modifiche in un RecordSet, a meno che non si sia usato Update
Dim Editori As RecordSet
Set Editori=MyDb.OpenRecordSet("Editori")
Do Until Editori.Eof
If Editori("Nome")="Diemme" Then
BeginTrans
Editori.Edit
Editori("Nome")="Dielle"
If Annullo Then
Editori.CancelUpdate
Else
Editori.Update
CommitTrans
End If
End If
Loop
Editori.Close
Un altro metodo interessante è Clone(), per creare copie esatte di Recordsets
Questo metodo non è però utile per il Backup dei dati poichè crea un Recordset e non un TableDef
Dim MyRecordSet As RecordSet
Dim ClonedSet As RecordSet
Set MyRecordSet=MyDb.OpenRecordSet("QueryEditori")
Set ClonedSet=MyRecordSet.Clone
Il quale crea in ClonedSet una copia di QueryEditori
.Eseguire ricerche in un RecordSet è un'operazione che può essere eseguita in vari modi, sia aprendo un RecordSet con una query SQL, sia con i metodi Find
MyRecordSet.FindFirst "Nome=""Enrico"""
è funzionalmente equivalente a
Set MyRecordSet=MyDb.OpenRecordSet("SELECT * FROM Persone WHERE Nome=""ENRICO""")
Il primo pezzo di codice trova il primo elemento della tabella dove il campo Nome è Enrico
Il secondo apre una tabella come QueryEditori, cioè basata su query SQL
E questo ci porta al secondo argomento di questo 3░ articolo: QueryDef come strumento rapido per creare Query SQL
QueryDef...le query facili e...le mie proprietà
Se ricordate quanto detto nell'articolo precedente in merito alle Query eseguite tramite i RecordSet ricorderete anche il problema della non persistenza dei dati, le QueryDef rispondono ad entrambe le esigenze con uno strumento facile e che sopratutto, a differenza delle query basate su RecordSet, occupa poco spazio su disco, poichè un QueryDef contiene solo la definizione della Query, non i risultati, ovvero nel caso la tabella Anagrafe occupasse su disco 5.487.152 bytes la query
SELECT * FROM Anagrafe
ne occuperebbe invece solo 22 poichè i risultati verrebbero caricati a Run-Time
Adesso vediamo come creare la nostra QueryDef
Set MyQueryDef= MyDb.CreateQueryDef("MiaQueryDef", "SELECT * FROM Impiegati WHERE Anni>33")
crea ed aggiunge(implicitamente) la query MiaQueryDef a MyDb.QueryDefs, questa query seleziona tutti i record di Impiegati dove Anni è maggiore di 33
Per eseguire la query aprire un RecordSet passando il nome dell'oggetto QueryDef
Set MyRecordSet=MyDb.OpenRecordSet("MiaQueryDef")
che equivale a
Set MyRecordSet=MyDb.OpenRecordSet("SELECT * FROM Impiegati WHERE Anni>33")
Esiste una proprietà che vorrei illustrare perchè ci porta nel merito di uno di quegli argomenti che di solito non sono molto noti al programmatore normale:Le proprietà personalizzate
La proprietà si chiama LogMessages che indica se ODBC può restituire messaggi in tabelle denominate nomeutente-numeroprogressivo all'esecuzione di un QueryDef, pertanto una proprietà non indispensabile anche perchè in questo corso useremo poco ODBC, ma valida come scusa per illustrare gli oggetti Property
Dim MyProperty As Property
Set MyProperty = MyQueryDef.CreateProperty("LogMessages", dbBoolean, True)
MyQueryDef.Properties.Append MyProperty
Questo fatto è molto importante a parte perchè consente di selezionare delle caratteristiche di Jet in modo esplicito come nel caso dell'archiviazione dei messaggi ODBC, ma anche perchè consente all'utente di creare sue proprietà per un oggetto, ad esempio questa proprietà che avvisa l'utente successivo se è stato tentato di violare il DB
Private Sub Form_Load()
Set MyProperty=MyDb.CreateProperty("Violato", dbBoolean, False)
MyDb.Properties.Append MyProperty
End Sub
Private Sub Login_Click()
Dim Name As String
Name=InputBox("Dimmi il tuo nome")
If Name<>"Enrico" Then
MyDb.Violato=True
MsgBox "Il Database è Sicuro, Vai via!", 16, "Protezione"
Exit Sub
ElseIf Name="Enrico" Then
If MyDb.Violato Then
MsgBox "Qualcuno ha tentato di violare il DataBase", 48, "Avviso"
MyDb.Violato=False
End If
End If
End Sub
Questo codice sfrutta le proprietà personalizzate per verificare se qualcuno con nome diverso da Enrico ha tentato l'accesso, se ciò avviene imposta su True la proprietà Violato e quando Enrico esegue il Login lo avvisa dell'accaduto
A pochi articoli dalla conclusione della nostra serie vi preannuncio già un argomento interessante, la sicurezza multiutente di Jet che è uno degli ultimi argomenti che ci restano da trattare
Operazioni sicure
La sicurezza di Jet come ogni suo elemento è basata sugli oggetti, se ricordate il primo articolo di questa serie parlammo dell'oggetto WorkSpace come area di transazioni protetta per un singolo utente, bene ora questo concetto sarà ripreso ed esteso, l'oggetto WorkSpace contiene i metodi CreateUser() e CreateGroup() per creare un oggetto User e Group
Set MeMedesimo = MyWorkSpace.CreateUser("Enrico", "MIO1PID", "Password")
In questo modo Enrico diventa utente di MyWorkSpace
Esiste poi l'oggetto Group
Set MioGruppo = MyWorkSpace.CreateGroup("Vari", "MIO2PID")
che crea il gruppo Vari per MyWorkSpace
Adesso vi chiederete come aggiungere MeMedesimo e MioGruppo a MyWorkSpace
MyWorkSpace.Users.Append MeMedesimo
MyWorkSpace.Groups.Append MioGruppo
che aggiungono ad Users ed a Groups
Creare poi delle impostazioni di sicurezza è effettivamente una delle operazioni più difficili di cui il modulo Jet disponga, esistono infatti degli oggetti Container e Document con le proprietà
ove Permissions ed UserName sono collegate poichè Permissions agisce sull'utente UserName, la proprietà Owner indica invece il proprietario dell'oggetto
Vi faccio comunque notare che per usare questi esempi sarà necessario disporre del file SYSTEM.MDW distribuito con Access per Windows 95 detto anche "Database di Sistema" poichè contiene tutti i dati di protezione ed è indispensabile per attivare la protezione, cioè la sicurezza multiutente