Brevfletning fra Excel til Word via VBA

I en tidligere artikel, har jeg beskrevet hvordan man kan oprette enkelte dokumenter i Word med data fra Excel, se Data i Excel, Brev i Word. Her vil jeg give en metode, hvor man kan lave noget, der minder om brevfletning.

Løsningen henter data fra Excel og "fletter" ind i Word, hver række i Excel danner sit eget dokumenti. Disse dokumenter udskrives enkeltvis og gemmes som separate filer med et navn der hentes i A-kolonnen i regnearket, suppleret med dato- og tidsstempel. Word vises ikke, men der vises en meddelelse, når fletningen er tilendebragt. Dokumenterne gemmes i en mappe (i eksemplet C:\Test), men dette kan naturligvis ændres. Mappen skal dog være oprettet;  i modsat fald virker funktionen ikke korrekt. Et færdigt eksempel på den sidste løsning kan findes under Excel, Færdige eksempler.

Løsningen er baseret på brugen af en skabelon med indsatte bogmærker i Word.

IFor at eksemplet skal virker, skal der sættes en reference til Words objekt bibliotek under Tools - References i VBA Editoren.

Oprettelse af Word-skabelonen

Først oprettes en Word skabelon med den faste tekst, der skal være i dokumentet. På de steder, hvor der skal overføres information fra regnearket, skal der indsættes bogmærker. Bogmærkerne er vist med "gråt" i eksemplet herunder.

I eksemplet herover ses den skabelon, som er er brugt i begge eksempler her. Bogstaverne A, B, C, D, E samt ordet Navn (alle skrevet med Fed og Kursiv), navnene på de pågældende bogmærker. Disse navnee optræder naturligvis ikke i den "rigtige" skabelon. Færdigflettet kunne det se således ud:

Bogmærkerne er her navngivet A til E og Navn. A til E repræsenterer de kolonner i Excel, som den ppågældende information kommer fra. Navn repræsenterer i dette tilfælde samme værdi som står i A-kolonnen. Dette skyldes del af Word ikke kan have det samme bogmærke stående to steder i dokumentet i modsætning til flettefelter, og dels at variablen navn også bruges andre steder i koden.

Når skabelonen er færdig skal den gemmes i det "almindelige" skabelonbibliotek. I eksemplet under Færdige Eksempler, har jeg kaldt skabelonen Flet.dot, men den kan hedde hvad som helst.

Bogmærkenavnene kunne have været oprettet på en måde, som ville gøre koden nemmere at skrive. Fx kunne jeg have kaldt dem B1, B2, B3 og så fremdeles, hvilket ville have gjort det muligt at loope igennem dem. Imidlertid gør den anvendte metode det nemt at overskud, hvor teksten fra kolonne A skal stå, hvor teksten fra kolonne B skal stå osv.

- Til top -

Regnearket

Regnarket som er brugt i eksemplet, ser således ud:

Den øverste række er anvendt til overskrifter og skal naturligvis ikke flettes med. Navn, adresse, postnummer og by står altid i kolonnerne A til og med D. Derefter kan der være så mange kolonner som nødvendigt, med information, der skal overføres til regnearket. Her er det E og F kolonnerne, der anvendes til dette formål. Den nedenstående kode er konstrueret sådan, at en tom celle  A-kolonnen medfører at fletningen afbrydes. Rækker der skal flettes med, skal altså stå i umiddelbar rækkefølge i forhold til hinanden uden tomme rækker i mellem.

- Til top -

Fletning til flere dokumenter, udskrivning og gemning uden visning på skærmen

Dette eksempel illustrerer en kode, som "arbejder i baggrunden". Det vil sige at Word bliver ikke vist på skærmen. For hver række i Excel-regnearket, oprettes et nyt dokument, som udskrives og gemmes. Når alle dokumenter er genereret vises en meddelelsesboks:

Koden til funktionen vises her kommenteret, men ellers uden yderligere kommentarer. Er du i tvivl om enkelte elementer, kan du med fordel læse artikelserien om Programmering. Husk at sætte en reference til Word objekt bibliotek, ellers virker det ikke.

Sub Flet()

' Der erklæres variable til Word-objektet, modtagernavn og til en dokumenttæller
    Dim Wdapp As Object
    Dim Navn As String
    Dim Counter As Integer

' Her undersøges om Word allerede er startet, i modsat fald startes programmet
    On Error Resume Next
    Set Wdapp = GetObject(, "Word.application")

    If Err.Number <> 0 Then
        Set Wdapp = CreateObject("Word.Application")
    End If

' De følgende linjer looper gennem rækkerne i regnearket
    For Each c In Range("A2:A20")

' Der tilføjes et nyt dokument baseret på skabelonen flet.dot
        Wdapp.Documents.Add "flet.dot"

' Hvis A-kolonnen er tom i en given række stoppes løkken
        If c.Value = "" Then
            Exit For

' Ellers fortsættes løkken med at gennemse dokumentet for bogmærker og indsætte tekst
' fra regnearket

        Else

' Først tildeles variablen Navn en værdi fra den aktuelle rækkes A-kolonne
            Navn = c.Value

' Bogmærket A søges frem
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="A"

' Indholdet af A-kolonnen i aktuel række, overføres til dokumentet ved bogmærket

            Wdapp.Selection.TypeText Text:=Range("A" & c.Row).Value

'Denne sekvens gentages for alle bogmærkers vedkommende
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="B"
            Wdapp.Selection.TypeText Text:=Range("B" & c.Row).Text
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="C"
            Wdapp.Selection.TypeText Text:=Range("C" & c.Row).Text
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="D"
            Wdapp.Selection.TypeText Text:=Range("D" & c.Row).Text
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="Navn"
            Wdapp.Selection.TypeText Text:=Range("A" & c.Row).Text
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="E"
            Wdapp.Selection.TypeText Text:=Range("E" & c.Row).Text
            Wdapp.Selection.Goto What:=wdGoToBookmark, Name:="F"
            Wdapp.Selection.TypeText Text:=Range("F" & c.Row).Text

' Når dokumentet er færdigflettet skal det printes ud
            Wdapp.ActiveDocument.PrintOut

' Nu skal dokumentet gemmes, så vi skal have genereret et navn. Dette skal bestå af indholdet fra
' A-kolonnen suppleret med dato og tidsstempel. Da værdien af funktionen Time vil blive returneret
' som fx 23:45, kan dette ikke indgå i et filnavn, som ikke tillader kolon. Derfor omformatteres
' dato og tid til noget, der kan gemmes


            Navn = Navn & " " & Format(Date + Time, "dd-mm-yy hh.mm")

' Så gemmes dokumentet
            Wdapp.ActiveDocument.SaveAs Filename:="C:\test\" & Navn & ".doc"

' Og dokumentet lukkes
            Wdapp.ActiveDocument.Close

'Tælleren tæller dokumentet
            Counter = Counter + 1

' If-sætningen afsluttes
        End If

' Der loopes til næste række i Excelfilen
    Next c

'Når alle dokumenter er udskrevet og gemt vises en meddelelsesboks
    MsgBox "Fletningen er færdig." & vbCrLf & Counter & " Dokumenter er blevet udskrevet og gemt i C:\Test.", _
        vbOKOnly + vbInformation

' Vi fortæller systemet at vi ikke vil se Word på skærmen
    Wdapp.Visible = False

' Og lukker Word ned
    Wdapp.Quit

'Til sidst tømmes objektvariablen for at frigive plads i arbejdshukommelsen
    Set Wdapp = Nothing

End Sub

Som tidligere omtalt, kan et eksempel på et regneark med denne kode og tilhørende Word-skabelon findes under Færdige Eksempler.

- Til top -
- Tilbage til makroer -
- Tilbage til Excel -