Разработка и Конфигурация · 8 мин
Как скопировать строку таблицы значений в 1С
Как скопировать строку таблицы значений в 1С: методы Добавить, Вставить, ЗаполнитьЗначенияСвойств, копирование по условию и типичные ошибки с примерами кода.
Таблица значений в 1С — один из самых используемых объектов при разработке: в ней хранят промежуточные результаты запросов, данные для обработки, строки документов и отчётов. Задача скопировать строку из одной таблицы в другую или продублировать строку внутри той же таблицы возникает постоянно — при формировании пакетов данных, разбиении строк, клонировании позиций документа.
Встроенного метода «СкопироватьСтроку» у таблицы значений нет, поэтому копирование выполняется комбинацией методов Добавить(), Вставить() и ЗаполнитьЗначенияСвойств(). Выбор способа зависит от того, совпадают ли структуры таблиц, куда нужно поместить копию и нужно ли копировать одну строку или группу по условию.
Ниже разобраны рабочие варианты кода, ограничения каждого метода и типичные ошибки, из-за которых копия получается пустой или падает с ошибкой типов.
Базовый способ: Добавить и ЗаполнитьЗначенияСвойств
Универсальный и самый частый приём: создать новую строку в целевой таблице и перенести в неё значения из исходной строки. Метод ЗаполнитьЗначенияСвойств копирует значения по совпадающим именам колонок (свойств).
НоваяСтрока = ТаблицаПриемник.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);
Если таблица одна и нужно продублировать строку внутри неё, код почти не меняется — источником и приёмником выступает одна таблица. Важно: дублирование внутри цикла Для Каждого по той же таблице приведёт к бесконечному циклу, потому что новые строки попадают в обход. Перед циклом зафиксируйте количество строк или соберите копируемые строки в отдельный массив.
Граница = ТЗ.Количество();
Для Инд = 0 По Граница - 1 Цикл
СтрокаИсточник = ТЗ[Инд];
НоваяСтрока = ТЗ.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);
КонецЦикла;Копирование строки в конкретную позицию через Вставить
Метод Добавить() всегда помещает строку в конец таблицы. Если копия должна встать сразу после исходной строки или в произвольную позицию, используйте Вставить(Индекс).
ИндексСтроки = ТЗ.Индекс(СтрокаИсточник);
НоваяСтрока = ТЗ.Вставить(ИндексСтроки + 1);
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);
Такой приём удобен, когда порядок строк имеет значение — например, при разбиении строки документа на две части с сохранением последовательности. Помните, что индексация строк начинается с нуля, а метод Индекс() ищет именно переданный объект строки, а не строку с такими же значениями.
Копирование нескольких строк по условию
Часто нужно перенести не одну строку, а все строки, удовлетворяющие отбору. Для этого сначала найдите строки методом НайтиСтроки() с параметрами отбора, затем скопируйте их в цикле.
Отбор = Новый Структура("Склад", ВыбранныйСклад);
НайденныеСтроки = ТЗИсточник.НайтиСтроки(Отбор);
Для Каждого СтрокаИсточник Из НайденныеСтроки Цикл
НоваяСтрока = ТЗПриемник.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточник);
КонецЦикла;
- 1Сформируйте структуру отбора с нужными полями
- 2Получите массив строк методом НайтиСтроки()
- 3В цикле добавляйте строки в приёмник через Добавить()
- 4Переносите значения через ЗаполнитьЗначенияСвойств()
- 5Проверьте количество строк в приёмнике после цикла
Если нужно скопировать таблицу целиком, отдельные строки перебирать не обязательно: метод ТЗ.Скопировать() возвращает полную копию таблицы со всеми строками и колонками, а ТЗ.СкопироватьКолонки() — пустую таблицу с той же структурой, что удобно для подготовки приёмника.
Ограничения ЗаполнитьЗначенияСвойств и работа с разными структурами
Метод ЗаполнитьЗначенияСвойств копирует только те поля, имена которых совпадают в обеих таблицах. Колонки, отсутствующие в приёмнике, молча игнорируются, а колонки приёмника, которых нет в источнике, останутся пустыми. Если имена колонок различаются, значения придётся переносить вручную по каждому полю.
НоваяСтрока = ТЗПриемник.Добавить();
НоваяСтрока.Товар = СтрокаИсточник.Номенклатура;
НоваяСтрока.Количество = СтрокаИсточник.Количество;
Второе ограничение — типы колонок. Если колонка приёмника имеет строгий тип (например, только число), а в источнике значение другого типа, присваивание может завершиться ошибкой преобразования. Перед копированием убедитесь, что типы совместимы, либо выполняйте явное преобразование.
Копирование строки табличной части документа
Табличная часть документа или справочника — не таблица значений, но приёмы похожи. Чтобы продублировать строку табличной части, добавьте новую строку и заполните её значениями исходной:
НоваяСтрока = Объект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ТекущаяСтрока);
На клиенте в управляемой форме текущую строку получают через Элементы.Товары.ТекущиеДанные. Учтите, что ЗаполнитьЗначенияСвойств на клиенте доступен, но при больших объёмах и сложной логике копирование лучше выполнять на сервере, чтобы не гонять данные между клиентом и сервером.
Проверка результата копирования
После копирования полезно убедиться, что данные перенеслись корректно. Минимальные проверки: количество строк в приёмнике выросло на ожидаемое число, ключевые поля новой строки совпадают с исходными, а поля, отсутствующие в источнике, не содержат мусора.
Как проверить результат
Увеличилось ровно на число скопированных строк
Не изменилось или выросло больше ожидаемого (цикл по живой таблице)
Совпадают с исходной строкой
Пустые поля — имена колонок не совпадают
Скопированы корректно, открываются
Ошибка преобразования типа при присваивании
Для отладки удобно вывести содержимое строки через Сообщить() по ключевым полям или сравнить таблицы до и после в отладчике. Если копия создаётся в цикле по большому массиву, замерьте время: на больших таблицах позапроходное копирование заметно медленнее, чем Скопировать() с последующим удалением лишнего.
Сравнение способов копирования
Универсально для одной или нескольких строк; требует совпадения имён колонок
Когда важна позиция копии внутри таблицы; нужно вычислять индекс
Быстро для копии всей таблицы или её части через Скопировать(МассивСтрок); создаёт новую таблицу
При разных именах колонок или необходимости преобразования значений; больше кода
Часто задаваемые вопросы
Можно ли скопировать строку простым присваиванием: НоваяСтрока = СтараяСтрока?
Нет. Такое присваивание не добавляет строку в таблицу — вы лишь получаете вторую ссылку на тот же объект строки. Новую строку всегда создают методами Добавить() или Вставить(), а значения переносят отдельно.
Почему после ЗаполнитьЗначенияСвойств часть полей пустая?
Метод копирует только поля с совпадающими именами. Проверьте имена колонок обеих таблиц: отличающиеся по имени поля нужно заполнять вручную.
Как скопировать строку в ту же таблицу без бесконечного цикла?
Зафиксируйте исходное количество строк до цикла и обходите таблицу по индексу до этой границы, либо сначала соберите копируемые строки в массив через НайтиСтроки() и только потом добавляйте копии.
Копируются ли значения ссылочных типов по ссылке или создаётся копия объекта?
Копируется ссылка, а не сам объект базы данных. Новая строка будет указывать на тот же элемент справочника или документ — дублирования объектов в базе не происходит.
Как быстро скопировать все строки таблицы в другую таблицу?
Используйте ТЗПриемник = ТЗИсточник.Скопировать() для полной копии. Если приёмник уже существует, выгрузите строки через Выгрузить() в другую таблицу значений или перенесите в цикле.
Работает ли ЗаполнитьЗначенияСвойств на тонком клиенте?
Да, метод доступен на клиенте. Но при копировании большого числа строк в форме документа эффективнее выполнить операцию в серверной процедуре, чтобы избежать лишних клиент-серверных вызовов.
Что важно запомнить
Строку таблицы значений копируют связкой Добавить() или Вставить() плюс ЗаполнитьЗначенияСвойств(). Следите за совпадением имён и типов колонок, не дублируйте строки внутри живого цикла по той же таблице, а для копии всей таблицы используйте метод Скопировать().