При разработке печатных форм, отчетов и специфических обработок в платформе 1С:Предприятие часто возникает задача создать дубликат или независимую копию существующего объекта ТабличныйДокумент. Начинающие разработчики нередко сталкиваются с проблемой: при передаче документа в функцию или попытке простого присвоения создается лишь еще одна ссылка на тот же самый объект в оперативной памяти, а не его независимый клон.
Рассмотрим, почему простой перенос ссылок не работает и какими способами можно получить полноценную копию табличного документа со всеми его ячейками, рисунками, сеткой и параметрами печати.
Объект ТабличныйДокумент относится к объектным типам данных платформы 1С. Использование ключевого слова Знач в параметрах процедур или функций копирует только указатель (ссылку) на область памяти. В результате любые изменения, внесенные в переданный документ внутри функции, будут отражаться и на исходном документе.
У объекта ТабличныйДокумент отсутствует встроенный метод вроде Скопировать() или Клон(), поэтому для решения задачи необходимо использовать альтернативные подходы платформы.
Наиболее быстрый, удобный и универсальный способ создать полную независимую копию — это использовать сериализацию в оперативную память с помощью объекта ХранилищеЗначения. Так как объект ТабличныйДокумент поддерживается механизмом сериализации, его можно поместить в хранилище и сразу же извлечь оттуда.
Разберем пример кода:
КопияТабДок = Новый ХранилищеЗначения(ИсходныйТабДок).Получить();
Преимущества данного метода:
АвтоМасштаб.Еще один рабочий способ создания точного клона без использования файловой системы — преобразование табличного документа в строку XML с последующим восстановлением объекта средствами платформы.
Посмотрим на реализацию этого способа:
СтрокаXML = ЗначениеВXML(ИсходныйТабДок);
КопияТабДок = ЗначениеИзXML(СтрокаXML);
Этот вариант работает аналогично хранилищу значений, сохраняя полную структуру документа и его параметры, однако может требовать чуть больше ресурсов на парсинг XML-строки.
Если по каким-то причинам требуется промежуточное сохранение или работы ведутся с файловой системой, можно записать документ во временный файл формата MXL методом Записать() и прочитать его в новый объект с помощью метода Прочитать().
Проанализируем пример кода:
ИмяФайла = ПолучитьИмяВременногоФайла("mxl");
ИсходныйТабДок.Записать(ИмяФайла);
КопияТабДок = Новый ТабличныйДокумент;
КопияТабДок.Прочитать(ИмяФайла);
УдалитьФайлы(ИмяФайла);
Данный метод гарантирует точное совпадение копии с оригиналом, однако при частых вызовах операции ввода-вывода на диске могут снижать производительность системы.
При формировании сложных отчетов или сборке печатной формы из нескольких частей разработчики иногда пытаются перенести содержимое методами Вывести() или ПолучитьОбласть(). Важно учитывать, что выведение областей копирует ячейки и их базовое форматирование, но теряет настройки самого документа (параметры печати, отображение сетки, колонтитулы и т.д.).
В таком случае свойства документа приходится копировать отдельно с помощью функции ЗаполнитьЗначенияСвойств().
Рассмотрим процедуру для переноса основных настроек табличного документа:
Процедура СкопироватьНастройкиТабДокумента(ТДИсточник, ТДПриемник)
СписокСвойств = "АвтоМасштаб,РазмерСтраницы,ИспользуемоеИмяФайла,ОтображатьЗаголовки,ОтображатьСетку,ТолькоПросмотр,КлючПараметровПечати,ОриентацияСтраницы,ШиринаСтраницы,ВысотаСтраницы";
ЗаполнитьЗначенияСвойств(ТДПриемник, ТДИсточник, СписокСвойств);
КонецПроцедуры
Важное замечание: При поэтапном выводе областей могут потеряться рисунки, параметры колонтитулов и именованные области. Поэтому для получения полной и точной копии объекта рекомендуется использовать Способ 1 с помощью ХранилищеЗначения.