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