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