При разработке внешних обработок в среде 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда добавленный реквизит, имеющий тип ссылки на документ, ведет себя непредсказуемо: он либо не выводится на форму в режиме «1С:Предприятие», либо вызывает критические ошибки при выполнении кода на сервере. Особенно остро эта проблема проявилась при переходе на новые релизы конфигурации «Управление торговлей» (начиная с версии 11.4). В рамках данной статьи мы подробно разберем причины такого поведения, проанализируем влияние архитектурных изменений конфигурации и рассмотрим пошаговые инструкции по исправлению подобных ошибок.
Проанализируем типичную ситуацию. Разработчик создает внешнюю обработку и добавляет реквизит с типом ДокументСсылка.ПоступлениеТоваров. При попытке программного обращения к этому документу, например, через метод НайтиПоНомеру(), платформа выдает ошибку: «Поле объекта не обнаружено». Рассмотрим пример проблемного кода:
&НаСервере
Процедура ПолучитьЗначенияПоУмолчанию()
// Попытка найти документ по номеру и дате
ПоступлениеТМЦ_ТЕСТ = Документы.ПоступлениеТоваров.НайтиПоНомеру("0ФЦБ-000008", Дата(2018, 9, 3));
КонецПроцедуры
Выясним причину ошибки. В версии УТ 11.4 (и соответствующих версиях ERP 2.4 или Комплексной автоматизации 2.4) компания «1С» произвела масштабный рефакторинг имен объектов метаданных. Документ, который пользователи привыкли видеть в интерфейсе под синонимом «Поступление товаров и услуг», в конфигураторе теперь имеет имя ПриобретениеТоваровУслуг. Старое имя ПоступлениеТоваровУслуг (или ошибочное ПоступлениеТоваров) более не существует в дереве метаданных как самостоятельный объект закупки.
Важно понимать: платформа 1С обращается к объектам по их Имени, а не по Синониму. Если в конфигураторе вы видите, что поле называется «Поступление товаров», обязательно проверьте его реальное имя в свойствах объекта. Для актуальных версий УТ правильный код будет выглядеть следующим образом:
&НаСервере
Процедура ПолучитьЗначенияПоУмолчанию()
// Правильное обращение к метаданным в УТ 11.4+
ПоступлениеТМЦ_ТЕСТ = Документы.ПриобретениеТоваровУслуг.НайтиПоНомеру("0ФЦБ-000008", Дата(2018, 9, 3));
КонецПроцедуры
Если имя объекта указано верно, но реквизит все равно не отображается на форме в рантайме, нам необходимо проверить механизм функциональных опций. В современных типовых решениях (УТ, ERP, КА) практически каждый документ связан с определенной функциональной опцией, которая включает или отключает соответствующий раздел учета.
Рассмотрим, как это работает:
ПриобретениеТоваровУслуг установлена связь с функциональной опцией, например, ИспользоватьЗакупки.Ложь.Для решения этой проблемы проверим настройки программы или программно проанализируем состояние опции с помощью метода ПолучитьФункциональнуюОпцию().
Еще один важный аспект, который мы должны учитывать — это права доступа. Если пользователь, под которым запускается внешняя обработка, не имеет прав на чтение объекта метаданных Документ.ПриобретениеТоваровУслуг, то поле на форме не просто будет пустым — платформа может полностью скрыть элемент управления.
Проанализируем ситуацию с RLS (Record Level Security). Даже при наличии общих прав на тип документа, ограничения на уровне записей могут блокировать доступ к конкретным экземплярам документов. Если программный код пытается подтянуть ссылку на документ, к которому у пользователя нет доступа, значение реквизита может сброситься или не отобразиться корректно.
Часто в процессе разработки мы вносим изменения во внешнюю обработку (меняем типы данных, переименовываем реквизиты), но при запуске в 1С видим «старую» картину. Это происходит из-за кэширования форм платформой 1С:Предприятие 8.3.
Посмотрим, как гарантированно обновить форму:
Для того чтобы ваша внешняя обработка была более устойчивой к изменениям метаданных (например, работала и в УТ 11.3, и в УТ 11.4), рекомендуется использовать проверку наличия объектов метаданных. Разберем пример безопасного поиска типа:
&НаСервере
Функция НайтиСсылкуНаДокумент(НомерДокумента, ДатаДокумента)
// Проверяем наличие нового имени документа
Если Метаданные.Документы.Найти("ПриобретениеТоваровУслуг") <> Неопределено Тогда
Возврат Документы.ПриобретениеТоваровУслуг.НайтиПоНомеру(НомерДокумента, ДатаДокумента);
// Проверяем наличие старого имени документа
ИначеЕсли Метаданные.Документы.Найти("ПоступлениеТоваровУслуг") <> Неопределено Тогда
Возврат Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру(НомерДокумента, ДатаДокумента);
КонецЕсли;
Возврат Неопределено;
КонецФункции
Использование подобных конструкций позволяет избежать жесткой привязки к конкретному релизу конфигурации и делает ваш код профессиональным и отказоустойчивым.
Подведем итоги нашего анализа. Если реквизит типа ДокументСсылка не отображается на форме или вызывает ошибку «Поле объекта не обнаружено»:
ПриобретениеТоваровУслуг), а не синоним и не устаревшее имя из прошлых версий.Соблюдение этих простых правил позволит значительно сократить время на отладку внешних отчетов и обработок в современных конфигурациях на базе 1С:Предприятие 8.3.