Разработка в расширениях конфигурации 1С — это удобный и безопасный стандарт кастомизации систем на платформе 1С:Предприятие 8.3. Однако разработчики часто сталкиваются с неприятной ситуацией: в расширение добавляется новый реквизит справочника или документа, он выносится на заимствованную форму, но в режиме «1С:Предприятие» поле ввода оказывается невидимым или недоступным для редактирования (на клиенте значение отображается как недоступное для чтения, хотя на сервере оно успешно обрабатывается).
В этой статье мы подробно проанализируем причины такого поведения платформы и разберем по шагам несколько надежных способов устранения этой проблемы.
Давайте выясним техническую причину этой неполадки. Начиная с версии платформы 1С 8.3.14, был изменен внутренний механизм заимствования форм. При переносе формы в расширение по умолчанию заимствуется только ее визуальная структура (элементы формы), в то время как сами реквизиты, команды и параметры формы не переносятся автоматически. Они остаются «ссылками» на основную конфигурацию.
Если основной реквизит формы Объект (имеющий тип СправочникОбъект или ДокументОбъект) не заимствован в расширение явным образом, платформа на клиенте пытается сопоставить путь к данным Объект.НовыйРеквизит с метаданными из основной конфигурации. Поскольку в основной конфигурации нашего нового реквизита нет, на клиенте он становится недоступным для чтения и отображения.
Вторая распространенная причина — особенности работы прав доступа и ролей внутри расширений, а также кэширование пользовательских настроек интерфейса. Рассмотрим пошаговые решения для каждой из этих ситуаций.
Это самый быстрый и стандартный метод, который решает проблему в большинстве случаев. Нам необходимо принудительно заставить форму расширения «знать» о существовании расширенного типа объекта на клиенте.
Выполним следующие шаги:
Объект и выделен жирным шрифтом.Объект. Обратите внимание на свойство Тип. Очень часто при обновлениях конфигурации или самого расширения этот тип может «слетать» (становиться пустым).СправочникОбъект.ДоговорыКонтрагентов).Выполнив эти действия, мы явно связываем контекст формы с расширенными метаданными, и путь к данным вида Объект.НовыйРеквизит начнет корректно распознаваться платформой на клиенте.
Если первый метод выполнен, но реквизит по-прежнему скрыт от глаз пользователей, дело почти наверняка в правах доступа. В платформе 1С действует важное правило безопасности при работе с расширениями.
«Эффект первой роли»: если в вашем расширении вообще нет собственных ролей, платформа автоматически предоставляет полные права на все новые объекты и реквизиты расширения всем пользователям. Но как только в расширении создается или заимствуется хотя бы одна роль (это часто происходит автоматически при генерации расширения), автоматическое распределение прав полностью отключается.
Чтобы восстановить доступ к реквизиту, выполним правильную настройку ролей:
ДоговорыКонтрагентов или документа ГрафикИсполненияДоговора)./ЗапускОбновленияИнформационнойБазы или выполним в консоли кода вызов метода:
Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеВспомогательныхТаблиц();
Бывают ситуации, когда код написан верно, права выданы, но у конкретного пользователя новое поле все равно не выводится на экран. Причина кроется в механизме сохранения настроек интерфейса 1С.
Платформа сохраняет индивидуальные настройки отображения элементов (видимость, положение, ширина колонок) для каждого пользователя индивидуально. Если пользователь открывал форму до того, как мы внесли изменения в расширение, сохраненный кэш старой формы может перекрывать новые элементы.
Давайте сбросим настройки формы к стандартным:
Чтобы полностью обезопасить себя от проблем со «слетанием» типов реквизита Объект и конфликтов интерфейса при обновлениях конфигурации поставщика, опытные разработчики рекомендуют использовать программный вывод элементов вместо визуального проектирования на заимствованной форме.
При таком подходе мы не заимствуем форму визуально и не переносим реквизит Объект. Мы заимствуем только модуль формы и динамически добавляем элементы на серверном этапе создания.
Рассмотрим пример реализации в модуле формы с использованием механизма переопределения метода ПриСозданииНаСервере:
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Проверим, что элемент еще не создан на форме, во избежание дублирования
Если Элементы.Найти("Расш1_НовыйРеквизит") = Неопределено Тогда
// Определим группу на форме, куда хотим поместить наше новое поле ввода
ГруппаРазмещения = Элементы.ГруппаОсновное;
// Создаем новое поле формы динамически
НовоеПоле = Элементы.Добавить("Расш1_НовыйРеквизит", Тип("ПолеФормы"), ГруппаРазмещения);
НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
// Связываем элемент формы с новым реквизитом расширения напрямую через Объект
НовоеПоле.ПутьКДанным = "Объект.Расш1_НовыйРеквизит";
НовоеПоле.Заголовок = "Дополнительная информация (расш.)";
КонецЕсли;
КонецПроцедуры
Этот способ гарантирует максимальную отказоустойчивость вашей доработки: элемент формы будет создаваться динамически и безошибочно обращаться к реквизиту расширения, не требуя ручной поддержки связей типов реквизита Объект при последующих обновлениях системы.