VB in Word: Koppen automatisch..

Status
Niet open voor verdere reacties.

Marion2u

Gebruiker
Lid geworden
15 apr 2009
Berichten
59
Hoi,

Mijn koppen zijn genummerd als volgt <1>, <2>,...
Het is de bedoeling dat deze dus een opmaakprofiel toegewezen krijgen. Via VB kan dit automatisch verlopen. Ik heb mijn programmatie erin gestopt maar toch heeft ie telkens een fout..Ikzelf zou niet weten waar die zit. Dit is de code

Code:
  Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "\<*\>"
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = True
    End With
    Selection.Find.Execute
    While Selection.Find.Found
       
    Select Case Selection.Characters.First
    Case "1"
    Selection.Style = ActiveDocument.Styles("Kop 1")
    Case "2"
    Selection.Style = ActiveDocument.Styles("Kop 2")
    Case "3"
    Selection.Style = ActiveDocument.Styles("Kop 3")
    Case Else
    MsgBox "Onbekend"
    End Select
    Wend
End Sub

Als iemand me kan vertellen waar de fout zit en waarom ik ook deze fout maak?

Kim
 
Er zitten een paar fouten in de code, dus je mag nog even knutselen...
Om maar gelijk de eerste aan te geven: je zoekt naar een string met <#> in de tekst.
Vervolgens wordt die, als die tekst wordt gevonden, gecheckt met de volgende opdracht:
Select Case Selection.Characters.First
Case "1"

En daar ga je de fout in, want het eerste teken in de zoektekst is :<

De tekst vind je wel met de volgende aanpassing:

Code:
    While Selection.Find.Found
        Select Case Selection
            Case "<1>"
                Selection.Style = ActiveDocument.Styles("Kop 1")

Maar ook deze aanpassing zal niet werken, omdat je de stijl:
- alleen toepast op de geselecteerde tekst.
- in een oneindige loop steeds opnieuw op dezelfde tekst herhaalt.
- de zoektekst niet vervangt; die blijft nog staan.

Dus er zijn nog een paar aanpassingen nodig:
- eerst moet je ervoor zorgen dat je de paragraaf opmaakt, en niet de selectie
- de code moet worden verwijderd
- de loop moet door naar de volgende tekst

Ik ben hier zelf ook niet overdreven bedreven in, maar ik zal kijken of ik die aanpassingen er nog bij kan verzinnen.
 
Ben ik toch beter dan ik zelf dacht...
Deze macro moet het doen!

Code:
Sub VervangStijl()
    
    Selection.HomeKey Unit:=wdStory
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = "<^#>"
    End With
    
    Do While Selection.Find.Execute
        Select Case Selection
            Case "<1>"
                Selection.Delete Unit:=wdCharacter, Count:=1
                Selection.Style = ActiveDocument.Styles("Kop 1")
            Case "<2>"
                Selection.Delete Unit:=wdCharacter, Count:=1
                Selection.Style = ActiveDocument.Styles("Kop 2")
            Case "<3>"
                Selection.Delete Unit:=wdCharacter, Count:=1
                Selection.Style = ActiveDocument.Styles("Kop 3")
            Case Else
                MsgBox "Onbekend"
        End Select
    Loop
    
End Sub
 
Laatst bewerkt:
Of met:
Code:
Sub tst()
  sq = Split(ActiveDocument.Content, vbCr)
  For j = 0 To UBound(sq)
    If InStr(sq(j), "<") * InStr(sq(j), ">") > 0 Then ActiveDocument.Paragraphs(j + 1).Style = ActiveDocument.Styles("kop " & Val(Mid(sq(j), InStr(sq(j), "<") + 1)))
  Next
End Sub
 
Daarmee laat je de <#> code wel staan... ;)
 
Dus, met dank aan snb, hier een versie die daar mee afrekent, en met een ander (net zo vervelend) probleem, namelijk dat er nergens in één alinea een < èn een > mag voorkomen, omdat-ie anders crasht:

Code:
Sub VervangStijl()
Dim sq() As String
Dim j As Integer, i As Integer, sKop As String
Dim myRange As Range

    sq = Split(ActiveDocument.Content, vbCr)
    For j = 0 To UBound(sq)
        For i = 1 To 5
            sKop = "<" & i & ">"
            If InStr(sq(j), sKop) > 0 Then
                ActiveDocument.Paragraphs(j + 1).Style = ActiveDocument.Styles("Kop " & i)
            End If
        Next i
    Next j

    Set myRange = ActiveDocument.Range(Start:=0, End:=0)
    With myRange.Find
        .ClearFormatting
        .Text = "<^#>"
        With .Replacement
            .ClearFormatting
            .Text = ""
        End With
        .Execute Replace:=wdReplaceAll
    End With

End Sub
 
Code:
Sub tst()
  sq = Split(ActiveDocument.Content, vbCr)
  For j = 0 To UBound(sq)
    If InStr(sq(j), "<") * InStr(sq(j), ">") > 0 And InStr(sq(j), "<") * InStr(sq(j), ">") < 4 Then ActiveDocument.Paragraphs(j + 1).Style = ActiveDocument.Styles("kop " & Val(Mid(sq(j), InStr(sq(j), "<") + 1)))
  Next
  ActiveDocument.Content.Find.Execute "<#>", , , , , , , , , "", 2
End Sub
 
Laatst bewerkt:
Ho Ho :p zo gevorderd hebben we het op school nog niet gezien haha!
Ik heb de eerste code geprobeerd en over genomen maar hij geeft een fout weer aan
"Select Case Selection"
 
Welke Word versie gebruik je?
Overigens heb ik vanmiddag nog uitgebreid met de laatste variant, en die doet 't wat mij betreft perfect, en is, met dank aan snb, ook nog sneller... In ieder geval op een klein docje, weet niet hoe het gaat met een groot document.
Zal overigens ook nog wel even naar de eerste variant kijken, want ik had er geen problemen mee.
 
Ik gebruik de 2007 versie.. de laatste code werkt inderdaad wel maar is een beetje te gevorderd voorlopig :)
 
Iets minder geavanceerd; maar je kunt ook de opmaak gebruiken bij zoeken/vervangen.

Code:
Sub Macro16()
  With ActiveDocument.Content.Find
    .ClearFormatting
    .Replacement.ClearFormatting
    For j = 1 To 5
      .Replacement.Style = ActiveDocument.Styles("Kop " & j)
      .Execute "<" & j & ">", , , , , , , , True, "<" & j & ">", wdReplaceAll
    Next
  End With
End Sub
 
Ik kan wel uitleggen wat er gebeurt, als dat helpt?
De code maakt gebruik van een zogenaamde Matrix variabele. En die werkt net iets anders als een gewone variabele. Bij een gewone variabele sla je één gegeven op, maar een Matrix kan de gegevens a.h.w. stapelen.
Dit kun je vergelijken met een Excel tabel, waarbij een normale variabele de waarde uit één cel opslaat, bijvoorbeeld A1, en een matrix waarden uit een rij, een kolom of een combinatie daarvan kan opslaan. Een matrix zou dan bijvoorbeeld de cellen uit A1:A20 opslaan, in 20 'records' of uit A1:C20, waarbij je dan 60 gegevens tegelijk hebt opgeslagen (3 kolommen x 20 rijen = 60 cellen)

Bij een Matrix variabele moet je specifiek aangeven uit welke 'rij' of 'kolom' je iets terug wilt hebben, vandaar dat je vaak een Loop routine ziet, die door de verschillende opties heenloopt.
Code:
Dim sq() As String
Hiermee wordt de matrix variabele gedeclareerd. Een gewone variabele declareer je met: Dim strTekst As String. Wil je hem als matrix gebruiken, dan wordt dat: Dim strTekst() As String.
Eigenlijk moet je daarna nog specifiek opgeven uit hoeveel rijen en kolommen de matrix bestaat, maar je kunt dat ook op een hele lepe manier doen, die dan ook vaak gebruikt wordt, namelijk met het SPLIT commando.
Code:
    sq = Split(ActiveDocument.Content, vbCr)
Hiermee wordt een bepaald gegeven gesplitst op een zelf aan te geven scheidingsteken. In het voorbeeld wordt de volledige tekst van het document ingelezen (ActiveDocument.Content) en gesplitst op basis van de Harde returns (vbCR). Kortom: er wordt een variabele gemaakt van elke zelfstandige alinea. Als je dus 56 keer op <Enter> drukt in je document, dan maakt de SPLIT functie 56 rijen aan in de matrix variabele.
Code:
    For j = 0 To UBound(sq)
        For i = 1 To 5
            sKop = "<" & i & ">"
            If InStr(sq(j), sKop) > 0 Then
                ActiveDocument.Paragraphs(j + 1).Style = ActiveDocument.Styles("Kop " & i)
            End If
        Next i
    Next j
Vervolgens wordt in een FOR...NEXT loop door alle variabelen gelopen, en wordt een actie uitgevoerd (of niet natuurlijk). Dat begint met de regel For j = 0 To UBound(sq). Een matrixvariabele telt standaard vanaf het getal Nul; voor het aantal keer dat de lus moet worden uitgevoerd, zoeken we met Ubound(sq) eerst de hoogste waarde van de matrix op. Dit geeft je het aantal regels in de matrix.
Er zit nog een tweede lus in, zoals je ziet, en die lus kijkt of de tekst <1> t/m <5> voorkomt in de tekst. Dat zijn namelijk je kopwaarden. Als je het getal verlaagt naar 3, dan worden dus 3 koppen ingesteld, verhoog je het getal dan kun je meer koppen maken. De lus sKop = "<" & i & ">" zet dus elke keer een nieuw cijfer tussen de haken.
Vervolgens wordt met de functie InStr(sq(j), sKop) > 0 gekeken of de tekst voorkomt in de ainea's. Als dat zo is, dan heb je een kop te pakken. De functie Instr geeft een getal dat groter is als Nul als de tekst gevonden wordt, vandaar dat je op deze manier checkt.
In de regel ActiveDocument.Paragraphs(j + 1).Style = ActiveDocument.Styles("Kop " & i) wordt de betreffende stijl vervolgens op de tekst toegepast.

Code:
Set myRange = ActiveDocument.Range(Start:=0, End:=0)
    With myRange.Find
        .ClearFormatting
        .Text = "<^#>"
        With .Replacement
            .ClearFormatting
            .Text = ""
        End With
        .Execute Replace:=wdReplaceAll
    End With

End Sub
Het laatste blokje gebruik je vervolgens om in één keer alle tekst <1> t/m <9> te vervangen door niks, zodat je alleen de koptekst overhoudt.
Duidelijk genoeg zo, of wil je meer informatie?
 
Nu werkt alles prima :) Heb een beetje moeten sleutelen en moeite moeten doen om het te begrijpen maar ik ben blij dat ik nu alles snap!! Bedankt!!:thumb:
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan