Fujitsu-Siemens
 
M A G A Z I N
 
PROGRAMIRANJE 
  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.

 

VRH STRANE

(c) 2004 OMEGA - sva prava zadržana