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

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

Как в 1С проверить, что колонка существует

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

При разработке на платформе 1С:Предприятие часто возникает ситуация, когда структура таблицы значений заранее неизвестна: данные загружаются из файла, приходят из внешнего источника или формируются динамически. Обращение к несуществующей колонке вызывает ошибку «Поле объекта не обнаружено», которая прерывает выполнение кода. Чтобы этого избежать, перед обращением к колонке нужно проверить её наличие.

Основной инструмент для такой проверки — коллекция Колонки таблицы значений и её метод Найти(). Метод возвращает объект колонки, если она найдена, и Неопределено, если колонки с таким именем нет. Этого достаточно для большинства прикладных задач.

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

Базовый способ: метод Найти у коллекции колонок

У любой таблицы значений есть свойство Колонки — это коллекция объектов типа «КолонкаТаблицыЗначений». У коллекции есть метод Найти(ИмяКолонки), который выполняет поиск по имени. Поиск нечувствителен к регистру: «Сумма», «СУММА» и «сумма» считаются одной и той же колонкой.

Типовой код проверки выглядит так:

Если ТаблицаДанных.Колонки.Найти("Сумма") = Неопределено Тогда

// Колонки нет — создаём её или пропускаем обработку

ТаблицаДанных.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));

Иначе

// Колонка существует, работаем с ней

ИтогСуммы = ТаблицаДанных.Итог("Сумма");

КонецЕсли;

Важно понимать, что метод возвращает не булево значение, а объект колонки или Неопределено. Поэтому сравнение пишут именно через = Неопределено или <> Неопределено. Попытка использовать результат напрямую в условии без сравнения приведёт к ошибке преобразования типов.

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

1c
Функция КолонкаСуществует(Таблица, ИмяКолонки)
    Возврат Таблица.Колонки.Найти(ИмяКолонки) <> Неопределено;
КонецФункции

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

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

РезультатЗапроса = Запрос.Выполнить();

Если РезультатЗапроса.Колонки.Найти("Количество") <> Неопределено Тогда

// Поле есть в результате

КонецЕсли;

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

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

Проверка в дереве значений и табличной части

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

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

МетаданныеТЧ = ДокументОбъект.Метаданные().ТабличныеЧасти.Товары;

Если МетаданныеТЧ.Реквизиты.Найти("Характеристика") <> Неопределено Тогда

// Реквизит есть в конфигурации

КонецЕсли;

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

Универсальная функция проверки

Чтобы не дублировать код, проверку удобно оформить как функцию общего модуля. Она принимает таблицу и имя колонки и возвращает булево значение:

Функция ЕстьКолонка(ТаблицаИлиДерево, ИмяКолонки) Экспорт

Если ТаблицаИлиДерево = Неопределено Тогда

Возврат Ложь;

КонецЕсли;

Возврат ТаблицаИлиДерево.Колонки.Найти(ИмяКолонки) <> Неопределено;

КонецФункции

Функцию можно расширить проверкой типа колонки. Например, если дальнейший код ожидает числовую колонку, имеет смысл сразу убедиться, что тип значения содержит «Число»:

Колонка = Таблица.Колонки.Найти("Сумма");

Если Колонка <> Неопределено

И Колонка.ТипЗначения.СодержитТип(Тип("Число")) Тогда

// Можно выполнять арифметические операции

КонецЕсли;

Порядок действий
  1. 1
    Определите, с каким объектом работаете: таблица значений, дерево значений, результат запроса или табличная часть
  2. 2
    Для таблицы, дерева или результата запроса вызовите Колонки.Найти("ИмяКолонки")
  3. 3
    Сравните результат с Неопределено
  4. 4
    Если колонки нет — добавьте её через Колонки.Добавить() либо пропустите обработку
  5. 5
    Проверьте тип колонки, если дальнейший код зависит от типа данных

Типичные ошибки и ограничения

Самая частая ошибка — обращение к колонке без проверки в цикле по строкам. Если колонка отсутствует, код падает на первой же итерации с ошибкой «Поле объекта не обнаружено». Проверку достаточно выполнить один раз до цикла, а не внутри него — это и быстрее, и понятнее.

Вторая распространённая проблема — путаница между таблицей значений и структурой. У структуры нет коллекции колонок; наличие ключа в ней проверяется методом Свойство("ИмяКлюча", НайденноеЗначение). Попытка вызвать Колонки.Найти() у структуры завершится ошибкой.

Третий нюанс — работа с динамически создаваемыми реквизитами формы. Колонка таблицы значений на форме и реквизит формы — не одно и то же. Если таблица выведена на форму, изменение её колонок требует использования методов ИзменитьРеквизиты(), а проверка наличия реквизита формы выполняется через массив ПолучитьРеквизиты().

Типичные ошибки
01
Обращение к колонке без проверки в обработках загрузки — код падает на первом файле с другой структурой
02
Проверка Найти() внутри цикла по строкам вместо одной проверки до цикла — лишние затраты ресурсов
03
Использование Колонки.Найти() для структуры вместо метода Свойство() — ошибка вызова метода
04
Сравнение результата Найти() с Истина вместо сравнения с Неопределено — ошибка преобразования типов

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

Если таблица значений создаётся полностью в вашем коде и её структура фиксирована, проверка наличия колонки избыточна — состав колонок известен на этапе разработки. Лишние проверки только усложняют чтение кода.

Проверка оправдана в трёх случаях: загрузка данных из внешних источников (Excel, CSV, обмены), универсальные обработки для разных конфигураций и динамическое формирование запросов или таблиц. Именно там структура данных может отличаться от ожидаемой.

Альтернативный подход — конструкция Попытка...Исключение. Иногда проще выполнить обращение к колонке внутри попытки и обработать исключение. Однако явная проверка через Найти() предпочтительнее: она быстрее, понятнее и не маскирует другие возможные ошибки внутри блока попытки.

Сравнение вариантов

Колонки.Найти()

Основной способ для таблиц, деревьев и результатов запросов. Быстро, явно, без побочных эффектов

Попытка...Исключение

Подходит как страховка, но скрывает причину ошибки и медленнее при массовых срабатываниях

Проверка через метаданные

Единственный вариант для табличных частей и реквизитов объектов конфигурации

Структура.Свойство()

Применяется для структур и соответствий вместо поиска по колонкам

Итог

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

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

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

Учитывает ли метод Найти регистр имени колонки?

Нет, поиск по имени колонки в коллекции колонок нечувствителен к регистру. Имена «Сумма», «СУММА» и «сумма» считаются одинаковыми, как и везде во встроенном языке 1С.

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

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

Что вернёт Найти, если передать пустую строку?

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

Как проверить наличие колонки в динамическом списке на форме?

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

Можно ли проверить колонку у таблицы, полученной из значения в строку?

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

Чем отличается проверка колонки от проверки ключа структуры?

У таблицы значений колонка — элемент коллекции Колонки, проверяется методом Найти(). У структуры данные хранятся как пары «ключ-значение», и наличие ключа проверяется методом Свойство(), который возвращает Истина или Ложь и может сразу вернуть значение ключа.