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

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

Как перенести данные из одной табличной части в другую в 1С

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

Табличные части — основной способ хранения строк документов и справочников в 1С: товары в накладной, начисления в расчёте зарплаты, услуги в акте. Задача перенести строки из одной табличной части в другую возникает постоянно: при вводе документа на основании, при объединении данных, при исправлении ошибок ввода. Инструмент зависит от того, кто вы — пользователь, работающий в интерфейсе, или разработчик, пишущий код.

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

Определите, какой у вас сценарий переноса

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

Если структуры совпадают и объекты разные, часто достаточно стандартного ввода на основании — он уже реализован в типовых конфигурациях. Если структуры различаются, потребуется сопоставление полей вручную в коде. Разовый перенос проще сделать обработкой, регулярный — встроить в бизнес-процесс документа.

Маршрут решения

Как выбрать способ переноса

Нужно создать документ на основе другого с теми же строкамиИспользуйте кнопку «Создать на основании» — типовой механизм уже переносит табличные части
Строки нужно перенести внутри одного документа между вкладкамиИспользуйте копирование строк через контекстное меню или простую процедуру на форме
Структуры табличных частей различаются или нужен отбор строкПишите программный перенос с сопоставлением реквизитов
Перенос массовый и повторяющийсяСоздайте внешнюю обработку заполнения табличной части

Ручной перенос строк в интерфейсе

В управляемых формах 1С строки табличной части можно скопировать стандартными средствами. Выделите нужные строки (с зажатой клавишей Ctrl или Shift), нажмите правую кнопку мыши и выберите «Копировать», либо используйте сочетание Ctrl+C. Затем перейдите в целевую табличную часть и вставьте строки через Ctrl+V или пункт «Вставить» контекстного меню.

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

Ограничение метода — отсутствие контроля. Платформа не проверит, заполнены ли обязательные реквизиты целевой табличной части, не пересчитает суммы и не подставит значения по умолчанию. После ручной вставки обязательно проверьте итоговые суммы документа и проведите его, чтобы убедиться в отсутствии ошибок.

Программный перенос перебором строк

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

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

Если СтрокаИсточник.Количество = 0 Тогда

Продолжить;

КонецЕсли;

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

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

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

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

КонецЦикла;

Обратите внимание на фильтр внутри цикла: строки с нулевым количеством пропускаются. Именно такая возможность отбора — главное преимущество перебора перед механическим копированием. Если имена реквизитов в обеих табличных частях совпадают, можно упростить заполнение через ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник) — функция скопирует все одноимённые свойства.

Работая с документом-получателем, не забудьте после заполнения пересчитать зависимые данные: суммы строк, итоги по документу, налоги. В типовых конфигурациях для этого есть процедуры обработчика ПриИзменении соответствующих реквизитов — вызывайте их программно для каждой добавленной строки или пересчитайте итоги по завершении цикла.

bsl
Для Каждого СтрокаИсточник Из Источник.Товары Цикл
    НоваяСтрока = Приемник.Товары.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);
КонецЦикла;

Перенос через выгрузку в таблицу значений

Когда нужно перенести всю табличную часть целиком без изменений, эффективнее выгрузить её в таблицу значений методом Выгрузить() и загрузить в приёмник методом Загрузить(). Это работает быстрее цикла на больших объёмах и требует минимум кода.

ТаблицаДанных = ОбъектИсточник.Товары.Выгрузить();

ОбъектПриемник.Товары.Загрузить(ТаблицаДанных);

Метод Загрузить() полностью замещает содержимое целевой табличной части — существующие строки будут удалены. Если нужно добавить строки к уже имеющимся, используйте цикл по таблице значений или метод Выгрузить с последующим добавлением строк вручную. Кроме того, Загрузить() требует совпадения колонок: лишние колонки в таблице значений вызовут ошибку, поэтому при разных структурах выгружайте только нужные колонки через параметр метода Выгрузить(, "Номенклатура, Количество, Цена").

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

Перенос между разными документами и обработка заполнения

При переносе между объектами, например из «Заказа покупателя» в «Реализацию товаров», правильное место для кода — процедура ОбработкаЗаполнения в модуле объекта документа-получателя. Она вызывается при вводе на основании и получает ссылку на документ-источник в параметре.

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

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

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Товары.Номенклатура, Товары.Количество

|ИЗ Документ.ЗаказПокупателя.Товары КАК Товары

|ГДЕ Товары.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ДанныеЗаполнения);

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

КонецЕсли;

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

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

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

Типичные ошибки и как их избежать

Самая частая ошибка — перенос значений без учёта типов. Если в источнике реквизит ссылочного типа, а в приёмнике — строка, присвоение пройдёт без ошибки, но данные окажутся бессмысленными. Всегда сверяйте типы колонок в конфигураторе перед написанием кода переноса.

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

Типичные ошибки
01
Использование Загрузить() без учёта того, что существующие строки приёмника будут удалены
02
Перенос строк без пересчёта сумм и итогов — документ показывает неверные итоги
03
Игнорирование различий типов реквизитов источника и приёмника
04
Забытый вызов Записать() — перенесённые данные теряются при закрытии формы
05
Копирование служебных колонок вроде номера строки, что нарушает нумерацию

Проверка результата переноса

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

Для документов выполните проведение: система контроля остатков и заполнения реквизитов выявит незаполненные поля и отрицательные остатки, которые возникли из-за некорректного переноса. Если перенос массовый, проверьте выборочно несколько документов из начала, середины и конца списка — этого достаточно, чтобы убедиться в стабильности алгоритма.

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

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

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

Совпадает с учётом заданного отбора

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

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

Итоговые суммы табличных частей
Норма

Суммы равны

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

Расхождение — ищите пропущенные или задвоенные строки

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

Проводится без сообщений об ошибках

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

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

Обязательные реквизиты строк
Норма

Все поля заполнены

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

Пустые колонки, которых не было в источнике

Частые вопросы

Можно ли перенести табличную часть между документами разных видов без программирования?

Да, если в конфигурации настроен ввод на основании: откройте документ-источник и нажмите «Создать на основании». Типовые конфигурации переносят табличные части автоматически. Если нужной пары документов нет в списке — без доработки или внешней обработки не обойтись.

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

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

Почему после Загрузить() пропали строки, которые были в документе раньше?

Метод Загрузить() предварительно очищает табличную часть — это его штатное поведение. Чтобы добавить строки к существующим, обходите таблицу значений циклом и используйте Добавить() для каждой строки.

Как перенести данные, если имена реквизитов в табличных частях разные?

Присваивайте значения явно по каждому полю: НоваяСтрока.Материал = СтрокаИсточник.Номенклатура. Функция ЗаполнитьЗначенияСвойств здесь не поможет — она копирует только одноимённые свойства. Составьте таблицу соответствия полей перед написанием кода.

Нужно ли перепроводить документ после программного переноса строк?

Да. Изменение табличной части делает прежние движения документа неактуальными. После записи объекта выполните проведение, чтобы регистры отразили новые данные, иначе отчёты покажут старые значения.

Как объединить одинаковые товары при переносе?

Выгрузите табличную часть в таблицу значений и вызовите метод Свернуть("Номенклатура", "Количество, Сумма") — строки с одинаковой номенклатурой сгруппируются, а количество и сумма сложатся. Затем загрузите результат в приёмник.

Итог

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

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