Как программно уменьшить высоту управляемой формы в 1С при скрытии элементов

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

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

Выясняем причину: почему платформа 1С «запоминает» высоту формы

Для начала проанализируем внутреннее поведение платформы 1С:Предприятие. Когда пользователь открывает любое окно, платформа считывает его геометрические параметры (ширину, высоту, положение на экране) из системного хранилища настроек (ХранилищеСистемныхНастроек). Этот кэш привязывается к имени формы и конкретному пользователю.

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

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

Решение 1. Разделение ключей сохранения положения окна (Рекомендуемый метод)

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

Рассмотрим пример реализации этого механизма в модуле формы. Пропишем условие в обработчике ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Определяем условие, при котором список должен быть скрыт
    НеобходимСписок = (Параметры.Свойство("ПоказыватьСписок") И Параметры.ПоказыватьСписок);

    Если НеобходимСписок Тогда
        Элементы.Список.Видимость = Истина;
        // Задаем уникальный ключ для формы в развернутом виде
        КлючСохраненияПоложенияОкна = "ФормаЭлемента_СоСписком";
    Иначе
        Элементы.Список.Видимость = Ложь;
        // Задаем уникальный ключ для компактного вида формы
        КлючСохраненияПоложенияОкна = "ФормаЭлемента_БезСписка";
    EndIf;

КонецПроцедуры

Как это работает: Платформа 1С сохранит в системную базу данных два независимых набора настроек геометрии для одного и того же объекта метаданных. При открытии компактной формы она автоматически сожмется до сохраненного «маленького» размера, а при открытии со списком — развернется до полного размера. Пользователь сможет настраивать размеры обоих вариантов окон независимо друг от друга.

Решение 2. Использование сворачиваемых групп вместо скрытия элементов

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

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


&НаСервере
Процедура НастроитьОтображениеГруппыНаСервере()

    // Проверяем наличие данных, например, рабочих мест
    ЕстьРабочиеМеста = (Объект.РабочиеМеста.Количество() > 0);
    
    ГруппаСписок = Элементы.ГруппаРабочиеМеста;
    
    Если ЕстьРабочиеМеста Тогда
        // Оставляем группу развернутой и доступной для работы
        ГруппаСписок.Поведение = ПоведениеОбычнойГруппы.Обычное;
        ГруппаСписок.Заголовок = "Список рабочих мест";
    Иначе
        // Делаем группу сворачиваемой
        ГруппаСписок.Поведение = ПоведениеОбычнойГруппы.Свертываемая;
        ГруппаСписок.Заголовок = "Нет рабочих мест (нажмите для раскрытия)";
    КонецЕсли;

КонецПроцедуры

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

Решение 3. Тонкая настройка свойств растягивания («Резиновость» формы)

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

Выполним аудит свойств формы и элементов по следующему чек-листу:

  1. Откройте свойства самой управляемой формы в конфигураторе. Убедитесь, что свойства АвтоМаксимальнаяВысота и АвтоМаксимальнаяШирина находятся в состоянии Истина (флаги установлены).
  2. Проанализируйте свойства родительских групп, в которых находится ваш скрываемый список. Свойство РастягиватьПоВертикали у этих групп должно быть установлено в значение Авто или Ложь. Если там принудительно установлено Истина, группа будет держать высоту даже при пустом содержимом.
  3. Перейдите к свойствам самого динамического списка или таблицы формы. Проверьте флаг АвтоМаксимальнаяВысота — его рекомендуется сбросить и задать свойство Высота в минимально необходимое значение (например, от 3 до 5 строк), чтобы элемент не требовал избыточного пространства при инициализации.

Решение 4. Принудительный разовый сброс геометрии формы

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

Посмотрим на пример реализации:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    // Генерация нового GUID полностью сбрасывает запомненные размеры при каждом открытии
    КлючСохраненияПоложенияОкна = Строка(Новый УникальныйИдентификатор);

КонецПроцедуры

Важное предупреждение: Частое использование этого метода может привести к постепенному накоплению «мусорных» записей настроек пользователей в системных таблицах базы данных. Используйте этот способ осмотрительно, отдавая предпочтение статическим строковым ключам из Решения 1.

Решение 5. Эмуляция сочетания клавиш Alt + Shift + R (для Windows-клиентов)

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

Данный метод реализуется на клиенте с использованием Windows Script Host:


&НаКлиенте
Процедура СжатьФормуПослеСкрытияЭлементов()

    Попытка
        // Создаем COM-объект для отправки нажатий клавиш в операционную систему
        Shell = Новый COMОбъект("WScript.Shell");
        // Отправляем комбинацию Alt (%) + Shift (+) + R
        Shell.SendKeys("%+R"); 
    Исключение
        // Данный код не сработает на Web-клиенте или под управлением ОС Linux
        ЗаписатьЛогОшибки("Не удалось выполнить автоматическое сжатие формы: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Решение 6. Создание двух специализированных форм (Архитектурный подход)

Если состав реквизитов формы кардинально меняется в зависимости от условий (например, в одном случае это огромный АРМ со множеством таблиц, а во втором — компактное окно подтверждения из одной кнопки), правильным архитектурным решением будет отказаться от универсальности одной формы.

Создайте две разные формы в конфигураторе:

  1. ФормаЭлементаПолная — со всеми списками, таблицами и графиками.
  2. ФормаЭлементаКомпактная — содержащая только шапку и минимальный набор управляющих кнопок.

При вызове открытия формы из списка или общего модуля программно определяйте условия и открывайте нужную форму:


&НаКлиенте
Процедура ОткрытьФормуОбъекта(СсылкаНаОбъект)

    ПараметрыОткрытия = Новый Структура("Ключ", СсылкаНаОбъект);
    
    // Проверяем условия для выбора интерфейса
    Если ТребуетсяКомпактныйВид(СсылкаНаОбъект) Тогда
        ОткрытьФорму("Справочник.Контрагенты.Форма.ФормаЭлементаКомпактная", ПараметрыОткрытия);
    Иначе
        ОткрытьФорму("Справочник.Контрагенты.Форма.ФормаЭлементаПолная", ПараметрыОткрытия);
    КонецЕсли;

КонецПроцедуры

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

← На главную