Как подключить внешнюю обработку в форму справочника или документа в виде отдельной страницы на обычных формах 1С?

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

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

Анализ задачи и выбор стратегии реализации

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

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

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

Шаг 1: Программное добавление новой страницы на форму

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


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

Здесь ОсновнаяПанель — это имя стандартного контейнера страниц на форме. Метод Добавить возвращает объект типа СтраницаПанели, который мы будем использовать как "родителя" для всех будущих элементов.

Шаг 2: Создание интерфейса на новой странице

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


Процедура ИнициализироватьВнешнююОбработкуНаФорме(СтраницаКонтейнер)
    // Определяем параметры расположения
    Отступ = 5;
    ШиринаПанели = ЭлементыФормы.ОсновнаяПанель.Ширина - (Отступ * 2);
    ВысотаПанели = ЭлементыФормы.ОсновнаяПанель.Высота - (Отступ * 10);

    // Добавляем табличное поле
    Таблица = ЭлементыФормы.Добавить(Тип("ТабличноеПоле"), "тпДанныеОбработки", Истина, СтраницаКонтейнер);
    Таблица.Верх = Отступ;
    Таблица.Лево = Отступ;
    Таблица.Ширина = ШиринаПанели;
    Таблица.Высота = ВысотаПанели;
    
    // Привязываем данные (например, к таблице значений во внешней обработке)
    Таблица.СоздатьКолонки();
КонецПроцедуры

Обратите внимание на последний параметр в методе ЭлементыФормы.Добавить. Мы передаем туда СтраницаКонтейнер, чтобы 1С понимала, что элемент должен отображаться именно на этой вкладке, а не поверх всей формы.

Шаг 3: Делегирование логики внешней обработке

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

В модуле внешней обработки:


Процедура ИнициализироватьИнтерфейс(ГлавнаяФорма, ИмяСтраницы) Экспорт
    // Получаем страницу по имени
    ЦелеваяСтраница = ГлавнаяФорма.ЭлементыФормы.ОсновнаяПанель.Страницы[ИмяСтраницы];
    
    // Создаем кнопку программно
    Кнопка = ГлавнаяФорма.ЭлементыФормы.Добавить(Тип("Кнопка"), "КнпВыполнитьДействие", Истина, ЦелеваяСтраница);
    Кнопка.Заголовок = "Запустить расчет";
    Кнопка.Верх = 20;
    Кнопка.Лево = 20;
    
    // Устанавливаем действие (самый сложный момент в обычных формах)
    // Действие должно ссылаться на процедуру в модуле ГЛАВНОЙ формы или общего модуля
    Кнопка.УстановитьДействие("Нажатие", "Подключаемый_ВыполнитьДействиеИзОбработки");
КонецПроцедуры

Важно помнить, что в обычных формах УстановитьДействие требует, чтобы процедура-обработчик физически находилась в модуле формы, где создан элемент, либо в общем модуле. Чтобы сохранить логику в обработке, в модуле формы документа мы создаем "прокси-процедуру":

В модуле формы документа:


Процедура Подключаемый_ВыполнитьДействиеИзОбработки(Кнопка) Экспорт
    // Здесь мы вызываем код из нашей внешней обработки
    ОбработкаОбъект = ВнешниеОбработки.Создать("C:\PathTo\MyProcess.epf");
    ОбработкаОбъект.ВыполнитьОсновнуюЛогику(ЭтаФорма);
КонецПроцедуры

Шаг 4: Динамическое копирование структуры формы

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

Разберем алгоритм клонирования по шагам:

  1. Создаем экземпляр внешней обработки и получаем её форму: ФормаШаблон = Обработка.ПолучитьФорму("Форма").
  2. В цикле обходим коллекцию ФормаШаблон.ЭлементыФормы.
  3. Для каждого элемента вызываем ЭлементыФормы.Добавить с теми же параметрами (Тип, Имя, Видимость).
  4. Копируем свойства: Верх, Лево, Ширина, Высота, Текст и т.д.

Проанализируем пример функции копирования:


Процедура СкопироватьЭлементы(Откуда, КудаСтраница)
    Для Каждого ЭлементИз Из Откуда.ЭлементыФормы Цикл
        // Пропускаем саму панель или системные кнопки, если нужно
        НовыйЭлемент = ЭлементыФормы.Добавить(ТипЗнч(ЭлементИз), ЭлементИз.Имя, Истина, КудаСтраница);
        
        // Заполняем основные свойства
        ЗаполнитьЗначенияСвойств(НовыйЭлемент, ЭлементИз, "Верх,Лево,Ширина,Высота,Заголовок,Подсказка");
        
        // Если это табличное поле, нужно настроить колонки
        Если ТипЗнч(ЭлементИз) = Тип("ТабличноеПоле") Тогда
            НовыйЭлемент.Данные = ЭлементИз.Данные;
            НовыйЭлемент.СоздатьКолонки();
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важный нюанс: При таком подходе необходимо внимательно следить за уникальностью имен элементов. Если на форме документа уже есть элемент с именем Кнопка1, и во внешней обработке он называется так же, возникнет ошибка конфликта имен. Рекомендуется добавлять префикс к именам создаваемых элементов (например, "ВнОбр_" + ЭлементИз.Имя).

Шаг 5: Организация взаимодействия и сохранение данных

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

Выясним, как это реализовать наиболее эффективно:


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

Ограничения и рекомендации

Рассмотрим основные трудности, с которыми мы можем столкнуться при реализации данного метода на платформе 1С 8.2:

1. Привязки элементов (Anchors): В обычных формах при изменении размера окна элементы должны "растягиваться". Программная настройка привязок (метод УстановитьПривязку) — это одна из самых сложных частей кода. Если форма документа имеет возможность изменения размера, вам придется детально описать, как каждый созданный элемент привязан к границам панели.
2. Контекст исполнения: Помните, что внешняя обработка живет в памяти, пока открыта форма. Если вы используете переменные модуля обработки для хранения промежуточных данных, не забудьте обеспечить их сохранность при переоткрытии формы.
3. Моральное устаревание: Данный метод является "костылем" для систем, которые невозможно перевести на управляемые формы. Если есть малейшая возможность использовать расширения конфигурации (платформа 8.3.6+), обязательно переходите на них, так как там добавление страниц реализуется штатно и без написания сотен строк кода по отрисовке интерфейса.

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

← На главную