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