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