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

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

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

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

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

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

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

Метод Свойство() — основной и безопасный способ

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

СтруктураПараметров = Новый Структура("Организация, Период", Организация, ТекущаяДатаСеанса());

ЗначениеКлюча = Неопределено;

Если СтруктураПараметров.Свойство("Организация", ЗначениеКлюча) Тогда

// Ключ есть, значение уже в переменной ЗначениеКлюча

Сообщить("Организация: " + ЗначениеКлюча);

Иначе

Сообщить("Ключ не найден");

КонецЕсли;

Важная особенность: если ключа нет, переменная-приёмник сохраняет своё прежнее значение. Поэтому перед вызовом её следует явно инициализировать — иначе можно получить «мусор» из предыдущей итерации цикла. Это одна из самых частых причин трудноуловимых ошибок при обработке массивов структур.

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

Проверка через сравнение с Неопределено

Второй распространённый приём — обратиться к ключу и сравнить результат с Неопределено. Он работает только если значение читается через метод Свойство() или если ключ гарантированно существует. Прямое обращение Структура.Ключ к отсутствующему свойству вызывает исключение «Поле объекта не обнаружено», поэтому как самостоятельная проверка этот вариант небезопасен.

ЗначениеКлюча = Неопределено;

СтруктураПараметров.Свойство("Склад", ЗначениеКлюча);

Если ЗначениеКлюча = Неопределено Тогда

// Ключа нет ИЛИ значение ключа равно Неопределено

КонецЕсли;

Здесь кроется принципиальный нюанс: сравнение с Неопределено не различает ситуации «ключа нет» и «ключ есть, но значение пустое». Если для логики программы эти случаи различны — например, отсутствие параметра означает «использовать значение по умолчанию», а явно переданное Неопределено означает «очистить» — полагаться на сравнение нельзя. Используйте возвращаемое значение метода Свойство(), которое отражает именно факт наличия ключа.

Перебор коллекции в цикле

Третий способ — обойти структуру конструкцией Для Каждого ... Из ... Цикл. Элементом перебора является КлючИЗначение, у которого доступны свойства Ключ и Значение. Такой подход оправдан, когда нужно проверить сразу несколько ключей, собрать статистику по составу структуры или выполнить действия для всех элементов.

КлючНайден = Ложь;

Для Каждого Элемент Из СтруктураПараметров Цикл

Если Элемент.Ключ = "Склад" Тогда

КлючНайден = Истина;

Прервать;

КонецЕсли;

КонецЦикла;

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

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

Свойство() с возвратом значения

Универсальный вариант: проверка и чтение за один вызов. Подходит всегда, требует инициализации переменной-приёмника.

Свойство() без второго параметра

Когда важен только факт наличия ключа, значение не нужно. Самый короткий и читаемый код.

Сравнение с Неопределено

Только если значение читается через Свойство() или ключ гарантированно есть. Не различает «нет ключа» и «значение Неопределено».

Перебор в цикле

Для проверки нескольких ключей или анализа состава структуры. Избыточен для одиночной проверки.

Проверка ключей во вложенных структурах

На практике параметры часто образуют иерархию: структура содержит другие структуры. Проверка «пути» к вложенному ключу требует последовательных вызовов Свойство() — обращение цепочкой Структура.Уровень1.Уровень2 без проверок упадёт с ошибкой на первом же отсутствующем уровне.

Функция ПолучитьВложенноеЗначение(Корень, Ключ1, Ключ2)

Уровень1 = Неопределено;

Если Не Корень.Свойство(Ключ1, Уровень1) Тогда

Возврат Неопределено;

КонецЕсли;

Если ТипЗнч(Уровень1) <> Тип("Структура") Тогда

Возврат Неопределено;

КонецЕсли;

Результат = Неопределено;

Уровень1.Свойство(Ключ2, Результат);

Возврат Результат;

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

Обратите внимание на проверку типа промежуточного значения: если по ключу Уровень1 лежит не структура, а, скажем, строка, попытка вызвать у неё Свойство() вызовет ошибку. Такая защита особенно важна при разборе JSON и данных обмена, где типы значений не контролируются вашей конфигурацией.

Порядок действий при проверке ключа
  1. 1
    Определите, нужно ли значение ключа или только факт его наличия
  2. 2
    Инициализируйте переменную-приёмник значением Неопределено
  3. 3
    Вызовите Структура.Свойство("ИмяКлюча", Значение) и проверьте возвращаемый результат
  4. 4
    Для вложенных структур проверяйте каждый уровень отдельно и контролируйте тип промежуточного значения
  5. 5
    Убедитесь, что ветка «ключ отсутствует» обрабатывается явно: значение по умолчанию, сообщение или исключение

Особые случаи: соответствие, фиксированная структура, параметры формы

У соответствия метод Свойство() отсутствует — там проверку выполняют через Соответствие.Получить(Ключ): метод вернёт Неопределено, если ключ не найден, и не вызовет исключения. Это делает соответствие удобнее для словарей с динамическими строковыми ключами, где регистр символов значим.

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

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

Типичные ошибки
01
Обращение Структура.Ключ без проверки — исключение «Поле объекта не обнаружено» при отсутствии ключа
02
Неочищенная переменная-приёмник в цикле: при отсутствии ключа в неё остаётся значение из предыдущей итерации
03
Сравнение с Неопределено вместо проверки возвращаемого значения Свойство() — невозможно отличить отсутствие ключа от пустого значения
04
Ожидание чувствительности к регистру: структура игнорирует регистр имён ключей, соответствие — нет
05
Использование метода Свойство() у соответствия — такого метода там нет, код не скомпилируется

Как убедиться, что проверка работает правильно

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

Полезный приём при отладке — временно вывести состав структуры перебором в журнал регистрации или в сообщения. Так видно, какие ключи реально приходят в код, и легко обнаружить расхождения в именах: лишний пробел, другой регистр, опечатка в литерале. Имя ключа в строковом виде платформа не проверяет на этапе компиляции, поэтому опечатки находятся только тестированием.

Контрольные точки

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

Ключ существует и заполнен
Норма

Свойство() вернуло Истина, переменная содержит ожидаемое значение

Тревожный признак

Вернулось Ложь — проверьте имя ключа и источник заполнения структуры

Ключ существует со значением Неопределено
Норма

Свойство() вернуло Истина, значение равно Неопределено

Тревожный признак

Код трактует ситуацию как отсутствие ключа — логика смешивает два разных случая

Ключ отсутствует
Норма

Свойство() вернуло Ложь, переменная-приёмник не изменилась

Тревожный признак

В переменной осталось старое значение — она не была инициализирована перед вызовом

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

Есть ли в структуре 1С метод СодержитКлюч или Найти?

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

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

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

Что будет, если обратиться к несуществующему ключу через точку?

Платформа вызовет исключение с текстом вида «Поле объекта не обнаружено (ИмяКлюча)». В клиентском коде это прервёт выполнение обработчика, на сервере — транзакцию, если она не обработана через Попытка/Исключение. Поэтому прямое обращение допустимо только после проверки через Свойство().

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

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

Работает ли Свойство() с фиксированной структурой и параметрами формы?

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

Можно ли проверить ключ без учёта регистра, если структура пришла из JSON?

Структура сама по себе нечувствительна к регистру имён ключей, поэтому Свойство("Имя") найдёт ключ "имя" или "ИМЯ". Однако если JSON разбирался в соответствие (через ПрочитатьJSON с параметром), регистр будет значим, и потребуется нормализация имён — например, приведение к одному регистру при заполнении.

Итог

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

Проверка ключа в структуре 1С выполняется методом Свойство(): он возвращает Истина при наличии ключа и заполняет переменную значением. Переменную-приёмник всегда инициализируйте перед вызовом, вложенные структуры проверяйте по уровням с контролем типа, а для соответствия используйте метод Получить(). Прямое обращение через точку без проверки приводит к исключению.