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

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

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

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

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

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

Ниже разобраны все рабочие способы проверки, их ограничения, типичные ошибки и готовые шаблоны кода, которые можно переносить в свои модули без доработки.

Метод Свойство() — основной способ проверки

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

Вторая форма — с двумя параметрами: Структура.Свойство("ИмяКлюча", Значение). Если ключ найден, метод вернёт Истина и запишет значение ключа во второй параметр (он передаётся по ссылке). Если ключа нет, метод вернёт Ложь, а переменная останется неопределённой. Это самый экономичный приём: одна строка заменяет проверку и чтение.

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

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

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

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

Иначе

// ключа нет — задаём поведение по умолчанию

КонецЕсли;

Проверка с подстановкой значения по умолчанию

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

Паттерн реализуется через двухпараметрический вызов Свойство(): сначала переменной присваивается значение по умолчанию, затем метод перезаписывает её, если ключ найден. Такой код короче и надёжнее, чем ветвление через Если...Иначе.

Функция ПолучитьПараметр(Структура, ИмяКлюча, ЗначениеПоУмолчанию)

Результат = ЗначениеПоУмолчанию;

Структура.Свойство(ИмяКлюча, Результат);

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

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

Подобная универсальная функция-обёртка снижает количество дублирующегося кода в модуле. Её удобно разместить в общем модуле с признаком «Сервер», чтобы использовать из любых прикладных объектов конфигурации.

Проверка наличия ключа через перебор структуры

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

Перебор оправдан в двух ситуациях. Первая — когда нужно проверить наличие сразу нескольких ключей или найти ключи по шаблону имени (например, все, начинающиеся с «Параметр_»). Вторая — когда требуется одновременно проанализировать и имена, и значения ключей.

ИскомыйКлюч = "Склад";

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

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

Если КлючИЗначение.Ключ = ИскомыйКлюч Тогда

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

Прервать;

КонецЕсли;

КонецЦикла;

Сравнение способов проверки

Свойство() с одним параметром

Быстрая проверка факта наличия ключа. Подходит, когда значение не нужно или читается отдельно.

Свойство() с двумя параметрами

Оптимальный вариант: проверка и чтение значения за один вызов. Рекомендуется по умолчанию.

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

Медленнее, но позволяет искать по шаблону имени и проверять несколько ключей за один проход.

Проверка через Попытка/Исключение и почему её избегают

Технически можно обратиться к ключу напрямую внутри блока Попытка...Исключение и перехватить ошибку «Поле объекта не обнаружено». Такой приём встречается в старом коде, однако использовать его как основной способ проверки не следует.

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

Конструкция Попытка/Исключение уместна только там, где ошибка действительно является исключительной ситуацией, а не штатной веткой алгоритма. Отсутствие необязательного параметра в структуре — штатная ситуация, и обрабатывать её нужно через Свойство().

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

Особенности работы с фиксированной структурой и вложенными структурами

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

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

ВложенноеЗначение = Неопределено;

ПромежуточныйУровень = Неопределено;

Если Структура.Свойство("Настройки", ПромежуточныйУровень)

И ТипЗнч(ПромежуточныйУровень) = Тип("Структура")

И ПромежуточныйУровень.Свойство("Режим", ВложенноеЗначение) Тогда

// вложенный ключ найден

КонецЕсли;

Обратите внимание на проверку типа промежуточного значения: без неё вызов Свойство() у значения, которое не является структурой, вызовет ошибку. Это особенно важно при разборе данных, полученных из JSON или из внешних систем, где состав и типы полей не гарантированы.

Порядок безопасного чтения вложенного ключа
  1. 1
    Проверьте ключ первого уровня методом Свойство() с выводом значения в переменную.
  2. 2
    Убедитесь через ТипЗнч(), что полученное значение — структура.
  3. 3
    Вызовите Свойство() уже у вложенной структуры для целевого ключа.
  4. 4
    Задайте значение по умолчанию на случай отсутствия любого из уровней.

Проверка данных из внешних источников: JSON и формы

При чтении JSON через ПрочитатьJSON() с параметром «в структуру» результатом является именно структура, состав ключей которой зависит от входящих данных. Перед обращением к любому полю такого объекта проверка через Свойство() обязательна: внешняя система может не передать часть полей, и прямое обращение оборвёт обработку.

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

Для разбора JSON с заранее известной схемой полезно сразу после чтения дополнить структуру недостающими ключами значениями по умолчанию. Тогда дальнейший код работает без проверок, а риск ошибки «Поле объекта не обнаружено» исчезает полностью.

Проверка результата и отладка

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

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

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

Сообщить(КлючИЗначение.Ключ);

КонецЦикла;

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

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

Вызов Свойство() в отладчике
Норма

Возвращает Истина для существующего ключа и Ложь для отсутствующего

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

Возвращает Ложь для ключа, который виден в табло, — проверьте опечатки и пробелы в имени

Значение, полученное вторым параметром
Норма

Переменная содержит значение ключа после вызова

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

Переменная осталась Неопределено при существующем ключе — значит, ключа нет или имя указано неверно

Поведение кода при отсутствии ключа
Норма

Срабатывает ветка со значением по умолчанию

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

Возникает ошибка «Поле объекта не обнаружено» — где-то осталось прямое обращение без проверки

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

Чем отличается проверка ключа от проверки значения на Неопределено?

Ключ может существовать в структуре, но содержать значение Неопределено — например, если его создали конструктором без заполнения. Сравнение Структура.Ключ = Неопределено вернёт Истина и для отсутствующего ключа (с ошибкой обращения), и для ключа со значением Неопределено. Метод Свойство() различает эти ситуации: он проверяет именно наличие ключа.

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

Да, ФиксированнаяСтруктура поддерживает метод Свойство() в обеих формах — с одним и с двумя параметрами. Логика идентична обычной структуре, поэтому код проверки не требует адаптации.

Можно ли проверить вложенный ключ одним вызовом, указав путь через точку?

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

Что быстрее: Свойство() или перебор в цикле?

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

Как проверить наличие реквизита у объекта справочника или документа?

Для объектов конфигурации метод Свойство() не применяется. Наличие реквизита определяют через метаданные: например, Метаданные.Справочники.Номенклатура.Реквизиты.Найти("ИмяРеквизита") вернёт объект метаданных или Неопределено. Это универсальный способ, не зависящий от конкретного экземпляра объекта.

Что вернёт Свойство() для ключа с пустым именем?

Структура допускает создание ключа только с корректным именем (идентификатором), поэтому ситуация с пустым ключом на практике не возникает. Если передать в Свойство() пустую строку, метод вернёт Ложь, так как такого ключа в коллекции нет.

Итог

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

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