Загрузка данных


Модуль Формы ФормаДокумента

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

&НаСервере
Процедура ЗаполнитьДаннымиПоУмолчанию()
	
	КодБазовогоКалендаря = Объект.ПроизводственныйКалендарь;
	Объект.Код = КодБазовогоКалендаря;
	
	ДанныеПоУмолчанию = Справочники.ГрафикРаботы.РезультатЗаполненияПроизводственногоКалендаряПоУмолчанию(
	Объект.Код, НомерТекущегоГода, КодБазовогоКалендаря); 
	
	Справочники.ГрафикРаботы.ОбновитьПериодыНерабочихДней(
	Справочники.ГрафикРаботы.ПериодыНерабочихДнейПоУмолчанию(), Объект.Код);
	
	ПреобразоватьДанныеПроизводственногоКалендаря(ДанныеПоУмолчанию);
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДаннымиТекущегоГода()
	
	НастроитьПолеКалендаря();
	
	СсылкаНаКалендарь = Объект.Ссылка;
	
	ПрочитатьДанныеПроизводственногоКалендаря(СсылкаНаКалендарь, НомерТекущегоГода);
	ПрочитатьНерабочиеДаты(); 
	
	ДниГрафика = Новый ФиксированноеСоответствие(
	РегистрыСведений.КалендарныеГрафики.ПрочитатьДанныеГрафикаИзРегистра(Объект.Ссылка, НомерТекущегоГода));
	
	//ПрочитатьПризнакРучногоРедактирования(Объект, НомерТекущегоГода);
	
	// Если нет ручных корректировок и данных тоже нет, то формируем результат по шаблону за выбранный год.
	Если ДниГрафика.Количество() = 0 Тогда //И ДниИзмененные.Количество() = 0
		ПараметрыЗаполнения = РегистрыСведений.КалендарныеГрафики.ПараметрыЗаполненияГрафика();
		ПараметрыЗаполнения.КодПроизводственногоКалендаря = Объект.Код;
		//ПараметрыЗаполнения.СпособЗаполнения = Объект.СпособЗаполнения;
		ПараметрыЗаполнения.ШаблонЗаполнения = Объект.РабочиеДни;
		ПараметрыЗаполнения.ПроизводственныйКалендарь = Объект.Ссылка;
		ПараметрыЗаполнения.УчитыватьПраздники = Объект.УчитыватьПраздничныеДни;
		ПараметрыЗаполнения.УчитыватьНерабочиеПериоды = Объект.УчитыватьНерабочиеПериоды;
		//ПараметрыЗаполнения.ДатаОтсчета = Объект.ДатаОтсчета;
		ДниВключенныеВГрафик = РегистрыСведений.КалендарныеГрафики.ДниВключенныеВГрафик(
		Объект.ДатаНачала, Дата(НомерТекущегоГода, 12, 31), ПараметрыЗаполнения);
		ДниГрафика = Новый ФиксированноеСоответствие(ДниВключенныеВГрафик);
	КонецЕсли; 
	
КонецПроцедуры  

&НаСервере
Процедура ПрочитатьДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода)
	
	// Загрузка данных производственного календаря за указанный год.
	ПреобразоватьДанныеПроизводственногоКалендаря(
	Справочники.ГрафикРаботы.ДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерГода));
	
КонецПроцедуры 

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

&НаСервере
Процедура УстановитьДоступностьУчитыватьНерабочиеПериоды(Форма)
	
	//Элементы = Форма.Элементы;
	//Объект = Форма.Объект;
	
	Элементы.УчитыватьНерабочиеПериоды.Видимость = Ложь;
	Если Не ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
		Возврат;
	КонецЕсли;
	
	Периоды = РегистрыСведений.КалендарныеГрафики.ПериодыНерабочихДней(Объект.ПроизводственныйКалендарь, Новый СтандартныйПериод(Объект.ДатаНачала, Объект.ДатаОкончания), Объект.Код);
	Если Периоды.Количество() = 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);
	КонецЕсли;
	
	//УстановитьСнятьПризнакСоответствияРезультатовШаблону(ЭтотОбъект, Ложь);
	//УстановитьСнятьМодифицированностьШаблона(ЭтотОбъект, Истина);
	
	Если КонтекстВыбора.ИдентификаторСтрокиШаблона <> Неопределено Тогда
		СтрокаШаблона = Объект.РабочиеДни.НайтиПоИдентификатору(КонтекстВыбора.ИдентификаторСтрокиШаблона);
		СтрокаШаблона.ДеньВключенВГрафик = ВыбранноеЗначение.РасписаниеРаботы.Количество() > 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"));
		Оповещение = Новый ОписаниеОповещения("НомерТекущегоГодаПриИзмененииЗавершение", ЭтотОбъект);
		ПоказатьВопрос(Оповещение, ТекстСообщения, РежимДиалогаВопрос.ДаНет);
		Возврат;
	КонецЕсли;
	
	ОбработатьИзменениеГода(ЗаписыватьДанныеГрафика); 
	
	Если ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
		ЗаполнитьДаннымиПоУмолчанию();
	КонецЕсли;
	
	Модифицированность = Ложь;
	
	Элементы.Календарь.Обновить(); 
	
КонецПроцедуры                      

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

&НаКлиенте
Процедура НомерТекущегоГодаПриИзмененииЗавершение(Ответ, ДополнительныеПараметры) Экспорт
	
	ОбработатьИзменениеГода(Ответ = КодВозвратаДиалога.Да);
	Модифицированность = Ложь;
	Элементы.Календарь.Обновить();
	
КонецПроцедуры

&НаКлиенте
Процедура ПеренестиДень(Команда)
	ВыделенныеДаты = Элементы.Календарь.ВыделенныеДаты;
	
	Если ВыделенныеДаты.Количество() = 0 Или Год(ВыделенныеДаты[0]) <> НомерТекущегоГода Тогда
		Возврат;
	КонецЕсли;
	
	ДатаПереноса = ВыделенныеДаты[0];
	ВидДня = ВидыДней.Получить(ДатаПереноса);
	
	ПараметрыВыбораДаты = Новый Структура(
	"НачальноеЗначение, 
	|НачалоПериодаОтображения, 
	|КонецПериодаОтображения, 
	|Заголовок, 
	|ПоясняющийТекст");
	
	ПараметрыВыбораДаты.НачальноеЗначение = ДатаПереноса;
	ПараметрыВыбораДаты.НачалоПериодаОтображения = НачалоГода(Календарь);
	ПараметрыВыбораДаты.КонецПериодаОтображения = КонецГода(Календарь);
	ПараметрыВыбораДаты.Заголовок = НСтр("ru = 'Выбор даты переноса'");
	
	ПараметрыВыбораДаты.ПоясняющийТекст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
	НСтр("ru = 'Выберите дату, на которую будет осуществлен перенос дня %1 (%2)'"), 
	Формат(ДатаПереноса, "ДФ='д ММММ'"), // АПК:1367 Хорошего решения нет, считаем сохранение порядка дата + месяц приемлемым решением в этом месте
	ВидДня);
	
	ОткрытьФорму("Справочник.ГрафикРаботы.Форма.ВыборДаты", ПараметрыВыбораДаты, ЭтотОбъект);
КонецПроцедуры

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

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

&НаКлиенте
Процедура ВписатьДатуПереноса(ПереносыДнейСоответствие, ДатаПереноса, ДатаНазначения)
	
	// Заполняет в соответствии с датами переносов дней корректную дату переноса.
	
	ИсточникДняДатыНазначения = ПереносыДней.Получить(ДатаНазначения);
	Если ИсточникДняДатыНазначения = Неопределено Тогда
		ИсточникДняДатыНазначения = ДатаНазначения;
	КонецЕсли;
	
	Если ДатаПереноса = ИсточникДняДатыНазначения Тогда
		ПереносыДнейСоответствие.Удалить(ДатаПереноса);
	Иначе	
		ПереносыДнейСоответствие.Вставить(ДатаПереноса, ИсточникДняДатыНазначения);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура УчитыватьПраздничныеДниПриИзменении(Элемент)
	
	//ЗаполнитьПоШаблонуНаСервере(); 
	//
	//Элементы.Календарь.Обновить(); 
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПоШаблонуНаСервере(СохранятьРучноеРедактирование = Ложь)
	
	ПараметрыЗаполнения = РегистрыСведений.КалендарныеГрафики.ПараметрыЗаполненияГрафика();
	ПараметрыЗаполнения.КодПроизводственногоКалендаря = Объект.Код;
	//ПараметрыЗаполнения.СпособЗаполнения = Объект.СпособЗаполнения;
	ПараметрыЗаполнения.ШаблонЗаполнения = Объект.РабочиеДни;
	ПараметрыЗаполнения.ПроизводственныйКалендарь = Объект.Ссылка;
	ПараметрыЗаполнения.УчитыватьПраздники = Объект.УчитыватьПраздничныеДни;
	ПараметрыЗаполнения.УчитыватьНерабочиеПериоды = Объект.УчитыватьНерабочиеПериоды;
	//ПараметрыЗаполнения.ДатаОтсчета = Объект.ДатаОтсчета;
	
	ДниВключенныеВГрафик = РегистрыСведений.КалендарныеГрафики.ДниВключенныеВГрафик(
	Объект.ДатаНачала, Объект.ДатаОкончания, ПараметрыЗаполнения);
	
	//Если РучноеРедактирование Тогда
	//	Если СохранятьРучноеРедактирование Тогда
	//		// Переносим ручные корректировки.
	//		Для Каждого КлючИЗначение Из ДниИзмененные Цикл
	//			ДатаИзменений = КлючИЗначение.Ключ;
	//			ДеньВключенВГрафик = КлючИЗначение.Значение;
	//			Если ДеньВключенВГрафик Тогда
	//				ДниВключенныеВГрафик.Вставить(ДатаИзменений, Истина);
	//			Иначе
	//				ДниВключенныеВГрафик.Удалить(ДатаИзменений);
	//			КонецЕсли;
	//		КонецЦикла;
	//	Иначе
	//		УстановитьСнятьМодифицированностьРезультата(ЭтотОбъект, Истина);
	//		УстановитьСнятьПризнакРучногоРедактирования(ЭтотОбъект, Ложь);
	//	КонецЕсли;
	//КонецЕсли;
	
	// Переносим результат в исходное соответствие заполнения, 
	// чтобы не затереть даты, не входящие в интервал заполнения.
	ДниГрафикаСоответствие = Новый Соответствие(ДниГрафика);
	ДатаДня = Объект.ДатаНачала;
	ДатаОкончания = Объект.ДатаОкончания;
	Если Не ЗначениеЗаполнено(ДатаОкончания) Тогда
		ДатаОкончания = КонецГода(Объект.ДатаНачала);
	КонецЕсли;
	Пока ДатаДня <= ДатаОкончания Цикл
		ДеньВключенВГрафик = ДниВключенныеВГрафик[ДатаДня];
		Если ДеньВключенВГрафик = Неопределено Тогда
			ДниГрафикаСоответствие.Удалить(ДатаДня);
		Иначе
			ДниГрафикаСоответствие.Вставить(ДатаДня, ДеньВключенВГрафик);
		КонецЕсли;
		ДатаДня = ДатаДня + 86400;
	КонецЦикла;
	
	ДниГрафика = Новый ФиксированноеСоответствие(ДниГрафикаСоответствие);
	
	//Если Не РезультатЗаполненПоШаблону Тогда
	//	УстановитьСнятьМодифицированностьРезультата(ЭтотОбъект, Истина);
	//	УстановитьСнятьПризнакСоответствияРезультатовШаблону(ЭтотОбъект, Истина);
	//КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура РабочиеДниДеньВключенВГрафикПриИзменении(Элемент)

	//ЗаполнитьПоШаблонуНаСервере();

	//Элементы.Календарь.Обновить(); 

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

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

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

&НаКлиенте
Процедура ПослеОтветаНаВопрос(Результат, ДопПараметры) Экспорт

	Если Результат = КодВозвратаДиалога.Да Тогда
		Записать();
		ЗаполнитьПоШаблонуНаСервере();
		Элементы.Календарь.Обновить();
	КонецЕсли;

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


Модуль Объекта 

Процедура ПередЗаписью(Отказ) 
	Если Не Ссылка.ЭтоГруппа Тогда    
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ
		|	ГрафикРаботы.Ссылка КАК ПроизводственныйКалендарь
		|ИЗ
		|	Справочник.ГрафикРаботы КАК ГрафикРаботы
		|ГДЕ
		|	ГОД(ГрафикРаботы.ДатаНачала) = &Год
		|	И НЕ ГрафикРаботы.ПометкаУдаления
		|	И ГрафикРаботы.Ссылка <> &Ссылка
		|
		|УПОРЯДОЧИТЬ ПО
		|	ГрафикРаботы.Наименование";   
		Запрос.УстановитьПараметр("Год", Год);      
		Запрос.УстановитьПараметр("Ссылка", Ссылка);

		РезультатМассив = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ПроизводственныйКалендарь");

		Если РезультатМассив.Количество() > 0 Тогда
			Отказ = Истина;
			Сообщить("График работы за " + Строка(Год) + " год уже существует.");
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Модуль Менеджера
Функция ПолучитьТаблицуПроизводственныхКалендарей() Экспорт

	ТекстовыйДокумент = ПолучитьМакет("ПроизводственныеКалендари");
	ТаблицаКалендарей = Прочитать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 -вкл
	
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		НаборЗаписей = РегистрыСведений.ПериодыНерабочихДнейКалендаря.СоздатьНаборЗаписей();
		Пока Выборка.Следующий() Цикл
			ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), Выборка);
			ЗаполнитьЗначенияСвойств(ТаблицаИзменений.Добавить(), Выборка);
		КонецЦикла;
		НаборЗаписей.Отбор.КодПроизводственногоКалендаря.Установить(Выборка.КодПроизводственногоКалендаря);
		НаборЗаписей.Записать();
	КонецЦикла; 
	
	ТаблицаИзменений.Свернуть("КодПроизводственногоКалендаря, Год");
	
	Возврат ТаблицаИзменений;
	
КонецФункции