Разработка и Конфигурация · 11 мин
Как скопировать табличный документ в другой табличный документ в 1С
Способы скопировать табличный документ в 1С: метод Скопировать(), Вывести(), ВставитьОбласть(), ПолучитьОбласть(). Примеры кода, типичные ошибки и FAQ.
Табличный документ в 1С — это объект «ТабличныйДокумент», который используется для печатных форм, отчетов и вывода данных пользователю. Задача скопировать один табличный документ в другой возникает часто: при объединении нескольких печатных форм, при выводе нескольких документов в одну форму, при сохранении промежуточного результата перед доработкой или при программной сборке итогового листа из нескольких частей.
В языке 1С есть несколько способов выполнить такое копирование: метод Скопировать(), доступный в новых версиях платформы, вывод документа целиком через Вывести(), копирование отдельных областей через ПолучитьОбласть() и ВставитьОбласть(), а также перенос содержимого через файл формата MXL. Выбор зависит от версии платформы, того, нужно ли копировать документ целиком или частично, и требуется ли сохранить форматирование, группировки и именованные области.
Ниже разобраны все рабочие сценарии с готовыми примерами кода, ограничениями каждого подхода и способами проверить результат. Примеры написаны на встроенном языке 1С и подходят как для управляемых, так и для обычных форм.
Какие объекты участвуют в копировании
Копирование выполняется между двумя объектами типа «ТабличныйДокумент»: источником и приемником. Источником может быть результат вызова функции печати, документ, загруженный из файла MXL, макет типа «ТабличныйДокумент» или реквизит формы. Приемник — обычно новый пустой табличный документ, который затем выводится пользователю или сохраняется.
Важно понимать, что табличный документ — это не просто сетка ячеек, а сложная структура: форматирование, объединенные ячейки, группировки строк, именованные области, параметры страницы, рисунки. Разные методы копирования переносят разный набор этих элементов, поэтому выбор способа напрямую влияет на результат.
Копирование целиком через метод Вывести()
Самый универсальный способ, работающий во всех актуальных версиях платформы, — метод Вывести(). Он добавляет содержимое исходного документа в конец приемника вместе с форматированием ячеек, объединениями и рисунками.
ТабДокИсточник = СформироватьПечатнуюФорму(СсылкаНаДокумент);
ТабДокПриемник = Новый ТабличныйДокумент;
ТабДокПриемник.Вывести(ТабДокИсточник);
// При необходимости — перенос параметров страницы
ТабДокПриемник.АвтоМасштаб = Истина;
ТабДокПриемник.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
Обратите внимание: Вывести() переносит область данных, но не переносит параметры страницы источника (поля, ориентацию, колонтитулы). Их нужно установить у приемника отдельно, иначе при печати документ может «разъехаться». Также метод добавляет содержимое в конец — если вызывать его несколько раз, документы последовательно допишутся друг за другом, что удобно для пакетной печати.
- 1Получите исходный табличный документ (из функции печати, макета или файла MXL)
- 2Создайте новый объект: Новый ТабличныйДокумент
- 3Вызовите Приемник.Вывести(Источник)
- 4Установите параметры страницы приемника: ориентацию, поля, масштаб
- 5Проверьте результат через Показать() или тестовую печать
Метод Скопировать() в новых версиях платформы
Начиная с платформы 8.3.9 у объекта «ТабличныйДокумент» есть метод Скопировать(), который создает полную копию документа, включая свойства самого объекта. Это самый «чистый» способ получить идентичный дубликат.
КопияТабДок = ТабДокИсточник.Скопировать();
Метод возвращает новый объект, поэтому дальнейшие изменения копии не затрагивают оригинал. Это важно: простое присваивание Копия = Источник не создает копию, а лишь дублирует ссылку на тот же объект — изменения отразятся в обеих переменных.
Если конфигурация должна работать на старых версиях платформы, проверьте режим совместимости: метод может быть недоступен, и код вызовет ошибку «Метод объекта не обнаружен». В таких случаях используйте Вывести() или перенос через MXL.
Копирование отдельных областей через ПолучитьОбласть() и ВставитьОбласть()
Когда нужно перенести не весь документ, а его часть — например, только шапку, конкретные строки или именованную область, — используется пара методов ПолучитьОбласть() и ВставитьОбласть().
// Копирование именованной области
ОбластьИсточника = ТабДокИсточник.ПолучитьОбласть("Шапка");
ТабДокПриемник.ВставитьОбласть(ОбластьИсточника.Область(),
ТабДокПриемник.Область(1, 1));
// Копирование диапазона строк с 5 по 10
ОбластьСтрок = ТабДокИсточник.ПолучитьОбласть("R5:R10");
ТабДокПриемник.ВставитьОбласть(ОбластьСтрок.Область("R1:R6"),
ТабДокПриемник.Область("R20"));
Метод ВставитьОбласть() требует указания области-назначения и по умолчанию вставляет содержимое со сдвигом существующих ячеек. Параметр «Сдвиг» управляет поведением: можно вставить область с раздвижкой вниз или вправо. Если нужно просто заполнить ячейки без раздвижки, рассмотрите альтернативу — последовательный вывод областей через Вывести(), который дописывает область в конец документа.
Для копирования по ячейкам существует и низкоуровневый подход — перебор ячеек источника с переносом Текст и свойств оформления. Он трудоемок и почти всегда избыточен: применяйте его только когда нужно выборочно трансформировать содержимое, а не копировать как есть.
// Перенос документа через файл MXL (универсально для любых версий)
ИмяФайла = ПолучитьИмяВременногоФайла("mxl");
ТабДокИсточник.Записать(ИмяФайла);
ТабДокПриемник = Новый ТабличныйДокумент;
ТабДокПриемник.Прочитать(ИмяФайла);
УдалитьФайлы(ИмяФайла);Перенос через файл MXL и объединение нескольких документов
Способ с записью во временный MXL-файл работает на любой версии платформы и сохраняет практически все свойства документа, включая параметры страницы. Минус — обращение к файловой системе: на сервере нужны права на временный каталог, а в веб-клиенте потребуется асинхронный механизм работы с файлами. Поэтому MXL чаще используют для обмена документами между базами, а не для копирования внутри одного сеанса.
Частая практическая задача — объединить печатные формы нескольких документов в один табличный документ для общей печати. Здесь применяется цикл с Вывести() и разделителями страниц:
ИтоговыйДокумент = Новый ТабличныйДокумент;
Первый = Истина;
Для Каждого Ссылка Из МассивДокументов Цикл
ТабДок = СформироватьПечатнуюФорму(Ссылка);
Если Не Первый Тогда
ИтоговыйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
ИтоговыйДокумент.Вывести(ТабДок);
Первый = Ложь;
КонецЦикла;
Метод ВывестиГоризонтальныйРазделительСтраниц() гарантирует, что каждая печатная форма начнется с новой страницы. Без него формы сольются, и нумерация страниц собьется.
Сравнение вариантов
Универсально, работает везде, удобно для объединения. Не переносит параметры страницы источника.
Полная копия объекта одной строкой. Требует платформу 8.3.9+, копирует только целиком.
Гибкий перенос частей документа. Требует аккуратной работы с адресами областей.
Сохраняет максимум свойств, подходит для обмена между базами. Нужен доступ к файловой системе.
Как проверить результат и типичные ошибки
После копирования откройте приемник методом Показать() или выведите на печать в тестовом режиме. Проверьте три вещи: полноту данных (количество строк и итоги), форматирование (шрифты, границы, объединенные ячейки) и разбиение на страницы. Если приемник создавался как пустой документ, его параметры страницы — стандартные, и они могут отличаться от задуманных.
Наиболее частая проблема — потеря ориентации страницы и полей при копировании через Вывести(). Вторая типичная ситуация — пустой приемник: если источник не был заполнен (например, функция печати вернула Неопределено), копирование пройдет без ошибок, но результат будет пустым. Всегда проверяйте, что источник содержит данные, например через ТабДокИсточник.ВысотаТаблицы > 0.
Как проверить результат
Все строки, итоги и надписи источника на месте
Часть данных отсутствует или обрезана
Шрифты, границы, объединения совпадают с источником
Потеряны границы ячеек или объединения
Разбиение на страницы корректное, поля как задано
Строки переносятся, документ выходит за поля
Практические рекомендации по выбору способа
Для большинства задач внутри одного сеанса достаточно Вывести() — он предсказуем, совместим со старыми платформами и позволяет наращивать документ частями. Если нужна точная копия объекта «один в один» и платформа не старше 8.3.9, берите Скопировать(). Частичный перенос областей оправдан при сборке нестандартных форм из кусков нескольких макетов.
При работе в клиент-серверном режиме помните, что табличный документ передается между клиентом и сервером целиком. Копирование больших документов (тысячи строк) лучше выполнять на сервере, чтобы не гонять объемные данные по сети лишний раз.
Что важно запомнить
Копируйте табличный документ через Вывести() в новый объект или методом Скопировать() (платформа 8.3.9+). Отдельные части переносите через ПолучитьОбласть() и ВставитьОбласть(). Не используйте простое присваивание и не забывайте про параметры страницы приемника.
Частые вопросы
Копируется ли форматирование ячеек при выводе через Вывести()?
Да, метод Вывести() переносит текст, форматирование, объединения ячеек и рисунки. Не переносятся только параметры страницы (поля, ориентация, колонтитулы) — их нужно установить у приемника отдельно.
Почему после «Копия = Источник» изменения появляются в обоих документах?
Присваивание не создает копию объекта, а копирует ссылку на тот же экземпляр в памяти. Обе переменные работают с одним документом. Для независимой копии используйте Скопировать() или Вывести() в новый ТабличныйДокумент.
Как скопировать табличный документ из макета?
Получите макет через ПолучитьМакет("ИмяМакета") — он уже вернет объект ТабличныйДокумент, с которым можно работать напрямую или вывести его в другой документ методом Вывести(). Изменения полученного экземпляра не затрагивают сам макет в конфигурации.
Работает ли копирование в тонком и веб-клиенте?
Методы Вывести(), Скопировать(), ПолучитьОбласть() и ВставитьОбласть() доступны во всех клиентах. Ограничение касается только переноса через MXL-файл: в веб-клиенте работа с файловой системой требует асинхронных методов и расширения для работы с файлами.
Как скопировать только значения ячеек без оформления?
Переберите ячейки источника в цикле и переносите только свойство Текст: Приемник.Область(НомерСтроки, НомерКолонки).Текст = Источник.Область(НомерСтроки, НомерКолонки).Текст. Границы перебора определяйте через ВысотаТаблицы и ШиринаТаблицы источника.
Можно ли объединить табличные документы из разных баз 1С?
Да, но напрямую объект между базами не передать. Сохраните документ в MXL-файл методом Записать(), передайте файл (через каталог, хранилище значения или веб-сервис) и прочитайте в другой базе методом Прочитать(). Формат MXL сохраняет содержимое и оформление.