При формировании печатных форм в формате Microsoft Word программисты 1С часто сталкиваются с ситуацией, когда заранее подготовленный макет таблицы имеет ограниченное количество строк. Если данных (например, номенклатуры в заказе) оказывается больше, чем строк в шаблоне, возникает необходимость динамического расширения таблицы. Стандартный вызов метода Rows.Add() без параметров добавляет строку строго в конец таблицы, что нарушает структуру документа, если после таблицы идет подвал (итоговые суммы, подписи). Рассмотрим, как решить эту задачу и вставлять строки именно в то место, где они необходимы.
Разберем самый чистый и эффективный способ с точки зрения объектной модели Word. Многие разработчики используют метод Add() коллекции Rows без аргументов. Однако этот метод принимает необязательный параметр, который указывает, перед какой строкой нужно вставить новую. Если мы передаем этот объект, Word раздвигает таблицу в нужном нам месте.
Проанализируем пример кода, где мы вставляем строку перед пятой строкой существующей таблицы:
// Получаем доступ к нужной таблице
Таблица = Документ.Tables(1);
// Определяем строку, ПЕРЕД которой нужно сделать вставку
СтрокаОриентир = Таблица.Rows(5);
// Выполняем вставку
Таблица.Rows.Add(СтрокаОриентир);
Важный нюанс: если вам нужно вставить строку после пятой, в качестве параметра метода Add следует передать шестую строку. При этом не забывайте, что после вставки индексы всех последующих строк сместятся на единицу, что нужно учитывать в счетчиках циклов.
Выясним причину, по которой у автора темы из обсуждения не получалось вставить строку в нужное место с помощью InsertRowsBelow. В его коде использовалась команда Документ.Tables(1).Select(), которая выделяет всю таблицу целиком. В этом случае Word по умолчанию считает «точкой вставки» конец выделения. Чтобы вставить строку в середину, нам нужно выделить конкретную ячейку или строку.
Рассмотрим правильный алгоритм работы через Selection:
InsertRowsBelow(1) для вставки ниже или InsertRowsAbove(1) для вставки выше.Пример реализации на языке 1С:
// Допустим, нам нужно вставить строку после текущей заполняемой строки (СтрокаНомер)
Таблица = Документ.Tables(1);
Таблица.Cell(СтрокаНомер, 1).Select(); // Выделяем первую колонку текущей строки
// Используем объект приложения для управления выделением
Ворд.Selection.InsertRowsBelow(1);
Этот способ удобен тем, что он имитирует действия пользователя, но он работает медленнее, чем прямое обращение к коллекции Rows, так как требует визуального перестроения фокуса в документе.
Зачастую просто добавить пустую строку недостаточно. Строки в макетах Word часто содержат специфическое форматирование: объединенные ячейки, установленные шрифты, границы или даже формулы. При обычном Rows.Add() новая строка может потерять эти свойства. Чтобы сохранить оформление, лучше всего использовать метод копирования «эталонной» строки.
Посмотрим на пример реализации такого подхода:
Таблица = Документ.Tables(1);
// Копируем в буфер обмена строку-шаблон (например, вторую строку таблицы)
Таблица.Rows(2).Range.Copy();
// Выбираем место вставки (строка, на место которой мы хотим вставить копию)
Таблица.Rows(ТекущийИндекс).Range.Paste();
Обратите внимание: метод Paste() в данном контексте может замещать содержимое текущей строки или вставлять новую в зависимости от настроек вставки Word. Для гарантированной вставки новой строки с форматированием часто комбинируют методы: сначала создают пустую строку через Rows.Add(Ориентир), а затем копируют в нее Range из шаблона.
Проанализируем ситуацию: если в документе сотни строк, постоянное обращение к COM-объекту для добавления каждой строки по отдельности может занять значительное время. Для ускорения работы рекомендуем придерживаться следующих правил:
Ворд.Application.ScreenUpdating = Ложь;
// ... ваш цикл заполнения ...
Ворд.Application.ScreenUpdating = Истина;
ЗаказПокупателя.Товары, эффективнее один раз добавить нужное количество строк в таблицу, а затем просто заполнять их данными по индексам ячеек, не вызывая методы вставки внутри цикла.Selection и метода Select(). Прямое обращение через Tables(N).Cell(R, C).Range.Text работает значительно быстрее и стабильнее.Разберем основные моменты, на которых спотыкаются разработчики:
Ворд.Visible = Истина) в процессе отладки, чтобы не оставлять в памяти системы «зависшие» процессы WINWORD.EXE при возникновении ошибок в коде 1С.Используя приведенные выше методы, вы сможете гибко управлять структурой таблиц в Word, создавая профессиональные и динамичные печатные формы любой сложности.