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

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

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

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

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

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

Ошибки при копировании колонок обычно связаны с потерей типов значений, неожиданным копированием данных вместо структуры или дублированием имён колонок. Ниже разобраны все рабочие способы с примерами кода, проверкой результата и разбором типичных проблем.

Что происходит при копировании колонок таблицы значений

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

Важно понимать, что методы копирования создают новый объект, а не ссылку на старый. Изменения в скопированной таблице не затронут исходную, и наоборот. Это отличает копирование от простого присваивания переменной: запись ТЗ2 = ТЗ1; создаёт лишь вторую ссылку на ту же таблицу, и правка одной переменной изменит данные в обеих.

Метод СкопироватьКолонки() — структура без данных

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

ТЗИсходная = Новый ТаблицаЗначений;

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

ТЗИсходная.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число"));

// Заполняем исходную таблицу данными

НоваяСтрока = ТЗИсходная.Добавить();

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

// Копируем только структуру

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

Сообщить(ТЗПустая.Количество()); // 0 — строк нет

Сообщить(ТЗПустая.Колонки.Количество()); // 2 — колонки на месте

Типы значений колонок переносятся полностью, включая составные типы. Если колонка исходной таблицы допускает и строку, и число, в новой таблице сохранится то же описание типов. Заголовки колонок также копируются, что удобно при выводе результата в табличное поле формы.

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

Как получить пустую копию структуры
  1. 1
    Убедитесь, что исходная таблица значений создана и колонки в ней определены
  2. 2
    Вызовите НоваяТЗ = ИсходнаяТЗ.СкопироватьКолонки()
  3. 3
    Проверьте: НоваяТЗ.Количество() должно быть равно 0
  4. 4
    Проверьте: НоваяТЗ.Колонки.Количество() должно совпадать с исходным
  5. 5
    Заполните новую таблицу строками через Добавить()

Метод Скопировать() — колонки вместе с данными

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

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

// Теперь ТЗКопия содержит те же колонки и те же строки

Метод поддерживает два необязательных параметра. Первый — структура отбора: копируются только строки, удовлетворяющие условию. Второй — список колонок через запятую: в результат попадут только указанные колонки. Комбинируя параметры, можно одной строкой кода получить выборку нужных данных в нужном составе.

Отбор = Новый Структура("Склад", Справочники.Склады.НайтиПоНаименованию("Основной"));

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

// В ТЗОтбор только две колонки и только строки по основному складу

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

Выборочное копирование отдельных колонок

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

ТЗНовая = Новый ТаблицаЗначений;

Для Каждого Колонка Из ТЗИсходная.Колонки Цикл

Если Колонка.Имя = "Номенклатура" Или Колонка.Имя = "Сумма" Тогда

ТЗНовая.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения, Колонка.Заголовок);

КонецЕсли;

КонецЦикла;

Ручной способ незаменим, когда нужно изменить структуру при копировании: переименовать колонку, сузить или расширить тип, добавить вычисляемое поле. Обратите внимание на свойство Колонка.ТипЗначения — именно через него передаётся описание типов исходной колонки, и вам не приходится конструировать его заново.

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

Способы копирования колонок

СкопироватьКолонки()

Вся структура без данных. Подходит для шаблонов и ручного заполнения. Нельзя выбрать часть колонок

Скопировать() с параметрами

Выборочные колонки и отбор строк одной командой. Данные копируются всегда — пустую таблицу так не получить

Колонки.Добавить() вручную

Полный контроль: переименование, изменение типов. Требует отдельного переноса данных перебором строк

Выгрузка одной колонки в массив

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

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

// Массив удобно передать в параметр запроса для отбора по списку

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

Обратная операция — ЗагрузитьКолонку(Массив, "ИмяКолонки") — заполняет колонку таблицы значениями из массива. Колонка должна существовать, а число элементов массива должно совпадать с числом строк таблицы, иначе платформа выдаст ошибку.

bsl
// Свернуть и выгрузить уникальные значения колонки
ТЗСвод = ТЗИсходная.Скопировать();
ТЗСвод.Свернуть("Номенклатура");
МассивУникальных = ТЗСвод.ВыгрузитьКолонку("Номенклатура");

Проверка результата и типичные ошибки

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

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

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

Количество колонок в новой таблице
Норма

Совпадает с ожидаемым составом

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

Колонок больше или меньше — проверьте параметры метода

Количество строк после СкопироватьКолонки()
Норма

Равно 0

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

Строки есть — вероятно, вызван Скопировать() вместо СкопироватьКолонки()

Тип значения колонки
Норма

Описание типов совпадает с исходным

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

Тип сброшен — при ручном добавлении не передан параметр ТипЗначения

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

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

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

Меняются обе — использовано присваивание переменной вместо метода копирования

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

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

Выбор метода под конкретную задачу

Чтобы не перебирать варианты каждый раз, удобно ориентироваться на конечную цель. Если нужен пустой каркас для заполнения — это СкопироватьКолонки(). Если нужна независимая копия данных для безопасной обработки — Скопировать() без параметров. Если нужна проекция таблицы на часть колонок с фильтром — Скопировать() с отбором и списком колонок. Если структура должна отличаться от исходной — ручное построение через Колонки.Добавить().

Маршрут решения

Как выбрать метод

Нужна только структура колонок без строкИспользуйте СкопироватьКолонки()
Нужна полная независимая копия таблицы с даннымиИспользуйте Скопировать() без параметров
Нужны только часть колонок и отбор строкИспользуйте Скопировать(Отбор, "Колонка1,Колонка2")
Нужно переименовать колонки или изменить типыСоздайте новую таблицу и добавьте колонки через Колонки.Добавить() с нужным описанием типов
Нужны значения одной колонки для параметра запросаИспользуйте ВыгрузитьКолонку("ИмяКолонки")

Для больших таблиц предпочтительнее вообще избегать промежуточных копий: запрос с выборкой нужных полей и условием выполнит ту же работу на уровне СУБД быстрее и экономнее по памяти. Копирование таблиц значений оправдано для небольших и средних объёмов, когда данные уже получены и требуется их программная трансформация.

Итог

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

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

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

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

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

Почему после СкопироватьКолонки() в новой таблице нет строк?

Это штатное поведение метода: он переносит только описание структуры — имена, типы, заголовки колонок. Строки нужно добавлять отдельно через Добавить() либо использовать Скопировать(), если данные тоже нужны.

Как скопировать колонки из результата запроса, не выгружая данные?

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

Сохраняются ли индексы таблицы значений при копировании?

Нет, индексы в новую таблицу не переносятся. Если исходная таблица имела индексы, добавленные через Колонки... либо метод Индексы.Добавить(), в скопированной таблице их нужно создать заново — иначе поиск через Найти() и НайтиСтроки() будет работать медленнее на больших объёмах.

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

Автоматического сопоставления по «похожим» именам нет. Создайте новую таблицу, добавьте в неё колонки с нужными именами и типами, затем переберите строки исходной таблицы и присвойте значения явно: НоваяСтрока.НовоеИмя = СтараяСтрока.СтароеИмя. Соответствие имён удобно хранить в структуре или соответствии.

Что быстрее: Скопировать() или запрос с выборкой полей?

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