Как проверить наличие вложенного свойства в структуре 1С

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

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

Проблема использования метода Свойство() для вложенных путей

Рассмотрим ситуацию: у нас есть переменная СтруктураТЧ, внутри которой находится другая структура ТекущаяСтрока, а в ней мы хотим найти ключ Цена. Распространенная ошибка — попытка вызвать метод Свойство() напрямую для всей цепочки или ожидание, что поиск будет рекурсивным.

Проанализируем, почему код СтруктураТЧ.Свойство("Цена") возвращает Ложь, даже если цена там точно есть. Метод Свойство() платформенного объекта Структура работает строго на одном уровне вложенности. Он ищет ключ «Цена» непосредственно в СтруктураТЧ. Поскольку «Цена» находится глубже, вложенная структура для него — это просто значение одного из ключей, содержимое которого метод не анализирует.

Решение 1: Последовательная проверка уровней

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

  1. Проверяем, существует ли в основной структуре ключ ТекущаяСтрока.
  2. Убеждаемся, что значение этого ключа не является Неопределено и имеет тип, поддерживающий метод Свойство().
  3. Проверяем наличие целевого свойства уже во вложенном объекте.

Рассмотрим пример кода:


// Безопасная проверка вложенного свойства
ЕстьЦена = Ложь;
Если СтруктураТЧ.Свойство("ТекущаяСтрока") Тогда
    ВложенныйОбъект = СтруктураТЧ.ТекущаяСтрока;
    // Проверяем, что это действительно структура или объект данных
    Если ТипЗнч(ВложенныйОбъект) = Тип("Структура") Тогда
        Если ВложенныйОбъект.Свойство("Цена") Тогда
            ЕстьЦена = Истина;
        КонецЕсли;
    КонецЕсли;
КонецЕсли;

Если ЕстьЦена Тогда
    // Работаем с ценой
КонецЕсли;

Решение 2: Использование блока Попытка — Исключение

В сообщениях форума часто упоминается этот метод как «самый простой». Действительно, блок Попытка позволяет не писать каскады условий. Мы просто обращаемся к свойству напрямую, и если его нет — платформа выбросит исключение, которое мы перехватим.

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


ЕстьЦена = Ложь;
Попытка
    ЗначениеЦены = СтруктураТЧ.ТекущаяСтрока.Цена;
    ЕстьЦена = Истина;
Исключение
    // Свойство не существует или путь некорректен
    ЕстьЦена = Ложь;
КонецПопытки;

Решение 3: Использование программного интерфейса БСП

Если ваша конфигурация построена на базе «Библиотеки стандартных подсистем» (БСП), то в вашем распоряжении есть готовые функции общего назначения. Рассмотрим функцию ЗначениеРеквизитаОбъекта или работу с функциями модуля ОбщегоНазначения.

Хотя стандартная функция ОбщегоНазначения.ЗначениеРеквизитаОбъекта чаще используется для ссылочных типов, для структур в БСП часто пишут вспомогательные методы типа СвойствоСтруктуры(), которые позволяют безопасно извлекать данные. Если такой функции нет, рекомендуем создать свою универсальную функцию, которая принимает строку пути (например, "ТекущаяСтрока.Цена") и возвращает значение или Неопределено.

Особенности объектов ДанныеФормыЭлементКоллекции

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

Почему Свойство() возвращает Ложь при видимом наличии ключа?

Иногда программист видит свойство в отладчике, но Свойство("Цена") упорно выдает Ложь. Разберем возможные причины:

  1. Разная раскладка: Буква «С» в слове «Цена» может быть латинской или кириллической. Визуально они идентичны, но для системы это разные идентификаторы.
  2. Невидимые символы: В ключе структуры могут оказаться неразрывные пробелы или символы переноса строки, если структура заполнялась автоматически (например, при чтении из JSON или XML).
  3. Тип контейнера: Убедитесь, что ТекущаяСтрока — это действительно Структура. Если это Соответствие, то метод Свойство() у него отсутствует, используется метод Получить().

Хитрость с ЗаполнитьЗначенияСвойств

Существует альтернативный способ проверить наличие поля, не вызывая ошибку. Мы можем использовать команду ЗаполнитьЗначенияСвойств. Для этого создадим небольшую структуру-приемник с полем, которое мы ищем.


// Создаем "трафарет"
Приемник = Новый Структура("Цена", "МаркерОтсутствия");
// Пытаемся заполнить его из нашей вложенной структуры
ЗаполнитьЗначенияСвойств(Приемник, СтруктураТЧ.ТекущаяСтрока);

Если Приемник.Цена <> "МаркерОтсутствия" Тогда
    // Свойство существовало и было перенесено
КонецЕсли;

Этот метод избавляет от необходимости использовать Попытку и работает достаточно быстро, так как ЗаполнитьЗначенияСвойств оптимизирована на уровне платформы.

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

← На главную