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