2. fogás Utazás a makrók birodalmába Gyorstalpaló tanfolyam, amelynek során meggyõzõdhetünk arról, milyen sokat segíthetnek a makrók a fárasztó és idõrabló feladatok automatizálásában. A Word 6-os és azutáni változataiban lehetõségünk van makrók, vagyis rövid, feladatok megoldását automatizáló programok írására, rögzítésére és lejátszására. Maga a makró kifejezés a makróparancs elnevezésbõl ered, ami parancsok egy ütemben végrehajtott sorozatára utal. Jellemzõen rögzítünk egy parancssorozatot, nevet adunk neki, majd újra és újra visszajátsszuk, amikor szükség van rá. Természetesen a Word makrói is használhatók ezen a módon, de ennél jóval többre is képesek. A Word makrók nyelve a Visual Basic for Applications, vagy VBA. Ez azt jelenti, hogy a program a rögzített makrókat erre a nyelvre fordítja, így késõbb megvizsgálhatjuk és szerkeszthetjük õket. A VBA a BASIC programnyelvek családjába tartozik, következésképpen könnyebben kezelhetõ, mint sok más nyelv, például a C vagy a Java. Más nyelvekhez hasonlóan azonban ahhoz, hogy igazán elsajátítsuk a használatát, sokat kell gyakorolnunk. Könyvünk szûkre szabott keretei nem adnak teret egy teljes VBA-bevezetõ kurzusnak; mindössze arra vállalkozhatunk, hogy bemutassuk, hogyan készíthetünk a késõbbiekben látottakhoz hasonló makrókat. Tipp A Word makrók kimerítõ tárgyalását megtalálhatjuk az O Reilly gondozásában megjelent Writing Word Macros címû könyvben. 2
10 Építõkockák A könyvben megjelenõ, valamint a rögzített makrók legtöbbje az eljárásokra (Sub) épül. Ezek mindegyike az alábbi sorral kezdõdik: Sub MakróNév A MakróNév itt értelemszerûen a makró neve. Az eljárások kivétel nélkül a következõ sorral érnek véget: End Sub A Word számára kiadott utasítások e két sor között kapnak helyet. Minderre a fõzés folyamata nagyszerû párhuzamot kínál. Gondoljunk úgy a makrókra, mint receptekre! Az elején felsoroljuk a hozzávalókat, majd a teendõk következnek, amelyekkel a hozzávalók halmazából valami ehetõt varázsolunk az asztalra. Egyes esetekben receptünket több kisebb receptre oszthatjuk egy a hús elkészítéséhez, egy a szószhoz, így egyszerûbbé válik a mûveletek követése. A makrók hasonlóképpen mûködnek. Figyeljük meg az alábbi példa elején a hozzávalók felsorolását, majd a kódot, ami ezek segítségével elvégzi a teendõket: Sub CountCommentsByBob( ) Dim ocomment As Comment Dim icommentcount As Integer Dim doc As Document icommentcount = 0 Set doc = ActiveDocument For Each ocomment In doc.comments If ocomment.author = "Bob" Then icommentcount = icommentcount + 1 End If Next ocomment MsgBox "Bob made: " & icommentcount & " comments" End Sub Ennyi elmélet után lássuk végre, hogyan is mûködnek makróink a Word dokumentumokban! Helló, Világ! 2 A számítástechnikai könyvekben hagyománnyá vált, hogy az elsõ egyszerû példaprogram a Helló, Világ! kiáltással adja tudtára a világnak létezését. A Word VBA-ban ez a programocska valahogy így fest: Sub HelloWorld MsgBox "Hello, World" End Sub
1. fejezet A Word kulisszái mögött 11 E makró létrehozásához nyissuk meg a Makrók párbeszédablakot az Eszközök, Makró, Makrók paranccsal. Az ablak alján található Makró helye lenyíló listában megszemlélhetjük, mely dokumentumok és sablonok vannak megnyitva ezekben tárolhatjuk makróinkat (lásd az 1.11. ábrát). A Minden aktív sablon és dokumentum választásával makrónkat a Normal.dot sablonba mentjük. 1.11. ábra Válasszuk ki, hol tároljuk a makrót Ez után írjuk be a Makrónév mezõbe a HelloWorld nevet, és a Létrehozás gombra kattintva hozzuk létre új makrónkat (lásd az 1.12. ábrát). 1.12. ábra Hozzunk létre új makrót a Makrók párbeszédablakban 2
12 E gomb megnyomása után a Word három mûveletet végez: 1. Készít egy NewMacros nevezetû új modult a Normal sablonban, amely makrónk kódját tartalmazza majd. 2. Elindítja a Visual Basic szerkesztõt (Visual Basic Editor). 3. A Word automatikusan megadja a makró elsõ és utolsó sorát, valamint néhány megjegyzést is készít a makróhoz. (Ezek a megjegyzések másoknak nyújtanak segítséget a program megértésében. A VBA-ban a megjegyzések mindig aposztróffal kezdõdnek.) A Visual Basic szerkesztõben már láthatjuk is makrónk vázát (1.13. ábra). A jobb felsõ részen elhelyezkedõ projektböngészõben (Project Explorer) megjelenik minden megnyitott dokumentum és sablon, köztük az esetleges bõvítmények is (ilyen például az MSWordXML ToolBox [92. fogás]). Vegyük észre, hogy a program kiemeli a Normal sablon Modules részében a NewMacros modult. 1.13. ábra A Visual Basic szerkesztõ 2 A makró elkészítéséhez vigyük a kurzort az End Sub feletti üres sorba, és írjuk be a következõt: MsgBox "Hello, World!" Most már futtathatjuk makrónkat az eszköztár Lejátszás gombjával (zöld háromszög). Eredményként az 1.14. ábrán látható párbeszédablakot kapjuk.
1. fejezet A Word kulisszái mögött 13 1.14. ábra Üdvözlet elsõ makrónktól Ha a Normal sablonban, ugyanebben a modulban további makrókat szeretnénk készíteni, egyszerûen kezdjünk egy új sort az End Sub után, és írjuk be a kódot. Ha más makrókból szeretnénk kódot beilleszteni, a Visual Basic szerkesztõ erre is lehetõséget ad. A makrók rendszerezése és hibáinak megkeresése Amennyiben makróink rendezéséhez újabb modult szeretnénk létrehozni, jelöljük ki a projektböngészõben azt a sablont vagy dokumentumot, ahová a modult helyezni szeretnénk, majd válasszuk az Insert, Module (Beszúrás, Modul) menüpontot. Az így készített modulok Module1, Module2 és ezekhez hasonló nevet kapnak (lásd az 1.15. ábrát). Ha más nevet szeretnénk nekik választani, a projektböngészõ alatt található Properties (Tulajdonságok) ablakban megtehetjük (lásd az 1.13. ábrát). 1.15. ábra Új modult illesztettünk a Normal sablonba Ha meg szeretnénk szüntetni vagy legalábbis észrevehetõvé tenni a programhibák elsõ számú forrását, az elgépelést, modulunkat feltétlenül kezdjük az alábbi sorral: Option Explicit Ez a kódsor arra utasítja a Wordöt, hogy gyõzõdjön meg arról, valóban meghatároztuk-e a kódban használt változókat. Visszatérve a fõzéshez, 2
14 ez olyan, mint mikor a receptet átolvasva meggyõzõdünk arról, hogy minden, amit felhasználtunk, megjelenik a hozzávalók listájában. Ha futtatni próbálunk egy makrót, amelynek egyik változóját elírtuk, a Word figyelmeztet, és kiemeli a szóban forgó változót (1.16. ábra). 1.16. ábra A Word segíthet makróink hibáinak felkutatásában Ha végeztünk a makró szerkesztésével, a File, Close and Return to Microsoft Word (Bezárás és visszatérés a Wordbe) menüponttal térjünk vissza a Wordhöz. Makrók futtatása Ha futtatni szeretnénk egy makrót a Wordbõl, válasszuk az Eszközök, Makró, Makrók menüpontot, válasszuk ki makrónkat a kapott listából, majd nyomjuk meg az Indítás gombot (lásd az 1.17. ábrát). 2 Ha gyakrabban használunk egy makrót, érdemes eszköztárgombot vagy billentyûkombinációt rendelni hozzá. Ehhez válasszuk az Eszközök, Testreszabás menüpontot, kattintsunk a Parancsok fülre, és válasszuk a Kategóriák oszlop Makrók pontját (1.18. ábra). Keressük meg makrónkat a Parancsok oszlopban, majd húzzuk át egy eszköztárra vagy menüre. Miután elhelyeztük, jobb gombbal rákattintva megváltoztathatjuk a nevét, illetve képet rendelhetünk az eszköztárgombjához (lásd az 1.19. ábrát).
1. fejezet A Word kulisszái mögött 15 1.17. ábra Makró futtatása a Wordbõl 1.18. ábra A Makrók kategória kiválasztása a Testreszabás párbeszédablakban 1.19. ábra Az eszköztárra vagy menübe helyezett makró gombfeliratának megváltoztatása 2
16 Ha olyan makrócsaládot használunk, illetve hozunk létre, ami rendszeresen segít a munkánkban, érdemes elhelyeznünk õket egy Macros sablonban [50. fogás], amelyet a Word indulásakor automatikusan betölt. A szerkesztõ apró segítségei A Visual Basic szerkesztõ teljes értékû fejlesztõkörnyezet, amely különféle módokon segíti VBA kódunk szerkesztését. IntelliSense. A VBA kód írása közben a szerkesztõ segít az utasítások nevének kiegészítésében (lásd az 1.20. ábrát). 1.20. ábra A Visual Basic szerkesztõ felgyorsíthatja a kód beírását A lehetõségek listája általában automatikusan megjelenik a kód beírása közben, de a CTRL+SZÓKÖZ billentyûkombinációval bármikor külön kérhetjük is ezt a listát. Az Immediate ablak. Az Immediate ablakban lehetõségünk van egyes utasítások azonnali végrehajtására. Ha egy utasítás elé a kódban kérdõjelet írunk, eredménye megjelenik az Immediate ablakban (lásd az 1.21. ábrát). 2 1.21. ábra Az Immediate ablak használata
1. fejezet A Word kulisszái mögött 17 Az Immediate ablak rendkívül jól használható a makrók tesztelésénél. Írjuk be például az alábbi sort egy makró kódjába: Debug.Print KiírandóKarakterlánc A KiírandóKarakterlánc kifejezést helyettesítsük egy karakterlánccal vagy egy karakterlánc értékû változóval, amelyen rajta szeretnénk tartani a szemünket. A változó aktuális értéke megjelenik az Immediate ablakban. Ezt a módszert mutatja be az 1.22. ábra. Kódellenõrzés lépésrõl lépésre. Makrónk tesztelésekor lehetõségünk van arra is, hogy lépésrõl lépésre futtassuk a kódot. A Word ilyenkor egy kódsor végrehajtása után jelzésünkre vár a továbbhaladáshoz. Ezzel lelassítjuk a makró futását, így könnyebben értelmezhetjük az eseményeket. Ha ilyenkor egy változó fölé helyezzük az egérmutatónkat, a Word egy buborékban megjeleníti a változó aktuális tartalmát. A lépésrõl lépésre haladáshoz helyezzük el valahol a mutatót a makró kódjában, és nyomjuk le az F8 billentyût. Ettõl kezdve az F8 megnyomásával léphetünk a következõ sorra. A következõ végrehajtandó sort a program sárgával jelöli, ráadásként baloldalt egy nyíl is megjelenik a kód mellett (lásd az 1.22. ábrát). 1.22. ábra A Visual Basic szerkesztõben lépésenként is követhetjük makróink mûködését 2
18 A Word objektummodellje A Word VBA-ban a Word minden alkotórészének megfelel valamilyen objektum. Objektumok a dokumentumok, a bekezdések, sõt a betûtípusok nevei is. Ráadásul ezek az objektumok kapcsolatban állnak egymással vizsgálatuk és módosításuk a makróprogramozás valódi alapja. A Word objektummodelljének böngészéséhez válasszuk a Visual Basic szerkesztõben a View, Object Browser (Megjelenítés, Objektumböngészõ) menüpontot. Az Object Browser elsõ látásra ijesztõ lehet, de ahogy belejövünk a makróprogramozásba, láthatjuk majd, milyen nélkülözhetetlen segítséget nyújt a Word összetevõinek szabályozásában és feladatainak automatizálásában. Az Object Browsert az 1.23. ábrán mutatjuk be. 1.23. ábra A VBA Object Browser használata 2
154 43. fogás Automatikus kereszthivatkozások A Kereszthivatkozás párbeszédablak használata különösen hosszabb dokumentumokban nem valami kényelmes, hiszen egyidejûleg csak pár címsort láthatunk. A következõkben megmutatjuk, hogyan készíthetünk kereszthivatkozásokat anélkül, hogy fel kellene keresnünk ezt a szûkös párbeszédablakot. Akárki is találta ki, hogy a Word Kereszthivatkozás párbeszédablaka (Beszúrás, Kereszthivatkozás vagy Beszúrás, Hivatkozás, Kereszthivatkozás) egyszerre csak kilenc elemet jeleníthet meg, nem igazán gondolkodott felhasználóbarát módon. A hosszabb dokumentumok ugyanis általában kilencnél több címsort, feliratot, vagy más, hivatkozásra csábító elemet tartalmaznak. A kereszthivatkozás létrehozása sokszor annyiból áll, hogy egy statikus szövegrészletet kijelölünk, majd dinamikus hivatkozássá alakítjuk úgy, hogy a Kereszthivatkozás párbeszédablak megfelelõ elemével helyettesítjük (lásd a 4.26. ábrát). Mivel azonban egyszerre csak kilenc elemet láthatunk a párbeszédablakban, hamar görgetõrobotnak érezhetjük magunkat. Ráadásul a helyzet a dokumentum terjedelmének növekedtével csak romlik, hiszen egyre több kereszthivatkozásra van szükség, és ezek megtalálása egyre hosszadalmasabb ebben az alulméretezett párbeszédablakban. 4.26. ábra A Kereszthivatkozás párbeszédablakban egyszerre csak kilenc elemet tekinthetünk meg 43 A következõkben bemutatjuk, miként készíthetünk a VBA segítségével automatikus kereszthivatkozásokat a címsorokra. Programunk összehasonlítja a kijelölt szövegrészletet a dokumentum címsoraival, és ha egyezést talál, létrehoz egy kereszthivatkozást.
4. fejezet A szerkesztés nagyágyúi 155 Hivatkozás Word-módra A következõkben bemutatott eljárás a Word VBA GetCrossReference- Items függvényét használja, amely megadja a hivatkozások lehetséges célpontjait a dokumentumban. Mivel a Word folyamatosan frissíti és indexeli ezt a listát, elérése igen gyors. Mindennek eredményeképpen az itt bemutatott makró gyorsabb, mint a következõ részben készített eljárás a sebességnek azonban ára van: csak olyan elemekre hivatkozhatunk, amelyeket a Word erre alkalmasnak tart (például a beépített címsorstílusokkal formázott címsorokra). Ha azonban saját címsorstílusokat is alkalmazunk, mondjuk a keretes anyagokban, az itt feltüntetett címek kívül esnek a Word látókörén. Helyezzük el az alábbi makrót egy szabadon választott sablonban [50. fogás], majd indítsuk el az Eszközök, Makró, Makrók párbeszédablakról (de elhelyezhetjük a megfelelõ parancsot egy eszköztáron vagy menüben is [1. fogás]). Ha aktuális kijelölésünk egynél több bekezdést tartalmaz, a makró egyszerûen kilép, nem végez semmilyen mûveletet. Sub InsertAutoXRef( ) Dim sel As Selection Dim doc As Document Dim vheadings As Variant Dim v As Variant Dim i As Integer Set sel = Selection Set doc = Selection.Document ' Kilép, ha a kijelölésben több bekezdés szerepel If sel.range.paragraphs.count <> 1 Then Exit Sub ' Összezárja a kijelölést, ha szóköz vagy bekezdésjel áll ' valamelyik végén sel.movestartwhile cset:=(chr$(32) & Chr$(13)), _ Count:=sel.Characters.Count sel.moveendwhile cset:=(chr$(32) & Chr$(13)), _ Count:=-sel.Characters.Count vheadings = doc.getcrossreferenceitems(wdreftypeheading) i = 1 For Each v In vheadings If Trim (sel.range.text) = Trim (v) Then sel.insertcrossreference _ referencetype:=wdreftypeheading, _ referencekind:=wdcontenttext, _ 43
156 referenceitem:=i Exit Sub End If i = i + 1 Next v MsgBox "Couldn't match: " & sel.range.text End Sub Makrónknak két lényeges gyengéje is van. Elõször is, ha több címsor is megfelel a kijelölt szövegnek, a kód hivatkozást hoz létre az elsõhöz, a többit pedig figyelmen kívül hagyja. Ez gondot okozhat, ha több, azonos szövegû címsorunk is van ilyen például e könyv majdnem minden fogásánál az A kód címsor. Másodszor, a kód semmiféle védelmet nem biztosít az önhivatkozások ellen. Ha a talált egyezés éppen a kijelölt szöveg, a hivatkozás helyettesíti a hivatkozó részt, így végül megszakadt hivatkozást kapunk (lásd a 4.27. ábrát). 4.27. ábra Az önhivatkozás eredménye egy megszakadt hivatkozás A szöveg akaratlan törlése ilyen módon a Word Kereszthivatkozás párbeszédablakában is fenyeget. Önhivatkozás készítésénél a Word üzenetben értesít arról, hogy hivatkozásunk üres de csak miután már törölte a szövegrészletet. Egy hatékonyabb hivatkozási módszer Az alábbi eljárás sebességében nem veheti el a versenyt a fenti kóddal, de rugalmassága miatt alkalmasabb kiindulópont lehet saját ötleteink megvalósításához. 43 Kódunk nem ragad le a Word beépített címsorstílusainál minden bekezdést átvizsgál a kijelölt szöveggel való egyezést keresve. Ez viszont azt jelenti, hogy olyan címekre is hivatkozhatunk, amelyeket felhasználói stílussal formáztak. Az eljárás, eltérõen az elõzõtõl, ellenõrzi azt is, hogy az egyezés nem maga a kijelölt szöveg, így kizárja az önhivatkozás lehetõségét.
4. fejezet A szerkesztés nagyágyúi 157 A kód öt eljárásra bontható: a MakeAutoXRef makróra és ennek támogató eljárásaira, amelyek a hivatkozás készítéséhez szükséges mûveleteket végzik el. Helyezzük el mind az öt eljárást egy szabadon választott sablonban [50. fogás], és a mûvelet elvégzéséhez futtassuk a MakeAutoXRef makrót. Kezdjük a MakeAutoXRef bemutatásával, amely a késõbb megadott eljárásokra támaszkodva átvizsgálja a dokumentum összes bekezdését. Ha talál olyan bekezdést, amely megegyezik a kijelölt szövegrészlettel, létrehoz az egyezés körül egy könyvjelzõt, és a kijelölt szöveget egy hivatkozással helyettesíti erre a könyvjelzõre. Ha az egyezõ bekezdésre már más is hivatkozik, a meglevõ könyvjelzõt veszi használatba. Sub MakeAutoXRef( ) Dim sel As Selection Dim rng As Range Dim para As Paragraph Dim doc As Document Dim sbookmarkname As String Dim sselectiontext As String Dim lselectedparaindex As Long Set sel = Selection Set doc = sel.document If sel.range.paragraphs.count <> 1 Then Exit Sub lselectedparaindex = GetParaIndex(sel.Range.Paragraphs.First) sel.movestartwhile cset:=(chr$(32) & Chr$(13)), _ Count:=sel.Characters.Count sel.moveendwhile cset:=(chr$(32) & Chr$(13)), _ Count:=-sel.Characters.Count sselectiontext = sel.text For Each para In doc.paragraphs Set rng = para.range rng.movestartwhile cset:=(chr$(32) & Chr$(13)), _ Count:=rng.Characters.Count rng.moveendwhile cset:=(chr$(32) & Chr$(13)), _ Count:=-rng.Characters.Count If rng.text = sselectiontext Then If Not GetParaIndex(para) = lselectedparaindex Then sbookmarkname = GetOrSetXRefBookmark(para) If Len(sBookmarkName) = 0 Then MsgBox "Couldn't get or set bookmark" Exit Sub End If sel.insertcrossreference _ referencekind:=wdcontenttext, _ 43
158 referenceitem:= _ doc.bookmarks(sbookmarkname), _ referencetype:=wdreftypebookmark, _ insertashyperlink:=true Exit Sub Else MsgBox "Can't self reference!" End If End If Next para End Sub A kód félkövérrel kiemelt része felelõs a hivatkozás elkészítéséért. Vegyük észre a hasonlóságot az elõzõ részben bemutatott eljárással. A segédeljárások. Az alábbi függvény eltávolít az átadott karakterláncból minden olyan karaktert, ami nem szerepelhet a Word könyvjelzõiben (a szóközöket kivéve ezeket egy másik eljárás aláhúzásokra cseréli): Dim i As Integer For i = 33 To 255 Select Case i Case 33 To 47, 58 To 64, 91 To 96, 123 To 255 str = Replace(str, Chr (i), vbnullstring) End Select Next i RemoveInvalidBookmarkCharsFromString = str End Function A következõ függvény az átadott karakterláncból egy érvényes könyvjelzõnevet készít, az XREF elõtaggal, valamint egy az egyediséget biztosító ötjegyû véletlen számmal [68. fogás] kiegészítve. Így például az Ez egy cím címsorból valami ilyesmi lesz: XREF56774_- Ez_egy_cím. Ezzel sokkal könnyebb dolgozni, mint a Word kereszthivatkozó könyvjelzõinél alkalmazott _Ref45762234 és hasonló nevekkel. 43 Function ConvertStringRefBookmarkName(ByVal str As String) _ As String str = RemoveInvalidBookmarkCharsFromString(str) str = Replace(str, Chr$(32), "_") str = "_" & str str = "XREF" & CStr(Int(90000 * Rnd + 10000)) & str ConvertStringRefBookmarkName = str End Function
4. fejezet A szerkesztés nagyágyúi 159 A következõ függvény egyszerûen meghatározza a bekezdés sorszámát a dokumentumban (vagyis például a dokumentum második bekezdésének sorszáma 2): Function GetParagraphIndex(para As Paragraph) As Long GetParagraphIndex = _ para.range.document.range(0, _ para.range.end).paragraphs.count End Function Végezetül, utolsó függvényünk kereszthivatkozó könyvjelzõt hoz létre azokban a bekezdésekben, amelyek nem tartalmaznak könyvjelzõt, és visszatér e könyvjelzõ nevével. Ha a bekezdés már rendelkezik könyvjelzõvel, a függvény ennek nevét adja vissza. Function GetOrSetXRefBookmark(para As Paragraph) As String Dim i As Integer Dim rng As Range Dim sbookmarkname As String If para.range.bookmarks.count <> 0 Then For i = 1 To para.range.bookmarks.count If InStr(1, para.range.bookmarks(i).name, "XREF") _ Then GetOrSetXRefBookmark = _ para.range.bookmarks(i).name Exit Function End If Next i End If Set rng = para.range rng.moveend unit:=wdcharacter, Count:=-1 sbookmarkname = ConvertStringRefBookmarkName(rng.Text) para.range.document.bookmarks.add _ Name:=sBookmarkName, _ Range:=rng GetOrSetXRefBookmark = sbookmarkname End Function Futtatás Makrónk nem sok idõt takarít meg, ha eléréséhez egy menüben kell keresgélnünk, ezért érdemes egy ügyes billentyûkombinációt rendelnünk hozzá. Ehhez válasszuk az Eszközök, Testreszabás menüpontot, és nyomjuk meg a Billentyûparancs gombot. Változtatásainkat mentsük ugyanabba a sablonba, ahol a kódot is elhelyeztük. Válasszuk a Kategóriák oszlop Makrók pontját, majd a Parancsok oszlopban keressük ki a MakeAutoXRef makrót. Ez után már csak ki kell választanunk a párbeszédablakban a kívánt billentyûkombinációt, és hozzárendelnünk a makróhoz. 43
160 44. fogás Rugalmasabb kereszthivatkozások A Word kereszthivatkozásokat kezelõ felülete meglehetõsen szûk körû lehetõségeket kínál. A következõkben bemutatjuk, hogyan tágíthatjuk a mozgásterünket. A Word Kereszthivatkozás párbeszédablaka nem túl sok dokumentumelemhez enged kereszthivatkozást készíteni lehetõségeink teljes listáját a 4.28. ábra mutatja. 4.28. ábra A Word beépített kereszthivatkozási típusai De mi a helyzet akkor, ha olyan elemekre szeretnénk hivatkozni, amelyek nem találhatók meg a listában? Ha olyan sablonnal dolgozunk, amely számos különbözõ címsortípust alkalmaz, köztük olyanokat is, amelyek nem szerepelnek a Word beépített stílusai között, igen nehéz dolgunk lesz, ha hivatkozni szeretnénk rájuk. A következõkben bemutatjuk, miként készítsük el saját kereszthivatkozási párbeszédablakunkat, valami olyasmit, mint amit a 4.29. ábrán láthatunk. A bal oldali oszlop felsorolja a dokumentum összes bekezdésstílusát, a jobb oldali pedig azokat a bekezdéseket, amelyek az adott stílust alkalmazzák. Amellett, hogy többféle stílusú bekezdésre enged hivatkozni, új párbeszédablakunk darabszámban is több elemet képes megjeleníteni, ami rengeteg görgetéstõl kímélhet meg. Tipp Ha más Word dokumentumra mutató kereszthivatkozást szeretnénk létrehozni, lapozzuk fel a Kereszthivatkozások dokumentumok között [78. fogás] címszót. 44 A párbeszédablak felépítése Az alábbiakban bemutatjuk, hogyan készíthetjük el a 4.29. ábrán látható párbeszédablakot. Az egyszerûség kedvéért a díszítõ elemeket, mint a listamezõk címeit, most elhagytuk, így ez a párbeszédablak mindössze az alap, amelybõl kiindulva elkészíthetjük a nekünk tetszõ változatot.
4. fejezet A szerkesztés nagyágyúi 161 Mindenekelõtt válasszuk az Eszközök, Makró, Visual Basic Editor menüpontot. Jelöljünk ki egy szabadon választott sablont [50. fogás] a Project Explorerben, és válasszuk az Insert, UserForm (Beszúrás, Felhasználói ûrlap) menüpontot. 4.29. ábra Egy jobb párbeszédablak a kereszthivatkozások kezelésére A Properties (Tulajdonságok) ablakban adjuk az ûrlapnak az ufxrefs nevet, címsora pedig legyen Cross Reference (Kereszthivatkozás). A bal alsó sarokban található méretezõfogantyút megragadva méretezzük át az ûrlapot úgy, hogy nagyjából 380 képpont széles és 260 képpont magas legyen. Ezt követõen az eszközkészketbõl (Toolbox) húzzunk két listamezõt az ûrlapra, a 4.30. ábrán látható módon. A Properties ablakban adjuk a bal oldalinak az lbstyles, a jobb oldalinak pedig az lbparas nevet. Végül helyezünk el az elsõ listamezõ alatt két CommandButton gombot. Legyen a nevük cmbinsert és cmbcancel, feliratuk pedig Insert (Beszúrás) és Cancel (Mégse). A kód Kódunk néhány, az Automatikus kereszthivatkozások [43. fogás] fogásnál megismert segédfüggvényre épül, nevezetesen az alábbiakra: GetOrSetXRefBookmark ConvertStringToXRefBookmarkName GetParagraphIndex 44
162 Fontos, hogy ezek az eljárások ugyanabban a sablonban legyenek, ahol a felhasználói ûrlap. 4.30. ábra Az ufxrefs ûrlapra magunk rajzolhatjuk fel a listamezõket Továbbra is nyitva tartva a felhasználói ûrlapot, a View, Code (Nézet, Kód) menüponttal lépjünk be az ûrlap kódmoduljába, és helyezzük el benne az alábbi kódot: Option Explicit Private colparagraphdata As Collection Private Sub cmbcancel_click( ) Unload Me End Sub Private Sub UserForm_Initialize( ) Dim v As Variant Dim sty As Style For Each sty In ActiveDocument.Styles If sty.type = wdstyletypeparagraph Then lbstyles.additem sty.namelocal End If Next sty lbstyles.selected(0) = True End Sub 44 Private Sub lbstyles_change( ) Dim col As Collection Dim para As Paragraph Dim k As Integer Set colparagraphdata = New Collection lbparas.clear k = 1 For Each para In ActiveDocument.Paragraphs If para.style = lbstyles.value Then
4. fejezet A szerkesztés nagyágyúi 163 Set col = New Collection col.add Key:="Index", Item:=k col.add Key:="Text", Item:=Left(para.Range.Text, _ para.range.characters.count - 1) colparagraphdata.add Item:=col lbparas.additem (col("text")) Set col = Nothing End If k = k + 1 Next para End Sub Private Sub cmbinsert_click( ) Dim lselectedparaindex As Long Dim sbookmarkname As String Dim para As Paragraph lselectedparaindex = colparagraphdata(lbparas.listindex + _ 1)("Index") Set para = ActiveDocument.Paragraphs(lSelectedParaIndex) sbookmarkname = GetOrSetXRefBookmark(para) If Len(sBookmarkName) = 0 Then MsgBox "Couldn't get or set bookmark" Unload Me End If Selection.InsertCrossReference _ referencekind:=wdcontenttext, _ referenceitem:=activedocument.bookmarks(sbookmarkname), _ referencetype:=wdreftypebookmark, _ insertashyperlink:=true Unload Me End Sub Ahogy új stílust választunk az lbstyles listamezõben, a program kiüríti a colparagraphdata gyûjteményt, majd feltölti azon bekezdések adataival, amelyek ezt az új stílust használják. Példánkban ezek az adatok: a bekezdés helyzete a dokumentumban (sorszáma), valamint a bekezdés szövege. Futtatás Helyezzük el az alábbi sorokat az egyik kódmodulban, a felhasználói ûrlapot tartalmazó sablonban: Sub ShowBetterCrossReferenceDialog ufxrefs.show End Sub 44
164 A párbeszédablak megjelenítéséhez futtassuk a ShowBetterCrossReferenceDialog makrót az Eszközök, Makró, Makrók menübõl, vagy helyezzük el egy menüben vagy eszköztáron [1. fogás]. Ha kijelölünk egy bekezdést, és az Insert gombra kattintunk, a program egy könyvjelzõt hoz létre e bekezdés körül, és az aktuális kijelölést egy erre a könyvjelzõre mutató kereszthivatkozással helyettesíti. A könyvjelzõt és a hivatkozást a 4.31. ábrán láthatjuk, továbbá az ábra alján megfigyelhetjük a megfelelõ mezõkódot is. 4.31. ábra Kódunk ilyen könyvjelzõt és hivatkozást hoz létre Ha a bekezdés, amelyre hivatkozni szeretnénk, már szerepel hivatkozásban, a meglevõ könyvjelzõt használjuk, új nem jön létre. 44