Настройка вложенного поля в 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