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

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

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

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

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

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

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

Метод Свойство() объекта Структура имеет два варианта вызова. Первый — с одним параметром: Структура.Свойство("ИмяПоля"). Он возвращает значение поля, если оно есть, и Неопределено, если поля нет. Второй вариант — с двумя параметрами: Структура.Свойство("ИмяПоля", ЗначениеПоля). В этом случае метод возвращает Истина или Ложь, а значение поля (если оно найдено) помещается во второй параметр.

Именно второй вариант считается каноническим для проверки существования ключа, потому что результат типа Булево однозначно отвечает на вопрос «есть ли поле», независимо от того, какое значение в нём хранится.

СтруктураДанных = Новый Структура;

СтруктураДанных.Вставить("Контрагент", Справочники.Контрагенты.ПустаяСсылка());

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

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

// Поле существует, его значение в переменной ЗначениеПоля

Сообщить("Поле найдено, значение: " + ЗначениеПоля);

Иначе

Сообщить("Поля Контрагент в структуре нет");

КонецЕсли;

Обратите внимание: имя поля передаётся строкой и чувствительно к регистру только в части точного совпадения с тем, как ключ был вставлен. На практике рекомендуется выносить имена ключей в константы модуля или использовать одинаковое написание во всём коде, чтобы избежать ошибок из-за опечаток.

bsl
ЗначениеПоля = Неопределено;
Если СтруктураДанных.Свойство("Контрагент", ЗначениеПоля) Тогда
    // Поле есть, значение доступно
КонецЕсли;

Сравнение с Неопределено: когда оно работает и когда подводит

Часто встречается вариант проверки через сравнение результата Свойство() с Неопределено:

Если СтруктураДанных.Свойство("Контрагент") <> Неопределено Тогда

// Поле есть и оно заполнено

КонецЕсли;

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

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

Проверка вложенных структур и полей в коллекциях

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

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

Если Параметры.Свойство("ДополнительныеСвойства")

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

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

// Все уровни существуют, значение получено

КонецЕсли;

Обратите внимание на проверку типа промежуточного значения. Если поле ДополнительныеСвойства существует, но содержит, например, строку, вызов у него метода Свойство() приведёт к ошибке. Проверка через ТипЗнч() устраняет этот риск.

Проверка нескольких полей сразу

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

ОбязательныеПоля = Новый Массив;

ОбязательныеПоля.Добавить("Организация");

ОбязательныеПоля.Добавить("Период");

ОбязательныеПоля.Добавить("Склад");

ОтсутствующиеПоля = "";

Для Каждого ИмяПоля Из ОбязательныеПоля Цикл

Если Не СтруктураДанных.Свойство(ИмяПоля) Тогда

ОтсутствующиеПоля = ОтсутствующиеПоля + ИмяПоля + ", ";

КонецЕсли;

КонецЦикла;

Если Не ПустаяСтрока(ОтсутствующиеПоля) Тогда

ВызватьИсключение "В структуре отсутствуют поля: " + ОтсутствующиеПоля;

КонецЕсли;

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

Порядок безопасного чтения поля
  1. 1
    Вызовите СтруктураДанных.Свойство("ИмяПоля", Значение) с двумя параметрами
  2. 2
    Проверьте булев результат: Истина — поле существует
  3. 3
    Если поле вложенное, предварительно проверьте тип промежуточного значения через ТипЗнч()
  4. 4
    Только после успешной проверки обращайтесь к значению
  5. 5
    Для набора обязательных полей организуйте цикл по массиву имён

Альтернативные способы: перебор ключей и соответствие

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

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

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

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

Оптимален для одиночной проверки. Точно отвечает на вопрос «есть ли ключ», не зависит от хранимого значения

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

Подходит, когда важно, что поле есть и заполнено. Не подходит, если поле может хранить Неопределено

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

Уместен для анализа всего состава структуры, избыточен для разовой проверки

Соответствие вместо структуры

Выбирайте, если ключи не являются корректными идентификаторами или формируются динамически

Типичные ошибки и ограничения

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

Вторая группа ошибок связана с неверной интерпретацией результата. Проверка Свойство("Поле") <> Неопределено молча пропускает поля со значением Неопределено, а проверка через ЗначениеЗаполнено() дополнительно отсекает пустые ссылки, нулевые числа и пустые строки — это уже проверка заполненности, а не наличия.

Отдельное ограничение: имена ключей структуры должны быть допустимыми идентификаторами встроенного языка. При попытке вставить ключ с недопустимым именем через Вставить() будет вызвано исключение ещё на этапе формирования структуры.

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

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

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

Для временной диагностики в рабочей базе удобно вывести состав структуры в журнал регистрации или сообщение, перебрав её в цикле. После завершения отладки такой вывод следует убрать или обернуть в условие, чтобы не засорять журнал.

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

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

Состав структуры в отладчике
Норма

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

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

Ключа нет или имя отличается регистром/опечаткой — проверка всегда даёт Ложь

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

Выполняется ветка Иначе или задано значение по умолчанию

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

Возникает исключение «Поле объекта не обнаружено»

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

Двухпараметрный вызов Свойство() возвращает Истина

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

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

Часто задаваемые вопросы

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

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

Можно ли проверить поле структуры в запросе 1С?

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

Что вернёт Свойство() для поля, вставленного со значением Неопределено?

Вызов с одним параметром вернёт Неопределено — как и для отсутствующего поля. Вызов с двумя параметрами вернёт Истина, а во второй параметр поместит Неопределено. Поэтому для точного определения наличия ключа всегда используйте двухпараметрный вариант.

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

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

Как задать значение по умолчанию, если поля нет?

Типовой приём: Значение = Неопределено; Если Не СтруктураДанных.Свойство("Поле", Значение) Тогда Значение = ЗначениеПоУмолчанию; КонецЕсли. В альтернативном варианте сначала проверяют наличие, а в ветке Иначе присваивают значение по умолчанию. Оба подхода эквивалентны, выбирайте более читаемый в контексте вашего кода.

Почему проверка возвращает Ложь, хотя поле точно вставлялось?

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

Итог

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

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