Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Automatyzacja pracy z Wordem — pomysł na papier firmowy

Mój poprzedni wpis na temat VBA został przyjęty raczej pozytywnie, postanowiłem więc pójść za ciosem i przychylić się do próśb czytelników, rozwijając temat o przykłady kodu, które można wykorzystać do zautomatyzowania wstawiana nagłówków i stopek w dokumentach firmowych. Sam stosowałem te rozwiązania z powodzeniem. Zaczynałem od najprostszego wariantu i stopniowo doskonaliłem metodę, wzbogacając ją o nowe warianty i możliwości. Podobnie zamierzam postąpić w tym wpisie, zaczynając od najprostszego do zautomatyzowania przypadku.

Nagłówki w papierze firmowym

Temat papieru firmowego jest za pewne dobrze znany wszystkim pracującym. Polityka firmy w tym zakresie bywa różna. Jedni zamawiają gotowy papier firmowy w drukarni, inni zaś drukują na czystym papierze, wstawiając dane firmy w nagłówek dokumentu. To drugie rozwiązanie być może jest tańsze, ale z pewnością bardziej kłopotliwe. Każdorazowe wstawianie nagłówkowa do dokumentu jest z pewnością upierdliwe. Dokumenty można powielać, tworzyć nowy na bazie starego, posiadającego już nagłówek, ale to też nie jest rozwiązanie idealne. Może się bowiem zdarzyć, że uległy zmianie dane teleadresowe albo logo firmy i nagle mamy setki albo i tysiące dokumentów z nagłówkiem zawierającym nieaktualne dane. Mam swój sposób rozwiązujący ten problem. Być może to również nie jest rozwiązanie idealne i nie każdemu podpasuje, aczkolwiek warto się z nim zapoznać chociażby po to, aby poznać pewne techniki w pracy z makrami VBA i zainspirować się do własnych, być może lepszych rozwiązań.

Nagłówek jako zewnętrzny plik

Mój pomysł na papier firmowy opiera się na założeniu, że skoro dane z nagłówka mogą się zmieniać, to fajnie by było, gdybyśmy je edytowali tylko w jednym dokumencie, a nie we wszystkich zawierających nagłówki firmowe. Dlatego proponuję utworzyć taki dokument, nazwać go np. nagłówek.docx i zapisać w jakimś sensownym miejscu, które przez dłuższy czas nie będzie zmieniało swojego położenia. Jeśli nie mamy firmowego serwera, a korzystamy z wielu stanowisk z Wordem, możemy zapisać go np. w Dropboxie. Podobnie uczyniłbym z plikiem normal.dotm, w którym są zapisane nasze makra. Na każdym stanowisku z Wordem wskazałbym ścieżkę do pliku normal.dotm w Dropboxie, dzięki czemu, jeśli dokonamy zmiany w naszych makra, to będą one automatycznie zaktualizowane dla wszystkich stanowisk.

Nagłówek wygodnie formatuje się jako tabelę bez obramowań. Oczywiście każdy może zrobić po swojemu, wedle upodobań i przyzwyczajeń.
Teraz musimy napisać makro, które będzie nam wstawiać do dokumentu ten nagłówek. Makra VBA obsługują pewien zakres domyślnie zdefiniowanych zdarzeń. Oznacza to, że jeśli takowe zdarzenie zaistnieje, to automatycznie wywołuje ono nasze makro. Przykładem takiego zdarzenia może być otworzenie dokumentu w Wordzie. Takie makra mają z góry określone, zarezerwowane nazwy. Spotkałem się z kilkoma nazwami makr reagującymi na otwierany dokument. Z mojego doświadczenia wynika, że najlepiej spisuje się makro o nazwie AutoOpen. Szczerze mówiąc to nie wiem na czym polegają różnice między poszczególnymi makrami reagującymi na to samo zdarzenie, ale z doświadczenia wiem, że makro Document_Open wykrzacza się na próbie wejścia do nagłówka dokumentu, a AutoOpen nie. Teoretycznie różnica jest taka, że Document_Open umieszczane jest bezpośrednio w dokumencie, więc możemy jest stosować dla wybranego dokumentu, a AutoOpen wstawia się do modułu, a więc ma za zadanie działać globalnie. Nigdzie jednak nie znalazłem wyjaśnienia dlaczego Document_Open krzaczy się z operacjami na nagłówku, a AutoOpen nie.

Wstawianie dokumentu do nagłówka

Makro wstawiające nasz dokument z nagłówkiem do nagłówka każdego otwieranego dokumentu ma następujący kod:

Sub AutoOpen() ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range.InsertFile FileName:="C:\Users\MojaFirma\Desktop\nagłówek.docx", Range:="", _ ConfirmConversions:=False, link:=True, Attachment:=False End Sub

Jak widać nie jest to nic strasznie skomplikowanego. Z aktywnego (właśnie otworzonego) dokumentu wybieramy pierwszą sekcję (jeśli nie mamy w dokumencie podziału na sekcje, to zawsze mamy jedną sekcję), a w niej nagłówki z opcją podstawowego nagłówka (jednakowego dla wszystkich stron). W jego zakresie wstawiamy plik podając ścieżkę do uprzednio zapisanego pliku z nagłówkiem.

Może się zdarzyć, że chcemy mieć inny nagłówek na pierwszej stronie niż na innych. W takiej sytuacji należy dokonać kilku drobnych modyfikacji w kodzie. Po pierwsze musimy najpierw ustawić w dokumencie opcję, że nagłówek pierwszej strony ma być inny niż pozostałych. Następnie dla nagłówka pierwszej strony zamieniamy typ nagłówka z wdHeaderFooterPrimary na wdHeaderFooterFirstPage. Następnie wstawiamy pozostałe nagłówki z opcją wdHeaderFooterPrimary podając odpowiednią lokalizację do pliku.

Sub AutoOpen() ActiveDocument.PageSetup.DifferentFirstPageHeaderFooter = True ActiveDocument.Sections(1).Headers(wdHeaderFooterFirstPage).Range.InsertFile FileName:="C:\Users\Jarosław\Desktop\nagłówek.docx", Range:="", _ ConfirmConversions:=False, link:=True, Attachment:=False ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Range.InsertFile FileName:="C:\Users\Jarosław\Desktop\dalszeNagłówki.docx", Range:="", _ ConfirmConversions:=False, link:=True, Attachment:=False End SubDla osób znających język angielski nie jest tajemnicą, że w pierwszej linijce kodu ustawiamy ustawienia strony aktywnego dokumentu, a w nich nagłówek pierwszej strony innych od pozostałych stron.

Drukowanie z różnych szuflad drukarki

Niektóre firmy mogą chcieć korzystać z systemu hybrydowego - tzn. papier firmowy z drukarni z nadrukowanym kolorowym logo i własnoręcznie nadrukowywane dane teleadresowe firmy w nagłówku. Jeśli w takiej sytuacji będziemy chcieli mieć pierwszą stronę z logo firmowym, a pozostałe strony drukowane już na zwykłym papierze (cóż, oszczędności) to pojawia nam się kłopot drukowania. Normalnie musielibyśmy drukować oddzielnie pierwszą kartkę i oddzielnie resztę dokumentu, bo podejrzewam, że papier firmowy z logo będzie znajdować się w innej kieszeni drukarki. W takiej sytuacji można rozważyć drukowanie dokumentów za pomocą makra VBA. Istnieje możliwość określania w kodzie numerów stron, które mają zostać wydrukowane. Nie będę w tym wpisie wdawać się w szczegóły, ale podpowiem tylko że istnieje możliwość wyboru tacy drukarki z poziomu VBA. Dzięki temu możemy za jednym zamachem wydrukować cały dokument, przydzielając odpowiednie strony dokumentu odpowiednim tacom drukarki. Podpowiem tylko jak wygląda przykładowy wybór tacy:

ActiveDocument.PageSetup.FirstPageTray = wdPrinterUpperBin

Dywersyfikacja nagłówków

Nie każda firma ma jeden szablon nagłówka czy stopki dla wszystkich swoich dokumentów. Być może każdy dział ma swój oddzielny nagłówek, albo stosowane są różne nagłówki w zależności od rodzaju dokumentu. Może być też tak, że w pewnych dokumentach w ogóle nie chcemy stosować nagłówków. Nasze makro w obecnej postaci wstawia nagłówki do absolutnie każdego otwieranego dokumentu. Co gorsza, jeśli otworzymy jakiś dokument, który do tej pory nie posiadał nagłówka i nie chcemy zmieniać tego stanu rzeczy, to nasze makro wstawi go przy każdym otworzeniu i trzeba ręcznie go usuwać.

Rozwiązanie tego problemu jest bardzo proste. Trzeba powiedzieć naszemu skryptowi jak traktować poszczególne dokumenty. Najłatwiej jest, gdy poszczególne typy dokumentów są zapisane w różnych folderach. Podejrzewam, że większość osób posiada jakąś sensowną strukturę katalogów. Można ją wykorzystać do identyfikacji typów dokumentów.
Aby wykryć lokalizację z jakiej jest otwierany dokument możemy użyć następującego kodu:Sub AutoOpen() Dim Lokalizacja As String Lokalizacja = ActiveDocument.Path If (Lokalizacja = "D:\Dropbox\Produkcja") Then 'Kod wstawiający nagłówek do dokumentów działu produkcji End If End Sub

Jeżeli nasza struktura katalogów jest rozbudowana (a przeważnie właśnie tak jest) to możemy ustawić warunek na określony poziom w strukturze katalogów. Powiedzmy, że najwyższym poziomem katalogów, dla których chcemy zastosować dany typ nagłówka jest katalog produkcja. Obecna postać makra sprawdza lokalizację dokumentu, a nam bardziej by pasowało, aby skrypt sprawdzał czy lokalizacja danego dokumentu zawiera się w naszym folderze Produkcja.
W tym celu należy skorzystać z jakiejś wbudowanej funkcji VBA przetwarzającej ciągi znaków. Ja użyję funkcji InStr, która przyjmuje trzy argumenty: pozycję początkową, ciąg1 i ciąg2. Funkcja ta porównuje ze sobą dwa ciągi znaków i zwraca pozycję pierwszego pojawienia się drugiego ciągu w pierwszym ciągu. Jeśli drugi ciąg nie pojawia się w pierwszym ciągu, to zwraca 0. Jeśli więc mamy, że nasz pierwszy ciąg reprezentuje lokalizację otwieranego dokumentu, a nasz drugi ciąg to lokalizacja folderu Produkcja:
"D:\Dropbox\Produkcja", to jeśli ten otwierany dokument będzie mieć np. lokalizację: "D:\Dropbox\Produkcja\2014\Pisma" to funkcja zwróci wartość 1 (bo lokalizacja folderu Produkcja zawiera się w lokalizacji otwieranego dokumentu i zaczyna się od 1 znaku), a jeśli lokalizacja miałaby np. postać: "D:\Dropbox\Księgowość\2013\Wyliczenia" to funkcja zwróci 0.
Na tej podstawie możemy przebudować nasze makro do następującej postaci:Sub AutoOpen() Dim Lokalizacja As String Dim Produkcja As String Dim dokProdukcyjny As Integer Produkcja = "D:\Dropbox\Produkcja" Lokalizacja = ActiveDocument.Path dokProdukcyjny = InStr(1, Lokalizacja, Produkcja) If (Not dokProdukcyjny = 0) Then 'Kod wstawiający nagłówek do dokumentów działu produkcji End If End Sub

Można powiedzieć prościej, że sprawdzamy czy Lokalizacja otwieranego dokumentu zaczyna się od ciągu znaków "D:\Dropbox\Produkcja". Jeśli tak, to wiemy, że należy do dokumentu wstawić nagłówek typowy dla dokumentów produkcyjnych.

Podsumowanie

Makra VBA mają to do siebie, że w większości przypadków zaspakajają bardzo specyficzne potrzeby. Ciężko jest wymyślić usprawnienia, które mogłyby być przydatne dla każdego. Najlepiej jest poznać specyfikę pracy danej firmy, zaobserwować powtarzające się czynności, które dałoby się zautomatyzować lub w rozmowie z pracownikami odkryć czego im brakuje w pracy z Wordem na ich konkretnym stanowisku pracy. Patrząc z tej perspektywy na makra VBA mogę śmiało pokusić się o stwierdzenie, że najlepiej predysponowanymi osobami do pisania makr VBA, są sami pracownicy. Oczywiście, że można spotkać nawet całe aplikacje komercyjnie napisane w VBA (przeważnie na bazie Accessa lub Excela), ale w większości przypadków istnieje duże zapotrzebowanie na drobne usprawnienia, które stopniem trudności nie przerastają przeciętnego pasjonata komputerów. Dlatego zachęcam wszystkich do próbowania tworzenia takich usprawnień. Daje to wiele satysfakcji, a przy okazji ułatwia życie. 

windows porady programowanie

Komentarze

0 nowych
kwpolska   5 #1 05.11.2014 16:39

A co jest złego z szablonami worda (.dot/.dotx)?

kaisuj   10 #2 05.11.2014 18:19

@kwpolska: Nie ma nic złego. Szalony nie zapewnią Ci jednak opisanej we wpisie funkcjonalności. No chyba, że czegoś nie wiem, to rozwiń swoją myśl.

kilgour   8 #3 06.11.2014 10:31

Pytanie z czystej ciekawości: z iloma odmianami papieru firmowego masz problem rozwiązywany w VBA?

Buber82   3 #4 06.11.2014 13:14

Ja posiadam gotowy dokument na papier firmowy, jako szablon. Po prostu używam gotowca kiedy chcę coś mieć na firmowym w wersji elektronicznej i zapisuję jako nowy plik. Do reszty mam gotowy papier :)

kaisuj   10 #5 06.11.2014 13:48

@Buber82: Wszystko jest pięknie, jeśli takich dokumentów masz nie wiele. Ja pracowałem w firmie, gdzie było ich tysiące, a może nawet dziesiątki tysięcy. Stosowanie szablonu absolutnie nie wchodziło w grę, bo nowe dokumenty były tworzone na podstawie starych, ponieważ spora część treści była taka sama, jak w starych dokumentach. Były setki typów takich dokumentów. Było kilka typów nagłówków, ale co ważniejsze, po zmianie np. numeru telefonu w nagłówku, tworząc dokument na podstawie starego, dostawało się nieaktualne dane adresowe. Co gorsze ciągle ktoś zapominał je ręcznie poprawić i dokumenty były drukowane z nieprawidłowymi danymi. Makra rozwiązały wszystkie problemy.

_qaz7   6 #6 06.11.2014 14:10

Dobrym przykładem byłoby wypisywanie danych do pisma w Wordzie na podstawie danych np. z Accessa czy Excela czy jakiejś innej bazy mającej wsparcie w ODBC czy ADO. Przydane przy automatyzowaniu tworzenia korespondencji.

pocolog   11 #7 07.11.2014 08:34

Armata na muche. Kompletnie nie rozumiem po co zaciagac takie narzedzia do banalnych spraw. Od tego sa chociazby szablony w ktorych w latwy sposob ustawisz od marginesow i czcionki po stopke czy znak wodny.
Argument ze potrzeba setki szablonow? Od czego sa katalogi i nazwy plikow? Argument ze kazdy musi miec takie same a wprowadzone zmiany mozna latwo wprowadzac: to dropboksa mozna zaciagnac do trzymania makra i pliku ze stopkami a szablonu juz nie? ;)

kaisuj   10 #8 07.11.2014 08:53

@pocolog: W sytuacji, kiedy tworzysz dokument, na podstawie innego dokumentu, bo powtarza Ci się w nim spora część treści, szablony są kompletnie bezużyteczne. Nie rozumiem dlaczego czepiliście się tych szablonów, jakby to było antidotum na wszystkie problem. Otóż nie jest. Jak pracujesz z setkami typów dokumentów podobnych do siebie i ciągle je powielasz, to szablony są kompletnie bezużyteczne. Musiałbyś mieć szablon do każdego typu dokumentu, co jest dopiero armatą na muchę, jak to określiłeś. Moim zdaniem dużo prościej jest napisać raz proste makro i mieć problem z głowy. Szablon jest dobry tam, gdzie walisz ciągle to samo, a gdy masz bardzo zróżnicowane dokumenty, na których pracujesz, to się nie sprawdza.

arlid   14 #9 07.11.2014 09:10

Ciekawy pomysł, gdy mamy potrzebę tworzenia takich dokumentów przez wiele osób. To bardzo wtedy ułatwi sprawę :)

pocolog   11 #10 07.11.2014 12:16

@kaisuj: Dlaczego szablony w takim wypadku sa bezuzyteczne? Przecież do tego one są stworzone. Bezsensem dla mnie jest przerabianie istniejących dokumentów bo wtedy mogą pojawić sie błędy. Z dokumentu który jest często powtarzany robi się szablon i przy próbie jego otwarcia tworzy ci się nowy plik który uzupełniasz o niezbędne dane. Albo ja kompletnie nie zrozumiałem problemu który występuje u ciebie w firmie ;)

kaisuj   10 #11 07.11.2014 13:55

@pocolog: Przyjmijmy, że z dniem 1 stycznia zmieniamy dane w nagłówku. Owszem, możemy te dane zmienić także w szablonie i wszystkie nowe dokumenty tworzone na podstawie szablonu będą zawierały prawidłowe dane. A co z dokumentami, które zostały utworzone przed 1 stycznia? Nie koniecznie musi być tak, że dany dokument tworzymy i drukujemy tylko raz, a potem archiwizujemy i zapominamy. Może być tak, że raz na jakiś czas potrzebujemy go właśnie wydrukować. I wtedy musimy ręcznie zmieniać dane adresowe w tym nagłówku, bo został utworzony jeszcze ze starej wersji szablonu. Idę o zakład, że bardzo często ktoś zapomni poprawić dane i wydrukuje z błędem. Taka jest ludzka natura. Większość osób nawet nie sprawdziłaby tych danych, bo byłaby przyzwyczajona, że z szablonu wstawiają się dobre dane. I właśnie makro VBA robi to automatycznie za nas. Taka sytuacja może Ci się wydawać wydumana, ale ja miałem z tym do czynienia na co dzień. Poza tym, nawet abstrahując od takiej sytuacji, wpis pokazuje różne techniki, które możesz wykorzystać inaczej: makro AutoOpen, edycję nagłówków z poziomu VBA, ustawienie kieszeni drukarki dla danego dokumentu itp. Dla osoby nowej w VBA jest to wartość sama w sobie, bez względu na podany przeze mnie przykład użycia.