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

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

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

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

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

Принципиально важно понимать разницу между копированием ссылки на объект и копированием самих данных. Оператор присваивания ТЗ2 = ТЗ1 не создаёт новую таблицу — обе переменные начинают ссылаться на один и тот же объект в памяти, и изменение строк через одну переменную тут же видно через другую. Для независимой копии нужны специальные методы, описанные ниже.

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

Способ 1. Полное копирование методом Скопировать()

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

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

После выполнения этой строки ТаблицаКопия — самостоятельный объект. Можно удалять в ней строки, менять значения, добавлять колонки — исходная таблица не изменится. Именно это отличает метод от простого присваивания.

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

// Скопировать только строки, где Склад = "Основной"

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

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

// Скопировать только две колонки

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

// Комбинация: отбор строк и список колонок

ТаблицаКопия = ИсходнаяТаблица.Скопировать(Отбор, "Номенклатура, Количество");

Способ 2. Добавление данных методом Загрузить()

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

ТаблицаПриемник.Загрузить(ИсходнаяТаблица);

Ключевая особенность: Загрузить() добавляет строки к тем, что уже есть в приёмнике, а не заменяет их. Если нужна чистая загрузка, предварительно очистите таблицу методом Очистить():

ТаблицаПриемник.Очистить();

ТаблицаПриемник.Загрузить(ИсходнаяТаблица);

Метод удобен, когда целевая таблица уже существует с заранее заданной структурой — например, это реквизит формы типа «ТаблицаЗначений» или табличная часть документа, подготовленная к заполнению. Колонки источника, которых нет в приёмнике, просто игнорируются; колонки приёмника, отсутствующие в источнике, остаются с пустыми значениями.

Способ 3. Построчное копирование в цикле

Цикл по строкам — самый гибкий способ. Он нужен, когда простого отбора по равенству недостаточно: условия сложные (сравнения, вычисления, проверки нескольких полей), данные при переносе нужно преобразовать, или структуры таблиц различаются.

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

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

И Не СтрокаИсточник.Пометка Тогда

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

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

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

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

КонецЕсли;

КонецЦикла;

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

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

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

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

Порядок действий при построчном копировании
  1. 1
    Создайте или очистите таблицу-приёмник с нужной структурой колонок
  2. 2
    Организуйте цикл Для Каждого по строкам исходной таблицы
  3. 3
    Внутри цикла проверьте условия отбора строк
  4. 4
    Добавьте новую строку методом Добавить() и заполните её поля
  5. 5
    После цикла проверьте количество строк в приёмнике через Количество()

Сравнение способов: что выбрать под свою задачу

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

СпособСоздаёт новую таблицуОтбор строкВыбор колонокКогда применять
Скопировать()ДаОтбор по равенствуДа, спискомПолная или простая фильтрованная копия
Загрузить()Нет, дополняет существующуюНетТолько по совпадению имёнЗаполнение готовой структуры, объединение таблиц
Цикл с Добавить()НетЛюбые условияЛюбая логикаСложные условия, преобразование данных
Присваивание =Нет (копия ссылки)——Только если независимость копии не нужна
Маршрут решения

Как выбрать способ

Нужна полная независимая копия таблицыИспользуйте ТЗ2 = ТЗ1.Скопировать()
Нужно скопировать строки по простому равенству поля значениюИспользуйте Скопировать() со структурой отбора
Таблица-приёмник уже существует и её структуру менять нельзяИспользуйте Загрузить() или цикл с ЗаполнитьЗначенияСвойств()
Нужны сложные условия или вычисления при переносеИспользуйте цикл Для Каждого с проверками
Нужно объединить несколько таблиц в однуПоследовательно вызовите Загрузить() для каждой таблицы-источника

Копирование отдельных колонок и объединение таблиц

Перенос одной колонки

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

МассивНоменклатуры = ИсходнаяТаблица.ВыгрузитьКолонку("Номенклатура");

ТаблицаПриемник.ЗагрузитьКолонку(МассивНоменклатуры, "Номенклатура");

Важно: если количество значений в массиве больше числа строк приёмника, недостающие строки будут добавлены автоматически. Если меньше — остаток строк получит пустые значения в этой колонке.

Объединение нескольких таблиц

Типовая задача — слить данные нескольких однотипных таблиц в одну сводную. Для этого достаточно последовательных вызовов Загрузить():

СводнаяТаблица = Таблица1.Скопировать();

СводнаяТаблица.Загрузить(Таблица2);

СводнаяТаблица.Загрузить(Таблица3);

После объединения часто требуется свернуть одинаковые строки с суммированием числовых полей — для этого служит метод Свернуть():

СводнаяТаблица.Свернуть("Номенклатура, Склад", "Количество, Сумма");
При объединении таблиц из разных источников заранее проверьте типы колонок: если в одной таблице колонка «Количество» имеет тип Число, а в другой — Строка, после Загрузить() и Свернуть() суммирование может работать некорректно. Приведите типы через ОписаниеТипов ещё на этапе формирования таблиц.
ПЗ
Практическое замечание

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

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

ТЗ = ДокументОбъект.Товары.Выгрузить();

// Дальше с ТЗ работаем как с обычной таблицей значений

ТЗ.Свернуть("Номенклатура", "Количество");

Обратный перенос — из таблицы значений в табличную часть — выполняется уже знакомым методом Загрузить(), который есть и у табличной части:

ДокументОбъект.Товары.Загрузить(ТЗ);

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

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

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

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

Сообщить("Исходная: " + ИсходнаяТаблица.Количество()

+ ", копия: " + ТаблицаКопия.Количество());

Кроме количества строк полезно сверить итоги по числовым колонкам через Итог() — расхождение сумм сразу покажет, что часть данных потерялась или задублировалась:

Если ИсходнаяТаблица.Итог("Сумма") <> ТаблицаКопия.Итог("Сумма") Тогда

// данные перенесены не полностью или с дублями

КонецЕсли;

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

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

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

Совпадает с исходной таблицей или с ожидаемым числом отобранных строк

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

Строк больше (дубли) или меньше (потери при отборе)

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

Итог() по суммам и количествам совпадает

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

Суммы расходятся — проверяйте отбор и повторные вызовы Загрузить()

Независимость копии
Норма

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

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

Изменения видны в обеих таблицах — использовано присваивание вместо Скопировать()

Структура колонок
Норма

Все нужные колонки присутствуют с правильными типами

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

Колонки отсутствуют или типы не совпадают — проверьте список колонок в параметрах

Итог

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

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

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

Почему после ТЗ2 = ТЗ1 изменения в одной таблице видны в другой?

Оператор присваивания копирует не данные, а ссылку на объект. Обе переменные указывают на одну и ту же таблицу значений в памяти. Чтобы получить независимую копию, используйте ТЗ2 = ТЗ1.Скопировать().

Как скопировать только строки, удовлетворяющие нескольким условиям?

Если условия — равенство полей конкретным значениям, передайте в Скопировать() структуру с несколькими ключами: Новый Структура("Склад, ВидНоменклатуры", "Основной", "Услуги"). Для неравенств, диапазонов и вычислений используйте цикл с проверками внутри.

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

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

Как объединить две таблицы без дублей строк?

Сначала объедините таблицы: Итог = ТЗ1.Скопировать(); Итог.Загрузить(ТЗ2);. Затем вызовите Итог.Свернуть() с перечнем колонок группировки и суммируемых колонок. Строки с одинаковыми значениями в колонках группировки сольются в одну.

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

Выгрузить() — метод табличной части объекта (документа, справочника), он создаёт таблицу значений из данных табличной части. Скопировать() — метод самой таблицы значений, создающий её независимую копию. У табличной части метода Скопировать() нет.

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

Вызовите метод Очистить() — он удаляет все строки, сохраняя структуру колонок. Если нужно удалить и колонки, присвойте переменной новый объект: ТЗ = Новый ТаблицаЗначений; и заново добавьте колонки.