Загрузка данных
Модуль Формы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
УстановитьУсловноеОформление();
ЗаполнитьСписокЗначенийПроизводственныйКалендарьНаСервере();
Если ЗначениеЗаполнено(Объект.Год) Тогда
НомерТекущегоГода = Объект.Год;
КонецЕсли;
ЗаполнитьДаннымиТекущегоГода();
СформироватьШаблонРасписания();
УстановитьДоступностьУчитыватьНерабочиеПериоды();
УстановитьДоступностьУчитыватьПраздники();
ЗаполнитьЦветаВидовДней();
ЗаполнитьСписокВидовДня();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДаннымиПоУмолчанию()
КодБазовогоКалендаря = Объект.ПроизводственныйКалендарь;
Объект.Код = КодБазовогоКалендаря;
ДанныеПоУмолчанию = Справочники.ГрафикРаботы.РезультатЗаполненияПроизводственногоКалендаряПоУмолчанию(
Объект.Код, НомерТекущегоГода, КодБазовогоКалендаря
);
Справочники.ГрафикРаботы.ОбновитьПериодыНерабочихДней(
Справочники.ГрафикРаботы.ПериодыНерабочихДнейПоУмолчанию(), Объект.Код
);
ПреобразоватьДанныеПроизводственногоКалендаря(ДанныеПоУмолчанию);
Модифицированность = Истина;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДаннымиТекущегоГода()
НастроитьПолеКалендаря();
СсылкаНаКалендарь = Объект.Ссылка;
//СсылкаНаКалендарь = Объект.ПроизводственныйКалендарь;
ПрочитатьДанныеПроизводственногоКалендаря(СсылкаНаКалендарь, НомерТекущегоГода);
ПрочитатьНерабочиеДаты();
ДниГрафика = Новый ФиксированноеСоответствие(
РегистрыСведений.КалендарныеГрафики.ПрочитатьДанныеГрафикаИзРегистра(Объект.Ссылка, НомерТекущегоГода));
//ПрочитатьПризнакРучногоРедактирования(Объект, НомерТекущегоГода);
// Если нет ручных корректировок и данных тоже нет, то формируем результат по шаблону за выбранный год.
Если ДниГрафика.Количество() = 0 Тогда //И ДниИзмененные.Количество() = 0
ПараметрыЗаполнения = РегистрыСведений.КалендарныеГрафики.ПараметрыЗаполненияГрафика();
ПараметрыЗаполнения.КодПроизводственногоКалендаря = Объект.Код;
//ПараметрыЗаполнения.СпособЗаполнения = Объект.СпособЗаполнения;
ПараметрыЗаполнения.ШаблонЗаполнения = Объект.РабочиеДни;
ПараметрыЗаполнения.ПроизводственныйКалендарь = Объект.Ссылка;
ПараметрыЗаполнения.УчитыватьПраздники = Объект.УчитыватьПраздничныеДни;
ПараметрыЗаполнения.УчитыватьНерабочиеПериоды = Объект.УчитыватьНерабочиеПериоды;
//ПараметрыЗаполнения.ДатаОтсчета = Объект.ДатаОтсчета;
ДниВключенныеВГрафик = РегистрыСведений.КалендарныеГрафики.ДниВключенныеВГрафик(
Объект.ДатаНачала, Дата(НомерТекущегоГода, 12, 31), ПараметрыЗаполнения
);
ДниГрафика = Новый ФиксированноеСоответствие(ДниВключенныеВГрафик);
КонецЕсли;
КонецПроцедуры
//&НаСервере
//Процедура ПрочитатьДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода)
//
// // Загрузка данных производственного календаря за указанный год.
// ПреобразоватьДанныеПроизводственногоКалендаря(
// Справочники.ГрафикРаботы.ДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода)
// );
//КонецПроцедуры
&НаСервере
Процедура ПрочитатьДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода)
// 1. Получаем данные из регистра сведений
ТЗДанные = Справочники.ГрафикРаботы.ДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода);
// Очередь проверки: сколько строк реально прочиталось из регистра
Сообщить(СтрШаблон("[ОТЛАДКА] Из регистра прочитано строк: %1", ТЗДанные.Количество()));
// 2. Если в регистре пусто — переходим на заполнение по умолчанию
Если ТЗДанные.Количество() = 0 И ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
Сообщить("[ОТЛАДКА] Регистр пуст! Вызывается заполнение по умолчанию из макета/функции.");
ТЗДанные = Справочники.ГрафикРаботы.РезультатЗаполненияПроизводственногоКалендаряПоУмолчанию(
Объект.ПроизводственныйКалендарь, НомерГода, Объект.ПроизводственныйКалендарь
);
Сообщить(СтрШаблон("[ОТЛАДКА] Из макета по умолчанию сформировано строк: %1", ТЗДанные.Количество()));
КонецЕсли;
ПреобразоватьДанныеПроизводственногоКалендаря(ТЗДанные);
КонецПроцедуры
//&НаСервере
//Процедура ПреобразоватьДанныеПроизводственногоКалендаря(ДанныеПроизводственногоКалендаря)
// // Данные производственного календаря используются в форме
// // в виде соответствий ВидыДней и ПереносыДней.
// // Процедура заполняет эти соответствия.
//
// ВидыДнейСоответствие = Новый Соответствие;
// ПереносыДнейСоответствие = Новый Соответствие;
//
// Для Каждого СтрокаТаблицы Из ДанныеПроизводственногоКалендаря Цикл
// ВидыДнейСоответствие.Вставить(СтрокаТаблицы.Дата, СтрокаТаблицы.ВидДня);
// Если ЗначениеЗаполнено(СтрокаТаблицы.ДатаПереноса) Тогда
// ПереносыДнейСоответствие.Вставить(СтрокаТаблицы.Дата, СтрокаТаблицы.ДатаПереноса);
// КонецЕсли;
// КонецЦикла;
//
// ВидыДней = Новый ФиксированноеСоответствие(ВидыДнейСоответствие);
// ПереносыДней = Новый ФиксированноеСоответствие(ПереносыДнейСоответствие);
// /// ???
// //ЗаполнитьПредставлениеПереносов(ЭтотОбъект);
//
//КонецПроцедуры
&НаСервере
Процедура ПреобразоватьДанныеПроизводственногоКалендаря(ДанныеПроизводственногоКалендаря)
ВидыДнейСоответствие = Новый Соответствие;
ПереносыДнейСоответствие = Новый Соответствие;
Для Каждого СтрокаТаблицы Из ДанныеПроизводственногоКалендаря Цикл
ВидыДнейСоответствие.Вставить(СтрокаТаблицы.Дата, СтрокаТаблицы.ВидДня);
Если ЗначениеЗаполнено(СтрокаТаблицы.ДатаПереноса) Тогда
ПереносыДнейСоответствие.Вставить(СтрокаТаблицы.Дата, СтрокаТаблицы.ДатаПереноса);
КонецЕсли;
КонецЦикла;
// Проверяем, сколько уникальных дат попало в массив до генерации отсутствующих дней
Сообщить(СтрШаблон("[ОТЛАДКА] В соответствие видов дней загружено исходных дат: %1", ВидыДнейСоответствие.Количество()));
// Дополнение отсутствующих дней года
ДатаДня = Дата(НомерТекущегоГода, 1, 1);
ДатаОкончания = Дата(НомерТекущегоГода, 12, 31);
СчетчикДописанныхДней = 0;
Пока ДатаДня <= ДатаОкончания Цикл
Если ВидыДнейСоответствие[ДатаДня] = Неопределено Тогда
НомерДня = ДеньНедели(ДатаДня);
Если НомерДня <= 5 Тогда
ВидДняПоУмолчанию = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий;
ИначеЕсли НомерДня = 6 Тогда
ВидДняПоУмолчанию = Перечисления.ВидыДнейПроизводственногоКалендаря.Суббота;
Иначе
ВидДняПоУмолчанию = Перечисления.ВидыДнейПроизводственногоКалендаря.Воскресенье;
КонецЕсли;
ВидыДнейСоответствие.Вставить(ДатаДня, ВидДняПоУмолчанию);
СчетчикДописанныхДней = СчетчикДописанныхДней + 1;
КонецЕсли;
ДатаДня = ДатаДня + 86400;
КонецЦикла;
Сообщить(СтрШаблон("[ОТЛАДКА] Автоматически дозаполнено пропущенных дней: %1", СчетчикДописанныхДней));
Сообщить(СтрШаблон("[ОТЛАДКА] Итого дней в соответствии: %1", ВидыДнейСоответствие.Количество()));
ВидыДней = Новый ФиксированноеСоответствие(ВидыДнейСоответствие);
ПереносыДней = Новый ФиксированноеСоответствие(ПереносыДнейСоответствие);
КонецПроцедуры
&НаСервере
Процедура УстановитьДоступностьУчитыватьНерабочиеПериоды()
Элементы.УчитыватьНерабочиеПериоды.Видимость = Ложь;
Если Не ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
Возврат;
КонецЕсли;
Периоды = РегистрыСведений.КалендарныеГрафики.ПериодыНерабочихДней(Объект.ПроизводственныйКалендарь, Новый СтандартныйПериод(Объект.ДатаНачала, Объект.ДатаОкончания), Объект.Код);
Если Периоды.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Элементы.УчитыватьНерабочиеПериодыГруппа.Видимость = Истина;
Пояснение = "";
Для Каждого ОписаниеПериода Из Периоды Цикл
Пояснение = Пояснение + ?(Не ПустаяСтрока(Пояснение), Символы.ПС, "") + ОписаниеПериода.Представление;
КонецЦикла;
Элементы.НерабочиеПериодыИнформация.Заголовок = Пояснение;
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Процедура ЗаполнитьПредставлениеПереносов(Форма)
// Формирует представление переносов в виде списка значений.
Форма.СписокПереносов.Очистить();
Для Каждого КлючИЗначение Из Форма.ПереносыДней Цикл
// С прикладной точки зрения переносится всегда выходной день на рабочий,
// поэтому из двух дат выбираем ту, которой соответствовал выходной день (сейчас соответствует рабочий).
ДатаИсточник = КлючИЗначение.Ключ;
ДатаПриемник = КлючИЗначение.Значение;
ВидДня = Форма.ВидыДней.Получить(ДатаИсточник);
Если ВидДня = ПредопределенноеЗначение("Перечисление.ВидыДнейПроизводственногоКалендаря.Суббота")
Или ВидДня = ПредопределенноеЗначение("Перечисление.ВидыДнейПроизводственногоКалендаря.Воскресенье") Тогда
// Обменяем даты местами, чтобы отобразить сведения о переносе как "А на Б", а не "Б на А".
ДатаПереноса = ДатаПриемник;
ДатаПриемник = ДатаИсточник;
ДатаИсточник = ДатаПереноса;
КонецЕсли;
Если Форма.СписокПереносов.НайтиПоЗначению(ДатаИсточник) <> Неопределено
Или Форма.СписокПереносов.НайтиПоЗначению(ДатаПриемник) <> Неопределено Тогда
// Перенос уже добавлен, пропускаем.
Продолжить;
КонецЕсли;
Форма.СписокПереносов.Добавить(ДатаИсточник, ПредставлениеПереноса(ДатаИсточник, ДатаПриемник));
КонецЦикла;
Форма.СписокПереносов.СортироватьПоЗначению();
УстановитьВидимостьСпискаПереносов(Форма);
КонецПроцедуры
&НаКлиентеНаСервереБезКонтекста
Функция ПредставлениеПереноса(ДатаИсточник, ДатаПриемник)
Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'с %1 %2 на %3 %4'"),
ДеньНеделиВФормулировкеСКакогоПереносим(ДатаИсточник),
Формат(ДатаИсточник, "ДФ='д ММММ'"), // АПК:1367 Хорошего решения нет, считаем сохранение порядка дата + месяц приемлемым решением в этом месте
ДеньНеделиВФормулировкеНаКакойПереносим(ДатаПриемник),
Формат(ДатаПриемник, "ДФ='д ММММ'")); // АПК:1367
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Функция ДеньНеделиВФормулировкеСКакогоПереносим(Дата)
Соответствие = Новый Соответствие;
Соответствие.Вставить(1, НСтр("ru = 'понедельника'"));
Соответствие.Вставить(2, НСтр("ru = 'вторника'"));
Соответствие.Вставить(3, НСтр("ru = 'среды'"));
Соответствие.Вставить(4, НСтр("ru = 'четверга'"));
Соответствие.Вставить(5, НСтр("ru = 'пятницы'"));
Соответствие.Вставить(6, НСтр("ru = 'субботы'"));
Соответствие.Вставить(7, НСтр("ru = 'воскресенья'"));
Представление = Соответствие[ДеньНедели(Дата)];
Если Представление = Неопределено Тогда
Возврат Формат(Дата, "ДФ='дддд'"); // АПК:1367 В данном случае отображение дня недели будет корректным с учетом локализации
КонецЕсли;
Возврат Представление;
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Функция ДеньНеделиВФормулировкеНаКакойПереносим(Дата)
Соответствие = Новый Соответствие;
Соответствие.Вставить(1, НСтр("ru = 'понедельник'"));
Соответствие.Вставить(2, НСтр("ru = 'вторник'"));
Соответствие.Вставить(3, НСтр("ru = 'среду'"));
Соответствие.Вставить(4, НСтр("ru = 'четверг'"));
Соответствие.Вставить(5, НСтр("ru = 'пятницу'"));
Соответствие.Вставить(6, НСтр("ru = 'субботу'"));
Соответствие.Вставить(7, НСтр("ru = 'воскресенье'"));
Представление = Соответствие[ДеньНедели(Дата)];
Если Представление = Неопределено Тогда
Возврат Формат(Дата, "ДФ='дддд'"); // АПК:1367 В данном случае отображение дня недели будет корректным с учетом локализации
КонецЕсли;
Возврат Представление;
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Процедура УстановитьВидимостьСпискаПереносов(Форма)
ВидимостьСписка = Форма.СписокПереносов.Количество() > 0;
ОбщегоНазначенияКлиентСервер.УстановитьСвойствоЭлементаФормы(Форма.Элементы, "СписокПереносов", "Видимость", ВидимостьСписка);
КонецПроцедуры
&НаСервере
Процедура УстановитьДоступностьУчитыватьПраздники()
Элементы.УчитыватьПраздничныеДни.Доступность = ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь);
Если Не Элементы.УчитыватьПраздничныеДни.Доступность Тогда
Объект.УчитыватьПраздничныеДни = Ложь;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПрочитатьНерабочиеДаты(ТекущийОбъект = Неопределено)
Если ТекущийОбъект = Неопределено Тогда
ТекущийОбъект = Объект;
КонецЕсли;
Даты = Новый Массив;
ПроизводственныйКалендарь = ?(ЗначениеЗаполнено(Объект.БазовыйКалендарь),
ТекущийОбъект.БазовыйКалендарь, ТекущийОбъект.Ссылка);
Если ЗначениеЗаполнено(ПроизводственныйКалендарь) Тогда
Периоды = РегистрыСведений.КалендарныеГрафики.ПериодыНерабочихДней(
ПроизводственныйКалендарь, Новый СтандартныйПериод(Дата(НомерТекущегоГода, 1, 1), Дата(НомерТекущегоГода, 12, 31)), Объект.Код);
Пояснение = "";
Для Каждого ОписаниеПериода Из Периоды Цикл
ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Даты, ОписаниеПериода.Даты);
Пояснение = Пояснение + ?(Не ПустаяСтрока(Пояснение), Символы.ПС, "") + ОписаниеПериода.Представление;
КонецЦикла;
Элементы.НерабочиеПериодыТекст.Заголовок = Пояснение;
КонецЕсли;
НерабочиеДаты = Новый ФиксированныйМассив(Даты);
Элементы.НерабочиеПериодыГруппа.Видимость = НерабочиеДаты.Количество() > 0;
КонецПроцедуры
&НаСервере
Процедура НастроитьПолеКалендаря()
Если НомерТекущегоГода = 0 Тогда
НомерТекущегоГода = ?(ЗначениеЗаполнено(Объект.Год), Объект.Год, Год(ТекущаяДатаСеанса()));
КонецЕсли;
Объект.Год = НомерТекущегоГода;
НомерПредыдущегоГода = НомерТекущегоГода;
Элементы.Календарь.НачалоПериодаОтображения = Дата(НомерТекущегоГода, 1, 1);
Элементы.Календарь.КонецПериодаОтображения = Дата(НомерТекущегоГода, 12, 31);
Объект.ДатаНачала = Дата(НомерТекущегоГода, 1, 1);
Объект.ДатаОкончания = Дата(НомерТекущегоГода, 12, 31);
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьСписокВидовДня()
Для Каждого МетаданныеВидаДней Из Метаданные.Перечисления.ВидыДнейПроизводственногоКалендаря.ЗначенияПеречисления Цикл
СписокВидовДня.Добавить(Перечисления.ВидыДнейПроизводственногоКалендаря[МетаданныеВидаДней.Имя], МетаданныеВидаДней.Синоним);
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьЦветаВидовДней ()
ЦветаОформления = Новый Соответствие;
ЦветаОформления.Вставить(Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий, WebЦвета.Черный);
ЦветаОформления.Вставить(Перечисления.ВидыДнейПроизводственногоКалендаря.Суббота, WebЦвета.ТемноКрасный);
ЦветаОформления.Вставить(Перечисления.ВидыДнейПроизводственногоКалендаря.Воскресенье, WebЦвета.Красный);
ЦветаОформления.Вставить(Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный, WebЦвета.ТемноСиний);
ЦветаОформления.Вставить(Перечисления.ВидыДнейПроизводственногоКалендаря.Праздник, WebЦвета.Фиолетовый);
ЦветаВидовДней = Новый ФиксированноеСоответствие(ЦветаОформления);
КонецПроцедуры
&НаСервере
Процедура СформироватьШаблонРасписания ()
Если Объект.РабочиеДни.Количество() > 0 Тогда
Возврат;
КонецЕсли;
ШаблонЗаполнения = Новый Массив;
ШаблонЗаполнения.Добавить(НСтр("ru = 'Понедельник'"));
ШаблонЗаполнения.Добавить(НСтр("ru = 'Вторник'"));
ШаблонЗаполнения.Добавить(НСтр("ru = 'Среда'"));
ШаблонЗаполнения.Добавить(НСтр("ru = 'Четверг'"));
ШаблонЗаполнения.Добавить(НСтр("ru = 'Пятница'"));
ШаблонЗаполнения.Добавить(НСтр("ru = 'Суббота'"));
ШаблонЗаполнения.Добавить(НСтр("ru = 'Воскресенье'"));
Для Каждого СтрДень Из ШаблонЗаполнения Цикл
ДобСтрДень = Объект.РабочиеДни.Добавить();
ДобСтрДень.ДеньВключенВГрафик = (СтрДень <> "Суббота" И СтрДень <> "Воскресенье");
ДобСтрДень.ДеньНедели = СтрДень;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура РабочиеДниПредставлениеРасписанияНажатие(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КонецПроцедуры
&НаСервере
Процедура УстановитьУсловноеОформление()
УсловноеОформление.Элементы.Очистить();
Элемент = УсловноеОформление.Элементы.Добавить();
ПолеЭлемента = Элемент.Поля.Элементы.Добавить();
ПолеЭлемента.Поле = Новый ПолеКомпоновкиДанных(Элементы.РабочиеДниПредставлениеРасписания.Имя);
ОтборЭлемента = Элемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборЭлемента.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.РабочиеДни.ПредставлениеРасписания");
ОтборЭлемента.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
Элемент.Оформление.УстановитьЗначениеПараметра("Текст", НСтр("ru = 'Заполнить расписание'"));
КонецПроцедуры
&НаКлиенте
Процедура РабочиеДниВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
СтрокаШаблона = Объект.РабочиеДни.НайтиПоИдентификатору(ВыбраннаяСтрока);
Если СтрокаШаблона <> Неопределено Тогда
НачатьЗаполнениеРасписанияДня(СтрокаШаблона.НомерСтроки, ВыбраннаяСтрока);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура НачатьЗаполнениеРасписанияДня(НомерДня, ИдентификаторСтрокиШаблона = Неопределено)
КонтекстВыбора = Новый Структура("НомерДня, ИдентификаторСтрокиШаблона", НомерДня, ИдентификаторСтрокиШаблона);
//ПереходящиеСмены = Объект.СпособЗаполнения = ПредопределенноеЗначение(
// "Перечисление.СпособыЗаполненияГрафикаРаботы.ПоЦикламПроизвольнойДлины");
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("РасписаниеРаботы", РасписаниеРаботы(КонтекстВыбора.НомерДня));
//ПараметрыФормы.Вставить("ПереходящиеСмены", ПереходящиеСмены);
ПараметрыФормы.Вставить("ТолькоПросмотр", ТолькоПросмотр);
ОбработчикЗакрытия = Новый ОписаниеОповещения("ЗавершитьЗаполнениеРасписанияДня", ЭтотОбъект, КонтекстВыбора);
ОткрытьФорму("Справочник.ГрафикРаботы.Форма.РасписаниеРаботы", ПараметрыФормы, ЭтотОбъект, , , , ОбработчикЗакрытия);
КонецПроцедуры
// Не было
&НаКлиенте
Функция ПолучитьРасписаниеРаботыДня(НомерДня)
РасписаниеДня = Новый Массив;
Для Каждого СтрокаРасписания Из Объект.РасписаниеРаботы Цикл
Если СтрокаРасписания.НомерДня = НомерДня Тогда
РасписаниеДня.Добавить(Новый Структура("ВремяНачала, ВремяОкончания", СтрокаРасписания.ВремяНачала, СтрокаРасписания.ВремяОкончания));
КонецЕсли;
КонецЦикла;
Возврат РасписаниеДня;
КонецФункции
&НаКлиенте
Функция РасписаниеРаботы(НомерДня)
РасписаниеДня = Новый Массив;
Для Каждого СтрокаРасписания Из Объект.РасписаниеРаботы Цикл
Если СтрокаРасписания.НомерДня = НомерДня Тогда
РасписаниеДня.Добавить(Новый Структура("ВремяНачала, ВремяОкончания", СтрокаРасписания.ВремяНачала, СтрокаРасписания.ВремяОкончания));
КонецЕсли;
КонецЦикла;
Возврат РасписаниеДня;
КонецФункции
&НаКлиенте
Процедура ЗавершитьЗаполнениеРасписанияДня(ВыбранноеЗначение, КонтекстВыбора) Экспорт
Если ВыбранноеЗначение = Неопределено Или ТолькоПросмотр Тогда
Возврат;
КонецЕсли;
// Удаляем ранее заполненное расписания для этого дня.
СтрокиДня = Новый Массив;
Для Каждого СтрокаРасписания Из Объект.РасписаниеРаботы Цикл
Если СтрокаРасписания.НомерДня = КонтекстВыбора.НомерДня Тогда
СтрокиДня.Добавить(СтрокаРасписания.ПолучитьИдентификатор());
КонецЕсли;
КонецЦикла;
Для Каждого ИдентификаторСтроки Из СтрокиДня Цикл
Объект.РасписаниеРаботы.Удалить(Объект.РасписаниеРаботы.НайтиПоИдентификатору(ИдентификаторСтроки));
КонецЦикла;
// Заполняем расписание работы на день.
Для Каждого ОписаниеИнтервала Из ВыбранноеЗначение.РасписаниеРаботы Цикл
НоваяСтрока = Объект.РасписаниеРаботы.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, ОписаниеИнтервала);
НоваяСтрока.НомерДня = КонтекстВыбора.НомерДня;
КонецЦикла;
//УстановитьСнятьПризнакСоответствияРезультатовШаблону(ЭтотОбъект, Ложь);
//УстановитьСнятьМодифицированностьШаблона(ЭтотОбъект, Истина);
Если КонтекстВыбора.ИдентификаторСтрокиШаблона <> Неопределено Тогда
СтрокаШаблона = Объект.РабочиеДни.НайтиПоИдентификатору(КонтекстВыбора.ИдентификаторСтрокиШаблона);
Если СтрокаШаблона <> Неопределено Тогда
СтрокаШаблона.ДеньВключенВГрафик = (ВыбранноеЗначение.РасписаниеРаботы.Количество() > 0);
СтрокаШаблона.ПредставлениеРасписания = ПредставлениеРасписанияДня(КонтекстВыбора.НомерДня);
КонецЕсли;
КонецЕсли;
//ЗаполнитьПоШаблонуНаСервере();
КонецПроцедуры
&НаКлиенте
Функция ПредставлениеРасписанияДня(НомерДня)
ПредставлениеИнтервалов = "";
Секунд = 0;
Для Каждого СтрокаРасписания Из Объект.РасписаниеРаботы Цикл
Если СтрокаРасписания.НомерДня <> НомерДня Тогда
Продолжить;
КонецЕсли;
ПредставлениеИнтервала = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
"%1-%2, ",
ПредставлениеВремениСуток(СтрокаРасписания.ВремяНачала, ДвенадцатиЧасовойФорматВремени),
ПредставлениеВремениСуток(СтрокаРасписания.ВремяОкончания, ДвенадцатиЧасовойФорматВремени)
);
ПредставлениеИнтервалов = ПредставлениеИнтервалов + ПредставлениеИнтервала;
Если СтрокаРасписания.ВремяНачала = СтрокаРасписания.ВремяОкончания И ЗначениеЗаполнено(СтрокаРасписания.ВремяНачала) Тогда
СекундИнтервала = 86400;
ИначеЕсли СтрокаРасписания.ВремяНачала < СтрокаРасписания.ВремяОкончания Тогда
СекундИнтервала = СтрокаРасписания.ВремяОкончания - СтрокаРасписания.ВремяНачала;
ИначеЕсли Не ЗначениеЗаполнено(СтрокаРасписания.ВремяОкончания) Тогда
СекундИнтервала = КонецДня(СтрокаРасписания.ВремяНачала) - СтрокаРасписания.ВремяНачала + 1;
Иначе
ОсновнаяЧасть = КонецДня(СтрокаРасписания.ВремяНачала) - СтрокаРасписания.ВремяНачала + 1;
ПереходящаяЧасть = СтрокаРасписания.ВремяОкончания - НачалоДня(СтрокаРасписания.ВремяОкончания);
СекундИнтервала = ОсновнаяЧасть + ПереходящаяЧасть;
КонецЕсли;
Секунд = Секунд + СекундИнтервала;
КонецЦикла;
СтроковыеФункцииКлиентСервер.УдалитьПоследнийСимволВСтроке(ПредставлениеИнтервалов, 2);
Если Секунд = 0 Тогда
Возврат НСтр("ru = 'Заполнить расписание'");
КонецЕсли;
Часов = Окр(Секунд / 3600, 1);
Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '%1 ч. (%2)'"), Часов, ПредставлениеИнтервалов);
КонецФункции
&НаКлиентеНаСервереБезКонтекста
Функция ПредставлениеВремениСуток(Знач ВремяСуток, ДвенадцатиЧасовойФорматВремени)
Если Не ЗначениеЗаполнено(ВремяСуток) Тогда
ВремяСуток = Дата(1980, 1, 1);
КонецЕсли;
ФорматВремени = ?(ДвенадцатиЧасовойФорматВремени,
НСтр("ru = 'ДФ=''чч:мм вв'''"), НСтр("ru = 'ДФ=ЧЧ:мм; ДП='"));
Возврат Формат(ВремяСуток, ФорматВремени);
КонецФункции
&НаСервере
Процедура ЗаполнитьСписокЗначенийПроизводственныйКалендарьНаСервере()
ТаблицаПроизводственныхКалендарей = Справочники.ГрафикРаботы.ПолучитьТаблицуПроизводственныхКалендарей();
Для Каждого Стр Из ТаблицаПроизводственныхКалендарей Цикл
Элементы.ПроизводственныйКалендарь.СписокВыбора.Добавить(Стр.code, Стр.Description);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ПроизводственныйКалендарьПриИзменении(Элемент)
ЗаполнитьДаннымиПоУмолчанию();
ПроизводственныйКалендарьПриИзмененииНаСервере();
Элементы.Календарь.Обновить();
КонецПроцедуры
&НаСервере
Процедура ПроизводственныйКалендарьПриИзмененииНаСервере()
УстановитьДоступностьУчитыватьНерабочиеПериоды();
УстановитьДоступностьУчитыватьПраздники();
КонецПроцедуры
&НаКлиенте
Процедура ИзменитьДень(Команда)
ВыделенныеДаты = Элементы.Календарь.ВыделенныеДаты;
Если ВыделенныеДаты.Количество() > 0 И Год(ВыделенныеДаты[0]) = НомерТекущегоГода Тогда
Оповещение = Новый ОписаниеОповещения("ИзменитьДеньЗавершение", ЭтотОбъект, ВыделенныеДаты);
ПоказатьВыборИзСписка(Оповещение, СписокВидовДня, , СписокВидовДня.НайтиПоЗначению(ВидыДней.Получить(ВыделенныеДаты[0])));
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ИзменитьДеньЗавершение(ВыбранныйЭлемент, ВыделенныеДаты) Экспорт
Если ВыбранныйЭлемент <> Неопределено Тогда
ИзменитьВидыДней(ВыделенныеДаты, ВыбранныйЭлемент.Значение);
Элементы.Календарь.Обновить();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ИзменитьВидыДней(ДатыДней, ВидДня)
// Устанавливает дням по всем датам массива определенный вид.
ВидыДнейСоответствие = Новый Соответствие(ВидыДней);
Для Каждого ВыбраннаяДата Из ДатыДней Цикл
ВидыДнейСоответствие.Вставить(ВыбраннаяДата, ВидДня);
КонецЦикла;
ВидыДней = Новый ФиксированноеСоответствие(ВидыДнейСоответствие);
КонецПроцедуры
&НаКлиенте
Процедура КалендарьПриВыводеПериода(Элемент, ОформлениеПериода)
Для Каждого СтрокаОформленияПериода Из ОформлениеПериода.Даты Цикл
ТекущаяДата = НачалоДня(СтрокаОформленияПериода.Дата);
ВидДня = ВидыДней.Получить(ТекущаяДата);
ЦветОформленияДня = ЦветаВидовДней.Получить(ВидДня);
Если ЦветОформленияДня = Неопределено Тогда
ЦветОформленияДня = WebЦвета.Черный;
КонецЕсли;
СтрокаОформленияПериода.ЦветТекста = ЦветОформленияДня;
Если ДниГрафика.Получить(ТекущаяДата) <> Неопределено Тогда
СтрокаОформленияПериода.ЦветФона = WebЦвета.Роса;
Иначе
СтрокаОформленияПериода.ЦветФона = WebЦвета.Белый;
КонецЕсли;
Если НерабочиеДаты.Найти(ТекущаяДата) <> Неопределено Тогда
СтрокаОформленияПериода.ЦветФона = WebЦвета.Фиолетовый;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ПриЗаписиНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
НомерГода = НомерТекущегоГода;
Если ПараметрыЗаписи.Свойство("НомерГода") И ЗначениеЗаполнено(ПараметрыЗаписи.НомерГода) Тогда
НомерГода = ПараметрыЗаписи.НомерГода;
КонецЕсли;
ЗаписатьДанныеПроизводственногоКалендаряНаСервере(НомерГода, ТекущийОбъект);
РегистрыСведений.КалендарныеГрафики.ЗаписатьДанныеГрафикаВРегистр(ТекущийОбъект.Ссылка, ДниГрафика,
Дата(НомерГода, 1, 1), Дата(НомерГода, 12, 31), Истина);
КонецПроцедуры
&НаСервере
Процедура ЗаписатьДанныеПроизводственногоКалендаряНаСервере(Знач НомерГода, Знач ТекущийОбъект = Неопределено)
// Запись данных производственного календаря за указанный год.
ДанныеПроизводственногоКалендаря = Новый ТаблицаЗначений;
ДанныеПроизводственногоКалендаря.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
ДанныеПроизводственногоКалендаря.Колонки.Добавить("ВидДня", Новый ОписаниеТипов("ПеречислениеСсылка.ВидыДнейПроизводственногоКалендаря"));
ДанныеПроизводственногоКалендаря.Колонки.Добавить("ДатаПереноса", Новый ОписаниеТипов("Дата"));
Для Каждого КлючИЗначение Из ВидыДней Цикл
СтрокаТаблицы = ДанныеПроизводственногоКалендаря.Добавить();
СтрокаТаблицы.Дата = КлючИЗначение.Ключ;
СтрокаТаблицы.ВидДня = КлючИЗначение.Значение;
// Если день перенесен с другой даты, вписываем дату переноса.
ДатаПереноса = ПереносыДней.Получить(СтрокаТаблицы.Дата);
Если ДатаПереноса <> Неопределено И ДатаПереноса <> СтрокаТаблицы.Дата Тогда
СтрокаТаблицы.ДатаПереноса = ДатаПереноса;
КонецЕсли;
КонецЦикла;
Справочники.ГрафикРаботы.ЗаписатьДанныеПроизводственногоКалендаря(ТекущийОбъект.Ссылка, НомерГода, ДанныеПроизводственногоКалендаря);
КонецПроцедуры
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
НомерТекущегоГода = ТекущийОбъект.Год;
ЗаполнитьДаннымиТекущегоГода();
КонецПроцедуры
&НаКлиенте
Процедура НомерТекущегоГодаПриИзменении(Элемент)
ЗаписыватьДанныеГрафика = Ложь;
Если Модифицированность Тогда
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Записать измененные данные за %1 год?'"),
Формат(НомерПредыдущегоГода, "ЧГ=0")
);
Оповещение = Новый ОписаниеОповещения("НомерТекущегоГодаПриИзмененииЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение, ТекстСообщения, РежимДиалогаВопрос.ДаНет);
Возврат;
КонецЕсли;
ПроверитьИОбработатьИзменениеГода(ЗаписыватьДанныеГрафика);
КонецПроцедуры
&НаСервере
Процедура ОбработатьИзменениеГода(ЗаписыватьДанныеГрафика)
Если ЗаписыватьДанныеГрафика Тогда
Если Объект.Ссылка.Пустая() Тогда
Записать(Новый Структура("НомерГода", НомерТекущегоГода));
Иначе
ЗаписатьДанныеПроизводственногоКалендаряНаСервере(НомерТекущегоГода, РеквизитФормыВЗначение("Объект"));
КонецЕсли;
КонецЕсли;
// 1. Сначала подгружаем дефолты из макета, если в регистре данных нет
Если ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
// Убедитесь, что передается строковый код календаря
КодКалендаря = ?(ТипЗнч(Объект.ПроизводственныйКалендарь) = Тип("Строка"),
Объект.ПроизводственныйКалендарь, Объект.ПроизводственныйКалендарь.Код);
ДанныеПоУмолчанию = Справочники.ГрафикРаботы.РезультатЗаполненияПроизводственногоКалендаряПоУмолчанию(
КодКалендаря, НомерТекущегоГода, КодКалендаря
);
ПреобразоватьДанныеПроизводственногоКалендаря(ДанныеПоУмолчанию);
КонецЕсли;
// 2. Затем считываем данные текущего года и формируем ДниГрафика
ЗаполнитьДаннымиТекущегоГода();
// 3. Формируем расписание фона по шаблону
ЗаполнитьПоШаблонуНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура НомерТекущегоГодаПриИзмененииЗавершение(Ответ, ДополнительныеПараметры) Экспорт
ПроверитьИОбработатьИзменениеГода(Ответ = КодВозвратаДиалога.Да);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьИОбработатьИзменениеГода(ЗаписыватьДанныеГрафика)
Если ГрафикНаГодУжеСуществует(НомерТекущегоГода, Объект.Ссылка) Тогда
ТекстПредупреждения = СтрШаблон("На %1 год уже создан график работы!", Формат(НомерТекущегоГода, "ЧГ=0"));
ПоказатьОповещениеПользователя(
"Внимание",
,
ТекстПредупреждения,
);
КонецЕсли;
ОбработатьИзменениеГода(ЗаписыватьДанныеГрафика);
Модифицированность = Ложь;
Элементы.Календарь.Обновить();
КонецПроцедуры
//&НаКлиенте
//Процедура ПеренестиДень(Команда)
// ВыделенныеДаты = Элементы.Календарь.ВыделенныеДаты;
//
// Если ВыделенныеДаты.Количество() = 0 Или Год(ВыделенныеДаты[0]) <> НомерТекущегоГода Тогда
// Возврат;
// КонецЕсли;
//
// ДатаПереноса = ВыделенныеДаты[0];
// ВидДня = ВидыДней.Получить(ДатаПереноса);
//
// ПараметрыВыбораДаты = Новый Структура(
// "НачальноеЗначение,
// |НачалоПериодаОтображения,
// |КонецПериодаОтображения,
// |Заголовок,
// |ПоясняющийТекст");
//
// ПараметрыВыбораДаты.НачальноеЗначение = ДатаПереноса;
// ПараметрыВыбораДаты.НачалоПериодаОтображения = НачалоГода(Календарь);
// ПараметрыВыбораДаты.КонецПериодаОтображения = КонецГода(Календарь);
// ПараметрыВыбораДаты.Заголовок = НСтр("ru = 'Выбор даты переноса'");
//
// ПараметрыВыбораДаты.ПоясняющийТекст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
// НСтр("ru = 'Выберите дату, на которую будет осуществлен перенос дня %1 (%2)'"),
// Формат(ДатаПереноса, "ДФ='д ММММ'"), // АПК:1367 Хорошего решения нет, считаем сохранение порядка дата + месяц приемлемым решением в этом месте
// ВидДня);
//
// ОткрытьФорму("Справочник.ГрафикРаботы.Форма.ВыборДаты", ПараметрыВыбораДаты, ЭтотОбъект);
//КонецПроцедуры
// Проверить
&НаКлиенте
Процедура ПеренестиДень(Команда)
ВыделенныеДаты = Элементы.Календарь.ВыделенныеДаты;
Если ВыделенныеДаты.Количество() = 0 Или Год(ВыделенныеДаты[0]) <> НомерТекущегоГода Тогда
Возврат;
КонецЕсли;
ДатаПереноса = ВыделенныеДаты[0];
ПараметрыВыбораДаты = Новый Структура;
ПараметрыВыбораДаты.Вставить("НачальноеЗначение", ДатаПереноса);
ПараметрыВыбораДаты.Вставить("НачалоПериодаОтображения", НачалоГода(ДатаПереноса));
ПараметрыВыбораДаты.Вставить("КонецПериодаОтображения", КонецГода(ДатаПереноса));
ПараметрыВыбораДаты.Вставить("Заголовок", НСтр("ru = 'Выбор даты переноса'"));
ПараметрыВыбораДаты.Вставить("ПоясняющийТекст", СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Выберите дату, на которую переносится %1'"),
Формат(ДатаПереноса, "ДФ='д ММММ'")
));
Оповещение = Новый ОписаниеОповещения("ПеренестиДеньЗавершение", ЭтотОбъект, ДатаПереноса);
ОткрытьФорму("Справочник.ГрафикРаботы.Форма.ВыборДаты", ПараметрыВыбораДаты, ЭтотОбъект, , , , Оповещение);
КонецПроцедуры
// Не было
&НаКлиенте
Процедура ПеренестиДеньЗавершение(ВыбраннаяДата, ДатаПереноса) Экспорт
Если ЗначениеЗаполнено(ВыбраннаяДата) И ВыбраннаяДата <> ДатаПереноса Тогда
ПереносыДнейСоответствие = Новый Соответствие(ПереносыДней);
ПереносыДнейСоответствие.Вставить(ДатаПереноса, ВыбраннаяДата);
ПереносыДней = Новый ФиксированноеСоответствие(ПереносыДнейСоответствие);
ЗаполнитьПредставлениеПереносовНаКлиенте();
Элементы.Календарь.Обновить();
КонецЕсли;
КонецПроцедуры
// Не было
&НаКлиенте
Процедура ЗаполнитьПредставлениеПереносовНаКлиенте()
СписокПереносов.Очистить();
Для Каждого КлючИЗначение Из ПереносыДней Цикл
ДатаИсточник = КлючИЗначение.Ключ;
ДатаПриемник = КлючИЗначение.Значение;
ВидДня = ВидыДней.Получить(ДатаИсточник);
Если ВидДня = ПредопределенноеЗначение("Перечисление.ВидыДнейПроизводственногоКалендаря.Суббота")
Или ВидДня = ПредопределенноеЗначение("Перечисление.ВидыДнейПроизводственногоКалендаря.Воскресенье") Тогда
ДатаПереноса = ДатаПриемник;
ДатаПриемник = ДатаИсточник;
ДатаИсточник = ДатаПереноса;
КонецЕсли;
Если СписокПереносов.НайтиПоЗначению(ДатаИсточник) <> Неопределено
Или СписокПереносов.НайтиПоЗначению(ДатаПриемник) <> Неопределено Тогда
Продолжить;
КонецЕсли;
СписокПереносов.Добавить(ДатаИсточник, ПредставлениеПереноса(ДатаИсточник, ДатаПриемник));
КонецЦикла;
СписокПереносов.СортироватьПоЗначению();
Элементы.СписокПереносов.Видимость = (СписокПереносов.Количество() > 0);
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ВРег(ИсточникВыбора.ИмяФормы) = ВРег("Справочник.ГрафикРаботы.Форма.ВыборДаты") Тогда
Если ВыбранноеЗначение = Неопределено Тогда
Возврат;
КонецЕсли;
ВыделенныеДаты = Элементы.Календарь.ВыделенныеДаты;
Если ВыделенныеДаты.Количество() = 0 Или Год(ВыделенныеДаты[0]) <> НомерТекущегоГода Тогда
Возврат;
КонецЕсли;
ДатаПереноса = ВыделенныеДаты[0];
ПеренестиВидДня(ДатаПереноса, ВыбранноеЗначение);
Элементы.Календарь.Обновить();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПеренестиВидДня(ДатаПереноса, ДатаНазначения)
// Нужно обменять местами два дня в календаре
// - обменяться видами дня
// - запомнить даты переноса
// * если переносимый день уже имеет дату переноса (уже был откуда-то перенесен),
// используем имеющуюся дату переноса
// * если даты совпадают (день возвращен на "свое место") - удаляем такую запись.
ВидыДнейСоответствие = Новый Соответствие(ВидыДней);
ВидыДнейСоответствие.Вставить(ДатаНазначения, ВидыДней.Получить(ДатаПереноса));
ВидыДнейСоответствие.Вставить(ДатаПереноса, ВидыДней.Получить(ДатаНазначения));
ПереносыДнейСоответствие = Новый Соответствие(ПереносыДней);
ВписатьДатуПереноса(ПереносыДнейСоответствие, ДатаПереноса, ДатаНазначения);
ВписатьДатуПереноса(ПереносыДнейСоответствие, ДатаНазначения, ДатаПереноса);
ВидыДней = Новый ФиксированноеСоответствие(ВидыДнейСоответствие);
ПереносыДней = Новый ФиксированноеСоответствие(ПереносыДнейСоответствие);
ЗаполнитьПредставлениеПереносов(ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура ВписатьДатуПереноса(ПереносыДнейСоответствие, ДатаПереноса, ДатаНазначения)
// Заполняет в соответствии с датами переносов дней корректную дату переноса.
ИсточникДняДатыНазначения = ПереносыДней.Получить(ДатаНазначения);
Если ИсточникДняДатыНазначения = Неопределено Тогда
ИсточникДняДатыНазначения = ДатаНазначения;
КонецЕсли;
Если ДатаПереноса = ИсточникДняДатыНазначения Тогда
ПереносыДнейСоответствие.Удалить(ДатаПереноса);
Иначе
ПереносыДнейСоответствие.Вставить(ДатаПереноса, ИсточникДняДатыНазначения);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура УчитыватьПраздничныеДниПриИзменении(Элемент)
//ЗаполнитьПоШаблонуНаСервере();
//
//Элементы.Календарь.Обновить();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоШаблонуНаСервере(СохранятьРучноеРедактирование = Ложь)
ПараметрыЗаполнения = РегистрыСведений.КалендарныеГрафики.ПараметрыЗаполненияГрафика();
ПараметрыЗаполнения.КодПроизводственногоКалендаря = Объект.Код;
//ПараметрыЗаполнения.СпособЗаполнения = Объект.СпособЗаполнения;
ПараметрыЗаполнения.ШаблонЗаполнения = Объект.РабочиеДни;
ПараметрыЗаполнения.ПроизводственныйКалендарь = Объект.Ссылка;
ПараметрыЗаполнения.УчитыватьПраздники = Объект.УчитыватьПраздничныеДни;
ПараметрыЗаполнения.УчитыватьНерабочиеПериоды = Объект.УчитыватьНерабочиеПериоды;
//ПараметрыЗаполнения.ДатаОтсчета = Объект.ДатаОтсчета;
ДниВключенныеВГрафик = РегистрыСведений.КалендарныеГрафики.ДниВключенныеВГрафик(
Объект.ДатаНачала, Объект.ДатаОкончания, ПараметрыЗаполнения);
//Если РучноеРедактирование Тогда
// Если СохранятьРучноеРедактирование Тогда
// // Переносим ручные корректировки.
// Для Каждого КлючИЗначение Из ДниИзмененные Цикл
// ДатаИзменений = КлючИЗначение.Ключ;
// ДеньВключенВГрафик = КлючИЗначение.Значение;
// Если ДеньВключенВГрафик Тогда
// ДниВключенныеВГрафик.Вставить(ДатаИзменений, Истина);
// Иначе
// ДниВключенныеВГрафик.Удалить(ДатаИзменений);
// КонецЕсли;
// КонецЦикла;
// Иначе
// УстановитьСнятьМодифицированностьРезультата(ЭтотОбъект, Истина);
// УстановитьСнятьПризнакРучногоРедактирования(ЭтотОбъект, Ложь);
// КонецЕсли;
//КонецЕсли;
// Переносим результат в исходное соответствие заполнения,
// чтобы не затереть даты, не входящие в интервал заполнения.
ДниГрафикаСоответствие = Новый Соответствие(ДниГрафика);
ДатаДня = Объект.ДатаНачала;
ДатаОкончания = Объект.ДатаОкончания;
Если Не ЗначениеЗаполнено(ДатаОкончания) Тогда
ДатаОкончания = КонецГода(Объект.ДатаНачала);
КонецЕсли;
Пока ДатаДня <= ДатаОкончания Цикл
ДеньВключенВГрафик = ДниВключенныеВГрафик[ДатаДня];
Если ДеньВключенВГрафик = Неопределено Тогда
ДниГрафикаСоответствие.Удалить(ДатаДня);
Иначе
ДниГрафикаСоответствие.Вставить(ДатаДня, ДеньВключенВГрафик);
КонецЕсли;
ДатаДня = ДатаДня + 86400;
КонецЦикла;
ДниГрафика = Новый ФиксированноеСоответствие(ДниГрафикаСоответствие);
//Если Не РезультатЗаполненПоШаблону Тогда
// УстановитьСнятьМодифицированностьРезультата(ЭтотОбъект, Истина);
// УстановитьСнятьПризнакСоответствияРезультатовШаблону(ЭтотОбъект, Истина);
//КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура РабочиеДниДеньВключенВГрафикПриИзменении(Элемент)
//ЗаполнитьПоШаблонуНаСервере();
//Элементы.Календарь.Обновить();
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьПоШаблону(Команда)
Если ПроверитьЗаполнение() Тогда
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
Оповещение=Новый ОписаниеОповещения("ПослеОтветаНаВопрос", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Данные не записанны. Записать?", РежимДиалогаВопрос.ДаНет);
Иначе
ЗаполнитьПоШаблонуНаСервере();
Элементы.Календарь.Обновить();
КонецЕсли;
КонецЕсли;
//ЗаполнитьПоШаблонуНаСервере();
//Элементы.Календарь.Обновить();
КонецПроцедуры
&НаКлиенте
Процедура ПослеОтветаНаВопрос(Результат, ДопПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
Записать();
ЗаполнитьПоШаблонуНаСервере();
Элементы.Календарь.Обновить();
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ГрафикНаГодУжеСуществует(Знач ВыбранныйГод, Знач ТекущаяСсылка)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Первые 1
| ГрафикРаботы.Ссылка КАК Ссылка
|ИЗ
| Справочник.ГрафикРаботы КАК ГрафикРаботы
|ГДЕ
| ГрафикРаботы.Год = &Год
| И НЕ ГрафикРаботы.ПометкаУдаления
| И ГрафикРаботы.Ссылка <> &ТекущаяСсылка";
Запрос.УстановитьПараметр("Год", ВыбранныйГод);
Запрос.УстановитьПараметр("ТекущаяСсылка", ТекущаяСсылка);
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции
Модуль Менеджера
Функция ПолучитьТаблицуПроизводственныхКалендарей() Экспорт
ТекстовыйДокумент = ПолучитьМакет("ПроизводственныеКалендари");
ТаблицаКалендарей = ПрочитатьXMLВТаблицу(ТекстовыйДокумент.ПолучитьТекст()).Данные;
Возврат ТаблицаКалендарей;
КонецФункции
Функция ПрочитатьXMLВТаблицу(Знач XML)
Если ТипЗнч(XML) <> Тип("ЧтениеXML") Тогда
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(XML);
Иначе
Чтение = XML;
КонецЕсли;
// Прочитаем первый узел и проверим его.
Если Не Чтение.Прочитать() Тогда
ВызватьИсключение НСтр("ru = 'Пустой XML'");
ИначеЕсли Чтение.Имя <> "Items" Тогда
ВызватьИсключение НСтр("ru = 'Ошибка в структуре XML'");
КонецЕсли;
// Получим описание таблицы и создадим ее.
ИмяТаблицы = Чтение.ПолучитьАтрибут("Description");
ИменаКолонок = СтрЗаменить(Чтение.ПолучитьАтрибут("Columns"), ",", Символы.ПС);
Колонок = СтрЧислоСтрок(ИменаКолонок);
ТаблицаЗначений = Новый ТаблицаЗначений;
Для Сч = 1 По Колонок Цикл
ТаблицаЗначений.Колонки.Добавить(СтрПолучитьСтроку(ИменаКолонок, Сч), Новый ОписаниеТипов("Строка"));
КонецЦикла;
// Заполним значения в таблице.
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.КонецЭлемента И Чтение.Имя = "Items" Тогда
Прервать;
ИначеЕсли Чтение.ТипУзла <> ТипУзлаXML.НачалоЭлемента Тогда
Продолжить;
ИначеЕсли Чтение.Имя <> "Item" Тогда
ВызватьИсключение НСтр("ru = 'Ошибка в структуре XML'");
КонецЕсли;
НовСтр = ТаблицаЗначений.Добавить();
Для Сч = 1 По Колонок Цикл
ИмяКолонки = СтрПолучитьСтроку(ИменаКолонок, Сч);
НовСтр[Сч - 1] = Чтение.ПолучитьАтрибут(ИмяКолонки);
КонецЦикла;
КонецЦикла;
// Заполним результат
Результат = Новый Структура;
Результат.Вставить("ИмяТаблицы", ИмяТаблицы);
Результат.Вставить("Данные", ТаблицаЗначений);
Возврат Результат;
КонецФункции
Функция ДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, Знач Годы) Экспорт
Если ТипЗнч(Годы) <> Тип("Массив") Тогда
Годы = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Годы);
КонецЕсли;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ПроизводственныйКалендарь", ПроизводственныйКалендарь);
Запрос.УстановитьПараметр("Годы", Годы);
Запрос.Текст =
"ВЫБРАТЬ
| ДанныеПроизводственногоКалендаря.Год КАК Год,
| ДанныеПроизводственногоКалендаря.Дата КАК Дата,
| ДанныеПроизводственногоКалендаря.ВидДня КАК ВидДня,
| ДанныеПроизводственногоКалендаря.ДатаПереноса КАК ДатаПереноса
|ИЗ
| РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПроизводственногоКалендаря
|ГДЕ
| ДанныеПроизводственногоКалендаря.Год В(&Годы)
| И ДанныеПроизводственногоКалендаря.ПроизводственныйКалендарь = &ПроизводственныйКалендарь
|
|УПОРЯДОЧИТЬ ПО
| ДанныеПроизводственногоКалендаря.Дата";
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Функция РезультатЗаполненияПроизводственногоКалендаряПоУмолчанию(КодКалендаря, НомерГода, Знач КодБазовогоКалендаря = Неопределено) Экспорт
ВидыДней = Новый Соответствие;
ПереносыДней = Новый Соответствие;
// Если есть данные в макете - используем их.
// Сразу получаем данные еще и по базовому календарю, если он задан.
КодыКалендарей = Новый Массив;
КодыКалендарей.Добавить(КодКалендаря);
ЕстьБазовыйКалендарь = Ложь;
Если КодБазовогоКалендаря <> Неопределено Тогда
КодыКалендарей.Добавить(КодБазовогоКалендаря);
ЕстьБазовыйКалендарь = Истина;
КонецЕсли;
// Отбираем данные из макета по обоим календарям.
// Получаем не полный набор, а только праздничные дни и переносы.
ДанныеИзМакета = ДанныеПроизводственныхКалендарейПоУмолчанию(КодыКалендарей, Ложь);
ОтборСтрок = Новый Структура("КодПроизводственногоКалендаря,Год");
ОтборСтрок.Год = НомерГода;
ЕстьДанныеКалендаря = Ложь;
ОтборСтрок.КодПроизводственногоКалендаря = КодКалендаря;
ДанныеКалендаря = ДанныеИзМакета.НайтиСтроки(ОтборСтрок);
Если ДанныеКалендаря.Количество() > 0 Тогда
ЕстьДанныеКалендаря = Истина;
ЗаполнитьВидыДнейДаннымиКалендаря(ДанныеКалендаря, ВидыДней, ПереносыДней);
КонецЕсли;
// Проверяем, есть ли в макете данные базового календаря.
ЕстьДанныеБазовогоКалендаря = Ложь;
Если ЕстьБазовыйКалендарь Тогда
ОтборСтрок.КодПроизводственногоКалендаря = КодБазовогоКалендаря;
ДанныеКалендаря = ДанныеИзМакета.НайтиСтроки(ОтборСтрок);
Если ДанныеКалендаря.Количество() > 0 Тогда
ЕстьДанныеБазовогоКалендаря = Истина;
Если Не ЕстьДанныеКалендаря Тогда
ЗаполнитьВидыДнейДаннымиКалендаря(ДанныеКалендаря, ВидыДней, ПереносыДней);
КонецЕсли;
КонецЕсли;
КонецЕсли;
// Дополняем данными по умолчанию на остальные дни.
ДатаДня = Дата(НомерГода, 1, 1);
Пока ДатаДня <= Дата(НомерГода, 12, 31) Цикл
Если ВидыДней[ДатаДня] = Неопределено Тогда
ВидыДней.Вставить(ДатаДня, ВидДняПоДате(ДатаДня));
КонецЕсли;
ДатаДня = ДатаДня + ДлинаСуток();
КонецЦикла;
// Если данных в макете не было, то обращаемся к заполнению постоянных праздников.
Если Не ЕстьДанныеКалендаря Тогда
Если ЕстьБазовыйКалендарь И ЕстьДанныеБазовогоКалендаря Тогда
// Постоянные праздники базового календаря запрашиваем только если их не было в макете.
КодБазовогоКалендаря = Неопределено;
КонецЕсли;
ЗаполнитьПостоянныеПраздничныеДни(ВидыДней, ПереносыДней, НомерГода, КодКалендаря, КодБазовогоКалендаря);
КонецЕсли;
// Преобразовываем в таблицу.
ДанныеПроизводственногоКалендаря = НовыеДанныеПроизводственныхКалендарей();
Для Каждого КлючИЗначение Из ВидыДней Цикл
НоваяСтрока = ДанныеПроизводственногоКалендаря.Добавить();
НоваяСтрока.Дата = КлючИЗначение.Ключ;
НоваяСтрока.ВидДня = КлючИЗначение.Значение;
ДатаПереноса = ПереносыДней[НоваяСтрока.Дата];
Если ДатаПереноса <> Неопределено Тогда
НоваяСтрока.ДатаПереноса = ДатаПереноса;
КонецЕсли;
НоваяСтрока.Год = НомерГода;
НоваяСтрока.КодПроизводственногоКалендаря = КодКалендаря;
КонецЦикла;
ДанныеПроизводственногоКалендаря.Сортировать("Дата");
Возврат ДанныеПроизводственногоКалендаря;
КонецФункции
Функция НовыеДанныеПроизводственныхКалендарей() Экспорт
ТаблицаДанных = Новый ТаблицаЗначений;
ТаблицаДанных.Колонки.Добавить("КодПроизводственногоКалендаря", Новый ОписаниеТипов("Строка", ,
Новый КвалификаторыСтроки(2)));
ТаблицаДанных.Колонки.Добавить("ВидДня", Новый ОписаниеТипов("ПеречислениеСсылка.ВидыДнейПроизводственногоКалендаря"));
ТаблицаДанных.Колонки.Добавить("Год", Новый ОписаниеТипов("Число"));
ТаблицаДанных.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
ТаблицаДанных.Колонки.Добавить("ДатаПереноса", Новый ОписаниеТипов("Дата"));
Возврат ТаблицаДанных;
КонецФункции
Функция ВидДняПоДате(Дата)
НомерДняНедели = ДеньНедели(Дата);
Если НомерДняНедели <= 5 Тогда
Возврат Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий;
КонецЕсли;
Если НомерДняНедели = 6 Тогда
Возврат Перечисления.ВидыДнейПроизводственногоКалендаря.Суббота;
КонецЕсли;
Если НомерДняНедели = 7 Тогда
Возврат Перечисления.ВидыДнейПроизводственногоКалендаря.Воскресенье;
КонецЕсли;
КонецФункции
Функция ДлинаСуток()
Возврат 24 * 3600;
КонецФункции
Функция ПраздничныеДниПроизводственногоКалендаря(КодПроизводственногоКалендаря, НомерГода)
ПраздничныеДни = Новый ТаблицаЗначений;
ПраздничныеДни.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
ПраздничныеДни.Колонки.Добавить("ПереноситьВыходной", Новый ОписаниеТипов("Булево"));
ПраздничныеДни.Колонки.Добавить("ДобавлятьПредпраздничный", Новый ОписаниеТипов("Булево"));
ПраздничныеДни.Колонки.Добавить("ТолькоНерабочий", Новый ОписаниеТипов("Булево"));
Если Метаданные.Обработки.Найти("ЗаполнениеКалендарныхГрафиков") <> Неопределено Тогда
МодульЗаполнениеКалендарныхГрафиков = ОбщегоНазначения.ОбщийМодуль("Обработки.ЗаполнениеКалендарныхГрафиков");
МодульЗаполнениеКалендарныхГрафиков.ЗаполнитьПраздничныеДни(КодПроизводственногоКалендаря, НомерГода, ПраздничныеДни);
КонецЕсли;
Возврат ПраздничныеДни;
КонецФункции
Процедура ЗаполнитьПостоянныеПраздничныеДни(ВидыДней, ПереносыДней, НомерГода, КодКалендаря, КодБазовогоКалендаря = Неопределено)
// Если нет - заполняем праздники и переносы.
ПраздничныеДни = ПраздничныеДниПроизводственногоКалендаря(КодКалендаря, НомерГода);
// Дополним таблицу также праздниками следующего года,
// т.к. они влияют на заполнение текущего года (31 декабря - предпраздничный, например).
ПраздничныеДниСледующегоГода = ПраздничныеДниПроизводственногоКалендаря(КодКалендаря, НомерГода + 1);
ДополнитьТаблицу(ПраздничныеДниСледующегоГода, ПраздничныеДни);
Если КодБазовогоКалендаря <> Неопределено Тогда
// Дополним таблицу также праздниками базового календаря.
ПраздничныеБазовогоКалендаря = ПраздничныеДниПроизводственногоКалендаря(КодБазовогоКалендаря, НомерГода);
ДополнитьТаблицу(ПраздничныеБазовогоКалендаря, ПраздничныеДни);
ПраздничныеДниСледующегоГода = ПраздничныеДниПроизводственногоКалендаря(КодБазовогоКалендаря, НомерГода + 1);
ДополнитьТаблицу(ПраздничныеДниСледующегоГода, ПраздничныеДни);
КонецЕсли;
// При совпадении выходного и нерабочего праздничного дней
// выходной день переносится на следующий после праздничного рабочий день
// за исключением выходных дней, совпадающих с нерабочими праздничными днями
// в период Новогодних каникул и Рождества Христова.
Для Каждого СтрокаТаблицы Из ПраздничныеДни Цикл
ПраздничныйДень = СтрокаТаблицы.Дата;
// Отметим как предпраздничный день,
// рабочий день непосредственно предшествующий праздничному дню.
Если СтрокаТаблицы.ДобавлятьПредпраздничный Тогда
ДатаПредпраздничногоДня = ПраздничныйДень - ДлинаСуток();
Если Год(ДатаПредпраздничногоДня) = НомерГода Тогда
// Предпраздничные дни другого года пропускаем.
Если ВидыДней[ДатаПредпраздничногоДня] = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий
И ПраздничныеДни.Найти(ДатаПредпраздничногоДня, "Дата") = Неопределено Тогда
ВидыДней.Вставить(ДатаПредпраздничногоДня, Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Год(ПраздничныйДень) <> НомерГода Тогда
// Праздничные дни другого года далее также пропускаем.
Продолжить;
КонецЕсли;
Если ВидыДней[ПраздничныйДень] <> Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий
И СтрокаТаблицы.ПереноситьВыходной Тогда
// Если праздничный день выпадает на выходной,
// и выходной, на который выпадает этот праздник, переносится -
// переносим выходной на ближайший рабочий день.
ДатаДня = ПраздничныйДень;
Пока Истина Цикл
ДатаДня = ДатаДня + ДлинаСуток();
Если ВидыДней[ДатаДня] = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий
И ПраздничныеДни.Найти(ДатаДня, "Дата") = Неопределено Тогда
ВидыДней.Вставить(ДатаДня, ВидыДней[ПраздничныйДень]);
ПереносыДней.Вставить(ДатаДня, ПраздничныйДень);
ПереносыДней.Вставить(ПраздничныйДень, ДатаДня);
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если СтрокаТаблицы.ТолькоНерабочий Тогда
ВидыДней.Вставить(ПраздничныйДень, Перечисления.ВидыДнейПроизводственногоКалендаря.Нерабочий);
Иначе
ВидыДней.Вставить(ПраздничныйДень, Перечисления.ВидыДнейПроизводственногоКалендаря.Праздник);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ДополнитьТаблицу(ТаблицаИсточник, ТаблицаПриемник) Экспорт
Для Каждого СтрокаТаблицыИсточник Из ТаблицаИсточник Цикл
ЗаполнитьЗначенияСвойств(ТаблицаПриемник.Добавить(), СтрокаТаблицыИсточник);
КонецЦикла;
КонецПроцедуры
Функция ДанныеПроизводственныхКалендарейПоУмолчанию(КодыКалендарей = Неопределено, ФормироватьПолныйНабор = Истина) Экспорт
//Если КалендарныеГрафики.ВерсияКалендарей() >= КалендарныеГрафики.ВерсияЗагруженныхКалендарей() Тогда
Возврат ДанныеПроизводственныхКалендарейИзМакета(КодыКалендарей, ФормироватьПолныйНабор);
// КонецЕсли;
//Возврат ДанныеПроизводственныхКалендарейИзФайлаКлассификатора(КодыКалендарей, ФормироватьПолныйНабор);
КонецФункции
Функция ДанныеПроизводственныхКалендарейИзМакета(КодыКалендарей = Неопределено, ФормироватьПолныйНабор = Истина) Экспорт
//Если Метаданные.Обработки.Найти("ЗаполнениеКалендарныхГрафиков") = Неопределено Тогда
// Возврат НовыеДанныеПроизводственныхКалендарей();
//КонецЕсли;
//
//МодульЗаполнениеКалендарныхГрафиков = ОбщегоНазначения.ОбщийМодуль("Обработки.ЗаполнениеКалендарныхГрафиков");
ТекстовыйДокумент = ПолучитьМакет("ДанныеПроизводственныхКалендарей");
ДанныеXML = ПрочитатьXMLВТаблицу(ТекстовыйДокумент.ПолучитьТекст());
ТаблицаКалендарей = ПолучитьТаблицуПроизводственныхКалендарей();
Возврат ДанныеПроизводственныхКалендарейИзXML(ДанныеXML, ТаблицаКалендарей, КодыКалендарей, ФормироватьПолныйНабор);
КонецФункции
Функция ПериодыНерабочихДнейИзМакета() Экспорт
ТекстовыйДокумент = ПолучитьМакет("ПериодыНерабочихДней");
ТаблицаПериодов = ПрочитатьXMLВТаблицу(ТекстовыйДокумент.ПолучитьТекст());
ТаблицаКалендарей = ПолучитьТаблицуПроизводственныхКалендарей();
Возврат ПериодыНерабочихДнейИзXML(ТаблицаПериодов, ТаблицаКалендарей);
КонецФункции
Функция ПериодыНерабочихДнейИзXML(Знач ДанныеXML, ТаблицаКалендарей) Экспорт
ТаблицаДанных = НоваяТаблицаПериодовНерабочихДней();
ДанныеМакета = ДанныеXML.Данные;
Для Каждого СтрокаМакета Из ДанныеМакета Цикл
ДобавитьНерабочийПериодВТаблицуИзМакета(ТаблицаДанных.Добавить(), СтрокаМакета);
ТаблицаКоды = ТаблицаКалендарей.НайтиСтроки(Новый Структура("Base",СтрокаМакета.Calendar));
КодыЗависимыхКалендарей = ВыгрузитьКолонку(ТаблицаКоды, "Code");
Для Каждого КодЗависимогоКалендаря Из КодыЗависимыхКалендарей Цикл
Если ДанныеМакета.НайтиСтроки(Новый Структура("Calendar", КодЗависимогоКалендаря)).Количество() <> 0 Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = ТаблицаДанных.Добавить();
ДобавитьНерабочийПериодВТаблицуИзМакета(НоваяСтрока, СтрокаМакета);
НоваяСтрока.КодПроизводственногоКалендаря = КодЗависимогоКалендаря;
КонецЦикла;
КонецЦикла;
ТаблицаДанных.Сортировать("КодПроизводственногоКалендаря, НомерПериода");
Возврат ТаблицаДанных;
КонецФункции
Функция НоваяТаблицаПериодовНерабочихДней()
ТаблицаДанных = Новый ТаблицаЗначений;
ТаблицаДанных.Колонки.Добавить("КодПроизводственногоКалендаря", Новый ОписаниеТипов("Строка", ,
Новый КвалификаторыСтроки(2)));
ТаблицаДанных.Колонки.Добавить("НомерПериода", Новый ОписаниеТипов("Число"));
ТаблицаДанных.Колонки.Добавить("ДатаНачала", Новый ОписаниеТипов("Дата"));
ТаблицаДанных.Колонки.Добавить("ДатаОкончания", Новый ОписаниеТипов("Дата"));
ТаблицаДанных.Колонки.Добавить("Основание", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(150)));
Возврат ТаблицаДанных;
КонецФункции
Процедура ДобавитьНерабочийПериодВТаблицуИзМакета(СтрокаТаблицы, СтрокаМакета)
СтрокаТаблицы.КодПроизводственногоКалендаря = СтрокаМакета.Calendar;
СтрокаТаблицы.НомерПериода = Число(СтрокаМакета.Order);
СтрокаТаблицы.ДатаНачала = Дата(СтрокаМакета.StartDate);
СтрокаТаблицы.ДатаОкончания = Дата(СтрокаМакета.EndDate);
СтрокаТаблицы.Основание = СтрокаМакета.Description;
КонецПроцедуры
Функция ДанныеПроизводственныхКалендарейИзXML(Знач ДанныеXML, ТаблицаКалендарей, КодыКалендарей = Неопределено, ФормироватьПолныйНабор = Истина) Экспорт
ТаблицаДанных = НовыеДанныеПроизводственныхКалендарей();
КлассификаторТаблица = ДанныеXML.Данные;
Если КлассификаторТаблица.Количество() = 0 Тогда
Возврат ТаблицаДанных;
КонецЕсли;
ГодыКалендарей = КлассификаторТаблица.Скопировать(, "Calendar,Year");
ГодыКалендарей.Свернуть("Calendar,Year");
ДополнитьКалендариГодыПоТаблицеКалендарей(ГодыКалендарей, ТаблицаКалендарей);
ГодыКалендарей.Сортировать("Calendar, Year");
ОтборСтрок = Новый Структура("Calendar,Year");
Для Каждого Сочетание Из ГодыКалендарей Цикл
Если КодыКалендарей <> Неопределено И КодыКалендарей.Найти(Сочетание.Calendar) = Неопределено Тогда
Продолжить;
КонецЕсли;
ДатыГода = Новый Соответствие;
ЗаполнитьЗначенияСвойств(ОтборСтрок, Сочетание);
СтрокиДанныхКалендаря = КлассификаторТаблица.НайтиСтроки(ОтборСтрок);
Для Каждого СтрокаКлассификатора Из СтрокиДанныхКалендаря Цикл
НоваяСтрока = ТаблицаДанных.Добавить();
НоваяСтрока.КодПроизводственногоКалендаря = СтрокаКлассификатора.Calendar;
НоваяСтрока.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря[СтрокаКлассификатора.DayType];
НоваяСтрока.Год = Число(СтрокаКлассификатора.Year);
НоваяСтрока.Дата = Дата(СтрокаКлассификатора.Date);
Если ЗначениеЗаполнено(СтрокаКлассификатора.SwapDate) Тогда
НоваяСтрока.ДатаПереноса = Дата(СтрокаКлассификатора.SwapDate);
КонецЕсли;
ДатыГода.Вставить(НоваяСтрока.Дата, Истина);
КонецЦикла;
КодБазовогоКалендаря = КодБазовогоКалендаря(Сочетание.Calendar, ТаблицаКалендарей);
Если КодБазовогоКалендаря <> Неопределено Тогда
ОтборСтрок.Calendar = КодБазовогоКалендаря;
СтрокиДанныхКалендаря = КлассификаторТаблица.НайтиСтроки(ОтборСтрок);
Для Каждого СтрокаКлассификатора Из СтрокиДанныхКалендаря Цикл
СтрокаКлассификатора.Calendar = Сочетание.Calendar;
ПараметрыОтбора = Новый Структура("КодПроизводственногоКалендаря,Дата");
ПараметрыОтбора.КодПроизводственногоКалендаря = СтрокаКлассификатора.Calendar;
ПараметрыОтбора.Дата = Дата(СтрокаКлассификатора.Date);
НайденныеСтроки = ТаблицаДанных.НайтиСтроки(ПараметрыОтбора);
Если НайденныеСтроки.Количество() > 0 Тогда
СтрокаКлассификатора.Calendar = КодБазовогоКалендаря;
Если НоваяСтрока <> Неопределено Тогда
ДатыГода.Вставить(НоваяСтрока.Дата, Истина);
КонецЕсли;
Продолжить;
КонецЕсли;
НоваяСтрока = ТаблицаДанных.Добавить();
НоваяСтрока.КодПроизводственногоКалендаря = СтрокаКлассификатора.Calendar;
НоваяСтрока.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря[СтрокаКлассификатора.DayType];
НоваяСтрока.Год = Число(СтрокаКлассификатора.Year);
НоваяСтрока.Дата = Дата(СтрокаКлассификатора.Date);
Если ЗначениеЗаполнено(СтрокаКлассификатора.SwapDate) Тогда
НоваяСтрока.ДатаПереноса = Дата(СтрокаКлассификатора.SwapDate);
КонецЕсли;
СтрокаКлассификатора.Calendar = КодБазовогоКалендаря;
Если НоваяСтрока <> Неопределено Тогда
ДатыГода.Вставить(НоваяСтрока.Дата, Истина);
КонецЕсли;
КонецЦикла;
КонецЕсли;
Если Не ФормироватьПолныйНабор Тогда
Продолжить;
КонецЕсли;
НомерГода = Число(Сочетание.Year);
ДатаДня = Дата(НомерГода, 1, 1);
Пока ДатаДня <= Дата(НомерГода, 12, 31) Цикл
Если ДатыГода[ДатаДня] = Неопределено Тогда
НоваяСтрока = ТаблицаДанных.Добавить();
НоваяСтрока.КодПроизводственногоКалендаря = Сочетание.Calendar;
НоваяСтрока.Год = НомерГода;
НоваяСтрока.Дата = ДатаДня;
НоваяСтрока.ВидДня = ВидДняПоДате(ДатаДня);
КонецЕсли;
ДатаДня = ДатаДня + ДлинаСуток();
КонецЦикла;
КонецЦикла;
Возврат ТаблицаДанных;
КонецФункции
Функция КодБазовогоКалендаря(КодКалендаря, КлассификаторКалендарей)
СтрокаКалендаря = КлассификаторКалендарей.Найти(КодКалендаря, "Code");
Если СтрокаКалендаря = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Если Не ЗначениеЗаполнено(СтрокаКалендаря["Base"]) Тогда
Возврат Неопределено;
КонецЕсли;
Возврат СтрокаКалендаря["Base"];
КонецФункции
Процедура ДополнитьКалендариГодыПоТаблицеКалендарей(КалендариГоды, ТаблицаКалендарей)
КалендариГоды.Сортировать("Calendar, Year");
Для Каждого СтрокаКалендаря Из ТаблицаКалендарей Цикл
ГодыКалендаря = КалендариГоды.НайтиСтроки(Новый Структура("Calendar", СтрокаКалендаря.Code));
ГодыБазовогоКалендаря = КалендариГоды.НайтиСтроки(Новый Структура("Calendar", СтрокаКалендаря.Base));
Если ГодыКалендаря.Количество() = 0 Тогда
// В макете вообще нет данных этого календаря - посмотрим базовый календарь.
Если ГодыБазовогоКалендаря.Количество() = 0 Тогда
// Для базового календаря тоже нет данных - добавим только на текущий год.
ДобавитьГодКалендаря(КалендариГоды, СтрокаКалендаря.Code, Год(ТекущаяДатаСеанса()));
Продолжить;
КонецЕсли;
Для Каждого СтрокаБазового Из ГодыБазовогоКалендаря Цикл
ДобавитьГодКалендаря(КалендариГоды, СтрокаКалендаря.Code, СтрокаБазового.Year);
КонецЦикла;
Продолжить;
КонецЕсли;
// Заполняем за все годы базового календаря, но не ранее минимального года из макета для этого календаря.
МинимальныйГод = ГодыКалендаря[0].Year;
Годы = ВыгрузитьКолонку(ГодыКалендаря, "Year");
Для Каждого СтрокаБазового Из ГодыБазовогоКалендаря Цикл
Если СтрокаБазового.Year >= МинимальныйГод И Годы.Найти(СтрокаБазового.Year) = Неопределено Тогда
ДобавитьГодКалендаря(КалендариГоды, СтрокаКалендаря.Code, СтрокаБазового.Year);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция ВыгрузитьКолонку(КоллекцияСтрок, ИмяКолонки, ТолькоУникальныеЗначения = Ложь) Экспорт
МассивЗначений = Новый Массив;
УникальныеЗначения = Новый Соответствие;
Для каждого СтрокаКоллекции Из КоллекцияСтрок Цикл
Значение = СтрокаКоллекции[ИмяКолонки];
Если ТолькоУникальныеЗначения И УникальныеЗначения[Значение] <> Неопределено Тогда
Продолжить;
КонецЕсли;
МассивЗначений.Добавить(Значение);
УникальныеЗначения.Вставить(Значение, Истина);
КонецЦикла;
Возврат МассивЗначений;
КонецФункции
Процедура ДобавитьГодКалендаря(КалендариГоды, КодКалендаря, Год)
НоваяСтрока = КалендариГоды.Добавить();
НоваяСтрока.Calendar = КодКалендаря;
НоваяСтрока.Year = Формат(Год, "ЧГ=");
КонецПроцедуры
Процедура ЗаполнитьВидыДнейДаннымиКалендаря(ДанныеКалендаря, ВидыДней, ПереносыДней)
Для Каждого СтрокаДанных Из ДанныеКалендаря Цикл
ВидыДней.Вставить(СтрокаДанных.Дата, СтрокаДанных.ВидДня);
Если ЗначениеЗаполнено(СтрокаДанных.ДатаПереноса) Тогда
ПереносыДней.Вставить(СтрокаДанных.Дата, СтрокаДанных.ДатаПереноса);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ЗаписатьДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода, ДанныеПроизводственногоКалендаря) Экспорт
НаборЗаписей = РегистрыСведений.ДанныеПроизводственногоКалендаря.СоздатьНаборЗаписей();
Для Каждого КлючИЗначение Из ДанныеПроизводственногоКалендаря Цикл
ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), КлючИЗначение);
КонецЦикла;
ЗначенияОтбора = Новый Структура("ПроизводственныйКалендарь, Год", ПроизводственныйКалендарь, НомерГода);
Для Каждого КлючИЗначение Из ЗначенияОтбора Цикл
НаборЗаписей.Отбор[КлючИЗначение.Ключ].Установить(КлючИЗначение.Значение);
КонецЦикла;
Для Каждого СтрокаНабора Из НаборЗаписей Цикл
ЗаполнитьЗначенияСвойств(СтрокаНабора, ЗначенияОтбора);
КонецЦикла;
НаборЗаписей.Записать(Истина);
//УсловияОбновления = УсловийОбновленияГрафиковРаботы(ПроизводственныйКалендарь, НомерГода);
//КалендарныеГрафики.РаспространитьИзмененияДанныхПроизводственныхКалендарей(УсловияОбновления);
КонецПроцедуры
Функция ПериодыНерабочихДнейПоУмолчанию() Экспорт
//Если КалендарныеГрафики.ВерсияКалендарей() >= КалендарныеГрафики.ВерсияЗагруженныхКалендарей() Тогда
Возврат ПериодыНерабочихДнейИзМакета();
//КонецЕсли;
Возврат ПериодыНерабочихДнейИзФайлаКлассификатора();
КонецФункции
Функция ПериодыНерабочихДнейИзФайлаКлассификатора()
ДанныеКлассификатора = ДанныеКлассификатора();
Возврат ПериодыНерабочихДнейИзXML(
ДанныеКлассификатора["ПериодыНерабочихДней"],
ДанныеКлассификатора["ПроизводственныеКалендари"].Данные);
КонецФункции
Функция ДанныеКлассификатора() Экспорт
ДанныеКлассификатора = Новый Структура;
ПроизводственныеКалендари = Новый Структура;
ПроизводственныеКалендари.Вставить("ИмяТаблицы", "");
ПроизводственныеКалендари.Вставить("Данные", Новый ТаблицаЗначений());
ДанныеПроизводственныхКалендарей = Новый Структура(Новый ФиксированнаяСтруктура(ПроизводственныеКалендари));
ПериодыНерабочихДней = Новый Структура(Новый ФиксированнаяСтруктура(ПроизводственныеКалендари));
ДанныеКлассификатора.Вставить("ДанныеПроизводственныхКалендарей", ДанныеПроизводственныхКалендарей);
ДанныеКлассификатора.Вставить("ПроизводственныеКалендари", ПроизводственныеКалендари);
ДанныеКлассификатора.Вставить("ПериодыНерабочихДней", ПериодыНерабочихДней);
//КалендарныеГрафикиЛокализация.ПриПолученииДанныхКлассификатора(ДанныеКлассификатора);
Возврат ДанныеКлассификатора;
КонецФункции
Функция ТаблицаИзмененийПроизводственныхКалендарей()
ТаблицаИзменений = Новый ТаблицаЗначений;
ТаблицаИзменений.Колонки.Добавить("КодПроизводственногоКалендаря", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(3)));
ТаблицаИзменений.Колонки.Добавить("Год", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(4)));
Возврат ТаблицаИзменений;
КонецФункции
Функция ОбновитьПериодыНерабочихДней(ТаблицаПериодов,КодПроизводственногоКалендаря) Экспорт
ТаблицаИзменений = ТаблицаИзмененийПроизводственныхКалендарей();
// АПК:96 -выкл результат должен содержать уникальные значения
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТаблицаПериодов", ТаблицаПериодов);
Запрос.УстановитьПараметр("КодПроизводственногоКалендаря", КодПроизводственногоКалендаря);
Запрос.Текст =
"ВЫБРАТЬ
| КлассификаторТаблица.КодПроизводственногоКалендаря КАК КодПроизводственногоКалендаря,
| КлассификаторТаблица.НомерПериода КАК НомерПериода,
| КлассификаторТаблица.ДатаНачала КАК ДатаНачала,
| КлассификаторТаблица.ДатаОкончания КАК ДатаОкончания,
| КлассификаторТаблица.Основание КАК Основание
|ПОМЕСТИТЬ ВТКлассификаторТаблица
|ИЗ
| &ТаблицаПериодов КАК КлассификаторТаблица
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТКлассификаторТаблица.КодПроизводственногоКалендаря КАК КодПроизводственногоКалендаря,
| ВТКлассификаторТаблица.НомерПериода КАК НомерПериода,
| ВТКлассификаторТаблица.ДатаНачала КАК ДатаНачала,
| ВТКлассификаторТаблица.ДатаОкончания КАК ДатаОкончания,
| ВТКлассификаторТаблица.Основание КАК Основание
|ИЗ
| ВТКлассификаторТаблица КАК ВТКлассификаторТаблица
|ГДЕ
| ВТКлассификаторТаблица.КодПроизводственногоКалендаря = &КодПроизводственногоКалендаря";
// АПК:96 -вкл
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
НаборЗаписей = РегистрыСведений.ПериодыНерабочихДнейКалендаря.СоздатьНаборЗаписей();
Пока Выборка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), Выборка);
ЗаполнитьЗначенияСвойств(ТаблицаИзменений.Добавить(), Выборка);
КонецЦикла;
НаборЗаписей.Отбор.КодПроизводственногоКалендаря.Установить(Выборка.КодПроизводственногоКалендаря);
НаборЗаписей.Записать();
КонецЦикла;
ТаблицаИзменений.Свернуть("КодПроизводственногоКалендаря, Год");
Возврат ТаблицаИзменений;
КонецФункции