Jak na relativně propojené tabulky v MS Access
Microsoft Access má své mouchy, ale na rychlý návrh jednoduchých databázových aplikací pro Windows se hodí — skoro všechno jde hezky naklikat, přičemž hned vidíte výsledek, a zbytek zařídí Visual Basicový kód. Access jsem použil například pro nové verze databázového programu Gulag.
Jenže právě u databází, kdy je vše v jediném souboru, je s těmi novými verzemi trochu problém — jak jednoduše dostat k uživateli novou verzi programu, aniž by si musel složitě přelévat svá již rozpracovaná data ze starého souboru do nového? Řešením, které nabízí Access, je neukládat všechno do jediného .mdb souboru, ale oddělit samotný program od vlastních dat a obojí uložit do samostatných souborů, které jsou pak vzájemně propojené.
Tohle samozřejmě není objev Microsoftu, nýbrž obecný, dlouhodobý a užitečný trend (při vývoji webu se důsledně odděluje programový kód od grafických šablon; nebo třeba celá filozofie UNIXu — spousta malých prográmků pro specifické účely, ale vzájemně bezvadně propojených, a podobně).
Zrada č. 1
To je všechno hezké, ale v praxi — a v případě MS Access databází — použitelné jen omezeně. Proč? Propojíte-li dva či více souborů v MS Accessu, vše krásně funguje, dokud pracujete na tomtéž počítači a se soubory fyzicky nehýbete. Tabulky jsou totiž propojeny absolutně a i když jsou třeba dokonce ve stejném adresáři, stačí je všechny přesunout na jiný počítač nebo někam jinam na disku a vazba mezi tabulkami zmizí jako přetržená nit…
Jak ale pak takový program třeba distribuovat? Jak umožnit uživatelům, aby si mohli třeba udělat pořádek na disku a program přesunout? Samozřejmě, že máte možnost tabullky opět ručně propojit pomocí speciální funkce Accessu, ale pro mé uživatele to byla velká potíž navíc. Osobně tuto vlastnost (rozuměj chybu v návrhu) Accessu nechápu. Ani teoreticky mě moc nenapadají nějaké výhody takového řešení (snad leda zabránění hypotetickému nechtěnému propojení souborů). Ale pojďme se místo planého lamentování poohlédnout po nějakém řešení.
To naštěstí existuje, dokonce pěkně předpřipravené, takříkajíc instantní! Jde o Visual Basicový kód Deva Ashishe dostupný na The Access Webu. Kód stačí ze stránky zkopírovat (samozřejmě s dodržením podmínek autora) a uložit např. do samostatného modulu aplikace. Pak zbývá zavolat funkci fRefreshLinks někde po startu aplikace, nejlépe jako handler události onOpen hlavního formuláře vašeho programu. Funguje to potom tak, že se po startu aplikace podívá na všechny definované tabulky a pokud zjistí, že některé z nich nejsou správně propojeny, zobrazí dialog pro výběr souboru s tabulkami. Kód si samozřejmě můžete upravit, aby se např. rovnou pokusil propojit dva soubory s předem známými názvy v aktuálním adresáři aplikace, a podobně.
Zrada č. 2
Bohužel, v mém případě to ale nestačilo. Výše uvedený postup nefunguje v případě, že hlavní formulář, ze kterého je volána funkce pro propojování tabulek, má některé z následujících vlastností:
- je datově propojený ne s obyčejnou tabulkou (objekt typu Table), ale s dotazem (Query), nebo
- obsahuje podformulář, který si data bere z jiné tabulky nebo dotazu než hlavní formulář.
V těchto případech dojde k tomu, že MS Access se pokusí přistoupit k tabulkám ještě předtím než vůbec vyvolá jakoukoliv událost formuláře (např. onOpen) a výsledkem je místo automatického propojení tabulek suchá hláška
Could not find file c:\...\xyz.mdb a program skončí!
Řešení tohoto problému je ale naštěstí celkem jednoduché. Stačí si vytvořit nový prázdný formulář, např. „startup“ a ten označit jako startovací formulář, který se otevře při spouštění Accessové aplikace (dělá se to v menu Nástroje -> Po spuštění...). Do kódu události onOpen tohoto formuláře pak zadejte kód pro spuštění propojovací funkce, otevření toho původního hlavního formuláře (zde nazván „main“) a zavření toho prázdného. Pak už se tabulky propojí normálně, aplikace zase začne fungovat a svět se opět stane růžovým… Ukázka kódu pro startovací formulář následuje:
Private Sub Form_Open(Cancel As Integer)'obnovime linky na tabulky Call fRefreshLinksDoCmd.OpenForm "main" DoCmd.Close acForm, "startup", acSaveNoEnd Sub
Enjoy!
