 |
| |
Mikanović
S. Radenko
MS Access - links |
|
Kada dođete u situaciju da, posle male
ispravke na Access aplikaciji morate da izgubite ceo dan (na putu
do sedišta firme za koju ste radili program i nazad), ozbiljno razmislite
o načinu na koji ste osmislili bazu i aplikaciju. Ako ste to sve
stavili na jednu "gomilu" (u jedan fajl), posle čitanja
ovog teksta to više nikada nećete uraditi.
Svak za sebe, svi za korisnika
| bazi pripadaju samo tabele |
Koncepcija odvajanja Access aplikacije od baze podataka zasniva
se na tome da bazi pripadaju samo tabele, dok aplikaciju čine svi
drugi Access objekti: Queries, Modules, Forms i Reports (Macros
smo prevazišli, a Pages ne daju efekte koje bismo očekivali), što
znači da morate imati najmanje 2 fajla (bazu-MDB i aplikaciju MDE).
Složićete se da ovo i nije nešto komplikovano, a efekti se ogledaju
u sledećem:
* povezivanje više aplikacija na istu bazu neće predstavljati problem,
za razliku od nekih ideja o otvaranju iste aplikacije (MDE fajl)
od strane više korisnika
* fleksibilno povezivanje kod slučaja više baza (poslovni periodi),
prenosa i izmena na aplikaciji (izmene na aplikaciji i slanje update-a
elektronskom poštom (ili FTP-om) ne utiče bazu podataka
* izbor baze na koju će se korisnik povezati, a prema njenom sinonimu
(npr: 2001, 2002, 2003,...)
* korisnik aplikacije ne može da utiče na dizajn baze, a ne mora
ni da zna ništa o njenoj lokaciji (slučaj korporativnog LAN-a)
* napredni korisnici mogu imaju svoje baze podataka na priručnim
medijima (HDD MobileRack, floppy disk, ZIP drive, Flash drive i
slično), što u današnje vreme mnogi koristiti već zahtevaju.
Obožavam Funkciju
| Funkcija je objekat tipa procedure,
ali daleko naprednija od svog prvog konkurenta Sub-procedure |
Između navedenog problema i fleksibilnog rešenja ima mnogo puteva
i puteljaka, a ja vam predlažem da pođete mojim, sigurnim i utabanim
putem. Na tom putu, iskoristiću vaše vreme na par minuta, da bih
vam skrenuo pažnju na jedan od najjednostavnijih objekata, koje
možete da kreirate i kontrolišete i sa manjim iskustvom, ali efekte
ćete sagledati tek 2-3 godine rada. Činjenica je da objektna orijentacija
(OO) u programiranju daje nesagledive prednosti, ali neiskusan programer
će do OO teško da dopre bez dobrog poznavanja mogućnosti tako jednostavnih
objekata kao što su funkcije. Funkcija je objekat tipa procedure,
ali daleko naprednija od svog prvog konkurenta Sub-procedure, što
ću pokušati da odbranim u par redova:
* prvo, procedura Function vraća vrednost, što se može koristi i
u cilju ispitivanja korektno odrađenog zadatka
* drugo, procedura Function se može koristiti u događaju (Event)
grafičkog objekta, što predstavlja prvi korak u smanjenju obima
kooda i centralizovanju događaja, pa npr. svojstvo Click tastera
"cmdOpen" može da ima vrednost '=OpenForm("Options")'
i unosi se preko Property prozora
* Pogled na moje aplikacije, rađene u proteklih 10 godina, govori
da - ja sve više koristim funkcije, a Sub procedure samo u malom
broju događajima objekata gde se ne zahteva naprednija tehnika.
Navešću prost primer - funkciju OpenForm za otvaranje forme:
Public Function OpenForm(myForm As String,
_
Optional myCriteria As String = "", _
Optional dMOD As Integer = 1, _
Optional wMOD As Integer = 0, _
Optional MyArgs As String = "")
'Copyright©1998, Mikac@InfoSKY.net
On Error GoTo Err_OpenForm
'Normal - myMode=0; Design - myMode=1; Preview - myMode=2; FormDS
- myMode=3
' dMOD
' acFormAdd = 0; acFormEdit = 1; acFormReadOnly = 2; acFormDS =
3;
' acFormPropertySettings = -1
' wMOD
' acHidden=1; acIcon=2; acNormal=0; acWindowNormal=0; acDialog 3
DoCmd.OpenForm myForm, 0, , myCriteria, dMOD, wMOD, MyArgs
OpenForm = True
Exit_OpenForm:
Exit Function
Err_OpenForm:
If Err.Number = 3075 Then
myCriteria = ""
Resume
End If
Resume Exit_OpenForm
End Function
Dakle, gde god mi u aplikaciji zatreba otvaranje neke postojeće
forme, koristim ovu funkciju, pa ako nešto ne radi kako treba -
zna se gde treba ispravljati. I sami možete razviti sličnu funkciju
za otvaranje objekata tipaReports.
Univerzalne funkcije za link(ovanje) tabela
Evo nas opet na glavnoj temi, koju ćemo rešiti kroz tri funkcije:
jednu za povezivanje i dve za prekid veza, aplikacije sa Access
bazom po Jet konceptu, gde verzija JetEngine nije od značaja (Access
2.0 = Jet 2.0, Access95 = Jet 3.0, Access 97 = Jet 3.5, Access2000/XP
= Jet 3.6), jer Access koristi driver za pristup bazama svih verzija:
Microsoft Jet 4.0 Database Engine Driver. Tabela se linkuje samo
u cilju uticaja na podatke, ali ne i dizajna i/ili formatizovanja,
pa su, u pristupu ovim tabelama, na raspolaganju samo komande za
tu namenu.
Funkcija Link2DB, koja je u nastavku prikazana, služi za
povezivanje (Link) aplikacije na sve tabele (izuzem sistemskih)
određene baze podataka, tj. svim tabelama za editovanje podataka.
U osnovi, koristi se ideja da se u aplikaciji kreira tabela sa linkom
na izvor podataka (tabelu u drugoj bazi). Ako tabela sa tim imenom
već postoji u aplikaciji - biće obrisana, pa treba voditi računa
o imenovanju tabela koje u aplikaciji eventualno moraju da se koriste
(tabele za podešavanje opcija i slično), ali i kod povezivanja na
baze koje mogu imati istoimene tabele.
Argumenti funkcije Link2DB:
dbFN - database file name (npr: c:\my documents\data.mdb")
dbPASS - pristupni password baze podataka, a ako baza nema password
treba poslati prazan string ""
Sinonim - je drugo, javno ime, baze (npr: podaci o klijentima),
za poruku korisniku u slučaju greške pri povezivanju
Vis - logička vrednost True/False kojom se određuje vidljivost "progress
bar"-a za vreme povezivanja sa bazom
Public Function Link2DB(dbFN As String, _
dbPASS As String, _
Optional Sinonim As String, _
Optional Vis As Boolean = False) As Boolean
'Copyright©1998, Mikac@InfoSKY.net
Dim wsp As Workspace
Dim dbs As Database, dbsAnother As Database
Dim tdf As TableDef, dbt As TableDef
Dim i As Integer, n As Integer
Set dbs = CurrentDb()
Set wsp = CreateWorkspace(0, "admin", "", dbUseJet)
Dim MyConnect As String
On Local Error GoTo Link2DBErr
Set dbsAnother = wsp.OpenDatabase(dbFN, False, False, _
"MS Access;PWD=" & dbPASS & ";DATABASE="
& dbFN)
i = 0
n = dbs.TableDefs.Count
For Each tdf In dbsAnother.TableDefs
i = i + 1
y = SysCmd(acSysCmdInitMeter, "Link to DB:", n)
If Left(tdf.Name, 4) <> "MSys" Then
If Vis Then y = SysCmd(acSysCmdUpdateMeter, 100 * i / n)
On Local Error Resume Next
dbs.TableDefs.Delete tdf.Name
On Local Error GoTo Link2DBErr
Set dbt = dbs.CreateTableDef(tdf.Name)
dbt.Connect = "MS Access;PWD=" & dbPASS & ";DATABASE="
& dbFN
dbt.SourceTableName = tdf.Name
dbs.TableDefs.Append dbt
End If
Next
Link2DB = True
Link2DBexit:
wsp.Close
y = SysCmd(acSysCmdClearStatus)
Set dbs = Nothing
Set dbsAnother = Nothing
Exit Function
Link2DBErr:
Select Case Err.Number
Case 3031 'pass
MsgBox "Nekorektan Password za povezivanje na: '" &
Sinonim & "'", vbCritical, "Opss..."
Case 3024, 3044 'file
MsgBox "Ne postoji fajl za povezivanje sa: '" & Sinonim
& "'", vbCritical, "Opss..."
Case 3045 'open in exclusive mode
MsgBox "Baza za povezivanje '" & Sinonim & "'
otvorena u Exclusive modu." & _
vbCrLf & "Promenite mod pristupa ili zatvorite odnosnu
bazu.", vbCritical, "Opss..."
Case Else
MsgBox Error
End Select
Link2DB = False
Resume Link2DBexit
End Function
Funkcija DisconnectDB neophodna je za prekid uspostavljenih
linkova sa bazom podataka, a treba je koristiti kada korisnik aplikacije
prekida linkove prema jednoj konkretnoj bazi podataka
Public Function DisconnectDB(dbFN As String,
_
Optional Sinonim As String = "", _
Optional Vis As Boolean = False) As Boolean
'Copyright©1998, Mikac@InfoSKY.net
Dim dbs As Database
Dim tdf As TableDef, dbt As TableDef
Dim i As Integer, n As Integer
Set dbs = CurrentDb
n = dbs.TableDefs.Count
y = SysCmd(acSysCmdInitMeter, "Link to DB:", n)
For i = n - 1 To 0 Step -1
Set tdf = dbs.TableDefs(i)
If InStr(LCase(tdf.Connect), LCase("DATABASE=" & dbFN))
> 0 Then
If Vis Then y = SysCmd(acSysCmdUpdateMeter, 100 * i / n)
On Local Error GoTo DisconnctDBErr
dbs.TableDefs.Delete tdf.Name
End If
Next
DisconnctDBexit:
y = SysCmd(acSysCmdClearStatus)
dbs.TableDefs.Refresh
Set dbs = Nothing
DisconnectDB = True
Exit Function
DisconnctDBErr:
MsgBox "Greška (" & Err.Number & ") pri raskidu
sa sa: '" & Sinonim & "'" & vbCrLf &
"Tabela: " & Chr(34) & tdf.Name & Chr(34)
& ", nije na raspolaganju!", vbCritical, "Opss..."
MsgBox Error
DisconnectDB = False
Resume DisconnctDBexit
End Function
Sledeća, i poslednja, funkcija je BreakAllLinks, a
predstavlja najbrži način raskidanja svih linkova koji su u aplikaciji
uvedeni za vreme rada korisnika. Dobro će poslužiti kada korisnik
izlazi iz aplikacije u kojoj ste koristili linkove na više baza
podataka. Zaostali linkovi iz aplikacije na tabele baze podataka
su osetljiva mesta za "razbijanje" lokacije i pristupnih
šifara baza podataka, kao i otkrivanje primenjene koncepcije.
Public Function BreakAllLinks(dbs As Database, _
Optional Vis As Boolean = False) As Boolean
'Copyright©1998, Mikac@InfoSKY.net
Dim tdf As TableDef, dbt As TableDef
Dim n As Long
n = dbs.TableDefs.Count
y = SysCmd(acSysCmdInitMeter, "Link to DB:", n)
For i = n - 1 To 0 Step -1
Set tdf = dbs.TableDefs(i)
If tdf.Connect <> "" Then
If Vis Then y = SysCmd(acSysCmdUpdateMeter, 100 * i / n)
On Local Error GoTo BreakAllLinksErr
dbs.TableDefs.Delete tdf.Name
End If
Next
BreakAllLinksExit:
y = SysCmd(acSysCmdClearStatus)
dbs.TableDefs.Refresh
Set dbs = Nothing
DoCmd.Close acForm, "_progress_"
BreakAllLinks = True
Exit Function
BreakAllLinksErr:
Resume BreakAllLinksExit
End Function
Rezime
Pokazao sam vam kako aplikacija može da se poveže sa izvorom podataka
(bazom), što predstavlja tek početak rada na ideji linkovanja. U
cilju jednostavnosti prikazao sam samo Jet pristup, ostavljajući
ODBC pristup za kasnije. Linkovanje Access aplikacija sa Access
bazom nije moguće preko ODBC-a, ali iz VisualBasic aplikacija se
čak i preporučuje. ODBC omogućava široki spektar drivera za pristup
različitim formatima izvora podataka, od najjednostavnijih takstualnih
(*.txt, *.csv), preko prevaziđenih XBase izvora (*.dbf, *.db), pa
do SQL Servera (Microsoft, InterBase, mySQL). Još nešto o čemu treba
razmišljati je povezivanje na tabele baza u kojima je aktiviran
sigurnosni sistem korisnika i dozvola. Pristup je nešto složeniji,
ali tema "sigurnosni sistem JetEngine" traži daleko više
prostora.
Iako to može da zvuči suviše kompleksno, Access omogućava i linkovanje
aplikacija, gde se iz radne aplikacije poziva funkcija, procedura
ili klasa iz neke druge. Primenjujući povezivanje aplikacija po
AddIns ili References metodi, funkcije dobijaju još više na značaju,
ali je daleko važnije savladati filozofiju objektno orijentisanog
programiranja i iskoristiti veliku filozofiju u za male i praktične
primere od značaja za korisnika aplikacije. O tome u nekom sledećem
članku.
|