В процессе работы с управляемыми формами в «1С:Предприятие 8.3» разработчики и администраторы иногда сталкиваются с крайне неприятным и трудновоспроизводимым поведением: периодически управляемая форма открывается абсолютно пустой. На ней отсутствуют кнопки, поля ввода, таблицы и другие элементы управления — отображается лишь пустое серое или белое окно. При этом при повторном открытии или у другого пользователя эта же форма может отображаться абсолютно нормально, со всеми элементами интерфейса.
Особенно часто эта проблема проявляется в типовых конфигурациях, например в «1С:Управление торговлей» (начиная с версий 11.0.9 и 11.1), при отображении всплывающего окна напоминаний пользователя. Давайте подробно проанализируем причины этой ошибки, разберем физику процесса рендеринга форм и рассмотрим эффективные практические способы решения этой проблемы.
Данное поведение не связано с ошибками в бизнес-логике вашей конфигурации. Это известный системный баг платформы «1С:Предприятие 8.3» (наиболее выраженный в линейках релизов 8.3.10–8.3.13, например 8.3.12.1529 и 8.3.13.1513). Выделяют три ключевые технические причины возникновения этого эффекта:
Доступность или Видимость крупных родительских групп (например, командных панелей или групп кнопок), алгоритм расчета высоты и ширины элементов дает сбой. Движок рендеринга ошибочно рассчитывает размеры элементов как нулевые, из-за чего вся форма визуально «схлопывается», становясь пустой.Давайте разберем по шагам, как локализовать и устранить этот баг как программными методами, так и с помощью администрирования системы.
Рассмотрим стандартный пример кода из общей формы напоминаний пользователя, который инициирует проблему при открытии:
&НаКлиенте
Процедура УстановитьВидимость()
ЕстьДанныеВТаблице = Напоминания.Количество() > 0;
Если Не ЕстьДанныеВТаблице И ЭтотОбъект.Открыта() Тогда
ЭтотОбъект.Закрыть();
КонецЕсли;
// Проблемная строка, вызывающая сбой рендеринга:
Элементы.ПанельКнопок.Доступность = ЕстьДанныеВТаблице;
КонецПроцедуры
В данном коде свойству Доступность контейнера ПанельКнопок напрямую присваивается результат вычисления логического выражения ЕстьДанныеВТаблице. Из-за особенностей компиляции кода в багнутых версиях платформы такое присвоение в момент открытия формы ломает дерево рендеринга интерфейса.
Проанализируем решение. Чтобы обойти эту ошибку компилятора, нам необходимо уйти от присвоения переменной и использовать жесткую условную конструкцию с явным указанием литералов Истина или Ложь. Перепишем процедуру следующим образом:
&НаКлиенте
Процедура УстановитьВидимость()
ЕстьДанныеВТаблице = Напоминания.Количество() > 0;
Если Не ЕстьДанныеВТаблице И ЭтотОбъект.Открыта() Тогда
ЭтотОбъект.Закрыть();
КонецЕсли;
// Обход бага платформы через явное присвоение значений
Если ЕстьДанныеВТаблице Тогда
Элементы.ПанельКнопок.Доступность = Истина;
Иначе
Элементы.ПанельКнопок.Доступность = Ложь;
КонецЕсли;
КонецПроцедуры
При таком подходе платформа корректно отрабатывает изменение доступности родительской группы элементов управления, и форма гарантированно перерисовывается без потери геометрии.
Если первый способ не помог или логика изменения видимости элементов более сложная, рекомендуется перенести момент изменения интерфейсных свойств элементов. Ошибка рендеринга возникает именно тогда, когда свойства Видимость или Доступность меняются синхронно в обработчиках событий ПриСозданииНаСервере или ПриОткрытии, когда геометрия окна еще окончательно не сформирована платформой.
Мы можем использовать асинхронный вызов процедуры настройки видимости с минимальной задержкой. Для этого применим метод ПодключитьОбработчикОжидания(). Посмотрим на пример реализации:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Подключаем однократный вызов процедуры с задержкой 0.1 секунды
ПодключитьОбработчикОжидания("УстановитьВидимостьСЗадержкой", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура УстановитьВидимостьСЗадержкой()
// Данный вызов произойдет, когда окно формы уже будет полностью инициализировано
УстановитьВидимость();
КонецПроцедуры
Сдвиг выполнения кода всего на 100 миллисекунд позволяет платформе «1С:Предприятие» сначала физически построить окно формы на экране пользователя, рассчитать размеры всех групп и только после этого применить правила доступности к кнопкам. Это полностью решает проблему «пустого» окна.
Еще один важный практический совет для разработчиков: старайтесь избегать программного управления доступностью или видимостью для целых родительских групп (таких как ГруппаФормы типа ОбычнаяГруппа или КоманднаяПанель).
Вместо отключения доступности всей панели, например:
Элементы.ПанельКнопок.Доступность = Ложь;
Рекомендуется управлять доступностью конкретных дочерних элементов (кнопок, полей), расположенных внутри этой панели, индивидуально. Отключение родительского контейнера заставляет движок компоновки пересчитывать размеры всех вложенных элементов, что на нестабильных релизах платформы часто приводит к их скрытию.
Также в свойствах проблемных групп в Конфигураторе можно попробовать снять флаги автоматического определения размеров («Автомаксимальная ширина» и «Автомаксимальная высота») и жестко задать минимальные размеры вручную. Это заблокирует попытки платформы сжать интерфейс до нулевых размеров.
Если вы являетесь системным администратором или пользователем и не имеете возможности вносить изменения в программный код конфигурации 1С, используйте следующие шаги для исправления ситуации:
/ClearCache.Мы подробно разобрали природу бага пустых управляемых форм и рассмотрели как программные методы его обхода, так и административные решения. Применение этих подходов позволит вам обеспечить стабильную и комфортную работу пользователей в любых прикладных решениях на платформе «1С:Предприятие 8.3».