СоздатьВТРасписанияРаботыНаПериод (БСП)

Автор: 1С
ОбщийМодуль.ГрафикиРаботы
БСП

Создать расписания работы на период. Создает в менеджере временную таблицу ВТРасписанияРаботы с колонками, соответствующими возвращаемому значению

// Создает в менеджере временную таблицу ВТРасписанияРаботы с колонками, соответствующими возвращаемому значению
// функции РасписанияРаботыНаПериод.
//
// Параметры:
//  МенеджерВременныхТаблиц - МенеджерВременныхТаблиц - менеджер, в котором будет создана временная таблица.
//	Графики       - Массив - массив элементов типа СправочникСсылка.Календари, для которых составляются расписания.
//	ДатаНачала    - Дата   - дата начала периода, за который нужно составить расписания.
//	ДатаОкончания - Дата   - дата окончания периода.
//
Процедура СоздатьВТРасписанияРаботыНаПериод(МенеджерВременныхТаблиц, Графики, ДатаНачала, ДатаОкончания) Экспорт
	
	ТекстЗапроса = 
	"ВЫБРАТЬ
	|	ШаблонЗаполнения.Ссылка КАК ГрафикРаботы,
	|	МАКСИМУМ(ШаблонЗаполнения.НомерСтроки) КАК ДлинаЦикла
	|ПОМЕСТИТЬ ВТДлинаЦиклаГрафиков
	|ИЗ
	|	Справочник.Календари.ШаблонЗаполнения КАК ШаблонЗаполнения
	|ГДЕ
	|	ШаблонЗаполнения.Ссылка В(&Календари)
	|
	|СГРУППИРОВАТЬ ПО
	|	ШаблонЗаполнения.Ссылка
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Календари.Ссылка КАК ГрафикРаботы,
	|	ДанныеПроизводственногоКалендаря.Дата КАК ДатаГрафика,
	|	ВЫБОР
	|		КОГДА ДанныеПроизводственногоКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный)
	|			ТОГДА ИСТИНА
	|		ИНАЧЕ ЛОЖЬ
	|	КОНЕЦ КАК ПредпраздничныйДень
	|ПОМЕСТИТЬ ВТПредпраздничныеДни
	|ИЗ
	|	РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Календари КАК Календари
	|		ПО ДанныеПроизводственногоКалендаря.ПроизводственныйКалендарь = Календари.ПроизводственныйКалендарь
	|			И (Календари.Ссылка В (&Календари))
	|			И (ДанныеПроизводственногоКалендаря.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания)
	|			И (ДанныеПроизводственногоКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный))
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	Календари.Ссылка КАК ГрафикРаботы,
	|	ДанныеПроизводственногоКалендаря.Дата КАК ДатаГрафика,
	|	ДанныеПроизводственногоКалендаря.ДатаПереноса
	|ПОМЕСТИТЬ ВТДатыПереноса
	|ИЗ
	|	РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Календари КАК Календари
	|		ПО ДанныеПроизводственногоКалендаря.ПроизводственныйКалендарь = Календари.ПроизводственныйКалендарь
	|			И (Календари.Ссылка В (&Календари))
	|			И (ДанныеПроизводственногоКалендаря.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания)
	|			И (ДанныеПроизводственногоКалендаря.ДатаПереноса <> ДАТАВРЕМЯ(1, 1, 1))
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	КалендарныеГрафики.Календарь КАК ГрафикРаботы,
	|	КалендарныеГрафики.ДатаГрафика КАК ДатаГрафика,
	|	РАЗНОСТЬДАТ(Календари.ДатаОтсчета, КалендарныеГрафики.ДатаГрафика, ДЕНЬ) + 1 КАК ДнейОтДатыОтсчета,
	|	ПредпраздничныеДни.ПредпраздничныйДень,
	|	ДатыПереноса.ДатаПереноса
	|ПОМЕСТИТЬ ВТДниВключенныеВГрафик
	|ИЗ
	|	РегистрСведений.КалендарныеГрафики КАК КалендарныеГрафики
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Календари КАК Календари
	|		ПО КалендарныеГрафики.Календарь = Календари.Ссылка
	|			И (КалендарныеГрафики.Календарь В (&Календари))
	|			И (КалендарныеГрафики.ДатаГрафика МЕЖДУ &ДатаНачала И &ДатаОкончания)
	|			И (КалендарныеГрафики.ДеньВключенВГрафик)
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВТПредпраздничныеДни КАК ПредпраздничныеДни
	|		ПО (ПредпраздничныеДни.ГрафикРаботы = КалендарныеГрафики.Календарь)
	|			И (ПредпраздничныеДни.ДатаГрафика = КалендарныеГрафики.ДатаГрафика)
	|		ЛЕВОЕ СОЕДИНЕНИЕ ВТДатыПереноса КАК ДатыПереноса
	|		ПО (ДатыПереноса.ГрафикРаботы = КалендарныеГрафики.Календарь)
	|			И (ДатыПереноса.ДатаГрафика = КалендарныеГрафики.ДатаГрафика)
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ДниВключенныеВГрафик.ГрафикРаботы,
	|	ДниВключенныеВГрафик.ДатаГрафика,
	|	ВЫБОР
	|		КОГДА ДниВключенныеВГрафик.РезультатДеленияПоМодулю = 0
	|			ТОГДА ДниВключенныеВГрафик.ДлинаЦикла
	|		ИНАЧЕ ДниВключенныеВГрафик.РезультатДеленияПоМодулю
	|	КОНЕЦ КАК НомерДня,
	|	ДниВключенныеВГрафик.ПредпраздничныйДень
	|ПОМЕСТИТЬ ВТДатыНомераДней
	|ИЗ
	|	(ВЫБРАТЬ
	|		ДниВключенныеВГрафик.ГрафикРаботы КАК ГрафикРаботы,
	|		ДниВключенныеВГрафик.ДатаГрафика КАК ДатаГрафика,
	|		ДниВключенныеВГрафик.ПредпраздничныйДень КАК ПредпраздничныйДень,
	|		ДниВключенныеВГрафик.ДлинаЦикла КАК ДлинаЦикла,
	|		ДниВключенныеВГрафик.ДнейОтДатыОтсчета - ДниВключенныеВГрафик.ЦелаяЧастьРезультатаДеления * ДниВключенныеВГрафик.ДлинаЦикла КАК РезультатДеленияПоМодулю
	|	ИЗ
	|		(ВЫБРАТЬ
	|			ДниВключенныеВГрафик.ГрафикРаботы КАК ГрафикРаботы,
	|			ДниВключенныеВГрафик.ДатаГрафика КАК ДатаГрафика,
	|			ДниВключенныеВГрафик.ПредпраздничныйДень КАК ПредпраздничныйДень,
	|			ДниВключенныеВГрафик.ДнейОтДатыОтсчета КАК ДнейОтДатыОтсчета,
	|			ДлинаЦиклов.ДлинаЦикла КАК ДлинаЦикла,
	|			(ВЫРАЗИТЬ(ДниВключенныеВГрафик.ДнейОтДатыОтсчета / ДлинаЦиклов.ДлинаЦикла КАК ЧИСЛО(15, 0))) - ВЫБОР
	|				КОГДА (ВЫРАЗИТЬ(ДниВключенныеВГрафик.ДнейОтДатыОтсчета / ДлинаЦиклов.ДлинаЦикла КАК ЧИСЛО(15, 0))) > ДниВключенныеВГрафик.ДнейОтДатыОтсчета / ДлинаЦиклов.ДлинаЦикла
	|					ТОГДА 1
	|				ИНАЧЕ 0
	|			КОНЕЦ КАК ЦелаяЧастьРезультатаДеления
	|		ИЗ
	|			ВТДниВключенныеВГрафик КАК ДниВключенныеВГрафик
	|				ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Календари КАК Календари
	|				ПО ДниВключенныеВГрафик.ГрафикРаботы = Календари.Ссылка
	|					И (Календари.СпособЗаполнения = ЗНАЧЕНИЕ(Перечисление.СпособыЗаполненияГрафикаРаботы.ПоЦикламПроизвольнойДлины))
	|				ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДлинаЦиклаГрафиков КАК ДлинаЦиклов
	|				ПО ДниВключенныеВГрафик.ГрафикРаботы = ДлинаЦиклов.ГрафикРаботы) КАК ДниВключенныеВГрафик) КАК ДниВключенныеВГрафик
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ДниВключенныеВГрафик.ГрафикРаботы,
	|	ДниВключенныеВГрафик.ДатаГрафика,
	|	ВЫБОР
	|		КОГДА ДниВключенныеВГрафик.ДатаПереноса ЕСТЬ NULL 
	|			ТОГДА ДЕНЬНЕДЕЛИ(ДниВключенныеВГрафик.ДатаГрафика)
	|		ИНАЧЕ ДЕНЬНЕДЕЛИ(ДниВключенныеВГрафик.ДатаПереноса)
	|	КОНЕЦ,
	|	ДниВключенныеВГрафик.ПредпраздничныйДень
	|ИЗ
	|	ВТДниВключенныеВГрафик КАК ДниВключенныеВГрафик
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Календари КАК Календари
	|		ПО ДниВключенныеВГрафик.ГрафикРаботы = Календари.Ссылка
	|ГДЕ
	|	Календари.СпособЗаполнения = ЗНАЧЕНИЕ(Перечисление.СпособыЗаполненияГрафикаРаботы.ПоНеделям)
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ДниВключенныеВГрафик.ГрафикРаботы,
	|	ДниВключенныеВГрафик.ДатаГрафика,
	|	ДниВключенныеВГрафик.НомерДня,
	|	ЕСТЬNULL(РасписанияРаботыПредпраздничногоДня.ВремяНачала, РасписанияРаботы.ВремяНачала) КАК ВремяНачала,
	|	ЕСТЬNULL(РасписанияРаботыПредпраздничногоДня.ВремяОкончания, РасписанияРаботы.ВремяОкончания) КАК ВремяОкончания
	|ПОМЕСТИТЬ ВТРасписанияРаботы
	|ИЗ
	|	ВТДатыНомераДней КАК ДниВключенныеВГрафик
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Календари.РасписаниеРаботы КАК РасписанияРаботы
	|		ПО (РасписанияРаботы.Ссылка = ДниВключенныеВГрафик.ГрафикРаботы)
	|			И (РасписанияРаботы.НомерДня = ДниВключенныеВГрафик.НомерДня)
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Календари.РасписаниеРаботы КАК РасписанияРаботыПредпраздничногоДня
	|		ПО (РасписанияРаботыПредпраздничногоДня.Ссылка = ДниВключенныеВГрафик.ГрафикРаботы)
	|			И (РасписанияРаботыПредпраздничногоДня.НомерДня = 0)
	|			И (ДниВключенныеВГрафик.ПредпраздничныйДень)
	|
	|ИНДЕКСИРОВАТЬ ПО
	|	ДниВключенныеВГрафик.ГрафикРаботы,
	|	ДниВключенныеВГрафик.ДатаГрафика";
	
	// Для вычисления номера в цикле произвольной длины для дня, включенного в график, используется следующая формула:
	// Номер дня = Дней от даты отсчета % Длина цикла, где % - операция деления по модулю.
	
	// Операция деления по модулю в свою очередь производится по формуле:
	// Делимое - Цел(Делимое / Делитель) * Делитель, где Цел() - функция выделения целой части.
	
	// Для выделения целой части используется конструкция:
	// если результат округления числа по правилам «1.5 как 2» больше исходного значения, уменьшаем результат на 1.
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;
	Запрос.УстановитьПараметр("Календари", Графики);
	Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
	Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);
	Запрос.Выполнить();
	
КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

Рекомендации

Похожие публикации

РасписанияРаботыНаПериод (БСП)

УстановитьНапоминание (БСП)

Напомнить (БСП)

Создать временную таблицу "Штатное расписание"

Определение периодов работы сотрудников по данным СКУД. Сгруппировать периоды в запросе

ЗакрытьФормуПодключенияТестовыхПериодов (БСП)

Создать временную таблицу периодов с заданной периодичностью

TurboConf - расширение Конфигуратора 1С