Случаются ситуации, что фоновое задание запущенное пользователем, продолжает работать и после выхода самого пользователя из 1С. Как же исключить повторный запуск фонового задания пользователем? Ну и заодно показать текущий прогресс выполнения задания. На самом деле всё оказалось просто. В 1С есть функционал получения полного списка выполняемых в текущий момент фоновых заданий:
ФоновыеЗадания.ПолучитьФоновыеЗадания();
После чего остаётся только пролистать все фоновые задания, идентифицировать нужное задание и передать его идентификатор в обработчик ожидания, который собственно и отображает например прогресс бар:
&НаКлиенте
Процедура ВыгрузкаКвитанцийНаБумаге(Команда)
этаформа.ИндикаторВыгрузкаКвитанций=0;
ЗапуститьФЗВыгрузкиКвитанций();
ПодключитьОбработчикОжидания("ИндикаторВыполненияВыгрузкиКвитанцийИсточник1",1,ложь);
ПодключитьОбработчикОжидания("ИндикаторВыполненияВыгрузкиКвитанцийИсточник2",1,ложь);
КонецПроцедуры
&НаСервере
Процедура ЗапуститьФЗВыгрузкиКвитанций()
Фоновые = ФоновыеЗадания.ПолучитьФоновыеЗадания();
Для Каждого Фоновое из Фоновые Цикл
если Фоновое.ИмяМетода="СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник1" тогда
если Фоновое.Состояние<>СостояниеФоновогоЗадания.ЗавершеноАварийно и Фоновое.Состояние<>СостояниеФоновогоЗадания.Завершено тогда
сообщить("-предыдущее задание еще не завершено!");
объект.ФЗ_ВыгрузкаКвитанций = Фоновое.УникальныйИдентификатор;
возврат;
конецесли;
конецесли;
если Фоновое.ИмяМетода="СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник2" тогда
сообщить("-предыдущее задание еще не завершено!");
если Фоновое.Состояние<>СостояниеФоновогоЗадания.ЗавершеноАварийно и Фоновое.Состояние<>СостояниеФоновогоЗадания.Завершено тогда
сообщить("-предыдущее задание еще не завершено!");
объект.ФЗ_ВыгрузкаКвитанций2 = Фоновое.УникальныйИдентификатор;
возврат;
конецесли;
возврат;
конецесли;
конеццикла;
Парм=Новый Структура("Период,ПроверятьНаличиевБД",объект.Период,объект.ПроверятьНаличиевБД);
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(Парм);
ФЗ = ФоновыеЗадания.Выполнить("СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник1",МассивПараметров);
объект.ФЗ_ВыгрузкаКвитанций = ФЗ.УникальныйИдентификатор;
ФЗ2 = ФоновыеЗадания.Выполнить("СК_ГР_ГеоаналитикаЗагрузки.ВыгрузитьКвитанцииВГеоаналитикуИсточник2",МассивПараметров);
объект.ФЗ_ВыгрузкаКвитанций2 = ФЗ2.УникальныйИдентификатор;
КонецПроцедуры
Т.е. если фоновое уже запущено — то просто получаем его идентификатор и отображаем прогресс бар. Если нет — запускаем
Задача: создать инструмент для распределения заявок по дням.
Решение: Наиболее удобным вариант я подумал что будет создание некого «дерева», узлами которого будут даты, а «ветвями» — заявки. Заявки можно будет перетаскивать между датами, тем самым равномерно распределяя нагрузку по дням.
Для того чтобы работать с деревьями, в 1С есть специальный тип: Дерево значений. Основной сущностностью у него являются строки. У каждой строки могут быть реквизиты (колонки). В то-же время каждая строка может иметь «потомков» — другие строки.
Создадим на форме «ДеревоОтключений» с типом «Дерево значений», и добавим у него реквизиты:
И перетащим его на форму. Далее по событию открытия, заполним дерево:
ДО = РеквизитФормыВЗначение("ДеревоОтключений");
ДО.Строки.Очистить();
Для Счетчик = 0 По Число(Сред(КонецМесяца(объект.ПериодОтключения), 1, 2)) Цикл
УДеньМесяца=ДО.Строки.Добавить();
если Счетчик=0 тогда
УДеньМесяца.ДатаОтключения="не распределено";
иначе
УДеньМесяца.ДатаОтключения=Формат(Дата(Год(объект.ПериодОтключения),Месяц(объект.ПериодОтключения),Счетчик),"ДФ=dd.MM.yyyy");
конецесли;
УДеньМесяца.expanded=false;
кол=0;
для каждого стр из МассивОтключаемых[Счетчик] цикл
ссср=УДеньМесяца.Строки.Добавить();
ссср.Отключаемый=стр;
ссср.ЛС=Строка(стр.ЛС);
ссср.Адрес=стр.АдресПотребителя;
кол=кол+1;
конеццикла;
если кол>0 тогда
УДеньМесяца.ЛС=Строка(кол);
конецесли;
КонецЦикла;
ЗначениеВРеквизитФормы(ДО,"ДеревоОтключений");
Получаем такую чудную картинку:
Теперь осталось только запретить перетаскивание во все колонки кроме «ДатаОтключения», чтобы избежать «не правильных» деревьев. Для этого заполним событие «ПриПеретаскивании»:
&НаКлиенте
Процедура ДеревоОтключенийПеретаскивание(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка, Строка, Поле)
//запретим если имя колонки куда тащим отличается от "ДатаОтключения"
если Поле.Имя<>"ДеревоОтключенийДатаОтключения" тогда
СтандартнаяОбработка=ложь;
конецесли;
//запретим если дата отключения пустая
Куда=ДеревоОтключений.НайтиПоИдентификатору(Строка);
если Куда.ДатаОтключения="" тогда
СтандартнаяОбработка=ложь;
конецесли;
//запретим перетаскивание "в корень"
если Куда.ДатаОтключения=ДеревоОтключений.НайтиПоИдентификатору(Элементы.ДеревоОтключений.ТекущаяСтрока).ПолучитьРодителя().ДатаОтключения тогда
СтандартнаяОбработка=ложь;
конецесли;
КонецПроцедуры
Для того чтобы обновить цифру с количеством «веток» в каждом узле, реализовал нечто подобное, разместив в событии «ОкончаниеПеретаскивания»:
&НаКлиенте
Процедура ДеревоОтключенийОкончаниеПеретаскивания(Элемент, ПараметрыПеретаскивания, СтандартнаяОбработка)
ОбновляюКоличествоЛС();
КонецПроцедуры
&НаКлиенте
Функция ОбновляюКоличествоЛС()
ЭлементыДерева = ДеревоОтключений.ПолучитьЭлементы();
для каждого стр из ЭлементыДерева цикл
клв=стр.ПолучитьЭлементы().Количество();
если клв<50 тогда
стр.ЛС=клв;
конецесли;
конеццикла;
КонецФункции
В рекруссию не пошел, т.к. в моём случае заведомо известно, что ветвей не более 1
Сиё может понадобиться, если необходимо ну…например вывести какую-то динамическую информацию на форму, причём со стилями не стандартными для 1С, т.е. штатными средствами 1С не выполнимыми или трудновыполнимыми.
В моём случае, я в это поле просто вывожу динамический список напоминаний. При клике на который открывается соответствующий документ.
Итак, создаём на форме реквизит «Прочие напоминания» с типом строка. Длина -0, т.е. не ограниченная. Затем перетаскиваем реквизит на форму и выбираем вид «Поле HTML документа»:
При открытии формы, заполняем HTML:
&НаСервере
Функция СформироватьСписокНапоминанийНаСервере(Исполнитель)
список_напоминаний=СК_ОбщиеФункции.СформироватьУведомленияОНапоминаемыхДатах(ложь,Исполнитель);
body="<ul>";
для каждого стр из список_напоминаний цикл
body=body+"<li><a href='"+стр.ссылка.номер+"'>"+стр.Пояснение+"</a></li>";
конеццикла;
body=body+"</ul>";
возврат body;
КонецФункции
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ПрочиеНапоминания="<html><head></head><body>"+СформироватьСписокНапоминанийНаСервере(Исполнитель)+"</body></html>";
КонецПроцедуры
Далее отлавливаем клик по полю HTML, и открываем документ:
&НаКлиенте
Процедура ПрочиеНапоминанияПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
если ДанныеСобытия.Свойство("href") тогда
РазделёныйМассивСсылки=СтрРазделить(ДанныеСобытия.href,"/");
НомерДокумента=РазделёныйМассивСсылки[РазделёныйМассивСсылки.Количество()-1];
ОткрытьЗначение(ПолучитьСсылкуНаДокумент(НомерДокумента));
конецесли;
СтандартнаяОбработка=ложь;
КонецПроцедуры