Word VBA: Get Range between Consecutive Headings

妖精的绣舞 提交于 2020-01-01 18:16:33

问题


I looked up some examples, but I cannot quite understand how the Range object works. I am trying to loop through each of my headings (of level 4) and have a nested loop that looks through all the tables in between the headings. I cannot figure out how to set that specific range, so any help will be greatly appreciated.

    Dim myHeadings As Variant
    myHeadings = ActiveDocument.GetCrossReferenceItems(wdRefTypeHeading)

    For iCount = LBound(myHeadings) To UBound(myHeadings)

      level = getLevel(CStr(myHeadings(iCount)))
      If level = 4 Then

         'This is where I want to set a range between myHeadings(iCount) to myHeadings(iCount+1)
         set aRange = ??


      End If

    Next iCount

回答1:


You are on the right track here. The myHeadings variable you have simply gives a list of the strings of the Level 4 Headings in the document. What you need to do is then search the document for those strings to get the range of the Level 4 Headings.

Once you have the range of each of the headings you can check for the tables in the range between these headings. I've modified your code slightly to do this. Also note its good practice to put Option Explicit at the top of your module to ensure all variables are declared.

My code will tell you how many tables are between each of the Level 4 headings. NOTE: It does not check between the last heading and the end of the document, I'll leave that up to you ;)

Sub DoMyHeadings()
    Dim iCount As Integer, iL4Count As Integer, Level As Integer, itabCount As Integer
    Dim myHeadings As Variant, tbl As Table
    Dim Level4Heading() As Range, rTableRange As Range

    myHeadings = ActiveDocument.GetCrossReferenceItems(wdRefTypeHeading)

    'We want to move to the start of the document so we can loop through the headings
    Selection.HomeKey Unit:=wdStory

    For iCount = LBound(myHeadings) To UBound(myHeadings)
        Level = getLevel(CStr(myHeadings(iCount)))
        If Level = 4 Then

            'We can now search the document to find the ranges of the level 4 headings
            With Selection.Find
                .ClearFormatting                                'Always clear find formatting
                .Style = ActiveDocument.Styles("Heading 4")     'Set the heading style
                .Text = VBA.Trim$(myHeadings(iCount))           'This is the heading text (trim to remove spaces)
                .Replacement.Text = ""                          'We are not replacing the text
                .Forward = True                                 'Move forward so we can each consecutive heading
                .Wrap = wdFindContinue                          'Continue to the next find
                .Format = True
                .MatchCase = False
                .MatchWholeWord = False
                .MatchWildcards = False
                .MatchSoundsLike = False
                .MatchAllWordForms = False
                .Execute
           End With

           'Just make sure the text matches (it should be I have a habit of double checking
            If Selection.Text = VBA.Trim$(myHeadings(iCount)) Then
                iL4Count = iL4Count + 1                             'Keep a counter for the L4 headings for redim
                ReDim Preserve Level4Heading(1 To iL4Count)         'Redim the array keeping existing values
                Set Level4Heading(iL4Count) = Selection.Range       'Set the range you've just picked up to the array
             End If
         End If
     Next iCount

    'Now we want to loop through all the Level4 Heading Ranges
    For iCount = LBound(Level4Heading) To UBound(Level4Heading) - 1
        'Reset the table counter
        itabCount = 0

        'Use the start of the current heading and next heading to get the range in between which will contain the tables
        Set rTableRange = ActiveDocument.Range(Level4Heading(iCount).Start, Level4Heading(iCount + 1).Start)

        'Now you have set the range in the document between the headings you can loop through
        For Each tbl In rTableRange.Tables
            'This is where you can work your table magic
            itabCount = itabCount + 1
        Next tbl

        'Display the number of tables
        MsgBox "You have " & itabCount & " table(s) between heading " & Level4Heading(iCount).Text & " And " & Level4Heading(iCount + 1).Text
    Next iCount
End Sub



回答2:


You could jump from one heading to the next using Goto. See below how to loop through level 4 headings.

Dim heading As Range
Set heading = ActiveDocument.Range(start:=0, End:=0)
Do   ' Loop through headings
    Dim current As Long
    current = heading.start
    Set heading = heading.GoTo(What:=wdGoToHeading, Which:=wdGoToNext)
    If heading.start = current Then
        ' We haven't moved because there are no more headings
        Exit Do
    End If
    If heading.Paragraphs(1).OutlineLevel = wdOutlineLevel4 Then

        ' Now this is a level 4 heading. Let's do something with it.
        ' heading.Expand Unit:=wdParagraph
        ' Debug.Print heading.Text

    End If
Loop

Don't look specifically for "Heading 4" because,

  • one may use non built-in styles,
  • it would not work with international versions of Word.

Check the wdOutlineLevel4 instead.

Now, to get the range for the whole level 4, here is a little known trick:

Dim rTableRange as Range
' rTableRange will encompass the region under the current/preceding heading
Set rTableRange = heading.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")

This will work better for the last heading 4 in the document or the last one below a heading 3.



来源:https://stackoverflow.com/questions/14737107/word-vba-get-range-between-consecutive-headings

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!