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

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

При работе с устаревшими или типовыми конфигурациями 1С на обычных формах (такими как Управление торговлей 10.3, Управление производственным предприятием 1.3 или Комплексная автоматизация 1.1) программисты часто сталкиваются с жестким ограничением: необходимо добавить новую команду или кнопку на форму списка документов, но при этом конфигурацию крайне желательно оставить на полной поддержке («на замке»).

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

Способ 1. Использование механизма внешних печатных форм (ВПФ)

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

Рассмотрим по шагам, как реализовать этот алгоритм:

  1. Создадим новую внешнюю обработку в конфигураторе.
  2. В модуле объекта обработки пропишем экспортную функцию Печать, которая является стандартной точкой входа для механизма ВПФ. Вместо формирования табличного документа мы инициализируем открытие основной формы нашей обработки.
  3. Зарегистрируем обработку в информационной базе через меню: Сервис -> Дополнительные отчеты и обработки -> Внешние печатные формы.Привяжем её к необходимому типу документа (например, РеализацияТоваровУслуг).

Посмотрим на пример кода, который необходимо разместить в модуле объекта внешней печатной формы:


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

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

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

Важная деталь (запуск в один клик): Чтобы пользователю не приходилось каждый раз открывать подменю печати, он может один раз нажать на кнопку с изображением принтера (или выбрать команду по умолчанию), сопоставить её с нашей ВПФ и нажать кнопку «По умолчанию». После этого вызов внешней обработки будет происходить по нажатию одной кнопки прямо из формы списка.

Способ 2. Использование расширений конфигурации (для платформы 8.3)

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

Проанализируем этот метод пошагово:

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

Пример кода обработчика нажатия кнопки в расширении формы списка:


&НаКлиенте
Процедура Расш1_КомандаВызоваОбработкиНажатие(Элемент)
    
    // Получаем текущую строку списка (выбранный документ)
    ТекущаяСтрока = ЭлементыФормы.ДокументСписок.ТекущаяСтрока;
    
    Если ТекущаяСтрока = Неопределено Тогда
        ПоказатьПредупреждение(, "Пожалуйста, выберите документ из списка!");
        Возврат;
    КонецЕсли;
    
    // Путь к внешней обработке на диске (или получение из двоичных данных)
    ПутьКФайлу = "C:\ExternalProcessings\MyProcessing.epf";
    
    Попытка
        ОбработкаОбъект = ВнешниеОбработки.Создать(ПутьКФайлу);
        ФормаОбработки = ОбработкаОбъект.ПолучитьФорму("Форма");
        ФормаОбработки.ДокументСсылка = ТекущаяСтрока;
        ФормаОбработки.Открыть();
    Исключение
        ЗаписьЖурналаРегистрации("ВызовОбработки", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        ПоказатьПредупреждение(, "Не удалось запустить внешнюю обработку!");
    КонецПопытки;
    
КонецПроцедуры

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

Способ 3. Программное внедрение кнопки через обработчик ожидания (Фоновый мониторинг окон)

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

Суть метода заключается в том, что при запуске системы в фоновом режиме запускается глобальный обработчик ожидания. Он с периодичностью в 1–2 секунды проверяет структуру открытых окон приложения. Как только обнаруживается форма списка целевого документа, алгоритм динамически добавляет на нее кнопку.

Рассмотрим структуру реализации этого механизма:

  1. Создается внешняя обработка, которая прописывается в автозапуск пользователя (или инициализируется через небольшую дописку в глобальном модуле ПриНачалеРаботыСистемы, если минимальные изменения кода все же допускаются).
  2. При запуске вызывается метод ПодключитьОбработчикОжидания("МониторингОкон", 2).
  3. В процедуре мониторинга происходит перебор открытых окон через свойство АктивноеОкно().

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


Процедура МониторингОкон() Экспорт
    
    АктивноеОкно = АктивноеОкно();
    Если АктивноеОкно = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Форма = АктивноеОкно.Содержимое;
    
    // Проверяем, что это форма списка нужного нам документа
    Если ТипЗнч(Форма) = Тип("Форма") И Найти(Форма.ИмяНастройкиПрограммы, "РеализацияТоваровУслуг") > 0 Тогда
        
        // Проверяем, не была ли кнопка уже добавлена ранее, чтобы избежать дублирования
        Если Форма.ЭлементыФормы.Найти("КнопкаВнешнейОбработки") = Неопределено Тогда
            
            // Определяем координаты для новой кнопки на форме
            НоваяКнопка = Форма.ЭлементыФормы.Добавить(Тип("Кнопка"), "КнопкаВнешнейОбработки", Истина, Форма.ПанельИнструментов);
            НоваяКнопка.Заголовок = "Запуск обработки";
            НоваяКнопка.Ширина = 120;
            НоваяКнопка.Высота = 25;
            
            // Важно: в обычных формах метод УстановитьДействие требует, чтобы обработчик клика 
            // находился строго в модуле самой формы. Чтобы обойти это, мы можем использовать 
            // перехват через подключение обработчика изменения связанных данных или использовать 
            // ПолеHTMLДокумента вместо кнопки для реализации полноценных JS-событий.
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

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

Способ 4. Горячие клавиши и «Быстрый запуск»

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

Для этого внешняя обработка регистрируется в справочнике «Дополнительные внешние обработки». В настройках этой обработки для конкретных пользователей настраивается так называемый Быстрый запуск и назначается сочетание клавиш (например, Ctrl + Shift + F12).

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

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


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

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

← На главную