Можно ли использовать 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 ответ

Решение

Существует ряд возможностей для "нацеливания" кодов полей на действие. Я считаю, что я продублировал ваши настройки защиты в моих тестах...

  1. Ближайший подход, который вы использовали до сих пор:

    ActiveWindow.View.ShowFieldCodes = True 'False, чтобы отключить их

  2. Лично мне не нравится изменять вещи на экране, перед пользователем, если нет другого способа выполнить задачу или если это не имеет заметного различия в скорости. Это означает, что я использую объект 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 не меняет диалоговое окно.

  1. Вместо использования 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), так как он яснее о происходящем и меньше кода.

Другие вопросы по тегам