Как программно запустить зарегистрированную внешнюю печатную форму (ВПФ) с типом команды «ВызовКлиентскогоМетода» без интерактивного участия пользователя?

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

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

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

Природа ВызоваКлиентскогоМетода и его ограничения

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

  1. Интерактивность: Основное назначение клиентских методов – это взаимодействие с пользователем. Если ВПФ имеет тип команды ВызовКлиентскогоМетода, это часто означает, что она может открывать промежуточную форму для ввода параметров, показывать диалоги, или выполнять другие действия, требующие пользовательского участия.
  2. Зависимость от формы: Клиентские методы "живут" в формах. Без открытой формы, напрямую вызвать клиентский метод из общего модуля, который выполняется на сервере, невозможно. Даже если ВПФ не открывает промежуточную форму для параметров, а просто выполняет какое-либо действие, ей всё равно нужен клиентский контекст, который обычно предоставляется формой.
  3. Отсутствие "командного интерфейса" для клиентских вызовов в БСП: Мы можем подтвердить, что в БСП не предусмотрено прямого "командного интерфейса" для автоматического, неинтерактивного запуска клиентских методов ВПФ. Механизмы БСП для работы с ВПФ, особенно в части пакетного выполнения, ориентированы на ВызовСерверногоМетода, поскольку только он может быть выполнен полностью в фоновом режиме без участия пользователя.

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

Рекомендуемый подход: Переход на ВызовСерверногоМетода

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

  1. Преимущества серверного вызова:
    • Пакетное выполнение: Серверные методы идеально подходят для пакетной обработки большого количества данных или документов.
    • Фоновые задания: Код серверных методов может быть выполнен в фоновых заданиях, что позволяет полностью автоматизировать процесс без необходимости запуска клиентского приложения или взаимодействия с пользователем. Пользователь может продолжать работу, пока на сервере выполняется длительная операция.
    • Независимость от клиента: Выполнение происходит на сервере, что снимает ограничения клиентского компьютера (производительность, сетевое соединение и т.д.).
  2. Как перестроить ВПФ под серверный вызов:

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

    1. Определите серверную экспортную функцию: Создайте в общем модуле вашей ВПФ (или в отдельном общем модуле, если это внешний отчет/обработка) экспортную функцию или процедуру, которая будет выполнять основную работу. Эта функция должна быть помечена директивой &НаСервере или находиться в серверном контексте.
    2. 
      // Пример серверной функции в модуле ВПФ
      // Допустим, это модуль объекта ВнешнейОбработки
                  
      &НаСервере
      Функция СформироватьДокументНаСервере(ПараметрыПечати)
          // Здесь будет вся логика формирования данных, обращения к базе
          // и, при необходимости, взаимодействие со сторонним ПО на сервере.
          // Например, формирование табличного документа, выгрузка данных в файл и т.д.
                      
          ТабличныйДокумент = Новый ТабличныйДокумент;
          // ... Ваш код по формированию ТабличногоДокумента ...
                      
          Возврат ТабличныйДокумент;
      КонецФункции
      
    3. Измените тип команды регистрации ВПФ: При регистрации ВПФ в БСП укажите тип команды ВызовСерверногоМетода и в качестве имени метода укажите вашу новую серверную функцию.
    4. 
      // В процедуре ПолучитьСведенияОВнешнейОбработке()
         // Вашей ВПФ
                  
         &НаКлиенте
         Процедура ПолучитьСведенияОВнешнейОбработке(Сведения)
             // ...
             Сведения.ТипКоманды = "ВызовСерверногоМетода";
             Сведения.ИмяМетода = "СформироватьДокументНаСервере"; // Имя вашей серверной функции
             // ...
         КонецПроцедуры
      
    5. Передача параметров: Если ваша ВПФ требует параметров (например, список документов, организации), передавайте их в серверную функцию. В случае программного вызова эти параметры формируются программно.
    6. Взаимодействие со сторонним ПО: Если ВызовКлиентскогоМетода использовался для взаимодействия со сторонним ПО на стороне клиента, то при переходе на серверный вызов необходимо либо найти аналогичное ПО на стороне сервера, либо изменить логику таким образом, чтобы сервер формировал необходимые данные, а клиентское ПО запускалось извне 1С с этими данными.
  3. Использование механизмов БСП для фоновых заданий:

    После перевода ВПФ на серверный вызов, вы сможете использовать стандартные средства БСП для пакетного и фонового выполнения. Например, подсистема "Длительные операции" или "Очередь заданий" позволяют планировать и контролировать выполнение таких задач.

    Мы используем функции из общего модуля ДополнительныеОтчетыИОбработки или ПодключаемыеКоманды для запуска серверных команд ВПФ. Например, для программного запуска вам потребуется получить объект внешней обработки и вызвать его метод, который ранее был зарегистрирован как серверный.

    
    // Пример кода для программного вызова серверной ВПФ
    // на клиенте или сервере (в зависимости от контекста, где запускается ваш код)
            
    &НаСервереБезКонтекста
    Функция ВыполнитьПечатьСервернойВПФ(СсылкаНаОбъект, ИдентификаторКоманды)
                
        // Находим зарегистрированную ВПФ по ее команде или имени
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ
            |    ДополнительныеОтчетыИОбработки.Ссылка КАК Ссылка
            |ИЗ
            |    Справочник.ДополнительныеОтчетыИОбработки КАК ДополнительныеОтчетыИОбработки
            |ГДЕ
            |    ДополнительныеОтчетыИОбработки.ИдентификаторКоманды = &ИдентификаторКоманды";
                
        Запрос.УстановитьПараметр("ИдентификаторКоманды", ИдентификаторКоманды);
                
        РезультатЗапроса = Запрос.Выполнить().Выбрать();
                
        Если РезультатЗапроса.Следующий() Тогда
            СсылкаНаВПФ = РезультатЗапроса.Ссылка;
                    
            // Получаем макет внешней обработки
            МакетОбработки = ДополнительныеОтчетыИОбработки.ПолучитьМакет(СсылкаНаВПФ);
            Если МакетОбработки = Неопределено Тогда
                Возврат Неопределено;
            КонецЕсли;
                    
            // Создаем временную внешнюю обработку
            ИмяФайла = УникальныйИдентификатор().Строка() + ".epf";
            ИмяВременногоФайла = КаталогВременныхФайлов() + ИмяФайла;
            МакетОбработки.Записать(ИмяВременногоФайла);
                    
            // Подключаем внешнюю обработку
            Попытка
                ВнешняяОбработкаОбъект = ВнешниеОтчетыИОбработки.Подключить(ИмяВременногоФайла);
                        
                // Формируем параметры для вызова серверного метода ВПФ
                // Это могут быть параметры, которые ожидает ваша функция СформироватьДокументНаСервере
                ПараметрыПечати = Новый Структура;
                ПараметрыПечати.Вставить("ОбъектыПечати", Новый Массив);
                ПараметрыПечати.ОбъектыПечати.Добавить(СсылкаНаОбъект); // Например, ссылка на документ
                // Добавьте другие необходимые параметры
                        
                // Вызываем серверный метод ВПФ
                // Имя метода должно соответствовать тому, что указано в Сведения.ИмяМетода
                Результат = ВнешняяОбработкаОбъект.СформироватьДокументНаСервере(ПараметрыПечати);
                        
                // При необходимости, отключаем внешнюю обработку
                ВнешниеОтчетыИОбработки.Отключить(ИмяВременногоФайла);
                        
                Возврат Результат;
            Исключение
                // Обработка ошибки
                Возврат Неопределено;
            КонецПопытки;
        КонецЕсли;
                
        Возврат Неопределено;
    КонецФункции
    

    Мы видим, что такой подход позволяет полностью автоматизировать запуск ВПФ, если её логика переведена на серверную сторону.

Обходной путь: Программное взаимодействие с формой ВПФ для ВызовКлиентскогоМетода

Однако, бывают ситуации, когда переход на ВызовСерверногоМетода невозможен или крайне затруднителен. Например, если ВызовКлиентскогоМетода используется для взаимодействия со сторонним программным обеспечением (ПО), которое работает исключительно на стороне клиента. В таком случае нам придётся имитировать действия пользователя, программно открывая форму ВПФ и вызывая её команды.

Давайте проанализируем, как мы можем это сделать:

  1. Программное получение формы ВПФ:

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

    
    &НаКлиенте
    Процедура ЗапуститьКлиентскуюВПФПрограммно()
                
        // 1. Получаем зарегистрированную ВПФ.
        //    Мы можем получить ее как элемент справочника ДополнительныеОтчетыИОбработки.
        //    Предположим, у нас есть ссылка на элемент справочника, например:
        //    СсылкаНаВПФ = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию("МояКлиентскаяВПФ");
        //    В реальной ситуации, мы могли бы получить ее из параметра или найти по ИдентификаторуКоманды.
                
        // Для примера, создадим "виртуальный" объект ВПФ.
        // В реальной жизни нужно загрузить ВПФ из базы или файла.
        // Мы покажем пример загрузки из файла, но обычно БСП загружает ВПФ во временное хранилище.
                
        ИмяФайлаВПФ = "C:\МоиОбработки\МояКлиентскаяВПФ.epf"; // Пример пути к файлу
                
        Если Не ФайлСуществует(ИмяФайлаВПФ) Тогда
            Сообщить("Файл ВПФ не найден: " + ИмяФайлаВПФ);
            Возврат;
        КонецЕсли;
                
        // Создаем временный объект внешней обработки
        ВнешняяОбработкаОбъект = Новый ВнешняяОбработка(ИмяФайлаВПФ);
                
        // Если ВПФ подключается через БСП, то она уже загружена во временное хранилище,
        // и нам нужно будет получить ее через механизм БСП, например, так:
        // ИдентификаторВПФ = "МояУникальнаяВПФДляСправочникаСотрудники";
        // ВнешняяОбработкаОбъект = ДополнительныеОтчетыИОбработки.ПолучитьОбъектОбработки(ИдентификаторВПФ);
        // Если ВнешняяОбработкаОбъект = Неопределено Тогда ... Возврат; КонецЕсли;
                
        // 2. Получаем форму ВПФ.
        //    Имя формы по умолчанию может быть "Форма", "ОсновнаяФорма" или другим,
        //    указанным в свойствах обработки.
        ИмяФормы = "Форма"; 
                
        Попытка
            // Здесь мы можем передать владельца формы, если ВПФ ожидает его
            // Например, ссылку на Справочник.Сотрудники, если ВПФ работает с ним
            ВладелецФормы = Справочники.Сотрудники.НайтиПоКоду("000000001"); // Пример владельца
            Если ВладелецФормы = Неопределено Тогда
                Сообщить("Владелец формы не найден!");
                Возврат;
            КонецЕсли;
                    
            ФормаВПФ = ВнешняяОбработкаОбъект.ПолучитьФорму(ИмяФормы, ВладелецФормы);
                    
            Если ФормаВПФ = Неопределено Тогда
                Сообщить("Не удалось получить форму ВПФ: " + ИмяФормы);
                Возврат;
            КонецЕсли;
                    
            // 3. Вызываем команды или методы формы.
            //    Нам нужно знать имя команды, которая соответствует клиентскому вызову.
            //    Обычно это команда печати или другая команда, которая выполняет логику ВПФ.
            ИмяКоманды = "КомандаПечати"; // Пример имени команды на форме ВПФ
                    
            // Перед вызовом команды, возможно, потребуется установить параметры формы.
            // Например, если на форме есть реквизиты, которые используются командой.
            Если ФормаВПФ.ЕстьРеквизит("Параметр1") Тогда
                ФормаВПФ.Параметр1 = "НекоеЗначение";
            КонецЕсли;
                    
            // Вызываем команду. Команда должна быть доступна в коллекции КомандыФормы.
            Если ФормаВПФ.Команды.Найти(ИмяКоманды) <> Неопределено Тогда
                ФормаВПФ.Команды[ИмяКоманды].Выполнить();
                Сообщить("Команда '" + ИмяКоманды + "' успешно выполнена.");
            Иначе
                Сообщить("Команда '" + ИмяКоманды + "' не найдена на форме ВПФ.");
            КонецЕсли;
                    
            // 4. Закрываем форму, если она была открыта (в большинстве случаев она не открывается видимо, 
            //    но создается в памяти)
            ФормаВПФ.Закрыть();
                    
        Исключение
            Сообщить("Ошибка при запуске клиентской ВПФ: " + ОписаниеОшибки());
        КонецПопытки;
                
    КонецПроцедуры
    

    Мы видим, что метод ПолучитьФорму() возвращает объект формы, с которым мы можем взаимодействовать. Мы можем устанавливать значения реквизитов формы, вызывать её процедуры и функции, а также выполнять команды.

  2. Вызов команд формы:

    После получения формы, мы можем обратиться к её коллекции Команды и выполнить нужную команду. Важно знать точное имя команды, которая запускает логику ВПФ. Это имя обычно совпадает с именем, указанным при регистрации ВПФ в качестве ИмяКоманды.

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

  3. Передача параметров:

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

  4. Ограничения подхода:

    Несмотря на то, что этот метод позволяет программно запустить клиентскую ВПФ, он имеет ряд существенных ограничений:

    • Требуется клиентский сеанс: Данный подход всё равно требует активного клиентского приложения 1С. Это означает, что для пакетного выполнения нам потребуется запускать клиент 1С (возможно, через командную строку) и выполнять этот код. Это не является "фоновым" выполнением в чистом виде.
    • Видимость интерфейса: Хотя форма может быть не показана пользователю явно (Форма.Открыть() не вызывается), она всё равно создается в памяти клиентского приложения, потребляя ресурсы.
    • Зависимость от структуры формы: Если ВПФ открывает сложную промежуточную форму для ввода параметров с интерактивными элементами (например, выбора нескольких позиций из списка), имитация всех пользовательских действий программно может быть очень сложной и хрупкой (любые изменения в форме ВПФ могут сломать наш код).
    • Взаимодействие со сторонним ПО: Если ВПФ взаимодействует со сторонним ПО, это ПО также должно быть доступно и настроено на стороне клиента, где запускается 1С.

Заключение

Мы разобрались, что прямого "командного интерфейса" в БСП для неинтерактивного программного запуска ВПФ с типом команды ВызовКлиентскогоМетода не существует, поскольку клиентские вызовы по своей природе ориентированы на пользовательский интерфейс и клиентский контекст. Мы рассмотрели два основных пути решения:

  1. Рекомендуемый путь: Переработка ВПФ под ВызовСерверногоМетода. Этот подход наиболее верен с архитектурной точки зрения, позволяет достичь полной автоматизации и пакетного выполнения через фоновые задания, освобождая нас от необходимости интерактивного взаимодействия.
  2. Обходной путь: Программное получение формы и вызов её команд. Этот метод может быть применен, когда клиентский контекст абсолютно необходим (например, для взаимодействия с клиентским сторонним ПО). Однако, он имеет ряд ограничений, связанных с необходимостью клиентского сеанса и сложностью имитации пользовательских действий.

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

← На главную