Как проверить наличие колонки в строке таблицы значений или данных формы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработки на платформе 1С:Предприятие часто возникает задача написать универсальную процедуру, в которую передается строка таблицы. При этом состав колонок таблицы может меняться в зависимости от контекста вызова. Если попытаться обратиться к несуществующей колонке напрямую через точку (например, Строка.МояКолонка), система выдаст ошибку времени выполнения, что приведет к аварийному завершению работы алгоритма. В этой статье мы подробно разберем, как безопасно проверить наличие колонки, работая с разными типами объектов: классической Таблицей Значений и объектом ДанныеФормыЭлементКоллекции.

Ситуация 1: Работа с Таблицей Значений на сервере

Рассмотрим ситуацию, когда мы работаем с объектом ТаблицаЗначений в серверном коде. Если у нас есть только объект строки, мы можем легко получить доступ к самой таблице-родителю и проверить ее состав колонок. Проанализируем, как это сделать правильно.

Для объекта СтрокаТаблицыЗначений существует метод Владелец(), который возвращает саму таблицу, которой принадлежит данная строка. У таблицы, в свою очередь, есть коллекция Колонки, обладающая методом Найти().

Разберем пример кода:


// Предположим, переменная СтрокаТЗ — это строка обычной Таблицы Значений
ИмяКолонки = "СуммаДокумента";

// Получаем таблицу-владельца и ищем колонку по имени
КолонкаСуществует = СтрокаТЗ.Владелец().Колонки.Найти(ИмяКолонки) <> Неопределено;

Если КолонкаСуществует Тогда
    Значение = СтрокаТЗ[ИмяКолонки];
    // Продолжаем работу с данными
КонецЕсли;

Этот способ является стандартным и наиболее производительным для серверных вычислений. Метод Найти() возвращает объект КолонкаТаблицыЗначений, если она есть, или Неопределено, если колонки с таким идентификатором не существует. Важно помнить, что поиск в 1С нечувствителен к регистру, поэтому "Сумма" и "сумма" будут считаться одной и той же колонкой.

Ситуация 2: Работа в Управляемых формах (ДанныеФормыЭлементКоллекции)

В управляемом интерфейсе данные таблиц на форме (например, табличных частей или динамических списков) представлены типом ДанныеФормыЭлементКоллекции. Этот объект ведет себя иначе, чем строка обычной таблицы значений. У него нет метода Владелец(), поэтому подход из предыдущего раздела здесь не сработает.

Для таких объектов разработчики платформы предусмотрели встроенный метод Свойство(). Этот метод позволяет проверить наличие реквизита (колонки) и одновременно получить его значение, если он существует. Выясним, как использовать этот метод наиболее эффективно.

Синтаксис метода следующий: Свойство(Ключ, НайденноеЗначение). Где Ключ — это имя проверяемой колонки в виде строки, а НайденноеЗначение — переменная, в которую будет записан результат, если колонка найдена.

Посмотрим на практический пример:


// Объект СтрокаЭлемент имеет тип ДанныеФормыЭлементКоллекции
ИмяПоля = "СтатусЗаказа";
ЗначениеПоля = Неопределено;

Если СтрокаЭлемент.Свойство(ИмяПоля, ЗначениеПоля) Тогда
    // Если мы зашли сюда, значит колонка существует
    // В переменной ЗначениеПоля уже лежит значение этой колонки
    Сообщить("Значение колонки: " + ЗначениеПоля);
Иначе
    Сообщить("Колонка '" + ИмяПоля + "' не найдена в текущей коллекции.");
КонецЕсли;

Важный нюанс: метод Свойство() возвращает булево значение (Истина/Ложь). Это делает его идеальным инструментом для проверки в условиях Если ... Тогда. Он предотвращает ошибки обращения к несуществующим реквизитам, даже если эти реквизиты были добавлены на форму программно через массив ИзменяемыеРеквизиты. Для реализации сложной динамической настройки интерфейса можно использовать инструмент для динамического заполнения управляемой формы по макету.

Альтернативные способы и оптимизация

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

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


КоллекцияКолонок = СтрокаТЗ.Владелец().Колонки;
ЕстьНужнаяКолонка = КоллекцияКолонок.Найти("СпециальныйПоказатель") <> Неопределено;

Для Каждого ТекущаяСтрока Из ТЗ Цикл
    Если ЕстьНужнаяКолонка Тогда
        // Безопасно обращаемся, так как мы заранее знаем, что колонка есть
        Данные = ТекущаяСтрока.СпециальныйПоказатель;
    КонецЕсли;
КонецЦикла;

Также существует "хитрый" способ с использованием функции ЗаполнитьЗначенияСвойств(). Этот метод часто применяется, когда нужно перенести данные из строки в структуру, не заботясь о том, все ли поля присутствуют в источнике. Если в строке-источнике нет какой-то колонки, 1С просто проигнорирует её, не вызывая исключения.

Разберем этот прием подробнее:


// Создаем структуру с интересующими нас именами полей
ПараметрыПроверки = Новый Структура("Количество, Цена, Сумма");

// Пытаемся заполнить структуру из строки таблицы
ЗаполнитьЗначенияСвойств(ПараметрыПроверки, ТекущаяСтрока);

// Теперь можно проверить, изменились ли значения в структуре 
// или просто работать с ними, зная, что ошибка не возникнет

Особенности работы на Клиенте

Необходимо помнить об ограничениях платформ. Объект ТаблицаЗначений доступен только на сервере. На тонком клиенте вы всегда будете иметь дело с ДанныеФормыКоллекция и её элементами. Если ваш программный код должен работать и на клиенте, и на сервере (например, в общем модуле), используйте метод Свойство(), так как он более универсален для объектов управляемого интерфейса. Для более глубокого изучения принципов разделения контекстов полезно использовать руководство по управлению местом выполнения кода в управляемых формах.

Подведем итоги нашего анализа:

  1. Для серверных таблиц значений используйте Строка.Владелец().Колонки.Найти("Имя"). Это надежно и дает доступ к метаданным колонки (типу, заголовку).
  2. Для управляемых форм и объектов ДанныеФормыЭлементКоллекции используйте метод Свойство("Имя"). Это самый безопасный и быстрый способ.
  3. Если колонок много или проверка идет в большом цикле, старайтесь выносить проверку состава колонок за пределы цикла, чтобы повысить производительность системы.
  4. Используйте ЗаполнитьЗначенияСвойств() для массового копирования данных без риска "падения" системы из-за отсутствующих полей.

Применяя эти методы, вы сделаете свой код более отказоустойчивым и профессиональным, избегая типичных ошибок начинающих разработчиков при работе с динамическими структурами данных в 1С.

← На главную