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