Разработка интерфейсов в системе 1С:Предприятие 7.7 стандартными средствами часто накладывает жесткие ограничения. Одно из таких ограничений — невозможность штатно создать удобные многостраничные закладки (вкладки/страницы) в произвольном месте формы, как это реализовано в более современных версиях платформы 1С v8. Для решения этой задачи разработчики часто прибегают к использованию внешних компонентов ActiveX через мощную библиотеку 1С++.
В этой статье мы подробно разберем, как внедрить ActiveX-элемент закладок на форму 1С 7.7, почему может не работать обработка событий смены страниц и как правильно организовать размещение и видимость реквизитов (например, нескольких Таблиц Значений) на созданных вкладках.
Штатный механизм закладок в 1С 7.7 привязан к самому верху или низу всей формы и не позволяет создавать локальные группы страниц в середине или в отдельных областях экрана. Использование ActiveX-компонента (например, Forms.MultiPage.1 или MSComctlLib.TabStrip) дает программисту полную свободу: мы можем разместить контейнер закладок любого размера в любой части диалога и динамически управлять отображением данных внутри него.
Однако при реализации этой схемы разработчики часто сталкиваются с двумя проблемами:
Change) не перехватывается модулем формы 1С.Давайте пошагово разберем, как решить эти проблемы и добиться стабильной работы интерфейса.
Для начала создадим сам элемент управления на форме. Обычно в качестве подложки (контейнера) на форму добавляется текстовый реквизит (например, с идентификатором ФормаЗакладки). Затем в процедуре ПриОткрытии() мы инициализируем объект ActiveX с помощью возможностей библиотеки 1С++.
Рассмотрим пример инициализации класса управления закладками:
// Создаем объект для управления атрибутом формы
АтрФормы = СоздатьОбъект("АтрибутФормы");
АтрФормы.УстановитьАтрибут(Форма, "ФормаЗакладки");
// Создаем сам объект ActiveX
Закладки = СоздатьОбъект("АктивИкс");
АтрФормы.СоздатьЭлементУправления(Закладки);
// Инициализируем конкретный класс элемента управления
Закладки.СоздатьЭУ("Forms.MultiPage.1");
После этого на форме появится полноценный контейнер страниц. Теперь нам необходимо научить систему реагировать на действия пользователя при переключении страниц.
Согласно документации 1С++, события от элементов ActiveX должны транслироваться в процедуры модуля формы, имеющие шаблон имени: [ИдентификаторЭлемента]_[ИмяСобытия]. Для нашего элемента процедура должна называться ФормаЗакладки_Change().
Если вы написали эту процедуру, но управление в нее при кликах по вкладкам не передается, проанализируем основные причины:
1С++ может быть активна опция строгой проверки типов. Если в файле описания классов defcls.txt для метода инициализации закладок первый параметр объявлен как жесткий тип (например, Строка), а передается реальный объект контекста формы (Контекст), то инициализация завершится с ошибкой в рантайме. При этом сам элемент ActiveX на форме может отображаться, но связь по событиям будет полностью разорвана.
defcls.txt для используемого класса.
Когда событие начинает успешно перехватываться, нам необходимо определить, на какую именно страницу перешел пользователь. Для этого мы запрашиваем у объекта ActiveX текущую активную страницу с помощью метода ТекущаяСтраница(). Этот метод возвращает COM-объект страницы, у которого мы можем прочитать свойство Name (или индекс).
Посмотрим на пример реализации обработчика:
Процедура ФормаЗакладки_Change()
// Получаем COM-объект выбранной страницы
ТекущаяСтраница = Закладки.ТекущаяСтраница();
Если ПустоеЗначение(ТекущаяСтраница) = 0 Тогда
ИмяСтраницы = ТекущаяСтраница.Name;
// Перенаправляем алгоритм в зависимости от выбранной вкладки
Если ИмяСтраницы = "Page1" Тогда
АктивизироватьВкладку(1);
ИначеЕсли ИмяСтраницы = "Page2" Тогда
АктивизироватьВкладку(2);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Теперь выясним, как отображать разные наборы реквизитов (например, две разные Таблицы Значений) на соответствующих вкладках. Размещать две ТЗ физически в одних и тех же координатах формы "друг под другом" крайне не рекомендуется: это приводит к визуальным багам, когда элементы просвечивают друг через друга или не реагируют на клики мыши. Рассмотрим два правильных архитектурных подхода.
В платформе 1С 7.7 существует штатный встроенный механизм работы со слоями формы. Мы можем сгруппировать реквизиты, относящиеся к разным вкладкам, по слоям:
СлойВкладки1.СлойВкладки2.В момент переключения закладок мы просто управляем видимостью этих слоев с помощью метода ИспользоватьСлой():
Процедура АктивизироватьВкладку(НомерВкладки)
Если НомерВкладки = 1 Тогда
// Показываем элементы первого слоя, скрываем второй
Форма.ИспользоватьСлой("СлойВкладки1", 1);
Форма.ИспользоватьСлой("СлойВкладки2", 0);
ИначеЕсли НомерВкладки = 2 Тогда
// Показываем элементы второго слоя, скрываем первый
Форма.ИспользоватьСлой("СлойВкладки1", 0);
Форма.ИспользоватьСлой("СлойВкладки2", 1);
КонецЕсли;
КонецПроцедуры
Если на ваших вкладках должны располагаться таблицы, лучшим решением с точки зрения быстродействия и стабильности интерфейса будет размещение на форме **всего одной физической Таблицы Значений**.
Вместо того чтобы скрывать и показывать разные таблицы, мы будем динамически перестраивать одну и ту же ТЗ при переключении страниц. Посмотрим, как это выглядит на практике:
Процедура АктивизироватьВкладку(НомерВкладки)
// Очищаем текущую структуру ТЗ на форме
ТаблицаФормы.Очистить();
// Удаляем старые колонки (если они меняются динамически)
КоличествоКолонок = ТаблицаФормы.КоличествоКолонок();
Для Ном = -КоличествоКолонок По -1 Цикл
ТаблицаФормы.УдалитьКолонку(Абс(Ном));
КонецЦикла;
Если НомерВкладки = 1 Тогда
// Настраиваем колонки для первой вкладки
ТаблицаФормы.НоваяКолонка("Товар", "Справочник.Номенклатура", , , "Наименование товара");
ТаблицаФормы.НоваяКолонка("Количество", "Число", 10, 2, "Кол-во");
// Заполняем ТЗ данными для первой вкладки из нашего кэша или запроса
ДанныеВкладки1.Выгрузить(ТаблицаФормы);
ИначеЕсли НомерВкладки = 2 Тогда
// Настраиваем колонки для второй вкладки
ТаблицаФормы.НоваяКолонка("Контрагент", "Справочник.Контрагенты", , , "Клиент");
ТаблицаФормы.НоваяКолонка("Сумма", "Число", 15, 2, "Сумма взаиморасчетов");
// Заполняем данными для второй вкладки
ДанныеВкладки2.Выгрузить(TablicaFormy);
КонецЕсли;
КонецПроцедуры
Этот подход гарантирует полное отсутствие графических артефактов, снижает потребление ресурсов оперативной памяти и позволяет легко масштабировать количество вкладок без изменения дизайна формы в конфигураторе.
Разработчикам, поддерживающим системы на базе 1С 7.7, необходимо учитывать специфику технологии ActiveX в современных реалиях операционных систем Windows:
Forms.MultiPage.1 физически находится в библиотеке FM20.DLL. Эта библиотека не является частью операционной системы Windows — она устанавливается исключительно вместе с пакетом Microsoft Office (Excel, Word). Если ваша база 1С будет запущена на сервере или рабочей станции, где MS Office отсутствует (например, установлен только LibreOffice или базы работают в чистой терминальной среде), этот ActiveX просто не создастся, и форма выдаст ошибку.
MSComctlLib.TabStrip.2 (или просто TabStrip). Он входит в общие библиотеки элементов управления ОС Windows (библиотека MSCOMCTL.OCX) и присутствует практически на любой машине по умолчанию, не требуя установленного офисного пакета.
Используя приведенные инструкции, вы сможете создавать современные, красивые и удобные многостраничные интерфейсы даже в рамках устаревшей платформы 1С 7.7, обеспечивая комфортную работу пользователей без необходимости экстренного перехода на новые версии платформы.