Прогресс бар 8.2 (УТ 11 без изменения конфигурации, для SQL)

Данный приём позволяет показать текущее состояние выполнения серверного кода пользователю (без внесения изменений в конфигурацию). Идея взята от сюда http://infostart.ru/public/157706/

1. Код модуля формы внешней обработки

//Устанавливаем количество обновлений индикатора на сервере.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
   
Обновлений = 10;
КонецПроцедуры


//Обнуляем прогресс бар, запускаем фоновую процедуру на сервере, подключаем обработчик ожидания
&НаКлиенте
Процедура НачатьИндикацию(Команда)

    Прогресс = 0;

    ВыполнитьНаСервере(УникальныйИдентификатор, Обновлений);

    ПодключитьОбработчикОжидания(«ОбработчикОжидания», 1, Ложь);

КонецПроцедуры


//Получаем сообщения от фонового задания и прогресс операции. Если операция закончилась отключаем обработчик ожидания.
&НаКлиенте
Процедура ОбработчикОжидания()

    ПолучитьПрогрессВыполнения(УникальныйИдентификатор, Прогресс);

    Состояние(НСтр(«ru = ‘Тест прогресс бара'»), Прогресс, НСтр(«ru = ‘Пустой цикл для тестирования'»));

    Если Прогресс = 100 Тогда
       
ОтключитьОбработчикОжидания(«ОбработчикОжидания»);
    КонецЕсли;

КонецПроцедуры

//Устанавливаем привилегированный режим, если у пользователя нет административных прав. Запускаем фоновое задания из внешней обработки с помощью метода который доступен в УТ 11.
&НаСервереБезКонтекста
Процедура ВыполнитьНаСервере(УникальныйИдентификатор, Обновлений)

    УстановитьПривилегированныйРежим(Истина);

    ЗаданиеПараметры = Новый Массив();
   
ЗаданиеПараметры.Добавить(Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(«Прогрес-бар [0.0.1]»));
   
ЗаданиеПараметры.Добавить(Новый Структура(«Обновлений», Обновлений));
   
ЗаданиеПараметры.Добавить(Неопределено);
   
ЗаданиеПараметры.Добавить(Неопределено);

    ФоновоеЗадание = ФоновыеЗадания.Выполнить(«ДополнительныеОтчетыИОбработки.ВыполнитьОбработкуНепосредственно», ЗаданиеПараметры, УникальныйИдентификатор, «ИндикацияПроцеса»);

КонецПроцедуры

 

&НаСервереБезКонтекста
Процедура ПолучитьПрогрессВыполнения(УникальныйИдентификатор, Прогресс)

    НайденныеЗадания = ФоновыеЗадания.ПолучитьФоновыеЗадания(Новый Структура(«Ключ», УникальныйИдентификатор));
    Если
НайденныеЗадания.Количество() = 0 Тогда Возврат; КонецЕсли;

    Задание = НайденныеЗадания[0];
    Если
Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
       
МассивСообщений = Задание.ПолучитьСообщенияПользователю(Истина);
        Если
МассивСообщений = Неопределено Тогда Возврат; КонецЕсли;
        Для Каждого
Сообщение Из МассивСообщений Цикл
            Если
Строка(Сообщение.ИдентификаторНазначения) = «00000000-0000-0000-0000-000000000000» Тогда
               
Прогресс = Число(Сообщение.Текст);
            Иначе
               
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Сообщение.Текст, Сообщение.КлючДанных, Сообщение.Поле, Сообщение.ПутьКДанным);
            КонецЕсли;
        КонецЦикла;;
    Иначе
       
Прогресс = 100;
    КонецЕсли;

КонецПроцедуры



2. Код модуля объекта внешней обработки

Функция СведенияОВнешнейОбработке() Экспорт
   
Версия = «0.0.1»;

    // Объявим переменную, в которой мы сохраним и вернем «наружу» необходимые данные
   
ПараметрыРегистрации = Новый Структура;

    // Объявим еще одну переменную, которая нам потребуется ниже
   
МассивНазначений = Новый Массив;

    // Первый параметр, который мы должны указать — это какой вид обработки системе должна зарегистрировать.
    // Допустимые типы: ДополнительнаяОбработка, ДополнительныйОтчет, ЗаполнениеОбъекта, Отчет, ПечатнаяФорма, СозданиеСвязанныхОбъектов
   
ПараметрыРегистрации.Вставить(«Вид», «ДополнительнаяОбработка»);

    // Теперь нам необходимо передать в виде массива имен, к чему будет подключена наша ВПФ
    // Имейте ввиду, что можно задать имя в таком виде: Документ.* — в этом случае обработка будет подключена ко всем документам в системе,
    // которые поддерживают механизм ВПФ
    //СчитатьДокументыНазначений(МассивНазначений);
   
ПараметрыРегистрации.Вставить(«Назначение», Новый Массив);

    // Теперь зададим имя, под которым ВПФ будет зарегистрирована в справочнике внешних обработок
   
ПараметрыРегистрации.Вставить(«Наименование», «Прогрес-бар [» + Версия + «]»);

    // Зададим право обработке на использование безопасного режима. Более подробно можно узнать в справке к платформе (метод УстановитьБезопасныйРежим)
   
ПараметрыРегистрации.Вставить(«БезопасныйРежим», Ложь);

    // Следующие два параметра играют больше информационную роль, т.е. это то, что будет видеть пользователь в информации к обработке
   
ПараметрыРегистрации.Вставить(«Версия», Версия);
   
ПараметрыРегистрации.Вставить(«Информация», «Прогрес-бар [» + Версия + «]»);

    // Создадим таблицу команд (подробнее смотрим ниже)
   
ТаблицаКоманд = ПолучитьТаблицуКоманд();

    // Добавим команду в таблицу
   
ДобавитьКоманду(ТаблицаКоманд, «Прогрес-бар [» + Версия + «]», «BP», «ОткрытиеФормы», Ложь, «BP»);

    // Сохраним таблицу команд в параметры регистрации обработки
   
ПараметрыРегистрации.Вставить(«Команды», ТаблицаКоманд);

    // Теперь вернем системе наши параметры
   
Возврат ПараметрыРегистрации;

КонецФункции

Функция ПолучитьТаблицуКоманд()

   // Создадим пустую таблицу команд и колонки в ней
  
Команды = Новый ТаблицаЗначений;

   // Как будет выглядеть описание печатной формы для пользователя
  
Команды.Колонки.Добавить(«Представление», Новый ОписаниеТипов(«Строка»));

   // Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
  
Команды.Колонки.Добавить(«Идентификатор», Новый ОписаниеТипов(«Строка»));

   // Тут задается, как должна вызваться команда обработки
   // Возможные варианты:
   // — ОткрытиеФормы — в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
   // — ВызовКлиентскогоМетода — вызвать клиентскую экспортную процедуру из модуля формы обработки
   // — ВызовСерверногоМетода — вызвать серверную экспортную процедуру из модуля объекта обработки
  
Команды.Колонки.Добавить(«Использование», Новый ОписаниеТипов(«Строка»));

   // Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
  
Команды.Колонки.Добавить(«ПоказыватьОповещение», Новый ОписаниеТипов(«Булево»));

   // Для печатной формы должен содержать строку ПечатьMXL
  
Команды.Колонки.Добавить(«Модификатор», Новый ОписаниеТипов(«Строка»));

   Возврат Команды;

КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = «»)

  // Добавляем команду в таблицу команд по переданному описанию.
  // Параметры и их значения можно посмотреть в функции ПолучитьТаблицуКоманд
 
НоваяКоманда = ТаблицаКоманд.Добавить();
 
НоваяКоманда.Представление = Представление;
 
НоваяКоманда.Идентификатор = Идентификатор;
 
НоваяКоманда.Использование = Использование;
 
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
 
НоваяКоманда.Модификатор = Модификатор;

КонецПроцедуры

// Пощитаем коэффициенты и сделаем соответствие чтобы знать когда обновлять прогресс. 
Процедура ВыполнитьКоманду(Параметры) Экспорт

    Обновлений  = Параметры.Обновлений;
   
Итераций = 10000000;
   
Коэф     = Цел(Итераций / Обновлений);
   
КоэфОбн  = 100 / Обновлений;

    ТочкиОбновления = Новый Соответствие;
    Для
i = 1 По Обновлений Цикл ТочкиОбновления[i * Коэф] = Цел(i * КоэфОбн); КонецЦикла;

    Сообщение = Новый СообщениеПользователю;
   
Сообщение.ИдентификаторНазначения = Новый УникальныйИдентификатор;
   
Сообщение.Текст = «Фоновая обработка данных успешно началась.»;
   
Сообщение.Сообщить();

    Для i = 1 По Итераций Цикл
        Если
ТочкиОбновления[i] <> Неопределено Тогда ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Строка(ТочкиОбновления[i])); КонецЕсли;

        // Основной код.

    КонецЦикла;

КонецПроцедуры




Плюсы:

    • Не нужно изменять основную конфигурацию;
    • все очень просто в реализации и использовании;
    • пользователь видит прогресс и одновременно делает что-то еще.

15 Comments

  1. Stamper

    не понял, почему для SQL.

    Reply
  2. pbazeliuk

    (1) Stamper, в файловой версии менеджер заданий не активен. И задания выполняются по очереди, а не асинхронно. Комментарий актуален к УТ 11, может в других конфигурациях есть выход.

    Reply
  3. Stamper

    (2)

    И задания выполняются по очереди, а не асинхронно.

    пожалуйста, немного поподробнее расскажи! или может быть, есть ссылочка?

    Reply
  4. pbazeliuk

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

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

    http://www.bit.ly/TO6csq

    Reply
  5. ksuman

    (4) можно было не объяснять почему это не работает в файловом варианте, а просто ответить: нет необходимости таких заморочек с ПрогрессБаром, т.к. можно управлять формой Прогресса — Явно;)

    Есть какая-дь более эффективная процедура управления Прогресс-баром из текущей формы внешней обработки при запуске длительной Глобальной процедуры на сервере, не меняя конфигурацию, притом что серверная процедура меняет значения элементов этой формы, но обновления реквизитов формы (ПрогрессБар + СтатуснаяСтрока) мы можем увидеть только по окончании выполнения на сервере и возврате в клиентский контекст?

    Reply
  6. NAKIS

    Спасибо, добавил плановому отделу в их обработочку) Теперь приятно радует глаз)

    А то все время были возмущения, мол нихрена не понятно, работает или зависло, а текстовое представления работы обработки им не нравилось…

    Reply
  7. pbazeliuk

    (5)В УФ такой процедуры нет. Можно реализовать это прыжками между контекстами «&НаКлиенте» на «&НаСервере», то есть порцию обработали в контексте сервера, вернулись на контекст клиента — показали прогресс, далее возвращаемся на контекст сервера для обработки следующей порции. Этот метод очень негативно влияет на время выполнения длительной операции.

    но обновления реквизитов формы (ПрогрессБар + СтатуснаяСтрока) мы можем увидеть только по окончании выполнения на сервере и возврате в клиентский контекст

    — Да, обновление интерфейса состоится только после возвращения в контекст клиента.

    В обычных формах проблем нет, для их реализовано множество различных ПрогрессБаров.

    Reply
  8. velber

    Бухгалтерия предприятия, редакция 3.0 (3.0.39.60)

    При выполнении выдает ошибку:

    {Форма.Форма.Форма(43)}: Ошибка при вызове метода контекста (Выполнить)

    ФоновоеЗадание = ФоновыеЗадания.Выполнить(«ДополнительныеОтчетыИОбработки.ВыполнитьОбработкуНепосредственно», ЗаданиеПараметры, УникальныйИдентификатор, «ИндикацияПроцеса»);

    по причине:

    Метод задания не найден: ДополнительныеОтчетыИОбработки:ВыполнитьОбработкуНепосредственно

    Reply
  9. velber

    Управление торговлей, редакция 11.1 (11.1.6.20)

    При выполнении выдает ошибку:

    Метод задания не найден: ДополнительныеОтчетыИОбработки:ВыполнитьОбработкуНепосредственно

    Reply
  10. pbazeliuk

    (8) velber, возможно, в БСП изменилось название метода или убрали ключевое слово «Экспорт» или изменились свойства общего модуля

    Reply
  11. fixin

    В типовых есть функция ДополнительныеОтчетыИОбработки.ВыполнитьКоманду. Её можно использовать для обработчика фонового задания, чтобы выполнить свою обработку, помещенную в справочник внешних обработок.

    Reply
  12. yuha33

    При выполнении выдает ошибку:

    Метод задания не найден: ДополнительныеОтчетыИОбработки:ВыполнитьОбработкуНепосредственно

    Можно тыкнуть пальцем, где взять этот код. В УТ11 я его не обнаружил. Ни в старой, ни в новой.

    Reply
  13. pbazeliuk

    (12) yuha33, посмотрите здесь как сделано http://infostart.ru/public/405368/. Работает под УТ 11

    Reply
  14. Andreyyy

    Подскажите, будут ли доступны в фоновом исполнении остальные процедуры/функции модуля объекта обработки из процедуры «ВыполнитьКоманду(Параметры)» ?

    Reply
  15. pbazeliuk

    (14) Andreyyy, будут доступны в контексте фонового задания только те методы, которые есть в самой обработке фонового задания. Так же контекст обработки, что инициировала фоновое задание будет недоступен.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *