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