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

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

1С: таблица значений — как скопировать строку

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

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

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

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

Базовый способ: Добавить и ЗаполнитьЗначенияСвойств

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

НоваяСтрока = ТаблицаЗначений.Добавить();

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

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

Если нужно перенести только часть колонок, их имена перечисляются третьим параметром через запятую:

ЗаполнитьЗначенияСвойств(НоваяСтрока, ИсходнаяСтрока, "Номенклатура, Количество, Цена");

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

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

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

Для Каждого Колонка Из ТаблицаИсточник.Колонки Цикл

ТаблицаПриемник.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);

КонецЦикла;

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

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

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

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

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

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

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

Копирование нескольких строк с отбором

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

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

НайденныеСтроки = ТаблицаИсточник.НайтиСтроки(Отбор);

Для Каждого Строка Из НайденныеСтроки Цикл

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

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

КонецЦикла;

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

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

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

ЗаполнитьЗначенияСвойств

Подходит для копирования одной или нескольких строк в существующую таблицу. Ограничение — перенос только по совпадающим именам колонок.

ТаблицаЗначений.Скопировать(Отбор)

Создаёт новую таблицу с копией отобранных строк. Не подходит, если строки нужно добавить в уже существующую таблицу.

Цикл по колонкам с присваиванием

Даёт полный контроль над соответствием колонок и преобразованием значений, но требует больше кода.

Копирование строки внутри одной таблицы (дублирование)

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

ИндексИсходной = ТаблицаЗначений.Индекс(ИсходнаяСтрока);

НоваяСтрока = ТаблицаЗначений.Вставить(ИндексИсходной + 1);

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

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

СтрокиДляКопирования = Новый Массив;

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

Если Строка.Пометка Тогда

СтрокиДляКопирования.Добавить(Строка);

КонецЕсли;

КонецЦикла;

Для Каждого Строка Из СтрокиДляКопирования Цикл

НоваяСтрока = ТаблицаЗначений.Добавить();

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

КонецЦикла;

Особенности: ссылки, типы и вложенные данные

При копировании строки переносятся сами значения, но для ссылочных типов (ссылки на справочники, документы) копируется ссылка, а не объект — обе строки будут указывать на один и тот же элемент базы. Обычно это именно то, что нужно, но при последующем изменении реквизитов объекта через одну строку изменения отразятся везде.

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

НоваяСтрока.Состав = ИсходнаяСтрока.Состав.Скопировать();

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

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

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

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

Если Не НоваяСтрока.Номенклатура = ИсходнаяСтрока.Номенклатура Тогда

ВызватьИсключение "Ошибка копирования строки: значения не совпадают";

КонецЕсли;

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

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

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

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

Увеличилось ровно на число скопированных строк

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

Строк больше или меньше ожидаемого — проверьте отбор и цикл

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

Совпадают с исходной строкой

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

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

Вложенные таблицы
Норма

Изменение копии не влияет на исходную строку

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

Обе строки ссылаются на одну вложенную таблицу

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

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

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

Почему после ЗаполнитьЗначенияСвойств часть колонок пустая?

Метод переносит значения только по совпадающим именам колонок. Проверьте, что в таблице-приёмнике колонки называются так же, как в источнике, либо перечислите нужные свойства третьим параметром и присвойте остальные значения вручную.

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

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

Как вставить копию строки не в конец, а в нужную позицию?

Используйте метод Вставить(Индекс) вместо Добавить(). Индекс нужной позиции можно получить через ТаблицаЗначений.Индекс(ИсходнаяСтрока), добавив единицу для вставки сразу после исходной строки.

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

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

Что быстрее: ЗаполнитьЗначенияСвойств или цикл по колонкам?

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

Итог

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

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