Разработка в экосистеме «1С:Предприятие 8.3» на базе современных типовых конфигураций (таких как «Управление торговлей 11», «ERP Управление предприятием» или «Комплексная автоматизация») часто преподносит сюрпризы. Один из классических сценариев: разработчик заимствует форму элемента справочника Номенклатура в расширение, визуально увеличивает поле наименования на всю ширину формы в редакторе, сохраняет изменения, но при запуске в режиме «1С:Предприятие» видит, что поле упорно возвращается к своему исходному узкому размеру.
В этой статье мы подробно разберем, почему платформа ведет себя подобным образом, как устроена работа со свойствами ширины в управляемом интерфейсе «Такси» и какими способами можно гарантированно решить эту задачу в соответствии со стандартами разработки «1С».
Когда мы меняем размеры элементов интерфейса непосредственно в визуальном редакторе формы внутри расширения, наши изменения сохраняются в метаданных расширения. Однако в режиме «1С:Предприятие» на форму начинает влиять сразу несколько факторов, которые переопределяют или полностью затирают эти настройки. Выделим три основные причины:
УправлениеФормами, в процессе создания формы на сервере (в обработчике ПриСозданииНаСервере) обходят элементы интерфейса и принудительно задают им свойства, отвечающие за адаптивность интерфейса под разные разрешения экранов. Для текстовых полей ввода БСП часто программно включает авто-ширину, сбрасывая ваши ручные настройки из конфигуратора.
Для правильного позиционирования элементов важно понимать, как платформа обрабатывает размеры. Начиная с версии платформы 8.3.7, для элементов управления управляемой формы используются два ключевых взаимосвязанных свойства:
АвтоМаксимальнаяШирина. Если это свойство установлено в значение Истина, платформа самостоятельно рассчитывает максимальный размер поля ввода на основании типа данных, связанных с этим полем. Для длинных текстовых полей (каковым и является наименование номенклатуры) платформа устанавливает жесткое ограничение, чтобы форма не расползалась на широкоформатных мониторах. В этом режиме любое значение в свойстве МаксимальнаяШирина полностью игнорируется платформой.
МаксимальнаяШирина. Это свойство начинает работать исключительно тогда, когда АвтоМаксимальнаяШирина установлена в значение Ложь. Если мы хотим, чтобы поле растягивалось на всю доступную ширину родительской группы или всей формы, нам необходимо установить МаксимальнаяШирина = 0.
Теперь рассмотрим практические способы решения проблемы, от быстрого (но не совсем правильного) до наиболее надежных и каноничных.
Этот способ обнаружил автор темы на форуме. Суть заключается в том, чтобы переопределить свойства элемента формы непосредственно в момент ее открытия на клиенте. Для этого используется обработчик события управляемой формы ПриОткрытии.
Рассмотрим пример кода в модуле формы расширения:
&После("ПриОткрытии")
Процедура Расш_ПриОткрытии(Отказ)
// Отключаем автоматический расчет максимальной ширины
Элементы.Наименование.АвтоМаксимальнаяШирина = Ложь;
// Задаем ширину принудительно (например, 100 символов)
Элементы.Наименование.МаксимальнаяШирина = 100;
КонецПроцедуры
Почему этот способ работает? Код на клиенте выполняется в самую последнюю очередь, уже после того, как отработали все серверные механизмы БСП и платформенное слияние форм. Мы принудительно «накатываем» нужные параметры поверх готовой формы.
Минусы этого подхода (Антипаттерн): Изменение компоновки интерфейса на клиенте вызывает так называемое «мерцание» интерфейса. При открытии формы пользователь сначала на долю секунды увидит стандартное узкое поле, которое затем резко растянется на весь экран. Кроме того, любые манипуляции с интерфейсом рекомендуется производить на сервере до передачи формы на клиент, чтобы экономить ресурсы клиентского приложения.
Это самый надежный, правильный и рекомендуемый стандарт разработки способ. Все изменения структуры, видимости и размеров элементов формы должны происходить на сервере в момент инициализации формы.
Проанализируем шаги реализации:
Номенклатура в наше расширение.ПриСозданииНаСервере с аннотацией &После. Это гарантирует, что наш код выполнится сразу после того, как отработает типовой код конфигурации и механизмы БСП.Пропишем следующий код:
&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Отключаем автоматическое ограничение ширины платформой
Элементы.Наименование.АвтоМаксимальнаяШирина = Ложь;
// Устанавливаем значение 0, чтобы поле растягивалось на всю ширину формы/группы,
// либо задаем конкретное число символов (например, 120)
Элементы.Наименование.МаксимальнаяШирина = 0;
КонецПроцедуры
При таком подходе форма будет сгенерирована сервером сразу в правильном виде, пользователь не заметит никаких визуальных задержек и мерцаний интерфейса при открытии.
В стандартах разработки 1С хорошим тоном считается минимизация заимствования форм в расширения. Чем меньше форм заимствовано «целиком», тем проще и безболезненнее будет проходить процесс обновления конфигурации на новые релизы от вендора. Если вам требуется только изменить ширину поля наименования и нет необходимости делать глобальные косметические перерисовки формы в конфигураторе, можно перехватить событие формы программно.
Для этого мы можем использовать возможности БСП по перехвату событий форм. Разберем этот процесс по шагам:
Шаг 1. Создаем в расширении общий модуль, например, Расш_МодификацияИнтерфейсаСобытия (установите свойства: Клиент (обычное приложение), Сервер, Внешнее соединение).
Шаг 2. В модуле формы или через подписку на системные события БСП (в зависимости от версии БСП в вашей конфигурации) мы можем выполнить перехват создания формы номенклатуры. Но наиболее простым и надежным решением в расширении все же будет перехват общего модуля БСП, отвечающего за создание форм, либо создание перехватчика в модуле менеджера справочника.
Если мы используем расширение, мы можем перехватить процедуру ПриСозданииНаСервере конкретной формы элемента справочника напрямую в модуле формы, не перенося при этом визуальные элементы формы в расширение. Для этого достаточно заимствовать форму, но не изменять ее визуально, а только добавить в ее модуль код обработки:
&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Попытка
ЭлементНаименование = Элементы.Найти("Наименование");
Если ЭлементНаименование <> Неопределено Тогда
ЭлементНаименование.АвтоМаксимальнаяШирина = Ложь;
ЭлементНаименование.МаксимальнаяШирина = 0;
КонецЕсли;
Исключение
// Запись в журнал регистрации в случае изменения структуры формы поставщиком
ЗаписьЖурналаРегистрации("Расширение.ИзменениеИнтерфейса",
УровеньЖурналаРегистрации.Предупреждение,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Использование безопасного поиска элемента через метод Найти() и конструкция Попытка...Исключение уберегут вашу конфигурацию от критических ошибок при обновлении базы данных, если фирма «1С» в будущем решит переименовать поле «Наименование» во что-то другое.
Если вы применили один из серверных способов программирования, обновили базу данных, но поле по-прежнему отображается узким, дело в сохраненных настройках вашей учетной записи 1С. Платформа запомнила старый вид формы.
Для того чтобы сбросить кэш отображения формы для вашего пользователя, выполните следующие действия в режиме «1С:Предприятие»:
Номенклатура.После выполнения этих шагов платформа полностью сотрет локальный кэш компоновки для данной формы и построит интерфейс заново, применив ваши программные настройки из расширения. Поле «Наименование» успешно растянется на всю доступную ширину.