VBA w MS Word Źródła: Steven Roman, Word.Makrodefinicje, Helion 2000 System pomocy VBA WinWord http://shop.oreilly.com/product/9781565927254.do http://examples.oreilly.com/9781565927254/Examples.zip
Podstawy komunikacji z użytkownikiem (przydatne podczas testowania procedur) MsgBox (Komunikat [,przycisk][,tytuł] Przykład typów przycisków: vbOKOnly równy 0 VbOKCancel równy 1 vbRetryCancel równy 5 Typy ikon (dodawane do przycisków) vbCritical równa 16 vbInformation równa 64 Przycisk domyślny vbDefaultButton1 równy 0 (przycisk pierwszy) vbDefaultButton2 równy 256 (przycisk drugi) Są też parametry "modalności" Przykłady: MsgBox "Kontynuować?", vbQuestion+vbYesNo InputBox (komunikat, [,tytuł][,WartośćDomyślna] sNazwisko=InputBox("Wpisz nazwisko", "Nazwisko", "Malinowski")
Operacje na łańcuchach znaków Len("Styczeń") zwróci 7 UCase(ŁańcuchZnaków) i LCase(ŁańcuchZnaków) Przykład: MsgBox(LCase("Malinowski")) Left (ŁańcuchZnaków,x) Right, Mid Przykład: MsgBox Right("Alicja Kwiatkowska", 11) Przykład: MsgBox Mid("Biblioteka.doc",12) do znalezienia położenia w łańcuchu: InStr(Początek, ŁańcuchPrzeszukiwany,ŁańcuchDoZnalezienia) Przykład: MsgBox InStr(1,"Alicja Kwiatkowska","Kwiatkowska") Konwersja liczba - łańcuch znaków Przykład: Str(123) Przykład: Val("4.5") Przykład: Val("1234 ulica Szeroka”) Uwaga: Val("$12,00") zwróci 0 !
Operacje na łańcuchach znaków Usuwanie spacji: Funkcje Trim, LTrim, RTrim Przykład: Trim(" dodatkowe ") Porównywanie łańcuchów znaków: ŁańcuchZnaków Like Wzór StrComp("ŁańcuchZnaków1, ŁańcuchZnaków2 [, compare]) Uwaga: ustawienia porównań: Option Compare Binary lub Text (lokalne, krajowe) Przykład: MyCheck = "aM5b" Like "a[L-P]#[!c-e]" MyStr1 = "ABCD": MyStr2 = "abcd" MyComp = StrComp(MyStr1, MyStr2, 1) ' Zwraca 0 MyComp = StrComp(MyStr1, MyStr2, 0) ' Zwraca -1.
Ważniejsze struktury sterujące Switch(wyraż1, wartość1, wyraż2, wartość2, ... , wyrażN, wartośćN) Uwaga: zawsze ocenia wszystkie wyrażenia a zwraca wartość odpowiadająca pierwszemu prawdziwemu Przykład: Sub WyswietlTypDokumentu(RozszerzenieDokumentu As String) Dim TypDokumentu As Variant TypDokumentu = Switch(RozszerzenieDokumentu = "dot", "Szablon", _ RozszerzenieDokumentu = "docx", "Dokument") 'Wyświetlenie rezultatu If Not IsNull(TypDokumentu) Then MsgBox TypDokumentu Else MsgBox "Typ nieznany" End If End Sub
Ważniejsze struktury sterujące If...Then Przykład: Usuwa bieżące zaznaczenie w aktywnym dokumencie jeśli zawiera ono wyraz "Bartok" Dim sTekst as String sTekst = Selection.Text If InStr(sTekst, "Bartok") Then Selection.Delete
Ważniejsze struktury sterujące Pętla For ... Next Przykłady: For i = 1 To ActiveDocument.Paragraphs.Count 'weź następny akapit Set akapit = ActiveDocument.Paragraphs(i) 'zmień styl z Nagłówek 1 na Nagłówek 2 If akapit.Style = "Nagłówek 1" Then akapit.Style = "Nagłówek 2" End If Next i
Ważniejsze struktury sterujące Pętla For ... Next Przykłady: For i = 0 to 10 iTablica(i) = 0 Next i Dim i As Integer Dim akapit As Paragraph For i = 1 to ActiveDocument.Paragraphs.Count 'weź następny akapit Set akapit = ActiveDocument.Paragraphs(i) 'jeżeli pierwszy wyraz to "Dziękuję", 'wyjdź z pętli For 'Words zwraca wyraz wraz ze spacjami po nim występującymi If Trim(akapit.Range.Words(1)) = "Dziękuję" Then Exit For akapit.Range.Bold = True
Ważniejsze struktury sterujące Pętla For Each - dla kolekcji obiektów For Each ZmiennaObiektowa In NazwaKolekcji 'blok kodu Next ZmiennaObiektowa jest równoważna ale bardziej zwięzła i szybsza niż: For i = 1 To Kolekcja.Count Next i
Ważniejsze struktury sterujące Pętla For Each - dla kolekcji obiektów Przykłady: Dim akapit As Paragraph For Each akapit In ActiveDocument.Paragraphs 'zmień styl z Nagłówek 1 na Nagłówek 2 If akapit.Style = "Nagłówek 1" Then akapit.Style = "Nagłówek 2" End If Next akapit
Ważniejsze struktury sterujące Pętla Do ... Loop Odmiany: Do {While | Until} Przykłady: Przechodzenie przez akapity dopóki zawierają dowolne znaki 'Weź pierwszy akapit Set akapit = ActiveDocument.Paragraphs(1) Do While akapit.Range.Characters.Count 'blok kodu 'Weź następny akapit 'Uwaga: pusty akapit tzn. zawierający znak końca akapitu ma .Count równy 1 Loop
Ważniejsze struktury sterujące Pętla Do ... Loop 'Oblicz liczbę wyrazów w akapicie Inna wersja: iLicznikWyrazow = akapit.Range.Words.Count 'Weź pierwszy akapit 'Wykonuj pętlę, dopóki są wyrazy Set akapit = ActiveDocument.Paragraphs(1) Do 'blok kodu Do While iWyraz <=iLicznikWyrazow 'Weź wyraz 'Weź następny akapit Set fragment = akapit.Range.Words(iWyraz) Loop While akapit.Range.Characters.Count > 1 'wyjdź z pętli, jeżeli wyraz jest pogrubiony If fragment.Bold = True Then Exit Do Przykład: 'Sformatuj wyraz kursywą Formatujemy kursywą każdy wyraz danego akapitu aż dojdziemy do wyrazu pogrubionego fragment.Italic = True 'Następny wyraz Dim akapit As Paragraph iWyraz = iWyraz + 1 Dim fragment As Range Loop Dim iWyraz As Long Dim iLicznikWyrazow As Long Uwaga na niebezpieczeństwo utworzenia nieskończonych pętli! 'Inicjalizuj iWyraz = 1
Ważniejsze struktury sterujące Select .. Case Select Case wyrażenie Case wartość1 ' blok instrukcji wykonywanych gdy wyrażenie jest równe wartość1 Case wartość2 ' blok instrukcji wykonywanych gdy wyrażenie jest równe wartość2 ... Case Else ' blok instrukcji wykonywanych w pozostałych przypadkach End Select
Funkcje obsługi plików i folderów Dir, FileLen, FileTimeDate, FileCopy, Kill, Name, RmDir, MkDir Przykład sprawdzenia czy plik istnieje: If Len(Dir("c:\nazwa_sprawdzanego_pliku.docx")) = 0 Then Msgbox "Plik nie istnieje" Else Msgbox "Plik istnieje" End If
Ważniejsze kolekcje obiektów Worda Characters, Documents, Paragraphs, RecentFiles, Columns, Rows, Tables, Sections, Sentences, Words, TabStops Przykłady korzystania z kolekcji Documents: MsgBox "Liczba otwartych dokumentów: " & Application.Documents.Count KolekcjaDocuments.Add(Szablon,True | False) czyli: Dim dok as Document Set dok = Application.Documents.Add("Nazwa szablonu", False) odwołanie przez referencję do otwartego dokumentu Application.Documents.Item("Chwilowy.doc") Application.Documents(2) Application.Documents("Chwilowy.doc")
Zmienna obiektowa Zmienna obiektowa (jest zmienną wskaźnikową) czyli kilka zmiennych obiektowych może wskazywać ten sam obiekt ActiveDocument.Paragraphs(1).Range.Font.Bold = True jest równoważne Dim fragment As Range Set fragment = ActiveDocument.Paragraphs(1).Range fragment.Bold = True Dim czcionka As Font Set czcionka = ActiveDocument.Paragraphs(1).Range.Font czcionka.Bold = True Zwalnianie zmiennej obiektowej: Set akapit = Nothing
Konstrukcje, które warto znać. Obiekt Document ActiveDocument - tylko do odczytu a zatem Documents("Mój list").Activate MsgBox Documents.Count ObiektDocument.Add(szablon, True | False) ' domyślnie szablon Normal ObiektDocument.Open(FileName, ConfirmConverstions, ReadOnly, ...) ObiektDocument.Close(SaveChanges, OriginalFormat, RouteDocument) Przykład: ActiveDocument.Close SaveChanges := wdSaveChanges, _ OriginalFormat :=wdOriginalDocumentFormat ObiektDocument.Save ObiektDocument.SaveAs(Filename, FileFormat, ... ) Właściwości związane z nazwą dokumentu: Name, FullName, Path Metody obiektu Document Documents("MójList").Activate
Konstrukcje, które warto znać. Obiekt Document Obiekt Bookmark - dodawanie zakładki ActiveDocument.Bookmarks.Add "Zaznaczenie", Selection.Range Usuwanie wszystkich zakładek Dim zakladka As Bookmark For Each zakladka In ActiveDocument.Bookmarks zakladka.Delete Next Zakladka Kolekcje Characters, Words, Sentences ActiveDocument.Words(1) - zwraca obiekt typu Range Obiekt Paragraphs - operacje na akapitach zmiana tekstu we fragmencie akapitu Akapit.Range.Text = "nowy tekst"
Konstrukcje, które warto znać. Obiekty Range i Selection Dostęp do tekstu pierwszego akapitu w aktywnym dokumencie: ActiveDocument.Paragraphs(1).Range.Text wybranie całego tekstu dokumentu: Set fragment = ActiveDocument.Range(0,0) fragment.WholeStory obiekt Selection - tylko jeden w dokumencie obiekty Range - wiele w dokumencie
Konstrukcje, które warto znać. Obiekty Range i Selection Przykład (najpierw trzeba wprowadzić w dokumencie tekst dwuakapitowy) Dim fragment As Range Dim zaznaczenie1 As Selection Dim zaznaczenie2 As Selection ActiveWindow.Split = True ActiveWindow.Panes(1).Activate ActiveDocument.Paragraphs(1).Range.Select Set Zaznaczenie1 = Selection ActiveWindow.Panes(2).Activate ActiveDocument.Paragraphs(2).Range.Select Set Zaznaczenie2 = Selection zaznaczenie2.MoveStart wdCharacter, zaznaczenie1.Characters.Count
Konstrukcje, które warto znać. Obiekty Range i Selection Tworzenie obiektu Range lub Selection ActiveDocument.Select Set zaznaczenie = ActiveDocument.ActiveWindow.Selection ActiveDocument.Fields(2).Select Set zaznaczenie = ActiveDocument.ActiveWindow.Selection.Delete Selection.Delete Wstawianie tekstu do dokumentu przez tzw. punkt wstawiania kursora Set fragment = ActiveDocument.Paragraphs(2).Range fragment.Collapse wdCollapseStart fragment.Text = "Wstawiony tekst ..."
Konstrukcje, które warto znać. Obiekty Range i Selection Wstawianie tekstu do dokumentu na początku/końcu dokumentu Set fragment = ActiveDocument.Range fragment.Collapse wdCollapseStart fragment.Text = "Początek dokumentu" & vbCr Set fragment = ActiveDocument.Range(Start:=0, End:=0) fragment.Text ="Początek dokumentu" & vbCr fragment.StartOf wdStory, wdMove Set fragment = ActiveDocument.Paragraphs(2).Range fragment.Collapse wdCollapseEnd fragment.Text = "Początek akapitu 3" & vbCr fragment.EndOf wdStory, wdMove fragment.Text = "Koniec dokumentu" & vbCr
Konstrukcje, które warto znać. Obiekty Range i Selection Obiekt Find Ważniejsze metody obiektu Range Przykład - szukanie w zdaniu łańcucha znaków i zaznaczenie go Next, Previous SetRange, Start, End Set fragment = ActiveDocument.Sentences(1) StartOf, EndOf fragment.Find.Text = "Alicja" HomeKey, EndKey fragment.Find.Execute Collapse, Expand If fragment.Find.Found = True Then Extend (dla obiektu Selection) fragment.Select WholeStory Endif Move, MoveEnd, MoveStart, MoveUp, MoveDown i inne Warto zajrzeć: http://stackoverflow.com/questions/20634065/word-vba-find-a-line-which-starts-with-a-term-and-delete-it
Konstrukcje, które warto znać. Obiekty Range i Selection Przykład: End If Dim fragment As Range ' niech zmienna fragment wskazuje ' Utwórz obiekt Range, który ' początek następnego akapitu ' wskazuje początek zaznaczenia Set fragment = fragment.Next(wdParagraph, 1) Set fragment = Selection.Range ' jeżeli dojdziemy do końca akapitu fragment.Collapse Direction:=wdCollapseStart ' metoda Next nie będzie mogła zostać wykonana, więc Do ' zatrzymaj się, jeżeli fragment nie znajduje ' referencja do obiektu fragment zostanie ustawiona na Nothing ' się już w obrębie zaznaczenia ' teraz czas zakończyć procedurę If Not fragment.InRange(Selection.Range) Then If fragment Is Nothing Then Exit Sub Exit Do fragment.Collapse wdCollapseStart Else ' powiększ obiekt Range, aby zawierał pierwszy wyraz Loop fragment.Expand wdWord ' jeżeli fragment.Range reprezentuje tylko znak ' akapitu, to nie wyświetlaj go, ponieważ otrzymalibyśmy ' dwa puste wiersze zamiast jednego If fragment.Text = vbCr Then Debug.Print Debug.Print fragment.Text
Konstrukcje, które warto znać. Obiekty Range i Selection Przykłady: Metody edycyjne (odpowiedniki funkcji dawnego Menu "Edycja") ActiveWindow.Selection.SetRange(0,0) fragment.Copy, fragment.Cut, fragment.Delete, fragment.Paste fragment.End = fragment.End + 1 fragment.End = fragment.Start fragment.PasteSpecial(IconIndex, Link, Placement, DisplayAsIcon, DataType, IconFileName, IconLabel) fragment.Start = fragment.End ActiveDocument.Characters(1).Select Metody wstawiające tekst Selection.EndOf wdLine, wdExtend ' zaznacza cały wiersz fragment.InsertAfter, fragment.InsertBefore Przykład: Set fragment = ActiveDocument.Paragraphs(1).Range Selection.Extend "#" ' zaznacza treść dokumentu od początku do znaku # ' usuń znak końca akapitu z obiektu Range fragment.MoveEnd wdCharacter, -1 fragment.InsertAfter "Koniec"
Konstrukcje, które warto znać. Obiekty Range i Selection Przykłady: Metody edycyjne (odpowiedniki funkcji dawnego Menu "Edycja") ActiveWindow.Selection.SetRange(0,0) fragment.Copy, fragment.Cut, fragment.Delete, fragment.Paste fragment.End = fragment.End + 1 fragment.End = fragment.Start fragment.PasteSpecial(IconIndex, Link, Placement, DisplayAsIcon, DataType, IconFileName, IconLabel) fragment.Start = fragment.End ActiveDocument.Characters(1).Select Metody wstawiające tekst Selection.EndOf wdLine, wdExtend ' zaznacza cały wiersz fragment.InsertAfter, fragment.InsertBefore Przykład: Set fragment = ActiveDocument.Paragraphs(1).Range Selection.Extend "#" ' zaznacza treść dokumentu od początku do znaku # ' usuń znak końca akapitu z obiektu Range fragment.MoveEnd wdCharacter, -1 fragment.InsertAfter "Koniec"
Konstrukcje, które warto znać. Obiekty Range i Selection Metody wstawiające akapit Sortowanie tekstu fragment.InsertParagraph (kasuje poprzedni w tym miejscu. Rozważyć uprzednie zwijanie fragmentu) fragment.Sort(ExcludeHeader,FieldNumber,SortFieldType, ...) fragment.InsertParagraphAfter fragment.InsertParagraphBefore Dim nowyDokument As Document Set nowyDokument = Documents.Add Metody symulacji klawiatury (dla obiektu Selection) nowyDokument.Content.InsertAfter "jabłko" & Chr(13) _ HomeKey, EndKey, EscapeKey, TypeBackspace, TypeParagraph, TypeText (rozważyć ReplaceSelection) & "cukinia" & Chr(13) & "brzoskwinia" & Chr(13) nowyDokument.Content.Sort SortOrder:=wdSortOrderAscending Przykład: Selection.TypeText "12345678"
Konstrukcje, które warto znać. Obiekty Find i Replace Przykłady: With Selection.Find .ClearFormatting 'bez formatowania .Text = "Być albo nie być" .Forward = True .Wrap = wdFindContinue End With Selection.Find.Execute Dim fragment As Range ' przeszukiwanie całego dokumentu Set fragment = ActiveDocument.Content With fragment.Find .ClearFormatting .Wrap = wdFindStop .Execute fragment.Select .Format .MatchCase .MatchWholeWord .MatchWildcards .MatchSoundsLike .MatchAllWordForms If Selection.Find.Found = True Then MsgBox "Znaleziono tekst" Else MsgBox "Nie znaleziono tekstu" End If
Konstrukcje, które warto znać. Obiekty Find i Replace Zastępowanie - przykład Selection.Find.ClearFormatting Selection.Find.Replacement.ClearFormatting With Selection.Find .Text = "Znajdź" .Replacement.Text = "zastąp" .Forward = True .Wrap = wdFindContinue .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildCards = False .MatchSoundsLike = False .MatchAllWordForms = False End With Selection.Find.Execute Replace:=wdReplaceAll
Programowanie w Wordzie z poziomu innej aplikacji Przykład: 'najpierw w IDE VBA musimy włączyć Tools | References | Microsoft Word X.0 Object Library Dim Wrd As Word.Application Set Wrd = New Word.Application Wrd.Visible = True Dim dokument As Document Set dokument = Wrd.Documents.Add dokument.Content = "być albo nie być" dokument.Save Wrd.Quit
Programowanie w Wordzie z poziomu innej aplikacji Przykład: Dim wrd As Word.Application On Error Resume Next ' Spróbuj uzyskać dostęp do uruchomionego Worda Set wrd = GetObject(, "Word.Application") If Err.Number = 429 Then ' z powodu tego błędu musimy utworzyć nowy obiekt Set wrd = CreateObject("Word.Application") ElseIf Err.Number <> 0 Then ' mamy inny błąd więc informujemy o nim MsgBox "Błąd: " & Err.Description Exit Sub End If wrd.Visible = True Dim Wrd As Object Dim dokument As Object Set Wrd = CreateObject("Word.Application") Wrd.Visible = True Set dokument = Wrd.Documents.Add dokument.Content = "Być albo nie być" dokument.Save