Как проверить наличие реквизита или свойства объекта в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Комплексная автоматизация IT и автоматизация бизнеса
← На главную

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

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

Способ 1. Использование метода Свойство() для Структуры

Если параметр ДанныеДляПечати является объектом типа Структура, наиболее лаконичным и быстрым решением будет вызов метода Свойство(). Он возвращает Истина, если ключ существует в структуре, и позволяет сразу записать значение в переменную.

Посмотрим на пример реализации:


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

	ОбластьМакета = Макет.ПолучитьОбласть("ИдентификаторГосКонтракта");
	ОбластьМакета.Параметры.ИдентификаторГосКонтракта = ДанныеДляПечати.ИдентификаторГосКонтракта;
	ТабДокумент.Вывести(ОбластьМакета);

КонецЕсли;

Способ 2. Использование функций Библиотеки Стандартных Подсистем (БСП)

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

  1. Универсальная функция БСП: В современных конфигурациях предусмотрена функция ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта().
    
    Если ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта(ДанныеДляПечати, "ДокументОснование") 
    	И ТипЗнч(ДанныеДляПечати.ДокументОснование) = Тип("ДокументСсылка.КорректировкаРеализации") Тогда
    
    	ОбластьМакета = Макет.ПолучитьОбласть("ИдентификаторГосКонтракта");
    	ОбластьМакета.Параметры.ИдентификаторГосКонтракта = ДанныеДляПечати.ИдентификаторГосКонтракта;
    	ТабДокумент.Вывести(ОбластьМакета);
    
    КонецЕсли;
    
  2. Проверка через метаданные документа: В устаревших конфигурациях (например, «Комплексная автоматизация 1.1» или «Управление торговлей 10.3») можно обратиться к функции ОбщегоНазначения.ЕстьРеквизитДокумента():
    
    МетаданныеДокумента = ДанныеДляПечати.Метаданные;
    Если ОбщегоНазначения.ЕстьРеквизитДокумента("ДокументОснование", МетаданныеДокумента) 
    	И ТипЗнч(ДанныеДляПечати.ДокументОснование) = Тип("ДокументСсылка.КорректировкаРеализации") Тогда
    
    	ОбластьМакета = Макет.ПолучитьОбласть("ИдентификаторГосКонтракта");
    	ОбластьМакета.Параметры.ИдентификаторГосКонтракта = ДанныеДляПечати.ИдентификаторГосКонтракта;
    	ТабДокумент.Вывести(ОбластьМакета);
    
    КонецЕсли;
    

Способ 3. Безопасное использование блока Попытка ... Исключение

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

Рассмотрим правильный пример выноса проверки во вспомогательную переменную:


ЕстьПоле = Ложь;
ЗначениеОснования = Неопределено;

Попытка
	ЗначениеОснования = ДанныеДляПечати.ДокументОснование;
	ЕстьПоле = Истина;
Исключение
	ЕстьПоле = Ложь;
КонецПопытки;

Если ЕстьПоле И ТипЗнч(ЗначениеОснования) = Тип("ДокументСсылка.КорректировкаРеализации") Тогда

	ОбластьМакета = Макет.ПолучитьОбласть("ИдентификаторГосКонтракта");
	ОбластьМакета.Параметры.ИдентификаторГосКонтракта = ДанныеДляПечати.ИдентификаторГосКонтракта;
	ТабДокумент.Вывести(ОбластьМакета);

КонецЕсли;

Способ 4. Универсальный подход через ЗаполнитьЗначенияСвойств

Проанализируем еще один платформенный прием, который работает безошибочно для любых источников данных (структура, выборка из результата запроса, строка таблицы значений или ссылочный объект). В нем используется эталонная структура с уникальным значением-маркером:


КлючПроверки = Новый УникальныйИдентификатор;
ПроверочнаяСтруктура = Новый Структура("ДокументОснование", КлючПроверки);
ЗаполнитьЗначенияСвойств(ПроверочнаяСтруктура, ДанныеДляПечати);

Если ПроверочнаяСтруктура.ДокументОснование <> КлючПроверки 
	И ТипЗнч(ПроверочнаяСтруктура.ДокументОснование) = Тип("ДокументСсылка.КорректировкаРеализации") Тогда

	ОбластьМакета = Макет.ПолучитьОбласть("ИдентификаторГосКонтракта");
	ОбластьМакета.Параметры.ИдентификаторГосКонтракта = ДанныеДляПечати.ИдентификаторГосКонтракта;
	ТабДокумент.Вывести(ОбластьМакета);

КонецЕсли;

Подведем итог: Для структур наиболее удобен метод Свойство(). При работе с универсальными объектами рекомендуется использовать функции БСП ОбщегоНазначенияКлиентСервер.ЕстьРеквизитИлиСвойствоОбъекта() или процедуру ЗаполнитьЗначенияСвойств(), избегая лишнего применения блока Попытка ... Исключение.

← На главную