Как вывести повторяющиеся блоки данных и динамические таблицы в макет Word из 1С

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

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

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

Метод 1: Использование «образца» и копирование блоков через буфер обмена

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

Рассмотрим пошагово, как это реализовать в коде 1С:


// 1. Инициализация приложения и получение макета
МакетОбъект = ПолучитьМакет("МойМакетWord");
MSWord = МакетОбъект.Получить();
Документ = MSWord.Application.Documents(1);
MSWord.Application.Visible = Ложь; // Отключаем видимость для ускорения

// 2. Определяем область-образец (например, первый абзац и первая таблица)
// Можно использовать закладку, чтобы точно выделить нужный кусок
RangeОбразец = Документ.Content; 
RangeОбразец.Copy(); // Копируем эталонный блок в буфер обмена

// 3. Основной цикл по данным (например, по сотрудникам)
Для Каждого СтрокаСотрудник Из СписокСотрудников Цикл
    
    // Переходим в конец документа для вставки нового блока
    КонецДокумента = Документ.Range();
    КонецДокумента.Collapse(0); // 0 соответствует константе wdCollapseEnd
    КонецДокумента.Paste();
    
    // Теперь работаем с только что вставленным фрагментом
    // Выполняем замену параметров (ФИО, Должность и т.д.)
    Замена = КонецДокумента.Find;
    Замена.Execute("[ФИО]", , , , , , , , , СтрокаСотрудник.ФИО, 2);
    
    // Работа с таблицей внутри вставленного блока
    // Обычно это будет последняя таблица в документе
    ТекущаяТаблица = Документ.Tables(Документ.Tables.Count);
    
    // Заполняем таблицу данными по конкретному сотруднику
    Для Каждого СтрокаДанных Из СтрокаСотрудник.ТаблицаДанных Цикл
        НоваяСтрока = ТекущаяТаблица.Rows.Add();
        НоваяСтрока.Cells(1).Range.Text = СтрокаДанных.Номер;
        НоваяСтрока.Cells(2).Range.Text = СтрокаДанных.Описание;
    КонецЦикла;
    
    // Удаляем пустую первую строку, если она была создана в макете как заголовок
    // Или просто начинаем заполнение со второй строки
КонецЦикла;

// 4. Удаляем самый первый (эталонный) блок, если он остался в начале
// Либо очищаем его в самом начале работы.

Метод 2: Работа с динамическими таблицами через объект Table

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

Для обращения к конкретной ячейке используется конструкция Таблица.Cell(НомерСтроки, НомерКолонки). Важно помнить, что нумерация в Word начинается с 1, а не с 0.

Пример программного создания и заполнения таблицы:


// Предположим, мы нашли нужную таблицу по индексу или через закладку
Попытка
    Таблица = Документ.Tables(1);
Исключение
    Сообщить("Таблица не найдена в макете!");
    Возврат;
КонецПопытки;

// Обойдем выборку данных
НомерСтрокиВорд = 2; // Допустим, первая строка - шапка
Для Каждого Данные Из Выборка Цикл
    Если НомерСтрокиВорд > 2 Тогда
        Таблица.Rows.Add(); // Добавляем новую строку, если данных больше, чем одна
    КонецЕсли;
    
    // Заполняем ячейки
    Таблица.Cell(НомерСтрокиВорд, 1).Range.Text = Данные.Артикул;
    Таблица.Cell(НомерСтрокиВорд, 2).Range.Text = Данные.Номенклатура;
    Таблица.Cell(НомерСтрокиВорд, 3).Range.Text = Данные.Количество;
    
    НомерСтрокиВорд = НомерСтрокиВорд + 1;
КонецЦикла;

Использование закладок (Bookmarks) для точного позиционирования

Разберем ситуацию, когда данных много и они разбросаны по документу. Использование простого поиска текста (например, <Организация>) может быть ненадежным, если это сочетание символов случайно встретится в основном тексте. Профессиональнее использовать «Закладки».

  1. В макете Word выделите место или текст и выберите Вставка -> Закладка. Дайте ей имя, например ПодписьДиректора.
  2. В коде 1С обращайтесь к ней напрямую.

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


// Запись значения в место закладки
Если Документ.Bookmarks.Exists("ПодписьДиректора") Тогда
    Закладка = Документ.Bookmarks("ПодписьДиректора");
    Закладка.Range.Text = "Иванов И.И.";
КонецЕсли;

Важный нюанс: при записи текста в закладку через свойство Range.Text сама закладка удаляется (заменяется текстом). Если вам нужно сохранить закладку для повторного обращения, потребуется более сложная манипуляция с сохранением диапазона Range.

Оптимизация производительности и завершение работы

Работа с COM-объектами MS Word через 1С — процесс довольно медленный. Проанализируем несколько советов, которые помогут ускорить формирование отчета и избежать зависания системы:

Всегда используйте конструкцию Попытка...Исключение для корректного закрытия приложения:


Попытка
    // Основной код заполнения...
    MSWord.Application.Visible = Истина;
Исключение
    Сообщить("Ошибка при печати: " + ОписаниеОшибки());
    // Если произошла ошибка, принудительно закрываем Word без сохранения
    MSWord.Application.Quit(0); // 0 = wdDoNotSaveChanges
КонецПопытки;

Подведем итоги

Мы рассмотрели три основных способа решения задачи автора. Для вывода списка сотрудников с персональными таблицами лучше всего подходит комбинированный метод: копирование блока-образца в цикле и последующее динамическое добавление строк в таблицу этого блока. Это позволяет сохранить сложное форматирование шаблона и при этом выводить неограниченный объем данных.

Используя объектную модель Tables, Rows и Cells, вы получаете полный контроль над структурой документа, что недоступно при использовании только функции «Найти и заменить».

← На главную