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])); КонецЕсли;
// Основной код.
КонецЦикла;
КонецПроцедуры
Плюсы:
- Не нужно изменять основную конфигурацию;
- все очень просто в реализации и использовании;
- пользователь видит прогресс и одновременно делает что-то еще.