Как средствами 1С в MS Word удалить строку (абзац), содержащую определенный текст

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При формировании печатных форм в формате MS Word через механизм Active Document или COM-соединение часто возникает задача динамического изменения структуры документа. Одной из самых распространенных проблем является необходимость полного удаления строки или целого абзаца, если в нем встречается определенный текст или если переменная (параметр) оказалась пустой. Простое замещение текста пустой строкой "" не решает задачу, так как в документе остается пустой абзац (пустая строка), что портит визуальное оформление.

В этой статье мы подробно разберем, как программно найти и полностью удалить абзац, чтобы текст снизу автоматически подтянулся вверх, и какие нюансы работы с объектами Word.Application следует учитывать.

Понятие «строки» в объектной модели MS Word

Прежде всего, проанализируем важный технический нюанс: в объектной модели Microsoft Word на программном уровне отсутствует строгое понятие «строка», так как текст динамически переносится в зависимости от шрифта, полей и размера страницы. То, что мы видим как строку, является либо Абзацем (Paragraph), либо частью текста внутри него. Поэтому, когда мы говорим об удалении «строки», мы чаще всего имеем в виду удаление всего абзаца, который содержит искомый текст.

Решение №1: Поиск текста и удаление абзаца через Selection

Рассмотрим наиболее популярный способ, основанный на использовании объекта Selection (выделение). Логика работы заключается в том, чтобы найти нужный фрагмент текста, «захватить» весь абзац, в котором он находится, и выполнить команду удаления.

Для реализации этого метода мы будем использовать следующие константы VBA (их нужно определить в 1С или использовать числовые значения):

Посмотрим на пример кода:


// Предположим, Word — это уже созданный COM-объект Word.Application
Selection = Word.Selection;
Find = Selection.Find;

// Настраиваем параметры поиска
Find.Text = "ТекстКоторыйНужноНайти";
Find.ClearFormatting();
Find.Forward = Истина;

// Выполняем поиск. Если текст найден, метод Execute вернет Истина
Если Find.Execute() Тогда
    // Перемещаемся в начало абзаца, где найден текст
    Selection.MoveUp(4, 1); // 4 — это wdParagraph
    
    // Выделяем весь абзац целиком
    Selection.MoveDown(4, 1, 1); // Третий параметр 1 — это wdExtend
    
    // Удаляем выделенный фрагмент
    Selection.Delete();
КонецЕсли;

Выясним причину использования MoveUp и MoveDown: метод Find.Execute выделяет только сам искомый текст. Чтобы удалить всю строку (абзац), нам нужно расширить это выделение до границ абзаца.

Решение №2: Циклическое удаление всех вхождений

Если искомый текст встречается в документе несколько раз и нужно удалить все строки с ним, проанализируем ситуацию с использованием цикла Пока. Рассмотрим готовую процедуру, которую можно встроить в любой модуль 1С:


Процедура Word_УдалитьАбзацСодержащийСтрокуПоиска(WordApplication, СтрокаПоиска)
    
    Find = WordApplication.Selection.Find;
    Find.Text = СтрокаПоиска;
    
    // Цикл по всем найденным вхождениям
    Пока Find.Execute() Цикл
        // Получаем текущее выделение (оно нашло текст)
        ТекущееВыделение = WordApplication.Selection;
        
        // Расширяем и удаляем
        ТекущееВыделение.MoveUp(4, 1); // wdParagraph
        ТекущееВыделение.MoveDown(4, 1, 1); // wdParagraph, 1 шаг, wdExtend
        ТекущееВыделение.Delete();
        
        // После удаления выделение сбрасывается, Find продолжит с новой позиции
    КонецЦикла;
    
КонецПроцедуры

Решение №3: Удаление через механизм закладок (Bookmarks)

Как показывает практика, работа с поиском текста может быть нестабильной, если текст формируется динамически или содержит спецсимволы. Самый надежный и профессиональный метод — использование Закладок (Bookmarks). Вы можете заранее в макете Word выделить всю строку (абзац) и назначить ей имя закладки.

Рассмотрим подробнее этот подход:

  1. В шаблоне Word выделите строку и выберите Вставка -> Закладка. Назовите ее, например, УдаляемаяСтрока1.
  2. В коде 1С, если условие для удаления выполняется, обратитесь к закладке напрямую.

// Проверяем существование закладки перед удалением
ИмяЗакладки = "УдаляемаяСтрока1";
Если Word.ActiveDocument.Bookmarks.Exists(ИмяЗакладки) Тогда
    // Выделяем область закладки
    Word.ActiveDocument.Bookmarks.Item(ИмяЗакладки).Select();
    // Удаляем выделение (вместе с абзацем)
    Word.Application.Selection.Delete();
КонецЕсли;

Этот метод считается лучшим, так как он не зависит от содержания текста и гарантированно удаляет именно ту область, которую вы разметили в макете.

Работа с DOCVARIABLE и полями

Часто в макетах используются поля типа { DOCVARIABLE "ИмяПеременной" }. Если вы программно установили значение переменной Word.Variables.Item("ИмяПеременной").Value = "Удалить";, обычный поиск Find.Execute может не найти этот текст, так как он видит «код поля», а не его результат.

Чтобы решить эту проблему, выполним следующие шаги: Во-первых, необходимо обновить поля в документе перед поиском: Word.ActiveDocument.Fields.Update();. Во-вторых, можно использовать замену спецсимволов. Например, замену текста вместе со знаком абзаца на «ничего».


Find = Word.Application.Selection.Find;
Find.Text = "УдалитьСтроку" + Символы.ВК; // Добавляем символ возврата каретки
Find.Replacement.Text = "";
Find.Execute(,,,,,,,,,, 2); // 2 — это wdReplaceAll

Оптимизация: Удаление пустых строк после обработки

Иногда удобнее сначала заменить весь ненужный текст на пустые строки, а в самом конце одним действием «схлопнуть» документ, удалив все лишние переходы на новую строку. В Word знак абзаца обозначается кодом ^p.

Посмотрим на пример удаления двойных абзацев:


Selection = Word.Application.Selection;
Selection.Find.ClearFormatting();
Selection.Find.Replacement.ClearFormatting();
Selection.Find.Text = "^p^p"; // Ищем два знака абзаца подряд
Selection.Find.Replacement.Text = "^p"; // Заменяем на один
Selection.Find.Execute(,,,,,,,,,, 2); // wdReplaceAll

Важные советы по работе с COM-объектами

При работе с 1С и Word важно помнить о «гигиене» памяти. После выполнения всех операций обязательно закрывайте приложение и освобождайте переменные:

Подведем итог: если структура документа жесткая — используйте закладки. Если структура гибкая и заранее неизвестно, что придется удалять — используйте поиск с расширением области выделения до абзаца (wdParagraph). Это обеспечит корректное смещение текста вверх и сохранит профессиональный вид вашего печатного документа.

← На главную