Popis práce Tato práce se zabývá propojením aplikací MS Office s pomocí kódů ve VBA. V tomto konkrétním příkladě je znázorněn případ komunikace mezi programy MS Access 2007 a MS Excel 2007. Díky možnostem exportu a importu dat mezi těmito dvěma programy a s pomocí možností jazyka VBA můžeme docílit efektivní a pohotové spolupráce mezi soubory s velice snadným ovládáním i pro méně zkušeného uživatele. Tento příklad je inspirován reálným využitím spolupráce aplikací v evidenci jedné pražské restaurace. 1
Zdrojová data Pracovat budeme s těmito soubory: evidence.accdb ; prijmy_2008-11-13.xlsx ; prijmy_2008-11-20.xlsx ; prijmy_2008-11-27.xlsx ; prijmy_2008-12-04.xlsx ; prijmy_kt.xlsm ; prijmy_vystup-kt.xlsx. Pro vysvětlení vzájemných vazeb jednotlivých souborů lze zmínit následující: zdrojem primárních dat budou soubory prijmy_2008-##-##.xlsx, tyto soubory obsahují příjmy za dny, konkrétně vždy za sedm dní, (resp. jednu směnu) v každém uvedeném souboru; tato data je zapotřebí naimportovat do souboru evidence.accdb ; soubor evidence.accdb slouží ke shromáždění dat ze souborů prijmy_2008-##-##.xlsx, ale zároveň poskytuje zdrojová data pro soubor prijmy_kt.xlsm ; soubor prijmy_kt.xlsm obsahuje kontingenční tabulku, která umožňuje podrobně analyzovat data ze souboru evidence.accdb. 2
Postup řešení 1. Nejdříve v aplikacích Access a Excel povolíme všechna makra a v Excelu dále povolíme všechna datová připojení a automatickou aktualizaci všech propojení sešitu. Import dat z Excelu do Accessu 2. Otevřeme soubor evidence.accdb. 3. Pomocí klávesové zkratky levý alt+f11 se přesuneme do editoru VBA. 4. V editoru VBA z hlavní nabídky vybereme volbu Insert a z podnabídky následně Module. Tím dojde k vytvoření nového Modulu s názvem Module1. 5. V podokně Properties změníme vlastnost (Name) z hodnoty Module1 na hodnotu pracovni a pomocí klávesové zkratky ctrl+s Modul uložíme. 6. Do námi vytvořeného Modulu pracovni vložíme nové makro pro import dat z Excelu ze souborů prijmy_2008-##-##.xlsx, a to pro začátek zapsáním textu Sub Import_Excelu na nový řádek pod nápis Option Compare Database a odešleme stisknutím klávesy Enter. Tím se nám vytvoří prostor pro další tvorbu tohoto makra. 7. V tomto bodě si deklarujeme proměnné potřebné pro toto makro. Pod nápis Sub Import_Excelu() napíšeme Dim Cesta As String a pod to Dim Soubor As String. 8. Nyní stanovíme proměnným jejich obsah. Na další řádek proto zapíšeme Cesta = CurrentProject.Path (proměnná Cesta tedy bude nabývat aktuální cesty k souboru evidence.accdb, což je pro nás nezbytné z důvodu možného přesouvání souborů). Na další řádek zapíšeme Soubor = Forms![soubory_d]![soubor_f].Value (proměnná Soubor bude tedy nabývat hodnot z pole [soubor_f] formuláře [soubory_d] ). 9. Nyní již máme stanoven význam proměnných, můžeme tedy přistoupit k napsání kódu pro samotný import. Na další řádek tedy zapíšeme DoCmd.TransferSpreadsheet acimport, acspreadsheettypeexcel12, "prijmy", Cesta & "\" & soubor & ".xlsx", True, "prijmy". Pro lepší pochopení jednotlivých náležitostí tohoto příkazu nám pomáhá interaktivní nápověda VBA, která se 3
zobrazuje během psaní kódu. Na vysvětlenou však uvedu jejich význam ve stejném pořadí jako v kódu: DoCmd.TransferSpreadsheet acimport - tím říkáme Accessu zhruba toto: proveď příkaz importu hodnot z listu tabulkového kalkulátoru. acspreadsheettypeexcel12 - tímto určíme verzi Excelu, ze které chceme importovat. "prijmy" - je jméno tabulky Accessu, do které se má importovat. Cesta & "\" & Soubor & ".xlsx" - je zřetězení hodnot našich proměnných a pevného textu. "True" - je potvrzení, že oblast Excelu, kterou chceme importovat je pojmenována. "prijmy" - je název pojmenované oblasti Excelu. 10. Na další rádek ještě doplníme MsgBox "Data byla úspěšně importována",, "Průběh importu", což nás informuje v případě hladkého průběhu importu. 11. Teď provedeme přiřazení tohoto kódu k události stisknutí u tlačítka Importovat na formuláři soubory_d. To učiníme tak, že v editoru jazyka VBA otevřeme okno pro psaní kódu pro formulář soubory_d (ve VBA pojmenováno Form_soubory_d). 12. Z levé vyklápěcí nabídky v záhlaví tohoto okna vybereme volbu importovat (což je interní název tlačítka Importovat ) a do míst, kam se nám automaticky umístí kurzor zapíšeme název námi vytvořeného prvního makra, tzn., Import_Excelu. Tím se tlačítko stane funkční. 4
13. Teď postupně prostřednictvím formuláře soubory_d naimportujem data ze souborů prijmy_2008-##-##.xlsx. 14. Máme-li všechna tato data naimportována, pokusíme se znovu naimportovat data např. ze souboru prijmy_2008-12-04.xlsx. Díky tomu dojde ke zobrazení systémového dialogu Accessu. Vybereme na něm možnost Ano, data se naimportují znovu, předchozí data jsou přepsána. 15. Bod 14 zopakujeme s tou výjimkou, že na systémovém dialogu Accessu vybereme Ne. V tu chvíli dojde k chybovému dialogu VBA. Na tomto dialogu zvolíme End. 16. Chceme zajistit, aby se tato chyba VBA již neopakovala, do kódu makra Import_Excelu za řádek s textem Soubory = Forms![soubory_d]![soubor_f].Value proto doplníme ještě On Error GoTo Zprava. Na konec makra před řádek End Sub pak doplníme Exit Sub a na 5
další řádek potom Zprava: MsgBox "Některá z Dat, která se pokoušíte importovat, v tabulce Příjmy již jsou. Importována proto nebyla žádná data. Chcete-li i přesto tato data znovu naimportovat, akci opakujte a v systémovém dialogu zvolte volbu Ano.",, "Průběh. Tím dojde k tomu, že místo chybového hlášení VBA dojde k zobrazení hlášení definovaného námi, což je pro běžného uživatele rozhodně srozumitelnější. Pomocí klávesové zkratky ctrl+s Modul uložíme. Soubor evidence.accdb můžeme uzavřít. Otevření kontingenční tabulky v Excelu 17. Otevřeme soubor prijmy_kt.xlsm. 18. Přejdeme na list pomoc do buňky A3 a zapíšeme do ní vzorec ="[prijmy_vystup-kt.xlsx]prijmy_d'!"&"r1c1"&":"&"r"&počet2('[prijmy_vystupkt.xlsx]prijmy_d'!$a:$a)&"c10". Důležitá je především vnořená fce POČET2, díky které zjistíme počet neprázdných buněk ve sloupci A listu prijmy_d souboru prijmy_vystup-kt.xlsx. Výsledek tohoto vzorce bude sloužit pro nastavení rozsahu zdrojových dat kontingenční tabulky kt_prij. Na výsledek tohoto vzorce se bude odkazovat proměnná Zdroj (viz bod 23 a 24). 19. Pomocí klávesové zkratky levý alt+f11 se přesuneme do editoru VBA. 20. V editoru VBA z hlavní nabídky vybereme volbu Insert a z podnabídky následně Module. Tím dojde k vytvoření nového Modulu s názvem Module1. 21. V podokně Properties změníme vlastnost (Name) z hodnoty Module1 na hodnotu pracovni a pomocí klávesové zkratky ctrl+s soubor uložíme. 22. Do modulu pracovni zapíšeme Sub Prij_Prech a odešleme stisknutím klávesy Enter. Tím se nám vytvoří prostor pro další tvorbu tohoto makra. 23. Nejdříve si deklarujeme proměnné. Do makra proto zapíšeme Dim Cesta As String a na další řádek Dim Zdroj As String. 24. Nyní nadefinujeme obsah těmto proměnným. Na další řádek proto zapíšeme Cesta = ActiveWorkbook.Path a na další řádek Zdroj = Sheets("pomoc").Range("A3").Value. 25. Protože nechceme, aby nám tzv. blikala obrazovka při běhu makra, na další řádek zapíšeme Application.ScreenUpdating = False. 6
26. Později se nám bude hodit, aby byla okna jednotlivých souborů Excelu na hlavním panelu Windows skryta pod jedno, to zajistíme zápisem Application.ShowWindowsInTaskbar = False na další řádek. 27. Nyní na další řádky zapíšeme Sheets("kt").Select ActiveSheet.PivotTables("kt_prij").ChangePivotCache ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= "'" & Cesta & "\" & Zdroj, Version:=xlPivotTableVersion12). Pozor, v rámci příkazu neřádkujeme! Chceme-li řádek zalomit uprostřed příkazu, můžeme využít znaky _ (mezera a podtržítko) a odeslat stiskem klávesy Enter. Tento příkaz nám umožní automaticky nastavit oblast zdrojových dat pro kontingenční tabulku kt_prij. 28. Na další řádek zapíšeme ActiveSheet.PivotTables("kt_prij").PivotCache.Refresh, což kontingenční tabulku aktualizuje. 29. Na další řádek zapíšeme ActiveSheet.PivotTables("kt_prij").PivotFields("datum").ShowDetail = False, díky čemuž se sbalí podrobnosti kontingenční tabulky. 30. Na další řádek zapíšeme Application.ScreenUpdating = True, což obnoví problikávání obrazovky. 31. Na konec tohoto makra zapíšeme ještě Range("C8").Select, což umožní přemístění do výchozího bodu kontingenční tabulky. 32. Abychom si makro mohli vyzkoušet, musíme si otevřít soubor prijmy_vystupkt.xlsx a do jeho jediného listu do buňky A3 zapíšeme hodnotu 14/11/08. Vrátíme se do souboru prijmy_kt.xlsm a makro spustíme. Soubor prijmy_vystupkt.xlsx musí zůstat otevřen. 33. Protože chceme, aby se soubor prijmy_vystup-kt.xlsx otevíral automaticky, vytvoříme si pro jeho otevření makro do souboru prijmy_kt.xlsm. Na další řádek za text End Sub předchozího makra zapíšeme Sub Prij_Vyst_Otev, čímž nazveme další makro a odešleme stisknutím klávesy Enter. 34. Dále deklarujeme potřebnou proměnnou Cesta a to zápisem Dim Cesta As String. 7
35. Na dalším řádku stanovíme obsah proměnné, kterým je opět Cesta = ActiveWorkbook.Path. 36. Protože opět nechceme, aby nám tzv. blikala obrazovka při běhu makra, na další řádek zapíšeme Application.ScreenUpdating = False 37. Na dalším řádku už zapíšeme příkaz k otevření příslušného sešitu Workbooks.Open Filename:=Cesta & "\" & "prijmy_vystup-kt.xlsx". 38. Sešit prijmy_vystup-kt.xlsx chceme mít sice otevřen, chceme ho ale nechat na pozadí, na další řádek zapíšeme proto příkaz Workbooks("prijmy_kt.xlsm").Activate, čímž opět aktivujeme sešit s kontingenční tabulkou. 39. Na závěr tohoto makra opět povolíme problikávání obrazovky, a to zápisem Application.ScreenUpdating = True na další řádek. 40. Budeme chtít, aby se tato dvě makra, tedy makro Prij_Vyst_Otev a makro Prij_Prech provedla automaticky při otevření sešitu prijmy_kt.xlsm. To zajistíme tak, že v editoru jazyka VBA otevřeme okno pro psaní kódu pro samotný sešit. 41. Z levé vyklápěcí nabídky v záhlaví tohoto okna vybereme volbu Workbook a do míst, kam se nám automaticky umístí kurzor zapíšeme názvy obou maker, tzn. na první řádek Prij_Vyst_Otev a na druhý řádek Prij_Prech. Pořadí tohoto zápisu je zcela zásadní! Tím se tato dvě makra spustí automaticky po otevření sešitu prijmy_kt.xlsm. Nyní ještě přejdeme do listu pomoc souboru prijmy_kt.xlsm. Pomocí klávesové zkratky ctrl+s soubor uložíme. Zavřeme všechny soubory Excelu a spustíme soubor prijmy_kt.xlsm, abychom si makra vyzkoušeli. Po opětovném otevření makra automaticky proběhnou, což poznáme mj. dle toho, že kurzor je teď na listu kt v buňce C8. 8
42. Oba soubory Excelu můžeme zavřít. Export dat z Accessu do Excelu 43. Nyní si opět otevřeme soubor evidence.accdb, pomocí klávesové zkratky levý alt+f11 se přesuneme do editoru VBA a zapíšeme si do našeho modulu pracovni další makro, konkrétně s názvem Export. 44. I v tomto makru si zadeklarujeme proměnnou a definujeme její obsah, tj.: Dim Cesta As String Cesta = CurrentProject.Path 45. Dále zapíšeme příkaz DoCmd.OutputTo acoutputquery, "prijmy_d", acformatxlsx, Cesta & "\prijmy_vystup-kt.xlsx", False, který vyexportuje data z tabulky prijmy do souboru prijmy_vystup-kt.xlsx. Poslední parametr False tohoto příkazu zajistí, aby se soubor prijmy_vystup-kt.xlsx neotevřel. 46. Za toto makro si napíšeme další makro s názvem Prijmy_Kt_zobraz. 47. V tomto novém makru si deklarujeme dvě proměnné, konkrétně: Dim Excel As Object Dim Cesta As String. 48. Proměnná Cesta bude mít tentokrát trochu odlišnou náplň, a to Cesta = CurrentProject.Path & "\prijmy_kt.xlsm". 49. Na další řádek zapíšeme Set Excel = CreateObject("Excel.Application"), což proměnnou Excel nastaví jako tvůrce objektu aplikace Excel. 50. Na další řádky si zapíšeme následující zápis: With Excel.Visible = True.Workbooks.Open (Cesta) End With 51. Tato dvě vytvořená makra přiřadíme nyní k události stisknutí u tlačítka Přehled (které je vnitřně pojmenováno jako prehled ) formuláře prijmy souboru 9
evidence.accdb, a to tím. To učiníme tak, že v editoru jazyka VBA otevřeme okno pro psaní kódu pro formulář prijmy a analogicky podle bodu 12 zapíšeme názvy obou maker v pořadí Export, Prijmy_Kt_Zobraz. 52. Stiskem tlačítka Přechod si makra vyzkoušíme. 53. Po přechodu do sešitu prijmy_kt.xlsx bychom ještě chtěli, aby bylo možné pomocí tlačítka Databáze přejít zpět do Accessu a Excel zavřít. Napíšeme si proto poslední makro s názvem Konec do modulu pracovni Excelu. Toto makro bude obsahovat následující příkazy: Application.ShowWindowsInTaskbar = True, který umožní opět zobrazit všechna okna na hlavním panelu Windows; Application.Quit, který ukončí aplikaci; Application.DisplayAlerts = False, který zamezí zobrazení systémového dialogu s dotazem na uložení sešitu Excelu (sešit nebude uložen); Application.ActivateMicrosoftApp xlmicrosoftaccess, který opět aktivuje aplikaci Access s otevřeným souborem evidence.accdb 54. Makro Konec přiřadíme tlačítku Databáze. To zajistíme tak, že v editoru jazyka VBA otevřeme okno pro psaní kódu pro list kt. Z levé vyklápěcí nabídky vybereme volbu databaze, což je interní název tlačítka Databáze. Do míst, kam se přemístí kurzor, zapíšeme Konec a pomocí klávesové zkratky ctrl+s soubor uložíme. 55. Uložíme všechny soubory a zavřeme je. Poté otevřeme soubor evidence.accdb a funkcionalitu si vyzkoušíme. Na závěr je nutné podotknout, že celou aplikaci vždy otevřeme pouze a jenom spuštěním souboru evidence.accdb, ostatní soubory se buď nespouštějí nebo se spouštějí pomocí tlačítek přímo v aplikaci! 56. To je vše. 10
Použité informační zdroje 1. WALKENBACH, John. Microsoft Excel 2003 : programování ve VBA. 1. vyd. Brno : Computer Press, 2006. 867 s. ISBN 80-251-0911-9. 2. HELD, Bernd. Access VBA : velká kniha řešení. 1. vyd. Brno : Computer Press, 2006. 639 s. ISBN 80-251-1112-1. 11