Загрузка данных
Причина, по которой календарь не окрашивается по умолчанию при выборе нового года, кроется в разрыве логики между загрузкой видов дней производственного календаря (праздники/выходные) и формированием рабочих дней самого графика (заполнение фона).
---
### Главные проблемы в логике
1. **Разрыв между `ВидыДней` и `ДниГрафика` (фоновая подкраска):**
* Окрашивание фона в процедуре `КалендарьПриВыводеПериода` происходит только для дат, попавших в соответствие `ДниГрафика`:
```bsl
Если ДниГрафика.Получить(ТекущаяДата) <> Неопределено Тогда
СтрокаОформленияПериода.ЦветФона = WebЦвета.Роса;
...
```
* В процедуре `ЗаполнитьДаннымиТекущегоГода()` алгоритм проверяет регистрационные данные `ДниГрафика`. Если в регистре записей за новый год нет, то заполнение `ДниГрафика` по шаблону выполняется через `РегистрыСведений.КалендарныеГрафики.ДниВключенныеВГрафик(...)`.
* Однако в параметрах заполнения передаются:
```bsl
ПараметрыЗаполнения.КодПроизводственногоКалендаря = Объект.Код; // Внимание: Объект.Код может быть пуст/не совпадать с кодом календаря
ПараметрыЗаполнения.ПроизводственныйКалендарь = Объект.Ссылка;
```
Если объект ещё новый или реквизит `Объект.Код` не содержит корректного кода производственного календаря, то функция `ДниВключенныеВГрафик` возвращает пустую коллекцию. В результате `ДниГрафика` остаются пустыми, и подкраска фона (WebЦвета.Роса) не срабатывает.
2. **Неопределённость с `КодПроизводственногоКалендаря` при вызове функций макета:**
* В `ОбработатьИзменениеГода` передаётся:
```bsl
КодКалендаря = ?(ТипЗнч(Объект.ПроизводственныйКалендарь) = Тип("Строка"),
Объект.ПроизводственныйКалендарь, Объект.ПроизводственныйКалендарь.Код);
```
* Если `Объект.ПроизводственныйКалендарь` — это ссылка на справочник `ПроизводственныеКалендари` (или иной элемент), а не заполненное строковое значение/код, получение `Объект.ПроизводственныйКалендарь.Код` может возвращать пустое значение или не находить соответствие в XML-макете (где поиск идёт строго по коду вида `"RU"` и т.п.).
3. **Отсутствие перезаполнения графика по шаблону при смене года:**
* В `ОбработатьИзменениеГода()` вызывается `ЗаполнитьДаннымиТекущегоГода()`, но если в регистре `КалендарныеГрафики` данных нет, подгрузка рабочих дней по шаблону должна гарантированно пересчитываться через `ЗаполнитьПоШаблонуНаСервере()`.
---
### Где и как исправить?
#### 1. Исправление в `ОбработатьИзменениеГода` (Модуль формы)
Необходимо корректно извлекать код производственного календаря и гарантировать формирование рабочих дней по шаблону, если за указанный год данных в регистре не было найденно:
```bsl
&НаСервере
Процедура ОбработатьИзменениеГода(ЗаписыватьДанныеГрафика)
Если ЗаписыватьДанныеГрафика Тогда
Если Объект.Ссылка.Пустая() Тогда
Записать(Новый Структура("НомерГода", НомерТекущегоГода));
Иначе
ЗаписатьДанныеПроизводственногоКалендаряНаСервере(НомерТекущегоГода, РеквизитФормыВЗначение("Объект"));
КонецЕсли;
КонецЕсли;
// Получаем строковый код производственного календаря
КодКалендаря = "";
Если ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
Если ТипЗнч(Объект.ПроизводственныйКалендарь) = Тип("Строка") Тогда
КодКалендаря = Объект.ПроизводственныйКалендарь;
Иначе
КодКалендаря = Объект.ПроизводственныйКалендарь.Код;
КонецЕсли;
ИначеЕсли ЗначениеЗаполнено(Объект.Код) Тогда
КодКалендаря = Объект.Код;
КонецЕсли;
// 1. Подгружаем данные производственного календаря из макета, если за новый год данных в регистре нет
Если Не ПустаяСтрока(КодКалендаря) Тогда
ТЗДанные = Справочники.ГрафикРаботы.ДанныеПроизводственногоКалендаря(Объект.Ссылка, НомерТекущегоГода);
Если ТЗДанные.Количество() = 0 Тогда
ДанныеПоУмолчанию = Справочники.ГрафикРаботы.РезультатЗаполненияПроизводственногоКалендаряПоУмолчанию(
КодКалендаря, НомерТекущегоГода, КодКалендаря
);
ПреобразоватьДанныеПроизводственногоКалендаря(ДанныеПоУмолчанию);
Иначе
ПреобразоватьДанныеПроизводственногоКалендаря(ТЗДанные);
КонецЕсли;
КонецЕсли;
// 2. Считываем/формируем данные графика и заполняем расписание
ЗаполнитьДаннымиТекущегоГода();
// 3. Если за новый год график пуст — принудительно заполняем его по шаблону рабочей недели
Если ДниГрафика.Количество() = 0 Тогда
ЗаполнитьПоШаблонуНаСервере();
КонецЕсли;
КонецПроцедуры
```
#### 2. Исправление в `ЗаполнитьДаннымиТекущегоГода` (Модуль формы)
Убедитесь, что параметр `КодПроизводственногоКалендаря` при заполнении из регистра/макета не оказывается пустым:
```bsl
&НаСервере
Процедура ЗаполнитьДаннымиТекущегоГода()
НастроитьПолеКалендаря();
СсылкаНаКалендарь = Объект.Ссылка;
ПрочитатьДанныеПроизводственногоКалендаря(СсылкаНаКалендарь, НомерТекущегоГода);
ПрочитатьНерабочиеДаты();
ДниГрафикаМассив = РегистрыСведений.КалендарныеГрафики.ПрочитатьДанныеГрафикаИзРегистра(Объект.Ссылка, НомерТекущегоГода);
ДниГрафика = Новый ФиксированноеСоответствие(ДниГрафикаМассив);
Если ДниГрафика.Количество() = 0 Тогда
ПараметрыЗаполнения = РегистрыСведений.КалендарныеГрафики.ПараметрыЗаполненияГрафика();
// Гарантируем наличие кода календаря
КодКалендаря = Объект.Код;
Если ПустаяСтрока(КодКалендаря) И ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
КодКалендаря = ?(ТипЗнч(Объект.ПроизводственныйКалендарь) = Тип("Строка"), Объект.ПроизводственныйКалендарь, Объект.ПроизводственныйКалендарь.Код);
КонецЕсли;
ПараметрыЗаполнения.КодПроизводственногоКалендаря = КодКалендаря;
ПараметрыЗаполнения.ШаблонЗаполнения = Объект.РабочиеДни;
ПараметрыЗаполнения.ПроизводственныйКалендарь = Объект.Ссылка;
ПараметрыЗаполнения.УчитыватьПраздники = Объект.УчитыватьПраздничныеДни;
ПараметрыЗаполнения.УчитыватьНерабочиеПериоды = Объект.УчитыватьНерабочиеПериоды;
ДниВключенныеВГрафик = РегистрыСведений.КалендарныеГрафики.ДниВключенныеВГрафик(
Объект.ДатаНачала, Объект.ДатаОкончания, ПараметрыЗаполнения
);
ДниГрафика = Новый ФиксированноеСоответствие(ДниВключенныеВГрафик);
КонецЕсли;
КонецПроцедуры
```