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