К статье
Практический материал

Разработка и Конфигурация · 9 мин

1С: как скопировать одну табличную часть в другую

Как скопировать табличную часть документа в другую табличную часть в 1С: методы Загрузить, Выгрузить, Заполнить, примеры кода для обычных и управляемых форм.

Копирование табличной части из одного документа в другой — типовая задача в 1С: заполнение реализации на основании заказа, перенос строк между документами, создание корректировок. В зависимости от того, где выполняется код (на сервере, в модуле объекта, на клиенте в управляемой форме), применяются разные методы: «Загрузить», «Выгрузить», «Заполнить» или построчное копирование.

Ключевой момент — табличная часть объекта и данные табличной части на форме ведут себя по-разному. В модуле объекта доступна сама коллекция строк, а в управляемой форме работа идёт через «ДанныеФормыКоллекция», и методы «Выгрузить/Загрузить» там недоступны напрямую. Именно из-за этой разницы у начинающих разработчиков возникает большинство ошибок.

Ниже рассмотрены рабочие способы копирования с примерами кода, условия их применения, типичные ошибки и способы проверки результата.

Способ 1: методы Выгрузить и Загрузить

Самый короткий вариант — выгрузить табличную часть в таблицу значений и загрузить её в приёмник. Метод «Выгрузить» возвращает таблицу значений со всеми колонками табличной части, а «Загрузить» заполняет коллекцию строк из этой таблицы.

// Копирование табличной части "Товары" из заказа в реализацию

ДокументРеализация.Товары.Загрузить(ДокументЗаказ.Товары.Выгрузить());

Метод «Загрузить» полностью замещает содержимое табличной части приёмника: все строки, которые были там до вызова, удаляются. Если нужно добавить строки к существующим, используйте построчное копирование (см. ниже).

Колонки сопоставляются по именам. Если в приёмнике нет колонки, которая есть в источнике, данные из неё просто не попадут в результат. Если в приёмнике есть колонка, отсутствующая в источнике, она останется пустой — её придётся заполнить отдельно (например, ставку НДС или склад из шапки документа).

Способ 2: построчное копирование через ЗаполнитьЗначенияСвойств

Когда нужно добавить строки к существующим, скопировать не все колонки или выполнить преобразование данных по ходу, применяется перебор строк с добавлением новых строк в приёмник.

Для Каждого СтрокаИсточник Из ДокументЗаказ.Товары Цикл

НоваяСтрока = ДокументРеализация.Товары.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);

// Дозаполнение колонок, которых нет в источнике

НоваяСтрока.Склад = СкладОтгрузки;

КонецЦикла;

«ЗаполнитьЗначенияСвойств» копирует значения одноимённых свойств. Можно передать список копируемых свойств вторым параметром, а исключения — третьим. Это удобно, когда нужно перенести только номенклатуру и количество, а цены пересчитать по текущим условиям.

Учтите, что «ЗаполнитьЗначенияСвойств» копирует и служебные свойства строки, если они совпадают по имени. В большинстве случаев это безопасно, но при нестандартной структуре лучше явно перечислить нужные колонки.

Способ 3: копирование в управляемой форме

В модуле управляемой формы табличная часть представлена как «ДанныеФормыКоллекция», у которой нет методов «Выгрузить» и «Загрузить». Здесь два рабочих подхода.

Построчное копирование на клиенте

Если источник тоже доступен на форме (например, вторая табличная часть того же объекта), строки перебираются напрямую:

Для Каждого СтрокаИсточник Из Объект.Товары Цикл

НоваяСтрока = Объект.Материалы.Добавить();

ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);

КонецЦикла;

Копирование через серверный вызов

Если источник — другой документ из базы, правильнее выполнить копирование на сервере. В тонком клиенте это делается через серверную процедуру с «&НаСервере», где объект приёмника получается через «РеквизитФормыВЗначение», заполняется и возвращается через «ЗначениеВРеквизитФормы».

&НаСервере

Процедура ЗаполнитьИзЗаказаНаСервере(ЗаказСсылка)

ДокОбъект = РеквизитФормыВЗначение("Объект");

ДокОбъект.Товары.Загрузить(ЗаказСсылка.Товары.Выгрузить());

ЗначениеВРеквизитФормы(ДокОбъект, "Объект");

КонецПроцедуры

Такой подход корректно работает с транзакцией формы и не требует записи документа до заполнения.

Порядок действий для копирования на сервере
  1. 1
    Получите объект приёмника: ссылка.ПолучитьОбъект() или РеквизитФормыВЗначение в форме
  2. 2
    Очистите или подготовьте табличную часть приёмника при необходимости
  3. 3
    Выполните Загрузить(Источник.ТабличнаяЧасть.Выгрузить()) или построчный цикл
  4. 4
    Дозаполните колонки, отсутствующие в источнике
  5. 5
    Запишите объект и проверьте результат в форме документа

Способ 4: стандартный механизм «Ввод на основании»

Если задача — заполнять один документ на основании другого, не всегда нужно писать код копирования вручную. В типовых конфигурациях предусмотрен механизм заполнения: в модуле объекта приёмника реализуется процедура «ОбработкаЗаполнения», которая получает документ-основание и заполняет табличные части.

Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)

Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда

Товары.Загрузить(ДанныеЗаполнения.Товары.Выгрузить());

КонецЕсли;

КонецПроцедуры;

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

Копирование между табличными частями с разной структурой

Частая ситуация: имена или состав колонок в источнике и приёмнике различаются. Например, в заказе колонка называется «КоличествоЗаказано», а в реализации — «Количество». В этом случае «Загрузить» не поможет — нужен построчный перенос с явным указанием соответствия.

Для Каждого СтрокаИсточник Из Заказ.Товары Цикл

НоваяСтрока = Реализация.Товары.Добавить();

НоваяСтрока.Номенклатура = СтрокаИсточник.Номенклатура;

НоваяСтрока.Количество = СтрокаИсточник.КоличествоЗаказано;

НоваяСтрока.Цена = СтрокаИсточник.Цена;

КонецЦикла;

Альтернатива — выгрузить в таблицу значений и переименовать колонки через «Колонки.Найти» перед загрузкой, но при разной бизнес-логике строк явный перебор читается и отлаживается проще.

Типичные ошибки
01
Вызов Выгрузить/Загрузить у реквизита формы — ошибка «Метод объекта не обнаружен», нужен серверный вызов с РеквизитФормыВЗначение
02
Загрузить затирает уже введённые пользователем строки — уточните у пользователя или используйте Добавить в цикле
03
Копирование ссылки вместо объекта: у ссылки табличная часть доступна только для чтения, изменять нужно объект
04
Забытые колонки приёмника без аналогов в источнике остаются пустыми — документ не проводится из-за незаполненных обязательных реквизитов
05
Копирование в ОбработкаЗаполнения без проверки ТипЗнч(ДанныеЗаполнения) — ошибка при создании документа другим способом

Проверка результата и ограничения

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

Учитывайте ограничения. Табличная часть ссылки доступна только для чтения — для изменения всегда нужен объект. При копировании больших табличных частей (тысячи строк) построчный перебор с обращениями к базе внутри цикла замедлит работу: выносите запросы за пределы цикла. В управляемой форме массовое добавление строк на клиенте может вызвать множество серверных вызовов — переносите такую логику на сервер.

Контрольные точки

Как проверить результат

Количество строк
Норма

Совпадает с числом строк источника

Тревожный признак

Строк меньше или больше — проверьте, не было ли фильтрации или дублей

Итоги по суммам и количеству
Норма

Итоги приёмника равны итогам источника

Тревожный признак

Расхождение — не скопировались колонки цен или сработал пересчёт

Проведение документа
Норма

Документ проводится без сообщений об ошибках

Тревожный признак

Ошибки о незаполненных реквизитах — дозаполните колонки после копирования

FAQ

Как скопировать табличную часть, не удаляя существующие строки?

Используйте построчный перебор с методом «Добавить» и «ЗаполнитьЗначенияСвойств» вместо «Загрузить». Метод «Загрузить» всегда полностью замещает содержимое табличной части приёмника.

Почему в управляемой форме не работает Выгрузить/Загрузить?

Реквизит формы с табличной частью имеет тип «ДанныеФормыКоллекция», у которого этих методов нет. Решение — серверная процедура с преобразованием «РеквизитФормыВЗначение», копирование в объекте и обратное преобразование «ЗначениеВРеквизитФормы».

Можно ли скопировать только часть строк по условию?

Да. В построчном цикле добавьте проверку «Если» перед добавлением строки. Либо выгрузите в таблицу значений и используйте «НайтиСтроки» с отбором, затем загрузите результат через временную таблицу.

Копируются ли итоги и подчинённые данные вместе со строками?

Копируются только значения колонок строк. Итоги, скидки, серии, штрихкоды и связанные данные пересчитываются прикладной логикой документа — после копирования вызовите соответствующие процедуры пересчёта или заполните их вручную.

Как скопировать табличную часть в таблицу значений для обработки?

Вызовите «ТаблицаЗначений = Объект.ТабличнаяЧасть.Выгрузить()». Полученную таблицу можно отсортировать, свернуть, отфильтровать и затем загрузить обратно или использовать в запросе через временную таблицу.

Что делать, если после копирования документ не проводится?

Смотрите текст сообщений об ошибках: чаще всего это незаполненные обязательные колонки приёмника, которых нет в источнике (склад, ставка НДС, счета учёта). Дозаполните их после цикла копирования из шапки документа или настроек по умолчанию.

Итог

Что важно запомнить

На сервере и в модуле объекта копируйте через Загрузить(Выгрузить()), в управляемой форме — построчно или через серверный вызов с РеквизитФормыВЗначение. Загрузить затирает существующие строки, а колонки без аналогов в источнике нужно дозаполнять вручную. Результат проверяйте по числу строк, итогам и успешному проведению.