Как настроить привязки и масштабирование элементов формы в 1С 7.7 при изменении ее размера?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Рассмотрим все доступные варианты решения этой задачи по шагам.

1. Как устроен штатный алгоритм масштабирования в 1С 7.7

Для начала проанализируем базовое поведение платформы. В отличие от современных версий (1С 8.x), в «семерке» нет полноценной объектной модели привязок (якорей или «anchors»). Вместо этого разработчикам доступен лишь один флаг в свойствах формы — «Изменяемый размер». Если этот флаг снят, окно формы жестко фиксируется в своих исходных размерах, и проблема масштабирования отпадает сама собой. Но если пользователям необходимо растягивать форму (например, чтобы видеть больше строк в табличной части), включается штатный геометрический алгоритм платформы.

Давайте выясним основные правила, по которым работает этот встроенный алгоритм:

  1. Правило «главного» объекта (первой таблицы): Платформа 1С 7.7 ищет на форме первый в порядке обхода элемент типа ТабличнаяЧасть (для документов) или ТаблицаЗначений (для отчетов и обработок). Именно эта таблица объявляется главным масштабируемым объектом формы. При растягивании окна по ширине или высоте меняются геометрические размеры только этого элемента.
  2. Разделение элементов на группы «До» и «После»: Все остальные элементы управления (кнопки, надписи, поля ввода) привязываются не к краям самой формы, а к границам этой главной таблицы. Платформа определяет их поведение на основе геометрических координат относительно ТЗ или ТЧ:
    • Элементы, которые расположены выше или левее левой/верхней границы масштабируемой таблицы, жестко закрепляются относительно левого и верхнего краев формы. Они остаются неподвижными.
    • Элементы, которые расположены ниже или правее правой/нижней границы таблицы, привязываются к ее правому и нижнему краю соответственно. При растягивании таблицы эти элементы начинают сдвигаться (уходить вправо и вниз).

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

2. Почему кнопки на одном слое ведут себя по-разному?

Вернемся к вопросу автора темы: почему кнопки, добавленные на один слой в разное время, ведут себя по-разному? Разберем эту ситуацию подробнее.

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

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

Чтобы исправить это стандартными средствами, выполните следующие действия в конфигураторе:

  1. Внимательно проверьте координаты всех кнопок. Сделать это можно через палитру свойств элемента. Убедитесь, что кнопки, которые должны вести себя одинаково, имеют абсолютно идентичную координату по вертикали (свойство Верх) или горизонтали (свойство Лево).
  2. Проверьте порядок обхода элементов на форме. Для этого в меню конфигуратора выберите «Диалог» — «Порядок обхода». Убедитесь, что нужная вам таблица значений (или табличная часть документа) стоит самой первой в списке.
  3. Попробуйте физически переместить проблемные кнопки ближе к правому или нижнему краю формы. Иногда сдвиг элемента всего на несколько пикселей вплотную к границе заставляет платформу корректно определить его привязку.

3. Хитрости («костыли») масштабирования без внешних библиотек

Если проектные ограничения не позволяют вам использовать внешние компоненты, разработчики часто прибегают к проверенным временем хитростям:

4. Профессиональное решение проблемы с помощью FormEx и 1С++

Для создания действительно качественного, отзывчивого и современного интерфейса в 1С 7.7 штатного функционала катастрофически не хватает. Опытные разработчики используют связку внешних компонент — FormEx.dll и 1cpp.dll.

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

Давайте разберем по шагам, как настроить профессиональное масштабирование.

Использование предопределенного события «ПослеОткрытия»

В стандартной платформе 1С 7.7 в процедуре ПриОткрытии() окно формы еще физически не создано в операционной системе, оно не имеет дескриптора окна (HWND). Из-за этого любые попытки изменить размеры элементов формы программно на данном этапе не увенчаются успехом.

Внешняя компонента FormEx решает эту проблему, добавляя в модуль формы предопределенную процедуру ПослеОткрытия(). В этой процедуре форма уже полностью отрисована, и мы можем безопасно управлять координатами любых элементов.

Для изменения координат конкретного элемента используется метод УстановитьКоординаты() объекта класса АтрибутФормы. Посмотрим на пример кода:


Процедура ПослеОткрытия()
    // Создаем объект для управления атрибутом формы из библиотеки FormEx
    АтрибутКнопки = СоздатьОбъект("АтрибутФормы");
    АтрибутКнопки.УстановитьАтрибут(Форма, "кнОК");
    
    // Получаем текущие координаты и принудительно задаем новые
    // Параметры: Лево, Верх, Ширина, Высота
    АтрибутКнопки.УстановитьКоординаты(100, 150, 80, 25);
КонецПроцедуры

Использование класса привязок «Общие.Форма.Привязка» (1С++)

Чтобы не прописывать вручную сложные математические формулы расчета координат для каждого элемента при каждом изменении размеров окна (событие `ПриИзмененииРазмераОкна`), в библиотеке классов 1С++ существует готовый класс привязок. Он позволяет декларативно привязать стороны любого элемента управления к сторонам формы или к другим элементам.

Сначала класс необходимо зарегистрировать в конфигурационном файле описания классов (обычно это файл defcls.prm в каталоге базы данных):

класс Общие.Форма.Привязка = Классы\Форма\Привязки\Общие.Форма.Привязка.ert{};

После регистрации класса мы можем легко инициализировать его прямо в модуле нашей формы. Давайте разберем практический пример привязки кнопки «ОК» к правому нижнему углу формы, а таблицы значений — по всей ширине и высоте окна.

В модуле формы пишем следующий код:


Переменная гРФорма; // Переменная для хранения объекта класса привязок

Процедура ПриОткрытии()
    // Инициализируем класс привязок из библиотеки 1С++
    гРФорма = СоздатьОбъект("Общие.Форма.Привязка");
    гРФорма.УстановитьФорму(Форма);
    
    // Настраиваем правила привязки для элементов формы.
    // Параметры метода Привязка():
    // 1. Идентификатор элемента формы.
    // 2. К какому краю привязываем элемент (L - Лево, R - Право, T - Верх, B - Низ).
    // 3. К какому объекту привязываем (обычно "Форма").
    
    // Привязываем таблицу значений "ТЗ_Данные" так, чтобы она растягивалась 
    // во все стороны вместе с изменением размеров формы
    гРФорма.Привязка("ТЗ_Данные", "R", "Форма", "R", "Форма");
    гРФорма.Привязка("ТЗ_Данные", "B", "Форма", "B", "Форма");
    
    // Привязываем кнопку "кнОК" к правому нижнему углу формы. 
    // Она не будет растягиваться, но будет смещаться вправо и вниз вслед за краем формы.
    гРФорма.Привязка("кнОК", "L", "Форма", "R", "Форма");
    гРФорма.Привязка("кнОК", "R", "Форма", "R", "Форма");
    гРФорма.Привязка("кнОК", "T", "Форма", "B", "Форма");
    гРФорма.Привязка("кнОК", "B", "Форма", "B", "Форма");
    
    // Привязываем кнопку закрытия "кнЗакрыть" рядом с кнопкой ОК
    гРФорма.Привязка("кнЗакрыть", "L", "Форма", "R", "Форма");
    гРФорма.Привязка("кнЗакрыть", "R", "Форма", "R", "Форма");
    гРФорма.Привязка("кнЗакрыть", "T", "Форма", "B", "Форма");
    гРФорма.Привязка("кнЗакрыть", "B", "Форма", "B", "Форма");
КонецПроцедуры

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

← На главную