11. august 2010 - 13:32Der er
22 kommentarer og 1 løsning
Slet sider i dokument ved hjælp af CheckBox
Hej,
Jeg har et dokument på 7 sider. Jeg vil gerne lave en makro, så jeg fx kun får side 1 frem hvis CheckBox 1 er sand og side 2-3 frem hvis CheckBox 2 er sand osv.
Hvordan du kan styre dit indhold i sidehoved og -fod kan jeg ikke sige noget om uden at vide, hvordan det er lavet.
Jeg gik ud fra, at dine checkbokse var formularfelter. For at få noget til at ske, skal du i givet fald tilknytte makro(er) til Exit (som det også er tilfældet i flere eksempler i det link, jeg nævnte).
Word er jo ikke noget sidelayout-program. Programmet opererer med fortløbende tekst, der ombrydes on-the-fly på basis af den valgte printer.
En mulighed er at udnytte følgende: VBA opererer med nogle forudfefinerede bogmærker. Se http://support.microsoft.com/kb/182586. Et af disse bogmærker er "\Page", som kan bruges sammen med Selection.
Følgende linjer vil gå til side 4 i det aktive dokument og slette indholdet. Hvis du skal slette indhold på flere sider, kan du slette én side ad gangen, men du skal så huske på, at de efterfølgende sider skifter sidetal. Hvis du f.eks. vil slette side 3-5, kan du lade en løkke slette side 3 i alt 3 gange.
Hvis jeg fx har 6 sider og 6 checkbokse, og hvis checkboks1 er false så skal side 1 slettes, og hvis checkboks2 er false skal side 2 slettes osv. Jeg vil kunne komme ud for at hvis checkboks1 er false, så vil den slette side 1, og så vil checkboks2 slette den forkerte side, hvis den ligeledes er false - anderledes, hvis checkboks1 er true.
Kan man måske vende den om, så den kun tager de sider med som er true? Eller vil det måske være nemmere at dele dokumentet i 6 dokumenter?
Du kan godt dele dokumentet i 6 enkelte dokumenter, men det er ikke nødvendigt.
I stedet for at basere dig på sider (der som sagt er en diffus størrelse i Word-sammenhæng), kan du sætte bogmærker om hver af siderne (navngiv dem f.eks. "Side1", "Side2" osv.). Så kan du lade makrokoden slette indholdet i bogmærkerne.
Koden nedenfor tjekker, om der findes et bogmærke med navnet "Side2". Hvis det findes, slettes indholdet i bogmærket (og dermed også selve bogmærket).
With ActiveDocument.Bookmarks If .Exists("Side2") Then .Item("Side2").Range.Delete End If End With
Ja, du skal markere teksten. Du har ikke skrevet noget om Word-version. Hvis det er 2003: Marker teksten, Indsæt > Bogmærke. Navnet må ikke have mellemrum og kan ikke starte med et tal, kan have op til 40 tegn, underscore tilladt.
Jeg har sidehoved og sidefod på hver side (med forskellige på hver side). Synes ikke at jeg kan give hele indholdet på siden et bogmærke - den sletter alt udentaget sidehoved og sidefod. Kan man få den til at tage det med i bogmærket?
Inkluder det efterfølgende sektionsskifte i bogmærket for hver side. Slå formateringsmærker til, så du kan se, hvad du markerer (Ctrl+Skift+8). Sidehoved/fod er egenskaber ved sektioner og forsvinder med sektionsskiftet. I sidste sektion (eller eneste sektion) i et dokument indeholder sidste afsnitstegn også sektionsinfo.
Så er jeg kommet lidt tættere på. Jeg kan dog ikke gennemskue hvad jeg skal ændre i koden. Makroen stoppe når en af checkboksene er true (har sat den til at den skal slette bogmærkerne som standart, hvis der ikke kommer et flueben i checkboksen).
dvs. hvis jeg har fleben i check2, så sletter den godt nok side1, men alt efter bliver ikke slettet. Derudover køre den slet ikke det sidste af makroen (søg og erstat).
---------- If Check1 = False Then
With ActiveDocument.Bookmarks If .Exists("side1") Then .Item("side1").Range.Delete End If End With
If Check2 = False Then
With ActiveDocument.Bookmarks If .Exists("side2") Then .Item("side2").Range.Delete End If End With
If Check3 = False Then
With ActiveDocument.Bookmarks If .Exists("side3") Then .Item("side3").Range.Delete End If End With
Tjek dine "If" og "End If". Hvis koden, du har vist, er et regulært udsnit fra en makro, så skal du have et "End if" efter hver "End With", hvis alle dine tjek skal køre:
If Check1 = False Then
With ActiveDocument.Bookmarks If .Exists("side1") Then .Item("side1").Range.Delete End If End With End If
If Check2 = False Then
With ActiveDocument.Bookmarks If .Exists("side2") Then .Item("side2").Range.Delete End If End With End If
If Check3 = False Then
With ActiveDocument.Bookmarks If .Exists("side3") Then .Item("side3").Range.Delete End If End With End If
Super, jeg havde alle "End if" til sidst i makroen - det hjalp at de blev flytte op lige efter hver enkelte.
Det eneste problem, som jeg har nu, er med den sidste side. Når den bliver slettet flytter den sidehoved og sidefod med til den forrige side (den overskriver forrige sektions sidehoved og sidefod). Er det normalt?
Ved nærmere eftertanke: Det er faktisk normalt, det du ser, fordi du jo nok også sletter sektionsskiftet mellem de to sidste sektioner ved samme lejlighed. Det kan være lidt tricky at styre. Du kan være nødt til at indbygge noget i koden, som kopierer hoved/fod fra foregående sektion til sidste sektion, inden du sletter sidste sektion. Det kan f.eks. gøres ved at kopiere det foregående sektionsskift som beskrevet i afsnittet "Merging sections" i denne artikel (eller du kan kopiere indholdet i hoved/fod direkte og insætte i sidste sektion):
Det ser ikke ud til at det lykkes for mig at løse problemet med at den flytter den sidste sidehoved/sidefod op, hvis den sidste side bliver slettet. Har prøvet at lave en kode, som sammenkæder sidehoved/sidefod før den sletter den sidste side, men det virker ikke som det skal.
Inden du sletter sidste sektionsskift skal sin kode sørge for, at hoved/fod i sidste sektion er ændret til at se ud som i foregående sektion. Hvis du stepper igennem din kode, mens du tjekker dokumentet, virker det så sådan?
Hvis du viser din kode, er der noget at forholde sig til.
Følgende makro har jeg lavet, men den går på fejl ved "WordBasic.GoToFooter".
If Checkkombi = False Then
Selection.MoveDown Unit:=wdScreen, Count:=36 If ActiveWindow.View.SplitSpecial <> wdPaneNone Then ActiveWindow.Panes(2).Close End If If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _ ActivePane.View.Type = wdOutlineView Then ActiveWindow.ActivePane.View.Type = wdPrintView End If ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader Selection.HeaderFooter.LinkToPrevious = Not Selection.HeaderFooter. _ LinkToPrevious WordBasic.GoToFooter Selection.HeaderFooter.LinkToPrevious = Not Selection.HeaderFooter. _ LinkToPrevious ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
With ActiveDocument.Bookmarks If .Exists("kombi") Then .Item("kombi").Range.Delete End If End With
Din kode ser ud til at være direkte fra en optaget makro. Optagne makroer kan være OK i en håndevending til ukomplekse løsninger, og de kan tit give en idé om, hvordan man selv kommer videre - men regn ikke med, at det er optimal kode. Tit vil en optaget makro kun gå godt i en situation, der er 100 % identisk med den situation, hvor makroen blev optaget.
Hver sektion kan have op til 3 forskellige hoveder og 3 forskellige fødder ("alm." sider, forskellig første side, forskellige lige sider). Følgende kode tager fat i sidste sektion og linker alle varianter af hoved/fod i den sektion til foregående sektion:
Dim oSec As Section
'Sæt reference til sidste sektion Set oSec = ActiveDocument.Sections.Last
'Link alle hoveder/fødder i sidste sektion til forrige sektion With oSec .Headers(wdHeaderFooterPrimary).LinkToPrevious = True .Headers(wdHeaderFooterFirstPage).LinkToPrevious = True .Headers(wdHeaderFooterEvenPages).LinkToPrevious = True .Footers(wdHeaderFooterPrimary).LinkToPrevious = True .Footers(wdHeaderFooterFirstPage).LinkToPrevious = True .Footers(wdHeaderFooterEvenPages).LinkToPrevious = True End With
Har dog valgt at have alle siderne, som enkelte sider for sig selv (dvs. 7 dokumenter), da jeg gerne vil have nogle sider for sig selv i en selvstændigt dokument efter at min oprindelige "søg og erstat makro" er kørt - Fx hvis jeg har valgt at beholde 5 sider i alt, så skal 1-3 være i et dokument og 4 og 5 i to andre dokumenter.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.