Как динамически изменять размер управляемой формы 1С при скрытии элементов?

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

В процессе разработки интерфейсов на управляемых формах в «1С:Предприятии 8.3» программисты часто сталкиваются со следующей проблемой. На форме создается несколько групп элементов, видимость которых зависит от определенных условий. При скрытии одной или нескольких групп (путем установки свойства Видимость = Ложь) ожидается, что форма автоматически сожмется и примет аккуратный вид. Однако на практике этого не происходит. Платформа оставляет пустые области, а само окно сохраняет максимальный размер, который когда-либо принимало. Это происходит из-за механизма оптимизации интерфейса и кэширования размеров окон.

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

Выясняем причину: почему платформа не сжимает форму?

Управляемый интерфейс строится на декларативном принципе. Разработчик описывает структуру формы, а отрисовкой и расчетом геометрии занимается платформа. При первом открытии формы 1С анализирует видимые элементы и рассчитывает оптимальный размер окна. Этот размер кэшируется в системных настройках пользователя.

Когда вы динамически скрываете элементы на уже открытой форме, платформа уменьшает или скрывает сами элементы управления внутри формы, но размер внешнего окна принудительно назад не уменьшает. Попытки изменить свойства формы Высота и Ширина программно также ни к чему не приводят, поскольку эти свойства в управляемом интерфейсе работают только на увеличение размера и не способны сжать окно меньше текущего физического размера.

Давайте рассмотрим эффективные методы решения этой проблемы.

Способ 1. Использование динамического «Ключа сохранения положения окна»

Самый простой и элегантный способ борьбы с нежелательным кэшированием размеров — управление свойством формы КлючСохраненияПоложенияОкна. Это строковое свойство определяет, под каким идентификатором платформа будет сохранять геометрические параметры окна для текущего пользователя.

Если мы просто очистим этот ключ или запишем туда случайный уникальный идентификатор при создании формы, как показано ниже:

ЭтаФорма.КлючСохраненияПоложенияОкна = Строка(Новый УникальныйИдентификатор);

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

Правильный подход заключается в выделении под каждое состояние формы своего фиксированного ключа. Предположим, у нас есть три сценария работы формы: «Быстрый ввод», «Стандартный режим» и «Расширенные настройки». Разберем по шагам, как настроить смену ключей:


&НаКлиенте
Процедура УстановитьРежимОтображения(Режим)
    
    Если Режим = "Минимум" Тогда
        Элементы.ГруппаПодробности.Видимость = Ложь;
        ЭтаФорма.КлючСохраненияПоложенияОкна = "ФормаВвода_Режим_Минимум";
    ИначеЕсли Режим = "Стандарт" Тогда
        Элементы.ГруппаПодробности.Видимость = Истина;
        ЭтаФорма.КлючСохраненияПоложенияОкна = "ФормаВвода_Режим_Стандарт";
    КонецЕсли;
    
КонецПроцедуры

Когда платформа видит изменение значения свойства КлючСохраненияПоложенияОкна, она пытается прочитать из системного кэша настройки именно для этого ключа. Если для этого режима настройки еще не были сохранены, форма корректно сожмется под текущий набор видимых элементов.

Способ 2. Использование панели «Страницы» вместо управления видимостью

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

Рассмотрим по шагам данный метод настройки интерфейса:

  1. Добавим на форму новую группу с видом Страницы. Назовем ее, например, ПанельРежимов.
  2. Для созданной группы установим свойство ОтображениеЗакладок в значение Не использовать. Это скроет верхнюю панель с вкладками от пользователя.
  3. Внутри этой группы создадим несколько подчиненных групп с видом Страница — по одной под каждый сценарий отображения (например, СтраницаПоиск, СтраницаВводКоличества, СтраницаОшибка).
  4. Разместим элементы управления на соответствующих страницах.
  5. В коде формы вместо скрытия отдельных элементов будем просто переключать активную страницу.

Пример программного переключения страниц:


&НаКлиенте
Процедура ПоказатьСтраницуОшибки()
    
    // Переключаем страницу панели на нужную
    Элементы.ПанельРежимов.ТекущаяСтраница = Элементы.СтраницаОшибка;
    
КонецПроцедуры

Опыт показывает, что платформа 1С гораздо более корректно рассчитывает и перестраивает размеры окон при переключении страниц, нежели при массовом изменении видимости отдельных групп на одной странице. Главное условие — у страниц и элементов внутри них должно быть отключено свойство РастягиватьПоВертикали.

Способ 3. Программный сброс настроек окна через Хранилище Системных Настроек

Если форма уже открыта, растянута пользователем, и нам требуется принудительно заставить платформу «забыть» старые размеры и пересчитать форму заново, мы можем использовать программную очистку кэша конкретного окна. Для этого обратимся к механизму системных настроек.

Этот метод особенно актуален при использовании Библиотеки Стандартных Подсистем (БСП). Рассмотрим пример процедуры, которая выполняет сброс кэша геометрии формы:


&НаСервере
Процедура СброситьНастройкиОкнаНаСервере()
    
    ИмяПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;
    
    // Формируем системный путь к настройкам окна нашей формы
    // Путь состоит из: ИмяОбъекта/ИмяФормы/ВариантИнтерфейса/НастройкиОкна
    КлючОбъекта = "Обработка.БыстрыйВводТоваров.Форма.ФормаВвода/Такси/НастройкиОкна";
    
    // Удаляем настройки геометрии окна из базы данных
    ХранилищеСистемныхНастроек.Удалить(КлючОбъекта, "", ИмяПользователя);
    
КонецПроцедуры

После вызова этого серверного метода при следующем открытии форма примет свой первоначальный компактный размер, рассчитанный конфигуратором по умолчанию.

Способ 4. Закрытие и повторное открытие формы (Пересоздание)

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

Проанализируем пример реализации такого подхода:

  1. При сканировании штрихкода на форме ввода мы определяем, что товар требует ввода акцизной марки (новый режим работы).
  2. Мы закрываем текущее окно с возвратом структуры параметров на форму-владелец.
  3. Форма-владелец сразу же открывает эту форму заново, но передает в параметрах признак Параметры.РежимРаботы = "Алкоголь".
  4. При создании на сервере новая форма сразу инициализируется в правильном режиме с нужным набором видимых элементов. Геометрия окна будет рассчитана платформой идеально под этот набор с первого кадра отрисовки.

Способ 5. Эмуляция сочетания клавиш «Восстановить положение окна»

В платформе «1С:Предприятие» заложена стандартная сервисная комбинация клавиш Alt + Shift + R. При ее нажатии активное окно мгновенно сжимается до своего минимально возможного размера, соответствующего текущим видимым элементам управления.

Несмотря на то, что во встроенном языке 1С нет прямого метода для выполнения этой команды, мы можем прибегнуть к программной эмуляции нажатия этих клавиш на стороне клиента через объект Windows Script Host.

Давайте посмотрим на пример реализации такого костыля:


&НаКлиенте
Процедура ПринудительноСжатьФорму()
    
    #Если Клиент Тогда
        Попытка
            Шелл = Новый COMОбъект("WScript.Shell");
            // Отправляем комбинацию Alt (%) + Shift (+) + R
            Шелл.SendKeys("%+R");
        Исключение
            // Обработка исключения, если запуск COM-объектов заблокирован политиками безопасности
        КонецПопытки;
    #КонецЕсли
    
КонецПроцедуры

Важное предупреждение: этот способ является платформозависимым. Он будет работать исключительно на операционных системах семейства Windows и только в тонком или толстом клиенте 1С. В веб-клиенте или под управлением Linux данный код не сработает, поэтому использовать его следует с осторожностью.

Правила верстки элементов для предотвращения «залипания» размеров

Помимо программных методов управления окнами, критически важно правильно спроектировать форму в конфигураторе. Проанализируем основные свойства элементов, на которые следует обратить внимание:

Используя предложенные методики, вы сможете легко побороть нежелательное поведение платформы при изменении видимости элементов и сделать работу пользователей в программе 1С максимально комфортной и приятной.

← На главную