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

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

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

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

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

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

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

Какие способы копирования строк существуют

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

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

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

Сравнение вариантов

Добавить() + ЗаполнитьЗначенияСвойств

Подходит для копирования отдельных строк и при разной структуре таблиц; переносятся только одноимённые колонки

Скопировать()

Подходит для копирования всей таблицы или строк по отбору; структура колонок сохраняется полностью

Выгрузить()

Подходит для выгрузки табличной части документа или справочника в новую таблицу значений

Ручное присваивание колонок

Подходит при полностью разной структуре, когда нужен контроль над каждым полем; требует больше кода

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

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

ТЗИсточник = ПолучитьТаблицуТоваров();

ТЗПриёмник = Новый ТаблицаЗначений;

ТЗПриёмник.Колонки.Добавить("Номенклатура");

ТЗПриёмник.Колонки.Добавить("Количество");

ТЗПриёмник.Колонки.Добавить("Цена");

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

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

НоваяСтрока = ТЗПриёмник.Добавить();

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

КонецЕсли;

КонецЦикла;

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

У метода есть третий необязательный параметр — список исключаемых свойств. Например, ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника, , "Цена") скопирует все совпадающие колонки, кроме «Цена».

Копирование всех строк или строк по отбору через Скопировать

Метод Скопировать() вызывается у таблицы-источника и возвращает новую таблицу значений. Без параметров он копирует структуру колонок и все строки целиком.

// Полная копия таблицы

ТЗКопия = ТЗИсточник.Скопировать();

// Копия только строк, удовлетворяющих отбору

Отбор = Новый Структура("Склад", СкладОсновной);

ТЗПоСкладу = ТЗИсточник.Скопировать(Отбор);

// Копия с ограничением состава колонок

ТЗКраткая = ТЗИсточник.Скопировать(, "Номенклатура, Количество");

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

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

Выгрузка строк из табличной части документа

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

// Выгрузить всю табличную часть документа

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

// Выгрузить только часть колонок

ТЗКратко = ДокументОбъект.Товары.Выгрузить(, "Номенклатура, Количество, Сумма");

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

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

Копирование при разной структуре колонок

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

НоваяСтрока = ТЗПриёмник.Добавить();

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

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

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

Такой способ незаменим, когда при копировании нужно выполнить преобразования: вычислить итоговое поле, подставить значение по умолчанию, привести тип. Заодно он делает код самодокументируемым — видно, какое поле откуда берётся.

Перед копированием проверьте, что колонки приёмника созданы и имеют подходящий тип. Присваивание значения несуществующей колонке вызовет ошибку «Поле объекта не обнаружено» в момент выполнения.

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

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

После переноса строк убедитесь, что данные действительно попали в приёмник. Самая частая проверка — количество строк: ТЗПриёмник.Количество() должно совпадать с ожидаемым числом.

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

Отдельно проверьте колонки со ссылочными типами: ссылки копируются как ссылки, и это нормально, но значения примитивных типов (числа, строки, даты) должны совпадать до копейки и до секунды. Расхождение обычно означает, что колонка не перенеслась из-за несовпадения имён.

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

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

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

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

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

Строк меньше — не сработал отбор или условие в цикле

Значения ключевых колонок
Норма

Суммы, количество и ссылки совпадают с источником

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

Пустые значения — имена колонок не совпадают

Состав колонок приёмника
Норма

Все нужные поля созданы до начала копирования

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

Ошибка «Поле объекта не обнаружено» при выполнении

Типичные ошибки и ограничения

Самая распространённая ошибка — попытка присвоить строку целиком: НоваяСтрока = СтрокаИсточника. Такое присваивание не добавляет строку в таблицу-приёмник; переменная просто начинает ссылаться на строку источника, и изменения затронут исходную таблицу.

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

Третья группа ошибок связана с типами колонок. Если колонка приёмника создана с ограниченным типом (например, только «Число» с длиной 10), значение большей длины будет усечено или приведёт к ошибке. Создавайте колонки с составным типом через ОписаниеТипов, когда заранее неизвестно, какие данные придут.

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

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

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

Используйте ТЗПриёмник = ТЗИсточник.СкопироватьКолонки() — метод создаст пустую таблицу с той же структурой колонок. После этого добавляйте строки через Добавить() и ЗаполнитьЗначенияСвойств() в цикле с нужным отбором.

Можно ли скопировать строки из таблицы значений в дерево значений?

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

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

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

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

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

Что быстрее: цикл с Добавить() или Скопировать() с отбором?

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

Как перенести строки между таблицами на управляемой форме?

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

Итог

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

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