Vba и поиск и замена слов

Обновлено: 06.07.2024

При использовании утилиты «Найти или заменить» в меню «Правка» текст будет найден или заменен независимо от того, где он находится в документе. Однако если вы запишете это действие, оно будет воздействовать только на текст в теле документа и не повлияет на текст, который находится в верхних или нижних колонтитулах документа, например, в текстовом поле, сносках или любая другая область, которая находится за пределами основной части документа.

Чтобы использовать макрос для поиска или замены текста, независимо от того, где он находится в документе, необходимо пройтись по каждому из StoryRanges в документе.

Существует 11 различных типов историй, которые могут быть частью документа, соответствующих следующим константам WdStoryType:

wdCommentsStory, wdEndnotesStory, wdEvenPagesFooterStory, wdEvenPagesHeaderStory, wdFirstPageFooterStory, wdFirstPageHeaderStory, wdFootnotesStory, wdMainTextStory, wdPrimaryFooterStory, wdPrimaryHeaderStory и wdTextFrameStory.

Следующий код будет перебирать первую статью для каждого типа материалов в документе, заменяя все экземпляры текста, который должен быть заменен в первой статье каждого типа:

Затемнить myStoryRange как диапазон

Для каждого myStoryRange в ActiveDocument.StoryRanges
С myStoryRange.Find
.Text = "findme"
.Replacement.Text = ""
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
Завершить
следующим myStoryRange

(Примечание для тех, кто уже знаком с VBA: в то время как при использовании Selection.Find необходимо указать все параметры поиска и замены, например .Forward = True, поскольку в противном случае настройки берутся из параметров поиска и замены. текущие настройки диалога, которые являются «липкими», в этом нет необходимости, если используется [Range].Find — где параметры используют свои значения по умолчанию, если вы не указываете их значения в своем коде).

Как упоминалось ранее, приведенный выше код будет действовать только для первой истории для каждого типа истории в документе. (Первый заголовок, первое текстовое поле и т. д.). Если ваш документ содержит разделы с несвязанными верхними и нижними колонтитулами или, например, содержит более одного текстового поля, код не будет действовать на второе и последующие вхождения каждого типа материала. Таким образом, чтобы убедиться, что код действует при каждом появлении текста, независимо от того, где он появляется, вы должны использовать метод NextStoryRange, как в следующем коде:

Затемнить myStoryRange как диапазон

Для каждого myStoryRange в ActiveDocument.StoryRanges
С myStoryRange.Find
.Text = "findme"
.Replacement.Text = ""
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
Завершить с помощью
Делать, пока нет (myStoryRange.NextStoryRange — ничто)
Установить myStoryRange = myStoryRange.NextStoryRange
С myStoryRange.Find
. Text = "findme"
.Replacement.Text = ""
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
Завершить
Цикл
Далее мой диапазон историй

Проблемы с циклическим переключением StoryRanges и некоторые обходные пути

Одним из способов решения этой проблемы является разработка всех ваших шаблонов таким образом, чтобы ни один из заголовков не был пустым — вставьте пробел во все пустые заголовки. Если это изменяет макет этого раздела, примените другой стиль в этом заголовке, чтобы он не менялся. Другого удовлетворительного обходного пути на самом деле не существует по причинам, которые вскоре будут обсуждаться в отдельной статье.

Скорость макроса
Еще одна проблема с приведенным выше кодом заключается в том, что он может быть очень медленным, если документ большой или если он содержит большое количество диапазонов статей. Это особенно проблема в Word 97. В Word 97 использование Selection.Find выполняется намного быстрее, чем использование [Range].Find. Таким образом, вы можете значительно ускорить приведенный выше код в Word 97, используя вместо этого следующее:

Затемнить myStoryRange как диапазон

'Сначала выполните поиск в основном документе, используя Выделение
С выделением.Найти
.Text = "findme"
.Replacement.Text = ""
.Forward = True < br />.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

'Теперь ищите все остальные истории, используя диапазоны
Для каждого myStoryRange In ActiveDocument.StoryRanges
If myStoryRange.StoryType <> wdMainTextStory Then
With myStoryRange.Find
.Text = " findme"
.Replacement.Text = ""
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
Завершить
Делать, пока нет (myStoryRange.NextStoryRange Is Nothing )
Set myStoryRange = myStoryRange.NextStoryRange
With myStoryRange.Find
.Text = "findme"
.Replacement.Text = ""
.Wrap = wdFindContinue
/>.Execute Replace:=wdReplaceAll
Завершить
Цикл
Завершить, если
Следующий myStoryRange

И самый быстрый, но ненадежный обходной путь.

Если вы хотите, чтобы ваш код выполнялся так же быстро, как замена через пользовательский интерфейс, и/или если вы хотите, чтобы он был полностью невосприимчив к ошибке "заголовки пропускаются, если первый заголовок пуст", единственный решение состоит в том, чтобы вызвать диалог Word «Найти и заменить» напрямую, выполнив кнопку меню (использование коллекции диалогов Word не помогает); и используя команду SendKeys для ее выполнения. Вы можете установить настройки диалогового окна так, как вы хотите, используя With Selection.Find . Конец с конструкцией без команды .Execute, прежде чем вы нажмете кнопку меню. Вам нужно будет включить DoEvents в свой код, чтобы команда могла завершить поиск.

Но использование SendKeys, как известно, ненадежно, особенно в этом случае, потому что диалоговое окно «Найти и заменить» немодально; так что это, как правило, не очень хороший метод. Он упоминается здесь для полноты картины.

Информация, иллюстрации и код, содержащиеся в моих "Советах по Microsoft Word", предоставляются бесплатно и без каких-либо рисков или обязательств.

Однако работа принадлежит мне. Если вы используете его в коммерческих целях или извлекаете выгоду из моих усилий в виде заработанного дохода или сэкономленного времени, то пожертвование, каким бы небольшим оно ни было, поможет обеспечить постоянную доступность этого ресурса.

Если вы хотите сделать пожертвование, используйте соответствующую кнопку пожертвования для доступа к PayPal. Спасибо!

Целью этой страницы советов и справки Microsoft Word является обсуждение и предоставление решения VBA для поиска и замены текста везде, где он может появиться в документе. Этот контент представляет собой измененную версию моей статьи на ту же тему, ранее опубликованную на веб-сайте часто задаваемых вопросов по Word MVP. Благодарим Дуга Роббинса, Питера Хьюетта и Джонатана Уэста за их вклад в эту статью.

Фон

Используя утилиту «Найти или заменить» в меню «Правка», вы можете найти или заменить текст «почти» в любом месте документа. Однако, если вы запишете это действие, область или «диапазон» результирующего записанного макроса будет действовать только на текст, содержащийся в теле документа (или, точнее, он будет действовать только на ту часть документа, которая содержит вставку). точка). Это означает, что если точка вставки находится в основной части документа, когда ваш макрос выполняется, он не повлияет на текст, который находится в верхних или нижних колонтитулах документа, например, или в текстовом поле, сносках или любая другая область, которая находится за пределами основной части документа.

В Word 2007 и более ранних версиях даже встроенная утилита «Найти и заменить» имеет недостаток. Например, текст в текстовом поле, расположенном в верхнем или нижнем колонтитуле, выходит за рамки диапазона поиска утилиты «Найти и заменить».

Существует от одиннадцати до семнадцати констант wdStoryType, которые могут формировать StoryRanges (или части) документа. Не все сюжетные диапазоны используются в каждом документе. Семнадцать возможных типов материалов в документе Word 2016 показаны ниже.

fr_anywhere_1

Базовый код

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

Дополнительный совет. Если вы не знаете, при использовании метода Selection.Find следует указать все параметры поиска и замены, например .Forward = True, поскольку в противном случае значения берутся из диалогового окна «Найти и заменить». текущие настройки, которые являются «липкими». В этом нет необходимости при использовании Range.Find, так как параметры являются их значениями по умолчанию, если вы не укажете значение в своем коде.

Приведенный выше базовый макрос имеет недостаток. Он действует только на «первый» StoryRange каждого из (одиннадцати-семнадцати) StoryType.

Хотя в документе есть только один диапазон StoryRange wdMainTextStory, он может иметь один или несколько диапазонов StoryRange в нескольких других типах StoryType. Например, документ может содержать несколько текстовых полей или несколько разделов с несвязанными верхними или нижними колонтитулами. Каждый из этих нескольких элементов является StoryRange в StoryType. Базовый код обрабатывает только первый StoryRange в этих типах StoryType.

Промежуточный код

Чтобы убедиться, что код работает с каждым StoryRange в каждом StoryType, вам необходимо:

  • Используйте метод NextStoryRange
  • Используйте небольшой «хитрость» VBA (предложенный Питером Хьюиттом для соединения) с любыми пустыми несвязанными верхними и нижними колонтитулами.

Упомянутый выше «обман» VBA просто возвращает значение StoryType основного заголовка раздела One. Доказано, что это устраняет проблему VBA, связанную с «перескакиванием» пустых несвязанных верхних и нижних колонтитулов и продолжением обработки последовательных верхних и нижних колонтитулов.

В приведенном выше промежуточном коде остается один недостаток. Как и утилита меню «Найти и заменить» в более ранних версиях Word, этот код не сможет обработать текстовые поля и фигуры, привязанные к StoryRange верхнего/нижнего колонтитула.

Полный код

Решение проблемы с текстовыми полями и формами верхнего/нижнего колонтитула заключается в том, что текстовые поля и фигуры содержатся в коллекции ShapeRange документа. Сначала мы проверяем ShapeRange каждого из шести StoryRange верхнего и нижнего колонтитула в каждом разделе документа на наличие формы. Если фигура найдена, мы затем проверяем .TextFrame.TextRange фигуры для параметра .Find.Text.

Этот последний макрос содержит весь код для поиска и замены текста «где угодно» в документе. Добавлено несколько усовершенствований, упрощающих применение нужного поиска и замены текстовых строк:

Примечание. Эта страница с советами, иллюстрации и примеры были разработаны с использованием Word 2016. Они полностью функциональны с Word 2003–2016.

Вот оно! Я надеюсь, что вы нашли эту страницу советов полезной и информативной.

Хотите ли вы оплатить консультационную работу или сделать пожертвование для поддержки этого сайта?

PayPal — это безопасный и простой способ оплаты в Интернете.

Используйте кнопку "Пожертвовать" в соответствующей валюте, чтобы сделать платеж или пожертвование.

Информация, иллюстрации и код, содержащиеся в моих "Советах по Microsoft Word", предоставляются бесплатно и без каких-либо рисков или обязательств.

Однако работа принадлежит мне. Если вы используете его в коммерческих целях или извлекаете выгоду из моих усилий в виде заработанного дохода или сэкономленного времени, то пожертвование, каким бы небольшим оно ни было, поможет обеспечить постоянную доступность этого ресурса.

Если вы хотите сделать пожертвование, используйте соответствующую кнопку пожертвования для доступа к PayPal. Спасибо!

Цель этой страницы справки и советов по Microsoft Word — предоставить сообществу пользователей Word «VBA Find and Replace©», надстройку шаблона Word для Word 2003\2007\2010.

VBA Find and Replace© предоставляет метод для поиска и замены текста в любом месте документа (или коллекции документов) с использованием отдельных определяемых пользователем пар переменных "найти" и "заменить" или заданного пользователем списка "найти" и "заменить". «заменить» пары. Он также предоставляет метод поиска текста и замены найденного текста пользовательской записью «Автотекст» или «Стандартный блок».

Эта надстройка существует уже некоторое время, и за эти годы я внес несколько "быстрых" изменений и модификаций, чтобы поддержать предложения ее многочисленных пользователей и поклонников. В результате он стал довольно сложным и немного громоздким, поэтому в этом релизе я решил придать ему свет и полностью переработать код. Цель, конечно же, заключалась в том, чтобы сделать надстройку проще в использовании. Я думаю, что я сделал это, но вы, пользователь, последний судья.

Существует две версии надстройки. Версии с одинаковыми номерами почти идентичны, за исключением пользовательских элементов управления, используемых для запуска надстройки. Версия .dot работает в Word2003\2007\2010. Версия .dotm предназначена для пользователей Word2007\2010. Элементы управления пользовательского интерфейса (UI) и их расположение показаны ниже.

Примечание. До этого обновления я не использовал нумерацию версий с этой надстройкой. Чтобы не сбивать с толку текущих пользователей, я начал нумерацию версий с 2.0.

Команда меню< бр />


В версии .dot добавлена ​​команда меню Word 2003

Команда ленты< бр />


В версиях .dot и .dotm добавлена ​​вкладка надстроек ленты Word 2007/2010

Команда группы FR


Версии .dotm добавить ленту Word 2007/2010 Вкладка «Главная»>Редактирование группы управления

Выполнение любого из элементов управления пользовательского интерфейса отображает пользовательский интерфейс надстройки. Как видно из рисунка, функции отключены до тех пор, пока они не будут квалифицированы. Например, вы не можете "ВЫПОЛНИТЬ" или определить пару переменных "Найти что/Заменить на" до тех пор, пока не будет выбран параметр "Искать с помощью".

Панель пользовательского интерфейса VBA FR

Примечание. Поскольку эта надстройка изначально предназначалась для выполнения нескольких операций поиска и замены с использованием определенного списка, по умолчанию установлено значение "Искать только слова целиком".

Выбор «одного слова/фразы» в качестве параметра поиска определяет и включает соответствующие элементы управления для пользовательского ввода. Обратите внимание, что вы по-прежнему не можете "ВЫПОЛНИТЬ", потому что вы не определили допустимую переменную "Найти что".

Панель пользовательского интерфейса VBSA FR

Определение термина "Найти что" определяет остальные элементы управления, что позволяет пользователю выполнить операцию.

VBA FR UI Panel 2

Примечание. Как и в случае со встроенной утилитой замены, если оставить поле «Заменить на» пустым, будет удален (ничего не заменен) любой найденный текст при выполнении процесса. Возможно, вас это раздражает, но на этот случай я добавил требование подтверждения.

VBA FR UI Panel 3

Если выбран параметр "Одно слово/фраза" и определена запись в поле "Найти что", становится доступной опция "Ввод автотекста (в качестве замены). Эта мощная функция позволяет выбрать определенный автотекст\строительный блок запись для использования в качестве переменной «Заменить на».

Панель пользовательского интерфейса VBA FR

После выполнения "ВЫБЕРИТЕ АВТОТЕКСТ" пользователь выбирает и вставляет предопределенный элемент автотекста\строительного блока из отображаемого диалогового окна. Этот процесс автоматически копирует выбранную запись AutoText\Building Block в системный буфер обмена, и надстройка использует содержимое буфера обмена в качестве переменной «Заменить на»


Примечание. Параметр "Автоматический ввод текста (в качестве замены)" доступен только с параметром поиска "одно слово/фраза".


Остальные параметры «Искать с помощью» используют один из трех определяемых пользователем списков, содержащих пары «Найти» и «Заменить», для выполнения повторяющихся операций замены в одном документе из коллекции документов в выбранной пакетной папке. Как пример «QuickList» показан ниже.


Надстройка предоставляет пользователю обратную связь по мере выполнения/завершения операции.


Журнал выполнения доступен при использовании параметра "Обрабатывать файлы в пакетной папке".


Кнопка "Информация/советы" предоставляет информацию и советы по использованию надстройки.

Дополнительные сведения о надстройках шаблонов и о том, как их загрузить, см. в разделе Организация ваших макросов/надстроек шаблонов по адресу: Установка макросов

Вот оно! Я надеюсь, что вы нашли эту страницу советов полезной и информативной.

Хотите ли вы оплатить консультационную работу или сделать пожертвование для поддержки этого сайта?

PayPal — это безопасный и простой способ оплаты в Интернете.

Используйте кнопку "Пожертвовать" в соответствующей валюте, чтобы сделать платеж или пожертвование.

Свойство Find возвращает объект Find, который можно использовать для поиска в диапазоне.

Свойства и методы

< TR>
Шрифт
ОчиститьФорматирование
FormatНужно ли искать форматирование в дополнение к тексту поиска или вместо него??< /TD>
Replacement
Выполнить
Вперед
Найдено
Frame
Выделение
MatchCase
MatchWholeWord
MatchWildcards
Без проверки правописания
ParagraphFormat
Стиль
Текст
Обтекание

Найти.Выполнить

FindText — необязательный вариант.Текст для поиска. Используйте пустую строку ("") для поиска только форматирования. Вы можете искать специальные символы, указав соответствующие коды символов. Например, «^p» соответствует знаку абзаца, а «^t» соответствует символу табуляции. Список специальных символов, которые вы можете использовать, см. в разделе Поиск и замена текста или других элементов.
MatchCase — необязательный вариант. Значение true, чтобы указать, что текст поиска чувствителен к регистру. Соответствует флажку «Учитывать регистр» в диалоговом окне «Найти и заменить» (меню «Правка»).
MatchWholeWord — необязательный вариант. Значение true, чтобы операция поиска находила только целые слова, а не текст, являющийся частью более крупного слова. Соответствует флажку «Найти только слова целиком» в диалоговом окне «Найти и заменить».
MatchWildcards — необязательный вариант. Значение true, чтобы текст поиска был специальным оператором поиска. Соответствует флажку «Использовать подстановочные знаки» в диалоговом окне «Найти и заменить».
MatchSoundsLike — необязательный вариант. Значение true, чтобы операция поиска находила слова, похожие на текст поиска. Соответствует флажку «Звучит как» в диалоговом окне «Найти и заменить».
MatchAllWordForms — необязательный вариант. Значение true, чтобы операция поиска нашла все формы искомого текста (например, "сидеть" находит "сидит" и "сидел"). Соответствует флажку «Найти все словоформы» в диалоговом окне «Найти и заменить».
Вперед - необязательный вариант. True для поиска вперед (к концу документа).

Перебор всех вхождений

Вы можете использовать свойство Found объекта Find для перебора нескольких найденных элементов вместо того, чтобы каждый раз проверять возвращаемое значение Execute.

Перебор абзацев в документе происходит очень медленно
Если вы ищете определенный текст, всегда используйте Range.Find

Замена тегов HTML

Если вы хотите найти и заменить специальные символы, вам может понадобиться поставить перед ними обратную косую черту

При успешном выполнении метода Execute объекта Find возвращается новый объект Range

В следующем примере выполняется поиск следующего абзаца с двойным интервалом после выделения.

В этом примере выполняется поиск всех абзацев с двойным интервалом в активном документе и замена форматирования на 1,5-строчный интервал.

В этом примере последовательно перебираются слова в myRange (от начала активного документа до конца выделения) и удаляется слово "BetterSolutions" (включая завершающий пробел), где бы оно ни встречалось в диапазоне.

Читайте также: