Настройка вложенного поля в Word с помощью VBA

Я строю большой документ по частям из шаблонов. Каждый шаблон имеет ключевое слово #OVERALLPAGENUMBER# в нижнем колонтитуле, который я программно заменяю (используя Excel VBA) на поле.

Если бы все, что мне было нужно, это номер страницы этого документа, то было бы достаточно следующего:

Dim storyRange As Object 'Word.Range
For Each storyRange In oDoc.StoryRanges
    Do
        With storyRange.Find
            .Text = "#OVERALLPAGENUMBER#"
            .Wrap = 1 'wdFindContinue
            .Execute
            While .found
                storyRange.Fields.Add Range:=storyRange, Type:=-1, Text:="PAGE", PreserveFormatting:=True
                .Execute
            Wend
        End With
        On Error Resume Next
        Set storyRange = storyRange.NextStoryRange
        On Error GoTo 0
    Loop While Not storyRange Is Nothing
Next

Я протестировал этот код, и он успешно помещает номер страницы в нижний колонтитул. Однако мне нужно вложенное поле (формула), которое добавляет фиксированный номер к номеру страницы, чтобы я мог отображать количество страниц в нескольких документах. Мое решение, если я делаю это вручную (используя Ctrl+F9), дает коды полей, которые выглядят так:

{ = 5 + { PAGE } }

И правильно выдает "6" на странице 1, "7" на странице 2 и т. Д.

Несмотря на то, что я пытаюсь, я не могу скопировать этот тип вложенности полей, используя VBA. (Макро рекордер здесь бесполезен). Кто-нибудь может найти способ создать эти поля программно?


Решение

Моя проблема была в том, что имея PreserveFormatting:=True мешал моим попыткам вложить одно поле в другое. Теперь работает следующее простое решение:

With storyRange.Find
    .Text = "#POLICYPAGENO#"
    .Wrap = 1 'wdFindContinue
    .Execute
    While .found
        storyRange.Select
        With oDoc.ActiveWindow
            .Selection.Fields.Add Range:=.Selection.Range, Type:=-1, Text:="PAGE", PreserveFormatting:=False
            .Selection.MoveLeft Unit:=1, Count:=1, Extend:=1
            .Selection.Fields.Add Range:=.Selection.Range, Type:=-1, PreserveFormatting:=False
            .Selection.TypeText Text:="= " & OverallPageNumber & " +"
        End With
        .Execute
    Wend
End With

1 ответ

Решение

Я уверен, что ваш метод поиска и замены будет выделять текст #OVERALLPAGENUMBER# каждый раз, когда он проходит. Если это так, вы можете заменить storyRange.Fields.Add Range:=storyRange, Type:=-1, Text:="PAGE", PreserveFormatting:=True со следующим, который просто поместит требуемый код поля в текущий выбор:

Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, PreserveFormatting:=False
Selection.TypeText Text:="= 5 +"
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, PreserveFormatting:=False
Selection.TypeText Text:="PAGE"
Selection.Fields.Update

Изменить: предыдущий код работает только если PreserveFormatting установлен в False, Похоже, что Word обновляет пустой код поля, если PreserveFormatting установлен в True, Вы можете перемещаться по выделенному фрагменту, чтобы сохранить форматирование следующим образом. Вам нужно только PreserveFormatting для внешнего поля.

Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, PreserveFormatting:=True
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Fields.ToggleShowCodes
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.MoveRight Unit:=wdCharacter, Count:=1
Selection.TypeText Text:="= 5 +"
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, PreserveFormatting:=False
Selection.TypeText Text:="PAGE"
Selection.Fields.Update

Я знаю, что это устарело, но, пытаясь сделать это вчера, я нашел более простое решение для создания вложенных полей, чем использование объекта Selection. Единственные решения, которые я нашел в Интернете, неправильно говорят о том, что нет возможности вставлять вложенные поля без использования объекта Selection. Однако я обнаружил, что вы можете вставить вложенное поле в диапазон Field.Code, что упрощает работу с кодом, делает его более быстрым и интуитивно понятным. Как в:

Dim storyRange As Object 'Word.Range
For Each storyRange In oDoc.StoryRanges
    Do
        With storyRange.Find
            .Text = "#OVERALLPAGENUMBER#"
            .Wrap = 1 'wdFindContinue
            .Execute
            While .Found
                Set fld1 = storyRange.Fields.Add(Range:=storyRange, Type:=-1, Text:="=p+" & OverallPageNumber, PreserveFormatting:=False)
                Set fld2 = storyRange.Fields.Add(Range:=fld1.Code.Characters(3), Type:=-1, Text:="PAGE", PreserveFormatting:=False)
                fld1.Update
                .Execute
            Wend
        End With
        On Error Resume Next
        Set storyRange = storyRange.NextStoryRange
        On Error GoTo 0
    Loop While Not storyRange Is Nothing
Next
Другие вопросы по тегам