Планировщик 1С. Настройка расписания повторяющихся событий и перемещение элементов мышью

01.03.18

Разработка - БСП (Библиотека стандартных подсистем)

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

В нашем "Календаре" отображаются стандартные "Задачи исполнителя" и элементы собственного справочника "События".

На основании справочника "События" можно стартовать бизнес-процессы, кроме того, для них доступна настройка повторения по расписанию. Нужно отметить, что повторяются события только в календаре, новые элементы справочника при этом не создаются. А вот бизнес-процессы на основании этих виртуальных повторяемых событий должны создаваться вполне реальные, с реальными датами. Рассмотрим пример реализации данной задачи.

Справочник "События" выглядит следующим образом:

Форма:

В режиме "Предприятие":

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

&НаКлиенте
Процедура ПослеИзмененияРасписания(РасписаниеРезультат, ДополнительныеПараметры) Экспорт
	
	Если РасписаниеРезультат <> Неопределено Тогда
		
		Модифицированность = Истина;
		Расписание = РасписаниеРезультат;
				
		ЗаполнитьЗначенияСвойств(Объект, Расписание);	
		
		//дни недели
		Объект.ПовторениеПоДнямНедели.Очистить();
		Для Каждого Элемент из Расписание.ДниНедели Цикл
			Строка = Объект.ПовторениеПоДнямНедели.Добавить();
			Строка.День = Элемент;
		КонецЦикла;		
		
		//месяцы
		Объект.ПовторениеПоМесяцам.Очистить();
		Для Каждого Элемент из Расписание.Месяцы Цикл
			Строка = Объект.ПовторениеПоМесяцам.Добавить();
			Строка.Месяц = Элемент;
		КонецЦикла;		
		
	КонецЕсли;
	
КонецПроцедуры

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

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

При заполнении календаря расписание элементов заполняется сходным образом:

//{Заполняем текст запроса по событиям}

Выборка = Запрос.Выполнить().Выбрать();
	
ДанныеКалендаря.Элементы.Очистить();
	
Пока Выборка.Следующий() Цикл

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

КонецЦикла;

Планировщик 1С обрабатывает элементы с заполненным расписанием следующим образом: на каждый период повтора создаётся элемент планировщика с датами начала и окончания, соответствующими периоду повтора, и значением единственного реального элемента, который мы добавили при обходе выборки.

Выглядит это так:

Обработка "ПередНачаломРедактирования" элемента планировщика у нас нестандартная и вызывает открытие формы задачи/события в зависимости от типа значения. Но какой бы элемент из повторяющихся мы не открывали, даты начала и окончания в форме будут исходные, в данном случае 18.08.2017 и 19.08.2017. 

Значит, из календаря будем открывать форму с параметрами, и обрабатывать их при создании на сервере.

&НаСервере
Функция ПолучитьПараметрыФормыСобытия(Событие, Начало, Конец)
	
	ПараметрыФормы = Новый Структура("Ключ, ПовторяемыйЭлемент, ДатаНачалаЭлементаПовторения, ДатаОкончанияЭлементаПовторения", Событие, Событие.Повторять, Начало, Конец);
	
	Возврат ПараметрыФормы;
	
КонецФункции

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

Обработчик при создании формы события:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ЗаполнитьРасписание();
	
	ДатаНачалаЭлементаПовторения = Параметры.ДатаНачалаЭлементаПовторения;
	ДатаОкончанияЭлементаПовторения = Параметры.ДатаОкончанияЭлементаПовторения;
	ПовторяемыйЭлемент = Параметры.ПовторяемыйЭлемент;

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

Если присмотреться, на размещённом в начале статьи скриншоте с формой события по два элемента с заголовками "Дата начала" и "Дата окончания". В зависимости от того, повторяемый это элемент или основной, видны либо реальные "Дата начала" и "Дата окончания", либо реквизиты формы "Дата начала элемента повторения" и "Дата окончания элемента повторения".

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Элементы.ДатаНачала.Видимость = НЕ ПовторяемыйЭлемент;
	Элементы.ДатаНачалаЭлементаПовторения.Видимость = ПовторяемыйЭлемент;
	
	Элементы.ДатаОкончания.Видимость = НЕ ПовторяемыйЭлемент;
	Элементы.ДатаОкончанияЭлементаПовторения.Видимость = ПовторяемыйЭлемент;
	
	Элементы.ФормаКоманднаяПанель.ПодчиненныеЭлементы["ФормаСоздатьНаОсновании"].Видимость = НЕ ПовторяемыйЭлемент;
	Элементы.ФормаГруппаСоздатьНаОсновании.Видимость = ПовторяемыйЭлемент;
	
КонецПроцедуры

Стандартный ввод на основании для повторяемых элементов тоже пришлось переписать:

&НаКлиенте
Процедура ВводНаОсновании(Команда)
	
	Основание = Новый Структура("Ссылка, Начало, Конец", Объект.Ссылка, ДатаНачалаЭлементаПовторения, ДатаОкончанияЭлементаПовторения);
	ПараметрыФормы = Новый Структура("Основание", Основание);
	ОткрытьФорму("БизнесПроцесс.СложноеЗадание.ФормаОбъекта", ПараметрыФормы);
	
КонецПроцедуры

Разумеется, все запущенные на основании повторяемых элементов бизнес-процессы будут подчинены единственному реальному событию.

А теперь о реализации так полюбившейся пользователям функции - перемещения элементов календаря мышкой с сохранением изменений. Планировщик позволяет перемещать элементы и изменять их границы мышью "из коробки". При этом у элементов планировщика меняются даты начала и окончания. Осталось только записать их в реальные объекты.

&НаКлиенте
Процедура ДанныеКалендаряПриОкончанииРедактирования(Элемент, НовыйЭлемент, ОтменаРедактирования)
	
	Для Каждого ВыделенныйЭлемент Из Элемент.ВыделенныеЭлементы Цикл
		ОбновитьДатыЗаписиКалендаря(ВыделенныйЭлемент.Значение, ВыделенныйЭлемент.Начало, ВыделенныйЭлемент.Конец);
	КонецЦикла;
		
КонецПроцедуры

&НаСервере
Процедура ОбновитьДатыЗаписиКалендаря(ЗаписьКалендаря, ДатаНачала, ДатаОкончания)
	
	ЗаписьКалендаряОбъект = ЗаписьКалендаря.ПолучитьОбъект();
	
	Если ТипЗнч(ЗаписьКалендаря) = Тип("СправочникСсылка.События") Тогда
		
		ЗаписьКалендаряОбъект.ДатаНачала = ДатаНачала;
		ЗаписьКалендаряОбъект.ДатаОкончания = ДатаОкончания;		
		
	ИначеЕсли ТипЗнч(ЗаписьКалендаря) = Тип("ЗадачаСсылка.ЗадачаИсполнителя") Тогда
		
		Если ЗначениеЗаполнено(ЗаписьКалендаряОбъект.ДатаПринятияКИсполнению) Тогда
			ЗаписьКалендаряОбъект.ДатаПринятияКИсполнению = ДатаНачала;
		ИначеЕсли ЗначениеЗаполнено(ЗаписьКалендаряОбъект.ДатаНачала) Тогда
			ЗаписьКалендаряОбъект.ДатаНачала = ДатаНачала;
		Иначе
			ЗаписьКалендаряОбъект.Дата = ДатаНачала;
		КонецЕсли;
			
		ЗаписьКалендаряОбъект.СрокИсполнения = ДатаОкончания;
		
	КонецЕсли;		
	
	ЗаписьКалендаряОбъект.Записать();
			
КонецПроцедуры

Удобно выделять элементы планировщика разных видов цветом. У элемента есть свойства "ЦветФона", "ЦветТекста" и "ЦветРамки". В зависимости от тех или иных условий можно выбирать какие угодно их сочетания. Планировщик сам позаботится о том, чтобы элементы остались видимыми. В нашей конфигурации задачи, не принятые к исполнению, выделяются одним цветом, принятые - другим, а для каждого события цвет выбирается пользователем и сохраняется в справочнике в реквизите типа "ХранилищеЗначений". При заполнении планировщика данными цвет события устанавливается так:

//получим цвет события
СобытиеОбъект = Выборка.Ссылка.ПолучитьОбъект();
СохранённыйЦвет = СобытиеОбъект.Цвет.Получить();
Если Не СохранённыйЦвет = неопределено Тогда
	ЦветСобытия = СохранённыйЦвет;
Иначе
	ЦветСобытия = ЦветаСтиля.СобытиеКалендаря;
КонецЕсли;	
Элемент.ЦветФона = ЦветСобытия;	

Вот и всё самое интересное, что мне удалось выяснить в процессе работы с планировщиком. Возможно, кому-нибудь эта информация будет полезна.

БСП задачи календарь планировщик

См. также

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Пример шаблона для многопоточного выполнения фонового задания на основе БСП. Шаблоны сделаны для процедуры и функции.

2 стартмани

03.05.2024    1258    18    Hitcher    3    

13

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    3562    dimanich70    8    

16

Механизмы платформы 1С БСП (Библиотека стандартных подсистем) Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Небольшая шпаргалка по функциям БСП касательно адреса. Так скажем, еще один способ помимо https://infostart.ru/1c/articles/1060970/

12.02.2024    1136    FilippovRI    0    

17

БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

07.02.2024    3451    YA_418728146    11    

52
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user878162 20.06.18 11:10 Сейчас в теме
Добрый день.
Подскажите пожалуйста, а как реализовали сам запуск по расписанию процессов? Именно с учетом периодичности. Как определяете что наступило время выполнить нужное действие?

Разбираюсь с подобной задачей, планировщик просто отрисовывает элементы с установленной периодичностью, но у него нет методов для проверки входит ли конкретная дата в этот диапазон. Подскажите в какую сторону смотреть и как проверить принадлежность определенной даты периодичности установленной в задании. Надеюсь понятно сформулировал :-)
2. WhiteOwl 435 20.06.18 17:27 Сейчас в теме
(1) а это уже совершенно другая история))) При завершении бизнес-процесса смотрим в его расписание и вручную анализируем - если повтор по дням, то ищем следующий подходящий день, если еженедельно - то через неделю и т.п. Определив дату, стартуем следующий бизнес процесс. Подробностей я, к сожалению, уже не помню. Можно посмотреть как реализован типовой повтор регламентных заданий. Также, возможно, что-то подобное есть в конфигурации "Документооборот" от 1С.
nlvhome; user878162; +2 Ответить
3. user878162 21.06.18 04:41 Сейчас в теме
4. mrcamomile 81 13.12.18 17:45 Сейчас в теме
(1) Можно вот так выкрутиться

РасписаниеЭП - расписание элемента планировщика
Функция ПолучитьДатыПоРасписанию(Знач ДатаНачала, Знач ДатаОкончания, РасписаниеЭП = Неопределено) Экспорт 
	
	Результат = Новый Массив;
	
	ДатаМаксимум = '21000101';
	ДатаНачала = НачалоДня(ДатаНачала);
	ДатаОкончания = НачалоДня(ДатаОкончания);
	Результат.Добавить(ДатаНачала);
	
	Если РасписаниеЭП = Неопределено Тогда 
		Возврат Результат;
	КонецЕсли;
		
	РРЗ = Новый РасписаниеРегламентногоЗадания;
	ЗаполнитьЗначенияСвойств(РРЗ, РасписаниеЭП);
	ДатаНачалаПоследнегоЗапуска = Результат[0];
	Пока 
		(ДатаОкончания = '00010101' И ДатаНачала < ДатаМаксимум)
		ИЛИ (ДатаОкончания > '00010101' И ДатаНачала < ДатаОкончания)
	Цикл
		ДатаНачала = ДатаНачала + 86400;
		ТребуетсяВыполнение = РРЗ.ТребуетсяВыполнение(ДатаНачала, ДатаНачалаПоследнегоЗапуска);
		Если ТребуетсяВыполнение Тогда
			Результат.Добавить(ДатаНачала);
			ДатаНачалаПоследнегоЗапуска = ДатаНачала;
		КонецЕсли;
	КонецЦикла; 
	
	Возврат Результат;
	
КонецФункции
Показать
5. mrcamomile 81 13.12.18 18:09 Сейчас в теме
(4) вот отличия между "РасписаниеРегламентногоЗадания" / "РасписаниеЭлементаПланировщика"
Прикрепленные файлы:
6. TheDemonHrono 24.02.19 19:50 Сейчас в теме
А как скачать, чтобы посмотреть по ближе?
7. WhiteOwl 435 24.02.19 21:56 Сейчас в теме
(6) к сожалению, никак. Это часть нетиповой конфигурации.
8. пользователь 30.10.19 11:05
Сообщение было скрыто модератором.
...
9. Adept 21.01.20 09:35 Сейчас в теме
А можешь показать код переключения представлений День/Неделя/Месяц?
10. Светлый ум 407 29.03.24 11:14 Сейчас в теме
+1 зачетный планировщик
Оставьте свое сообщение