Можно ли использовать Fields.ToggleShowCodes в защищенном документе Word?
У меня есть документ Word с поддержкой макросов (.docm), и я использую Word 2007.
Один макрос применяет стиль "Интенсивная ссылка" ко всем перекрестным ссылкам.
Я пытаюсь использовать Fields.ToggleShowCodes
показать поля перед поиском ссылок.
Проблема в том, что это работает только тогда, когда документ не защищен. Есть ли способ сделать это, когда документ защищен?
У меня есть обходной путь; я могу использовать SendKeys("%{F9}")
нажать ALT+F9. Это работает, но это некрасиво. Я действительно придираюсь, но я думаю, что мог бы быть лучший способ.
РЕДАКТИРОВАТЬ:
Для справки: это шаблон для документов с контролем версий. Защита ограничивает стили, которые можно использовать, и блокирует части документа, например верхний и нижний колонтитулы, которые содержат свойства документа и историю изменений. Эти свойства вводятся с помощью форм (многие из них являются пользовательскими). Редактируемые части основного текста реализованы в виде исключений, применимых для всех - это то место, где находятся перекрестные ссылки.
РЕДАКТИРОВАТЬ 2:
Вот код (за исключением макроса CharFormat, который не имеет значения):
Sub InitUpdate()
'
' InitUpdate Macro - shows field codes (ALT+F9), waits 1ms (to allow for
' key presses), then calls the ExecUpdate macro.
' Used at the start of the Update Refs procedure.
'
SendKeys "%{F9}"
Application.OnTime When:=Now + 0.001, Name:="ExecUpdate"
End Sub
Sub IntenseRef()
'
' IntenseRef Macro - changes all cross references to
' 'intense reference' style (bold and blue text).
' Used in Update Refs procedure.
'
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.Style = ActiveDocument.Styles("Intense Reference")
With Selection.Find
.Text = "^19 REF"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchKashida = False
.MatchDiacritics = False
.MatchAlefHamza = False
.MatchControl = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
' Replace method causes an error if it runs before the active doc. has been
' clicked (i.e. when the file is first opened) or header/footer editing mode
' is enabled.
On Error GoTo ErrHandler
Selection.Find.Execute Replace:=wdReplaceAll
Exit Sub
ErrHandler:
If Err <> 0 Then
MsgBox ("Select anywhere in the main text first...")
Err.Clear
End If
End Sub
Sub ExecUpdate()
'
' ExecUpdate Macro - changes reference styles.
' Field codes are then hidden (ALT+F9) and the fields are updated.
' Used in Update Refs procedure (final part).
'
CharFormat
IntenseRef
SendKeys "%{F9}"
ActiveDocument.Fields.Update
End Sub
РЕДАКТИРОВАТЬ 3:
Добавлен комментарий к коду, объясняющий необходимость обработчика ошибок.
1 ответ
Существует ряд возможностей для "нацеливания" кодов полей на действие. Я считаю, что я продублировал ваши настройки защиты в моих тестах...
Ближайший подход, который вы использовали до сих пор:
ActiveWindow.View.ShowFieldCodes = True 'False, чтобы отключить их
Лично мне не нравится изменять вещи на экране, перед пользователем, если нет другого способа выполнить задачу или если это не имеет заметного различия в скорости. Это означает, что я использую объект Range, где это возможно, вместо Selection. У объекта Range есть свойство, которое позволяет получать доступ к полевым кодам, даже если они не отображаются:
Range.TextRetrievalMode.IncludeFieldCodes
, Но тогда вы должны также использовать Range вместо Selection для Find.
Для начала:
Dim rng As word.Range
Set rng = ActiveDocument.content
rng.TextRetrievalMode.IncludeFieldCodes = True
With rng.Find
'And so on, as you already have
Другое различие между Range.Find и Selection.Find заключается в том, что параметры последнего влияют на диалоговое окно в пользовательском интерфейсе, а использование Range.Find не меняет диалоговое окно.
- Вместо использования Find, зациклите коллекцию Fields в документе, проверьте Field.Type и, если это поле REF, примените стиль.
Что-то вроде этого:
Sub LoopRefFields()
Dim fld As word.Field
For Each fld In ActiveDocument.Fields
If fld.Type = wdFieldRef Then
fld.code.Style = "Intense Reference"
End If
Next
End Sub
Если документ содержит много полей, вы можете проверить, какой подход наиболее быстрый. Лично я предпочитаю (3), так как он яснее о происходящем и меньше кода.