 |
| |
Mikanović S. Radenko
Top10 MS Access/VBA Tips |
|
Šta? Znao si ovo? ...Nemoguće,
moj komšija Đura se kune da je on prvi ovo "otkrio"...
je jedna od vrlo čestih situacija u nedozrelom informatičkom društvu,
kao što je na ovoj našoj planeti Zemlji, zato što neiskusan korisnik
ili programer ima osećaj da otkriva nešto što još niko nije. Kada
spoznamo, da su otkrića do kojih smo došli, takva samo za nas lično
- mnogo više, bez sujete i ljubomore, ćemo razmenjivati iskustva
sa drugima, kritikovati ih i prihvatati njihove kritike.
Svi mi pravimo greške, a ja, pored toga, još i mnogo teže primećujem
svoje od tuđih grešaka i zbog toga sam mnogo vremena izgubio tražeći
odgovor na pitanje: "ko sad greši, ja ili program". Pod
programom mislim na razvojni alat, a kakve su greške i situacije
moguće videćete u sledećim pasusima. Ovu manu pokušavam da eliminišem
na tako što sa kolegama dajem svoje aplikacije na testiranje i to
isto očekujem od njih.
Možda bi trebalo da napomenem i to da su neki od zapisa stari oko
2-3 godine i a da se odnose na MS Access 2000/XP, VisualBasic/VBA,
a poneki i na operativni sistem. Jednostavno sam ih nazivao problemi
i čuvao na gomili po principu pitanje i odgovor, dok je članak (kao
i njegovo ime) nastao spontano. Tips-i su poređani od najjednostavnijih
do nešto komplikovanijih, ali ih treba samo posmatrati kao mali
segment u problematici razvoja aplikacija pod MS Access-om.
#1 Report - Paper Size
Q: Korektno ste podesili Paper Size na A4, a kada je otvori korisnik
(na drugom računaru) - Report nije u toj veličini papira.
A: Problem nastaje kada MS Access, posle štampanja Report-a na neki
drugi (a ne Default) printer, sam prebaci svojstvo PrinterForReport
na vrednost Specific Printer (smatrajući da ste to želeli). Još
ako ste vi odštampali na štampač koji kod korisnika ne postoji pod
tim imenom - eto problema, jer će od njega svaki put tražiti taj
štampač.
Rešenje (bez programiranja) je da posle svakog štampanja kod vas
- detaljno pregledate PageSetup i:
a) postavite Paper Size na A4 (ili već ono što je korisnik tražio),
b) obavezno postavite PrinterForReport na Default Printer
c) sačuvate ove promene.
#2 Vertical svojstvo i matrični štampač
Q: Label (ili TextBox) objekat, koji se postavi vertikalno, ne
prikazuje se realno, tj. jedno se vidi dok dizajnirate, a drugo
u Preview-u Report-a. Najlakše je reći da ove objekte Access malo
skrati vertikalno i proširi horizontalno.
Situacija: MS Access Report, Vertical Label, Page Setup Orientation
podešena na Landscape, Default Printer neki matrični štampač.
A: Dešava se zbog toga što MS Access u dizajn modu radi u (apriori)
Portrait orijentaciji, odnosno MS Access ga smatra takvim, pa se
posle rotacije u Landscape (u Preview modu) - uočava razlika u horizontalnoj
(Hz) i vertilanoj (V) rezoluciji, koju omogućava tekući štampač.
Kako matrični štampači (posebno 9pin-ski) imaju izrazitu razliku
Hz i V rezolucije, to je kod njih ovaj problem znatno izražen.
Iz situacije se možete izvući na jedan od načina:
a) koristite svojstvo Vertical samo kod izveštaja sa Portrait orijentacijom.
b) za Default printer podesite neki univerzalni laserski štampač,
kao npr. HP LaserJet IIIP
Zanimljivost vezana za HP LaserJet IIIP je to što je dokument na
ovom štampaču (vizuelno) vrlo sličan onom na svim novijim verzijama,
što znači da su razlika u Preview-u skoro i nema)
#3 Vezivanje Label-a uz TextBox
Q: MS Acces, kod postavljanja novog objekta TextBox (ali i ostalih
objekata za editovanje podataka), za sam objekat vezuje novi Label,
što je od velike pomoći, a naročito kod ugrađivanja HotKey (standardnog
za OS Windows). Problem nastaje kada slučajno ili namerno obrišete
Label, a kasnije (posle par dana) želite da ga vratite.
A: Rešenje ćete dobiti kreiranjem novog objekta Label, pa nad njim
izvršite Cut. Onda selektujete TextBox (ili drugi objekat) za koji
želite da ga vežete i izvršite akciju Paste. Tako će Label i TextBox
biti vezani dok ih ne razdvojite manuelno.
#4 Explicitna pred-deklaracija
Q: MS Access aplikacija ne radi, a kompajliranje (i kreiranje
MDE fajla) je prošlo korektno?
A: Ako u modulu (forme ili coda) nije dodeljena pred-deklaracija
Option Explicit, može se desiti da aplikacija radi u nekomplajliranom
obliku (.mdb), kompajliranje prolazi bez problema, a ne radi u kompajliranom
(.mde).
Iako razloga može biti više, najgori je onaj, koji se najteže otkriva
- kada se neka javna promenljiva sukobi sa "nedeklarisanom"
promenljivom u modulu koji nema Option Explicit pred-deklaraciju.
U toj situaciji nema greške u razvoju, jer se MDB i MDE aplikacija
ne izvršavaju kroz isti prevodilac, pa se greška ne može tada ni
detektovati. MDE aplikacija ne radi, kada se kompajlira i to samo
u proceduri u kojoj se koristi nedeklarisana promenljiva, koja se
sukobi sa javnom promenljivom. Ovaj problem dolazi do izražaja tek
kada, preko References, koristite deljenje resursa sa nekom bibliotekom
(MDE, DLL,...) i napravite grešku slično gore navedenoj.
Dakle treba:
a) Što više koristiti explicitno pred-deklarisanje promenljivih,
tj. svakom modulu, ispred bilo kakve procedure, upisati red sa dve
reči: Option Explicit. Na taj način će VBA tražiti deklaraciju tipa
za svaku korišćenu promenljivu ili greškom ukucano ime za neku promenljivu.
Ako ste, iz nekog razloga, u modulu koristili implicitno deklarisanje,
svedite obim koda u tom modulu na najmanju moguću meru.
b) Što manje koristiti Public ili Global deklaraciju promenljive,
a i tada to raditi samo u jednom modulu, promenljivoj dodeliti specifično,
što složenije i duže ime, da se ne podudari sa nekom lokalnom promenljivom.
#5 Null u Registry-u
Q: Pozivanje funkcije GetSetting(AppName, Section, Key[, default])
dovodi do problema OutOfMemory!
A: GetSetting() može da dovede do problema OutOfMemory, u situacijama:
kada pod argumentom Key nije upisano ništa; kada argumenta uopšte
nema; kada "ima" vrednost Null ili prazan string ("").
Ako argument izostavite, VB će uočiti grešku u sintaksi, ali ako
se uputi argument sa nedozvoljenom vrednošću, može se desiti navedena
greška u radu, a što se dešava kada se primeni: funkcija GetSetting(),
jer u Registry value nema vrednosti, kao npr:
GetSetting(AppName, "Settings", "DefaultRCPT",
"")
Kako se uopšte može upisati Null vrednost u Windows Registry? Manuelno
kroz Regedit i slanjem Null vrednosti funkcijom SaveSetting().
#6 Unicode u Registry-u
Q: Ako Windows 98 nije podešen za Unicode, njegov Registry (format
REGEDIT4) neće razumeti fajl urađen 16-obitno, bez obzira što u
fajlu nema YU slova i što je na računaru podignuta MultilanguageSupport.
A: Jedan od načina rešavanja ovakvog problema je korišćenje opcije
"Save as ANSI" prilikom čuvanja *.reg fajla koji se prosleđuje
na neki računar pod OS Windows 98. Drugi je način daleko komplikovaniji,
a sastoji se u podešavanju Windows 98 za naše područje ili reinstaliranju
sa ciljem promene regiona.
#7 VBA & OE
Q: Problem VBA aplikacija u korišćenju Recordset-a posle startovanja
OE.
Situacija: Windows98, MS Access2000, OutlookExpress 6
1. korisnik se povezao preko DialUp-a na Internet
2. preuzeo poštu (e-mail), koristeći pri tom OutlookExpress.
3. zatvorio sve otvorene aplikacije
4. Pokrenuo MS Access aplikaciju i dobio grešku u rezultatima funkcija,
koje pristupaju Recordset-u linkovanih tabela, a daju rezultat #ERROR#.
A: Recordset ima veze sa Replace funkcijom, a ovo je samo jedan
od vidljivih simptoma grešaka ove funkcije.
Peti argument funkcije Replace je obavezan izvan jezičkog regiona
English (nije dokumentovano), jer OutlookExpress u međuvremenu koristio
JetEngine sa regionalnim pristupom koji je podešen u njemu samom,
a MS Access koristi sistemska podešavanja. Sukob realno nastaje
u samom Access-u usled neodvojivosti funkcionisanja Recordset-a
i VBA. Ako se ova greška pojavi, korisniku može pomoći samo restart
operativnog sistema (dok sam programer ne ispravi grešku).
#8 Uklanjanje Reference
Q: Kada neka nekorišćena Referenca ne može da se ukloni na standardan
način, kako je ukloniti? Ne pomaže ni Compact, ni Decompile niti
šta drugu. Da li je kreiranje nove aplikacije, pa potom import objekata,
jedino rešenje?
A: Standardan način podrazumeva sledeći red operacija: Tools/References
i skinuti čeker, ali šta kad to VBA odbija da učini.
Trebalo bi :
1) naći broj ili ime te reference, pa potom
2) VBA komandom je ukloniti iz liste Referenci
a) ako znate Index Reference koju treba skinuti (i): Application.References.Remove
Application.References.Item(i)
b) ako znate ime Reference (Name): Application.References.Remove
Application.References.Item("Name")
c) ako znate samo FullPath na fajl:
Private Function RemoveReference(strRefFullPath As String) As Boolean
Dim ref As Reference, i as Integer
For i = 1 To Application.References.Count
Set ref = Application.References.Item(i)
If ref.FullPath = strRefFullPath Then
Application.References.Remove Application.References.Item(i)
Exit For
End If
Next
End Function
3) Potom zatvoriti aplikaciju (Exit), otvoriti ponovo (Open), pa
izvršiti Compilei Compact.
#9 ActiveX & Compile
Q: Radio sam na jednoj od Access aplikacija, a problem nastade
na jednoj formi. Osim uobičajenih objekata, na njoj sam koristio
i objekat MonthView za pregled i odabir datuma u mesecu. Imao sam
dosta "zahvata" na tom objektu, a posle izvesnog vremena,
prilikom pokretanja, Compact ili Compile-a mi se pojavi poruka da
objekat ne postoji (MonthView), a code u pozadini te forme više
nije hteo da radi.
A: Rešenje:
a) Decompile - je najlakše rešenje (ako i to prođe), a komandna
linija (Run ili DosPromt) izgleda ovako:
"C:\Program Files\Microsoft Office 2000\Office\msaccess.exe"
"C:\Works\ACCESS\AMMA\APP.mdb" /decompile
Ne zaboravite da na aplikaciji uklonite Startup formu i uvedete
vidljivost Database Window. Kada ponovo otvorite aplikaciju, trebalo
bi da izvršite Compile, a posle toga Compact i Make MDE, pa ako
uspe - problem nije veliki.
b) Problem postaje nešto veći, ako akcije pod a) ne uspeju, a tada
treba pokušati sa Export/Import zahvatom:
Kreirajte slepu kopiju fajla aplikacije, pa iz glavne aplikacije
uklonite (obrišite) problematičnu formu, a potom Compact & Compile.
Ako to prođe, izvršite Import one forme iz slepe kopije fajla, a
neposredno posle završetka procesa Import, uđite u VBA code te forme,
izvršite neku beznačajnu promenu (otkucajte prazan red na početku),
pa izvršite Save. Ako Compact & Compile ne prođu - niste uspeli.
c) Ako ništa navedeno ne pomogne, probajte sledeće:
Kreirajte slepu kopiju fajla aplikacije, pa iz glavne aplikacije
uklonite (obrišite) problematičnu formu, a potom Compact & Compile.
Kreirajte novu praznu formu, uporedo otvorite slepu kopiju aplikacije.
Otvorite u dizajn modu problematičnu formu u slepoj kopiji, pa selektujte
sve objekte i prekopirajte ih na praznu formu u glavnu aplikaciju.
Otvorite u ViewCode modu problematičnu formu u slepoj kopiji, pa
selektujte sav code i prekopirajte na isto mesto u formu glavne
aplikacije. Zatvorite slepu kopiju, sačuvajte i zatvorite formu
koju radite u glavnoj aplikaciji. Isprobajte uobičajenim redosledom:
Compile, Compact, pa Make MDE.
Savet: Problem kontrole MontView nastaje kada default (podrazumevana)
vrednost polja podatka za koje je objekat vezan, izlazi iz njenog
definisanog opsega DateMin-DateMax. U ovom slučaju, Access ne može
da ispravi "brljotinu" koju je napravio u sistemskoj tabeli,
ali je najgore što nikakvi manuelni zahvati na njoj nisu dozvoljeni.
Sličan problem se javlja i sa drugim ActiveX objektima, npr. ListView
može da izgubi vezu sa ImageList kontrolom u kojoj su smeštene slike
za prikaz u ListView. Generalno, ActiveX treba više kontrolisati
iz code-a, a manje iz njihovog Page Properties-a. Dakako, ovde će
doći do izražaja vaše poznavanje samog objekta, ali vam u tome može
pomoći Object Browser u VBA (taster F2).
#10 Link ka Xbase formatu
Q: Aplikacijom sam se linkovao na jednu DBF tabelu (format DBase
III+). Svaki pristup ovoj tabeli je bio ReadOnly i No Locks,
što znači da ne tražim Exclusive pristup ili editovanje tih podataka.
Istu Access aplikaciju sam instalirao na 4 PC-a pod Win98 i dobio
poruku o grešci:
"The Microsoft Jet database engine cannot open the file Filename.
It is already opened exclusively by another user, or you need permission
to view its data."
i već zaključim da je greška u aplikaciji, jer NIKO ne pristupa
tom fajlu, a on POSTOJI.
Procesi u kojima sam pristupao toj tabeli očigledno se ne zatvaraju,
jer mi je pristup dozvoljen samo kroz jednu formu, ali ne i kroz
dve. Kad instalirah aplikaciju na sledećoj Win98 mašini, a ono nema
greške!!!
A: Problem je u tome što na "starijim mašinama" (Win9x),
gde nije korišten JetEngine, niko nije "doneo" zakrpu
za JetEngine još od prve verzije koja je došla sa MS Office-om.
U međuvremenu mnoge greške su otkrivene i zakrpljene, pa se preporučuje
instalacija jedne od njih (u zavisnosti od OS) ili Microsoft Data
Access Components 2.5 (ako planirate i ADO konekcije).
Greška je vezana za fajl 'msxbde40.dll' koji se od strane JetEngine
koristi za pristup Xbase formatima baza.
Lokacije na kojima možete da potražite ove zakrpe su:
Win9X_NT (obavezno): http://download.microsoft.com/download/e/8/c/e8c5729c-d90a-4d15-bdc1-cbc9eae82924/Jet40SP7_9xNT.exe
Windows 2000 (neobavezno): http://download.microsoft.com/download/9/d/c/9dcd9e1c-badc-4fe4-a52e-8f2fdfb652db/Windows2000-KB829558-x86-ENU.exe
WinXP (neobavezno): http://download.microsoft.com/download/a/d/f/adfdf363-0b09-4f39-bf89-1b4bc234fe97/WindowsXP-KB829558-x86-ENU.exe
Rezime
Nadam se da će vam rešenja ovih problema, koja sam lično i imao
i rešio, pomoći da provedete manje vremena za monitorom, a to vreme
potrošite na sport i druženje. U sledećem članku ću vam izložiti
najčešće probleme koje sam imao u kombinaciji alata VB+ADO+SQL,
a do tada - javite se sa vašim pitanjima na adresu magazina.
|