Hovedsiden Infosiden Fra Access til Word Vidar Nakling
www.nakling.no

Fra Access til Word

Bakgrunn

Dette eksemplet er inspirert av en løsning for Mattilsynet (tidligere Statens Landbrukstilsyn). I mange forvaltningsdatabaser  skrives det ut enkeltsider fra Accessrapporter. Dette ønsket tilsynet å endre slik at resultatet kunne lagres separat som en Wordfil.

Oppgaven var å lage et dokument basert på en eksisterende Wordmal og fylle det ut med riktige data fra Accessbasen. Dokumentet ble så overtatt av tilsynets standard arkivsystem med navning, nummerering og gjenfinning.

I eksemplet er det i stedet en ganske fiktiv statlig instans som regjerer, Statens Giftinspektorat. For å følge med på fremstillingen her må leseren ha litt erfaring med Accessdatabaser.

Installasjon

Statgift.exe pakker ut to filer: Accessdatabasen Staftgift2K.mdb og en Wordmal, Import.dot.
Disse må ligge i samme mappe. Foreslått mappe er C:\VnDemo\AccessDemo. Systemet som demoen kjører på må ha både Word og Access installert.

Dette eksempelet vil bare virke for Office 2000 og senere.

Bruk

Start basen med å dobbeltklikke på Staftgift2K. Hovedskjemaet ser slik ut:

Bruk postvelgeren i bunnen av skjemaet til å lete blant allerede registrerte tillatelser. Knappen Skriv tillatelse skriver ut en importtillatelse i Word og henter ut nødvendige dat fra feltene i skjemaet.

Knappen Vis rapport viser den tilsvarende Accessrapporten

Med knappen for Ny post i postvelgeren nederst til venstre kan du selv  lage en ny tillatelse, velge saksbehandlere, klientfirma og giftstoffer, men vask hendene godt etterpå!

 

Systemdokumentasjon for utviklere:

Tabellstrukturen ser slik ut:

:

 

tblKlient

Inneholder en post (record) for hvert firma eller klient som er er registrert

tblPermit

Inneholder en post for hver tildelt tillatelse. Et firma kan godt ha flere tillatelser, men det er kun et firma pr tillatelse.

tblPermitDetails

Inneholder alle giftstoffene som inngår i en tillatelse. Hver tillatelse hart minst en post i denne tabellen, men det kan være flere. Av formateringshensyn setter vi en grense på 15 PermitDetails for en og samme tillatelse. Dvs. hvis et firma skal få  tillatelse til å håndtere f. eks. 18 giftstoffer, må det utstedes to tillatelser.

tblGift

Inneholder spesifikasjonen over hvert enkelt giftstoff. Erfarne toksikologer vil sikkert ha flere felt og undertabeller her, men denne duger for prinsippets skyld

I tblPermit er det laget oppslagsfelt for tblKlient og i tblPermitDetail er det laget oppslagsfelt for tblGift. Dvs. i stedet for GiftId i tblPermitDetail ser du selve giftnavnet og kan velge andre navn fra en kombinasjonsboks (rullegardinliste).

I tillegg er det støttetabeller for postnummer, saksbehandlere og mengdeenheter.

Dette skjemaet er et hoved/delskjema, laget med skjemaveiviseren og felt fra tabellene tblPermit og tblPermitDetail. I tillegg er postkilden for hovedskjemaet utvidet til å bli en spørring (egentlig bare en SQL-setning, siden den ikke er lagret separat) for å få med feltene fra Klienttabellen og postnummertabellen. Denne grunnlagspørringen kan du se ved å åpne skjemate i utformingsvisning, vise egenskapsvinduet og lete under postkilde.

Det som er emnet for denne gjennomgangen - å lage Worddokumenet - finnes i koden for knappen "Skriv Tillatelse"

Recordsett

Metoden her er ADO, selv om en godt kunne brukt den eldre protokollan DAO også. For hver Officeversjon som kommer, opplever jeg mer og mer problemer med DAO og biblioteksversjoner, og bruker helst ADO når jeg kan.

Hovedmekanismen er to SQL-setninger som i sin tur definerer hvert sitt recordsett. Et recordsett er en konstruksjon som tilsvarer en tabell og har poster og felt som en tabell. Grunnlaget for et recordsett kan være en tabell, en lagret spørring i basen eller en SQL-setning. SQL-setningene jeg bruker her er laget ved å definere to spørringer i basen og kopiere SQL-definisjonen derfra. De to spørringene, som godt kunne vært slettet etterpå,  er lagret som sqlPermit og sqlPermitDetalj. Ta gjerne en titt på dem i utformingsvisning, så skjønner du mer av sammenhengen. I selve koden er  SQL-setningnen definert slik:

strSqlmain = "SELECT tblPermit.PermitId, tblKlient.Firmanavn, 'etc......
strSqlmain = strSqlmain & " FROM tblSaksbehandler INNER JOIN ((tblKlient'etc....

Denne setningen representerer et recordsett som er en samling felt fra ymse tabeller, med en post for hver post i Permit-tabellen. Så kommer en tilføyelse:

strSqlmain = strSqlmain & " Where PermitId = " & strPermit

som reduserer recordsettet til kun den ene tillatelsen som vises i skjemaet akkurat nå. Tilsvarende for det neste recordsettet, som til slutt får like mange poster som det er i delskjemaet.

Med disse SQL-setningene og de tilhørende recordsettene:

Set rstmain = db.OpenRecordset(strSqlmain, dbOpenDynaset)
Set rstsub = db.OpenRecordset(strSqlsub, dbOpenDynaset)

kan vi i ro og mak plukke ut de feltene som skal med i dokumentet

Wordokumentet

lager vi ved å skaffe oss et Word-objekt og lage et nytt dokument.

strWordmal = Application.CurrentProject.Path & "\Import.dot"

On Error Resume Next
Set myWord = GetObject(, "Word.Application")
If myWord Is Nothing Then
    Set myWord = New Word.Application
End If
On Error GoTo ErrHand

myWord.Visible = True
Set newdoc = myWord.Documents.Add(Template:=strWordmal)

 

Utfylling

Nå skal dokumentet  fylles ut.  Det er nødvendig at vi kjenner til oppsettet av dette dokumentet i detalj. Jeg foretrekker å bruke Words standard navigasjonsknagger - bokmerkene.

Engangsinformasjonen - det som kun har med den spesielle tillatelsen å gjøre skjer på denne måten ved å hente dem fra den ene posten i recordsettet rstmain:

newdoc.Bookmarks("bmFirma").Range.Text = rstmain!Firmanavn
newdoc.Bookmarks("bmKontakt").Range.Text = rstmain!Kontaktperson

All giftstoffene hentes ved at vi spaserer nedover i recordsettet for delskjemaet, rstsub:

newdoc.Bookmarks("bmLinjer").Select

rstsub.MoveFirst
Do While Not rstsub.EOF
    myWord.Selection.TypeText rstsub!Giftnavn
    myWord.Selection.TypeText vbTab
    myWord.Selection.TypeText rstsub!Mengde
    myWord.Selection.TypeText vbTab
    myWord.Selection.TypeText rstsub!Enhet
    myWord.Selection.TypeParagraph
    rstsub.MoveNext
Loop

Metodene MoveFirst og MoveNext er blant standardmetodene for navigasjon i recordsett. Det er til enhver tid en "aktiv" post i et recordsett, referer du til et feltnavn er det den aktive postens felt du får tak i.

Siden vi ikke vet hvor mange linjer i dokumentet som skal fylles ut her, bruker jeg et utgangsbokmerke, og skriver feltinnhold og tabulatortegn etter hverandre etterfulgt av et linjeskift og så videre til vi er ferdige. Selve tabulatorposisjonene er allerede definert i dokumentet, men vi kunne satt dem programmatisk også. (Se Til Word fra Excel II for et eksempel)

Det var det - bare litt oppryddingskode igjen nå, vi ender opp med Worddokumentet - ulagret - som det aktive vinduet på skjermen.

Kvalitetssikring

I tillegg til de sekvensene jeg har omtalt over er det to omganger med tester for feilutfylling, litt før vi setter i gang og litt etter at recordsettene er laget, men før vi starter på Worddokumentet.

 


Begrensninger i dette eksempelet:

For å gjøre fremstillingen og nedlastningen så  enkel som mulig har jeg forenklet dette en del:

  • Erfarne byråkrater og toksikologer vil selvfølgelig ha med langt flere felt og tabeller.

  • Dokumentmalen er  plassert i samme katalog som databasen. Via Wordobjektet kunne vi fått tak i Words mal-kataloger og hentet den derfra, eller den kunne ligget på en egen separat katalog.

  • En slik base bør absolutt være delt, med en datadel og en applikasjonsdel. Datadelen er kun tabellene, applikasjonsdelen er alt det andre, skjemaer, spørringer, rapporter og VBA-kode. Nå kan nye versjoner av applikasjonsdelen distribueres uten at dataene blir berørt.

  • Det skulle vært flere skjemaer for vedlikehold av de tabellene som er der, med søkemuligheter. Skjemaene burde også - i alle fall etter min oppfatning -  være utstyrt med egne knapper for ny post, angre endring og lagre endring, samt advarsel når du forlater en post uten å ha lagret. (Da lagrer jo Access vanligvis automatisk, no questions asked.)

  • Drevne forvaltere ville også kreve en form for postlåsing, når noe er lagt inn skal det være vanskelig å endre det. Likeledes vil mange ønske at det ferdige dokumentet er skrivebeskyttet, slik at det heller ikke kan endres etter at det er produsert..

 

Tilbake til toppen av siden

Copyright © 2015 Vidar Nakling

Microsoft and Windows are registered trademarks of Microsoft Corporation.