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