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