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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

КонецЕсли;

КонецЦикла;

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

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

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

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

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

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

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

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

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

Учитывайте типы колонок: если в приемнике колонка имеет ограниченный тип (например, только «Число»), а из источника придёт значение другого типа, значение будет приведено к типу колонки или заменено значением по умолчанию. Проверяйте соответствие типов до переноса, особенно при работе с произвольными таблицами, полученными из запросов.

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

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

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

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

НоваяСтрока.КлючСтроки = Новый УникальныйИдентификатор;

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

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

Как проверить, что строка скопирована правильно

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

Если ТаблицаТоваров.Количество() <> ОжидаемоеКоличество Тогда

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

КонецЕсли;

При массовом копировании полезно сравнить итоги: например, сумма по колонке «Количество» в приемнике должна совпадать с суммой отобранных строк источника. Расхождение итогов — признак того, что часть строк потерялась или скопирована дважды.

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

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

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

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

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

Не изменилось или выросло больше ожидаемого

Значения колонок
Норма

Совпадают с исходной строкой по всем нужным полям

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

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

Ключевые поля
Норма

Ключи связей уникальны у новой строки

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

Дубликаты ключей, «подтянулись» чужие связанные данные

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

Итог приемника равен сумме отобранных строк

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

Расхождение итогов

Типичные ошибки при копировании строк

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

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

Ещё одна проблема — копирование строки с колонками, которых нет в приемнике, через ручное перечисление. Если колонка отсутствует, обращение к ней вызовет ошибку «Поле объекта не обнаружено». Перед переносом проверяйте наличие колонки через ТаблицаПриемник.Колонки.Найти("ИмяКолонки").

Итог

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

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

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

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

Отдельного метода «СкопироватьСтроку» в платформе нет. Минимальный вариант — две строки кода: НоваяСтрока = ТЗ.Добавить() и ЗаполнитьЗначенияСвойств(НоваяСтрока, ИсходнаяСтрока). Для копии всей таблицы целиком есть метод Скопировать().

Чем отличается Скопировать() от Выгрузить() и Загрузить()?

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

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

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

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

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

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

Если таблица является реквизитом формы типа «ТаблицаЗначений», код аналогичен: НоваяСтрока = ИмяРеквизита.Добавить() и заполнение значений. Для табличных частей объекта на клиенте доступен тот же синтаксис через Объект.ИмяТабличнойЧасти, но сложные пересчёты лучше выносить в серверную процедуру.

Что делать, если при копировании возникает ошибка «Поле объекта не обнаружено»?

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