Document 166440
Download
Report
Transcript Document 166440
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
Next i
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
'blok kodu
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
Inna wersja:
'Weź pierwszy akapit
Set akapit = ActiveDocument.Paragraphs(1)
Do
'blok kodu
'Weź następny akapit
Loop While akapit.Range.Characters.Count > 1
Set akapit = ActiveDocument.Paragraphs(1)
'Oblicz liczbę wyrazów w akapicie
iLicznikWyrazow = akapit.Range.Words.Count
'Wykonuj pętlę, dopóki są wyrazy
Do While iWyraz <=iLicznikWyrazow
'Weź wyraz
Set fragment = akapit.Range.Words(iWyraz)
'wyjdź z pętli, jeżeli wyraz jest pogrubiony
If fragment.Bold = True Then Exit Do
Przykład:
Formatujemy kursywą każdy wyraz danego akapitu aż 'Sformatuj wyraz kursywą
fragment.Italic = True
dojdziemy do wyrazu pogrubionego
'Następny wyraz
iWyraz = iWyraz + 1
Dim akapit As Paragraph
Loop
Dim fragment As Range
Dim iWyraz As Long
Dim iLicznikWyrazow As Long
'Inicjalizuj
iWyraz = 1
'Weź pierwszy akapit
Uwaga na niebezpieczeństwo utworzenia
nieskończonych pętli!
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
jest równoważne
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
Set fragment = ActiveDocument.Range
fragment.StartOf wdStory, wdMove
fragment.Text = "Początek dokumentu" & vbCr
Set fragment = ActiveDocument.Paragraphs(2).Range
fragment.Collapse wdCollapseEnd
fragment.Text = "Początek akapitu 3" & vbCr
Set fragment = ActiveDocument.Range
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
Set fragment = ActiveDocument.Sentences(1)
fragment.Find.Text = "Alicja"
fragment.Find.Execute
If fragment.Find.Found = True Then
fragment.Select
Endif
Next, Previous
SetRange, Start, End
StartOf, EndOf
HomeKey, EndKey
Collapse, Expand
Extend (dla obiektu Selection)
WholeStory
Move, MoveEnd, MoveStart, MoveUp,
MoveDown i inne
Warto zajrzeć:
http://stackoverflow.com/questions/20634065/
word-vba-find-a-line-which-starts-with-a-termand-delete-it
Konstrukcje, które warto znać.
Obiekty Range i Selection
Przykład:
Dim fragment As Range
' Utwórz obiekt Range, który
' wskazuje początek zaznaczenia
Set fragment = Selection.Range
fragment.Collapse Direction:=wdCollapseStart
Do
' zatrzymaj się, jeżeli fragment nie znajduje
' się już w obrębie zaznaczenia
If Not fragment.InRange(Selection.Range) Then
Exit Do
Else
' powiększ obiekt Range, aby zawierał pierwszy
wyraz
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
Else
Debug.Print fragment.Text
End If
' niech zmienna fragment wskazuje
' początek następnego akapitu
Set fragment = fragment.Next(wdParagraph, 1)
' jeżeli dojdziemy do końca akapitu
' metoda Next nie będzie mogła zostać wykonana,
więc
' referencja do obiektu fragment zostanie
ustawiona na Nothing
' teraz czas zakończyć procedurę
If fragment Is Nothing Then Exit Sub
fragment.Collapse wdCollapseStart
End If
Loop
Konstrukcje, które warto znać.
Obiekty Range i Selection
Przykłady:
ActiveWindow.Selection.SetRange(0,0)
fragment.End = fragment.End + 1
fragment.End = fragment.Start
fragment.Start = fragment.End
Metody edycyjne (odpowiedniki funkcji dawnego
Menu "Edycja")
fragment.Copy, fragment.Cut, fragment.Delete,
fragment.Paste
fragment.PasteSpecial(IconIndex, Link, Placement,
DisplayAsIcon, DataType, IconFileName, IconLabel)
ActiveDocument.Characters(1).Select
Metody wstawiające tekst
Selection.EndOf wdLine, wdExtend ' zaznacza cały fragment.InsertAfter, fragment.InsertBefore
wiersz
ActiveDocument.Characters(1).Select
Selection.Extend "#" ' zaznacza treść dokumentu
od początku do znaku #
Przykład:
Set fragment =
ActiveDocument.Paragraphs(1).Range
' 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:
ActiveWindow.Selection.SetRange(0,0)
fragment.End = fragment.End + 1
fragment.End = fragment.Start
fragment.Start = fragment.End
Metody edycyjne (odpowiedniki funkcji dawnego
Menu "Edycja")
fragment.Copy, fragment.Cut, fragment.Delete,
fragment.Paste
fragment.PasteSpecial(IconIndex, Link, Placement,
DisplayAsIcon, DataType, IconFileName, IconLabel)
ActiveDocument.Characters(1).Select
Metody wstawiające tekst
Selection.EndOf wdLine, wdExtend ' zaznacza cały fragment.InsertAfter, fragment.InsertBefore
wiersz
ActiveDocument.Characters(1).Select
Selection.Extend "#" ' zaznacza treść dokumentu
od początku do znaku #
Przykład:
Set fragment =
ActiveDocument.Paragraphs(1).Range
' 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.InsertParagraphAfter
fragment.InsertParagraphBefore
fragment.Sort(ExcludeHeader,FieldNumber,SortFie
ldType, ...)
Metody symulacji klawiatury (dla obiektu
Selection)
HomeKey, EndKey, EscapeKey, TypeBackspace,
TypeParagraph, TypeText (rozważyć
ReplaceSelection)
Przykład:
Selection.TypeText "12345678"
Przykład:
Dim nowyDokument As Document
Set nowyDokument = Documents.Add
nowyDokument.Content.InsertAfter "jabłko" &
Chr(13) _
& "cukinia" & Chr(13) & "brzoskwinia" &
Chr(13)
nowyDokument.Content.Sort
SortOrder:=wdSortOrderAscending
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
.Text = "Być albo nie być"
.Wrap = wdFindStop
.Execute
End With
fragment.Select
With Selection.Find
.ClearFormatting 'bez formatowania
.Text = "Być albo nie być"
.Forward = True
.Wrap = wdFindContinue
.Format
.MatchCase
.MatchWholeWord
.MatchWildcards
.MatchSoundsLike
.MatchAllWordForms
End With
Selection.Find.Execute
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:
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