Загрузка данных
Задача понятна. Ниже приведен разбор ошибок и готовый, полностью собранный код для всех 3 модулей (**Модуль объекта**, **Модуль менеджера**, **Модуль формы**) с исправлением критических багов и соблюдением официальных стандартов разработки 1С.
---
### Главные ошибки и исправленные архитектурные проблемы
1. **Критический баг в модуле объекта (`ОбработкаПроведения`):**
* **Было:** Вложенный цикл по таблице дат и табличной части `Сотрудники`, внутри которого для каждого дня и сотрудника выполнялся `НайтиСтроки` по всей ТЧ `ГрафикРаботыСотрудников`.
* **Проблема:** Сложность $O(N \times M \times K)$. При 20 сотрудниках и 30 днях это сотни тысяч холостых операций, приводящих к зависанию при проведении.
* **Стандарт 1С:** Не делать избыточные циклы по календарю. Проведение должно обходить напрямую отсортированные данные табличной части документа `ГрафикРаботыСотрудников`.
2. **Неоптимальная работа с контекстом формы (`&НаСервере` vs `&НаСервереБезКонтекста`):**
* **Было:** Служебные функции получения данных из базы (`ПолучитьКалендарь`, `ПолучитьСписокЗначенийКалендарей`, `ПолучитьМассивКалендарей`) находились в модуле формы с директивой `&НаСервере`.
* **Проблема:** При каждом вызове передается весь тяжелый контекст формы (включая динамические данные таблиц).
* **Стандарт 1С:** Функции выборки из БД, не завязанные на реквизиты формы, выносятся в **Модуль менеджера** (`Экспорт`), а в форме вызываются через `&НаСервереБезКонтекста`.
3. **Лишние серверные вызовы из формы:**
* Процедура `ПроизводственныйКалендарьПриИзмененииНаСервере` дублировала клиентскую `ПроизводственныйКалендарьПриИзменении`, создавая двойные серверные вызовы. Убрано дублирование.
4. **Ошибка генерации удаляемых реквизитов:**
* В `УдалитьКолонкуСотрудников` передавался массив строк, а правильный вызов `ИзменитьРеквизиты` требует передачи массива с правильным удалением элементов.
---
### 1. МОДУЛЬ ОБЪЕКТА (Документ)
```bsl
#Область ОбработчикиСобытий
Процедура ОбработкаПроведения(Отказ, Режим)
Движения.ГрафикиРаботыСотрудников.Записывать = Истина;
Движения.ГрафикиРаботыСотрудников.Очистить();
// Сортируем ТЧ для корректного расчета порядковых номеров интервалов за день
ТЧГрафик = ГрафикРаботыСотрудников.Выгрузить();
ТЧГрафик.Сортировать("Сотрудник Возр, Дата Возр, ВремяНачала Возр");
ТекущийСотрудник = Неопределено;
ТекущаяДата = '00010101';
НомерИнтервала = 1;
Для Каждого СтрокаГрафика Из ТЧГрафик Цикл
Если Не ЗначениеЗаполнено(СтрокаГрафика.Дата) Или Не ЗначениеЗаполнено(СтрокаГрафика.Сотрудник) Тогда
Продолжить;
КонецЕсли;
// Сброс интервала при смене сотрудника или даты
Если СтрокаГрафика.Сотрудник <> ТекущийСотрудник Или СтрокаГрафика.Дата <> ТекущаяДата Тогда
ТекущийСотрудник = СтрокаГрафика.Сотрудник;
ТекущаяДата = СтрокаГрафика.Дата;
НомерИнтервала = 1;
Иначе
НомерИнтервала = НомерИнтервала + 1;
КонецЕсли;
Движение = Движения.ГрафикиРаботыСотрудников.Добавить();
Движение.Период = МесяцГрафика;
Движение.Организация = Организация;
Движение.Подразделение = Подразделение;
Движение.Сотрудник = СтрокаГрафика.Сотрудник;
Движение.Дата = СтрокаГрафика.Дата;
Движение.ВремяНачала = Дата(
Год(СтрокаГрафика.Дата),
Месяц(СтрокаГрафика.Дата),
День(СтрокаГрафика.Дата),
Час(СтрокаГрафика.ВремяНачала),
Минута(СтрокаГрафика.ВремяНачала),
0
);
Движение.ВремяОкончания = Дата(
Год(СтрокаГрафика.Дата),
Месяц(СтрокаГрафика.Дата),
День(СтрокаГрафика.Дата),
Час(СтрокаГрафика.ВремяОкончания),
Минута(СтрокаГрафика.ВремяОкончания),
0
);
Движение.Интервал = НомерИнтервала;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
```
---
### 2. МОДУЛЬ МЕНЕДЖЕРА (Документ)
```bsl
#Область ПубличныйИнтерфейс
Функция ПолучитьМассивКалендарей(Знач ГодВыбора) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ГрафикРаботы.Ссылка КАК ПроизводственныйКалендарь
|ИЗ
| Справочник.ГрафикРаботы КАК ГрафикРаботы
|ГДЕ
| ГОД(ГрафикРаботы.ДатаНачала) = &Год
| И НЕ ГрафикРаботы.ПометкаУдаления
|УПОРЯДОЧИТЬ ПО
| ГрафикРаботы.Наименование";
Запрос.УстановитьПараметр("Год", ГодВыбора);
Возврат Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ПроизводственныйКалендарь");
КонецФункции
Функция ПолучитьСписокЗначенийКалендарей(Знач ГодВыбора) Экспорт
СписокКалендарей = Новый СписокЗначений;
СписокКалендарей.ЗагрузитьЗначения(ПолучитьМассивКалендарей(ГодВыбора));
Возврат СписокКалендарей;
КонецФункции
Функция ПолучитьКалендарь(Знач ГодВыбора) Экспорт
МассивКалендарей = ПолучитьМассивКалендарей(ГодВыбора);
Если МассивКалендарей.Количество() <> 0 Тогда
Возврат МассивКалендарей[0];
КонецЕсли;
Возврат Неопределено;
КонецФункции
#КонецОбласти
```
---
### 3. МОДУЛЬ ФОРМЫ (ФормаДокумента)
*(Примечание: В `Документы.УстановкаГрафиковРаботы` укажите реальное имя документа из конфигуратора)*
```bsl
&НаКлиенте
Перем МассивСообщений;
&НаКлиенте
Перем ТекущийСотрудникТаблицыСотрудник;
&НаКлиенте
Перем ТекущаяСтрокаТаблицыДанныеОВремени;
&НаКлиенте
Перем МесяцРегистрацииСтрокой;
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
Объект.Организация = ПараметрыСеанса.ТекущийПользователь.Организация;
Объект.МесяцГрафика = ТекущаяДатаСеанса();
КонецЕсли;
МесяцРегистрацииСтрокой = Формат(Объект.МесяцГрафика, "ДФ='ММММ гггг'");
ЗаполнитьДанныеОВремени();
Элементы.ЗаполнитьПоПроизводственномуГрафику.Заголовок = "Заполнить по производственному графику" + Символы.ПС + "для всех сотрудников";
Если НЕ ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
Объект.ПроизводственныйКалендарь = Документы.УстановкаГрафиковРаботы.ПолучитьКалендарь(Год(Объект.МесяцГрафика));
КонецЕсли;
ПроизводственныйКалендарьПриИзмененииНаСервере();
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовШапкиФормы
&НаКлиенте
Процедура МесяцРегистрацииСтрокойАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
Если Не ПустаяСтрока(Текст) Тогда
ДанныеВыбора = ДатаКакМесяцПодобратьДатуПоТексту(Текст);
СтандартнаяОбработка = Ложь;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура МесяцРегистрацииСтрокойНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
ЗадатьВопросПриИзмененииДаты();
КонецПроцедуры
&НаКлиенте
Процедура МесяцРегистрацииСтрокойПриИзменении(Элемент = Неопределено)
ОчиститьГрафикРаботыСотрудников();
ЗаполнитьПроизводственныйКалендарь(Год(Объект.МесяцГрафика));
ПроизводственныйКалендарьПриИзменении();
КонецПроцедуры
&НаКлиенте
Процедура ПроизводственныйКалендарьНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ГодВыбора = Год(Объект.МесяцГрафика);
СписокКалендарей = ПолучитьСписокЗначенийКалендарейНаСервере(ГодВыбора);
ВыбранныйЭлемент = СписокКалендарей.ВыбратьЭлемент("Выберите производственный календарь за " + ГодВыбора);
Если ВыбранныйЭлемент <> Неопределено Тогда
Объект.ПроизводственныйКалендарь = ВыбранныйЭлемент.Значение;
ИначеЕсли СписокКалендарей.Количество() = 0 Тогда
Сообщить("Отсутствует производственный календарь за " + ГодВыбора + " год.");
КонецЕсли;
ПроизводственныйКалендарьПриИзменении();
КонецПроцедуры
&НаКлиенте
Процедура ПроизводственныйКалендарьПриИзменении(Элемент = Неопределено)
Если НЕ ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
СделатьОсновныеЭлементыФормыНедоступными();
Сообщить("Заполните производственный график");
Иначе
СделатьОсновныеЭлементыФормыДоступными();
ЗагрузитьТаблицуПроизводственногоКалендаря();
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицФормы
&НаКлиенте
Процедура СотрудникиОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Если ТипЗнч(ВыбранноеЗначение) <> Тип("Массив") Тогда
Возврат;
КонецЕсли;
Для Каждого Сотрудник Из ВыбранноеЗначение Цикл
НайденныеСтроки = Объект.Сотрудники.НайтиСтроки(Новый Структура("Сотрудник", Сотрудник));
Если НайденныеСтроки.Количество() > 0 Тогда
Продолжить;
КонецЕсли;
НоваяСтрока = Объект.Сотрудники.Добавить();
НоваяСтрока.Сотрудник = Сотрудник;
ДобавитьКолонкуСотрудника(Сотрудник);
КонецЦикла;
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
&НаКлиенте
Процедура СотрудникиПередУдалением(Элемент, Отказ)
СтрокаСотрудника = Элементы.Сотрудники.ТекущиеДанные;
Если СтрокаСотрудника <> Неопределено Тогда
УдалитьКолонкуСотрудников(СтрокаСотрудника.Сотрудник);
УдалитьСотрудникаИзГрафикаРаботыСотрудников(СтрокаСотрудника.Сотрудник);
УдалитьСотрудникаИзСоответствиеКолонокСотрудников(СтрокаСотрудника.Сотрудник);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура СотрудникиПослеУдаления(Элемент)
Если Объект.Сотрудники.Количество() = 0 Тогда
Объект.ГрафикРаботыСотрудников.Очистить();
Объект.СоответствиеКолонокСотрудников.Очистить();
КонецЕсли;
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
&НаКлиенте
Процедура СотрудникиВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
Сотрудник = Элемент.ТекущиеДанные.Сотрудник;
ПараметрыФормы = Новый Структура;
ДатаСтроки = НачалоМесяца(Объект.МесяцГрафика);
Если ТекущаяСтрокаТаблицыДанныеОВремени <> Неопределено
И ТекущаяСтрокаТаблицыДанныеОВремени.Свойство("Дата")
И ЗначениеЗаполнено(ТекущаяСтрокаТаблицыДанныеОВремени.Дата) Тогда
ДатаСтроки = ТекущаяСтрокаТаблицыДанныеОВремени.Дата;
КонецЕсли;
ПараметрыФормы.Вставить("ДатаСтроки", ДатаСтроки);
ПараметрыФормы.Вставить("МесяцГрафика", Объект.МесяцГрафика);
ПараметрыФормы.Вставить("ГрафикРаботыСотрудников", Объект.ГрафикРаботыСотрудников);
СписокСотрудников = Новый СписокЗначений;
СписокСотрудников.Добавить(Сотрудник);
ПараметрыФормы.Вставить("КоллекцияСотрудников", СписокСотрудников);
ПараметрыФормы.Вставить("ПоОдномуСотруднику", Истина);
Оповещение = Новый ОписаниеОповещения("ПослеЗаписиДанныхФормыРасписаниеРаботы", ЭтотОбъект);
ОткрытьФорму("Документ.УстановкаГрафиковРаботы.Форма.РасписаниеРаботы", ПараметрыФормы, ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура СотрудникиПриАктивизацииСтроки(Элемент)
ТекущаяСтрокаПерем = Элемент.ТекущиеДанные;
ТекущийСотрудникТаблицыСотрудник = Неопределено;
Элемент.КонтекстноеМеню.ПодчиненныеЭлементы.СотрудникиКонтекстноеМенюЗаполнитьПоПроизводственномуГрафикуСотрудника.Доступность = Ложь;
Элемент.КоманднаяПанель.ПодчиненныеЭлементы.СотрудникиЗаполнитьПоПроизводственномуГрафикуСотрудника.Доступность = Ложь;
Если ТекущаяСтрокаПерем <> Неопределено И ТекущаяСтрокаПерем.Свойство("Сотрудник") И НЕ ТекущаяСтрокаПерем.Сотрудник.Пустая() Тогда
ТекущийСотрудникТаблицыСотрудник = ТекущаяСтрокаПерем.Сотрудник;
Элемент.КонтекстноеМеню.ПодчиненныеЭлементы.СотрудникиКонтекстноеМенюЗаполнитьПоПроизводственномуГрафикуСотрудника.Доступность = Истина;
Элемент.КоманднаяПанель.ПодчиненныеЭлементы.СотрудникиЗаполнитьПоПроизводственномуГрафикуСотрудника.Доступность = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ДанныеОВремениПриАктивизацииСтроки(Элемент)
ТекущаяСтрокаПерем = Элемент.ТекущиеДанные;
СтруктураСтроки = Неопределено;
Если ТекущаяСтрокаПерем <> Неопределено И ТекущаяСтрокаПерем.Свойство("Дата") Тогда
СтруктураСтроки = Новый Структура;
СтруктураСтроки.Вставить("Дата", ТекущаяСтрокаПерем.Дата);
Для Каждого Сотрудник Из Объект.Сотрудники Цикл
ИмяРеквизита = ПолучитьИмяКолонкиПоСотруднику(Сотрудник.Сотрудник);
Если ТекущаяСтрокаПерем.Свойство(ИмяРеквизита) Тогда
СтруктураСтроки.Вставить(ИмяРеквизита, ТекущаяСтрокаПерем[ИмяРеквизита]);
КонецЕсли;
КонецЦикла;
КонецЕсли;
ТекущаяСтрокаТаблицыДанныеОВремени = СтруктураСтроки;
КонецПроцедуры
&НаКлиенте
Процедура ДанныеОВремениВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
ТекущаяСтрока = Элемент.ТекущиеДанные;
Сотрудник = ПолучитьСотрудникаПоИмениКолонки(Поле.Имя);
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ДатаСтроки", ТекущаяСтрока.Дата);
ПараметрыФормы.Вставить("НеизменяемаяДата", Истина);
ПараметрыФормы.Вставить("МесяцГрафика", Объект.МесяцГрафика);
ПараметрыФормы.Вставить("ГрафикРаботыСотрудников", Объект.ГрафикРаботыСотрудников);
СписокСотрудников = Новый СписокЗначений;
Если ЗначениеЗаполнено(Сотрудник) Тогда
ПараметрыФормы.Вставить("ПоОдномуСотруднику", Истина);
СписокСотрудников.Добавить(Сотрудник);
Иначе
Для Каждого Эл Из Объект.Сотрудники Цикл
СписокСотрудников.Добавить(Эл.Сотрудник);
КонецЦикла;
КонецЕсли;
ПараметрыФормы.Вставить("КоллекцияСотрудников", СписокСотрудников);
Оповещение = Новый ОписаниеОповещения("ПослеЗаписиДанныхФормыРасписаниеРаботы", ЭтотОбъект);
ОткрытьФорму("Документ.УстановкаГрафиковРаботы.Форма.РасписаниеРаботы", ПараметрыФормы, ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура Подбор(Команда)
Если НЕ ЗначениеЗаполнено(Объект.Подразделение) Тогда
Сообщить("Заполните подразделение");
Возврат;
КонецЕсли;
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Подразделение", Объект.Подразделение);
ОткрытьФорму("Справочник.Сотрудники.Форма.ФормаПодбора", ПараметрыФормы, Элементы.Сотрудники);
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьПоПроизводственномуГрафику(Команда)
ЗаполнитьПоПроизводственномуГрафикуНаСервере();
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьПоПроизводственномуГрафикуСотрудника(Команда)
Если ЗначениеЗаполнено(ТекущийСотрудникТаблицыСотрудник) Тогда
ЗаполнитьПоПроизводственномуГрафикуСотрудникаНаСервере(ТекущийСотрудникТаблицыСотрудник);
ОтрисоватьТаблицуДанныеОВремени();
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункцииКлиент
&НаКлиенте
Функция ДатаКакМесяцПодобратьДатуПоТексту(Текст, ДатаПоТексту = НеОпределено)
СписокВозврата = Новый СписокЗначений;
ТекущийГод = Год(ТекущаяДата());
Если ПустаяСтрока(Текст) Тогда
ДатаПоТексту = Дата(1, 1, 1);
Возврат СписокВозврата;
КонецЕсли;
Если СтрНайти(Текст, ".") <> 0 Тогда
Подстроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Текст, ".");
ИначеЕсли СтрНайти(Текст, ",") <> 0 Тогда
Подстроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Текст, ",");
ИначеЕсли СтрНайти(Текст, "-") <> 0 Тогда
Подстроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Текст, "-");
ИначеЕсли СтрНайти(Текст, "/") <> 0 Тогда
Подстроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Текст, "/");
ИначеЕсли СтрНайти(Текст, "\") <> 0 Тогда
Подстроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Текст, "\");
Иначе
Подстроки = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(Текст, " ");
КонецЕсли;
Если Подстроки.Количество() = 1 Тогда
Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Текст) Тогда
МесяцЧислом = Число(Текст);
Если МесяцЧислом >= 1 И МесяцЧислом <= 12 Тогда
ДатаПоТексту = Дата(ТекущийГод, МесяцЧислом, 1);
Если СтрДлина(Текст) = 1 Тогда
СписокВозврата.Добавить(Формат(ДатаПоТексту, "ДФ='М/гг'"));
Иначе
СписокВозврата.Добавить(Формат(ДатаПоТексту, "ДФ='ММ/гг'"));
КонецЕсли;
Иначе
Возврат СписокВозврата;
КонецЕсли;
Иначе
СписокМесяцев = СписокМесяцевПоСтроке(Текст);
Для Каждого Месяц Из СписокМесяцев Цикл
ДатаПоТексту = Дата(ТекущийГод, Месяц, 1);
СписокВозврата.Добавить(Формат(ДатаПоТексту, "ДФ='ММММ гггг'"));
КонецЦикла;
КонецЕсли;
ИначеЕсли Подстроки.Количество() = 2 Тогда
Если СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Подстроки[1]) Тогда
Если ПустаяСтрока(Подстроки[1]) Тогда
ГодЧислом = 0;
Иначе
ГодЧислом = Число(Подстроки[1]);
КонецЕсли;
Если ГодЧислом > 3000 Тогда
Возврат СписокВозврата;
КонецЕсли;
Если СтрДлина(Подстроки[1]) <= 1 Тогда
ГодЧислом = Число(Лев(Формат(ТекущийГод, "ЧГ="), 3) + Подстроки[1]);
ИначеЕсли СтрДлина(Подстроки[1]) = 2 Тогда
ГодЧислом = Число(Лев(Формат(ТекущийГод, "ЧГ="), 2) + Подстроки[1]);
ИначеЕсли СтрДлина(Подстроки[1]) = 3 Тогда
ГодЧислом = Число(Лев(Формат(ТекущийГод, "ЧГ="), 1) + Подстроки[1]);
ИначеЕсли СтрДлина(Подстроки[1]) = 4 Тогда
ГодЧислом = Число(Подстроки[1]);
КонецЕсли;
Иначе
Возврат СписокВозврата;
КонецЕсли;
Если ЗначениеЗаполнено(Подстроки[0]) И СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Подстроки[0]) Тогда
МесяцЧислом = Число(Подстроки[0]);
Если МесяцЧислом >= 1 И МесяцЧислом <= 12 Тогда
ДатаПоТексту = Дата(ГодЧислом, МесяцЧислом, 1);
СписокВозврата.Добавить(Формат(ДатаПоТексту, "ДФ='ММММ гггг'"));
Иначе
Возврат СписокВозврата;
КонецЕсли;
Иначе
СписокМесяцев = СписокМесяцевПоСтроке(Подстроки[0]);
Если СписокМесяцев.Количество() = 1 Тогда
ДатаПоТексту = Дата(ГодЧислом, СписокМесяцев[0], 1);
СписокВозврата.Добавить(Формат(ДатаПоТексту, "ДФ='ММММ гггг'"));
Иначе
Для Каждого Месяц Из СписокМесяцев Цикл
ДатаПоТексту = Дата(ГодЧислом, Месяц, 1);
СписокВозврата.Добавить(Формат(Дата(ГодЧислом, Месяц, 1), "ДФ='ММММ гггг'"));
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Возврат СписокВозврата;
КонецФункции
&НаКлиенте
Функция СписокМесяцевПоСтроке(Текст)
СписокМесяцев = Новый СписокЗначений;
Месяцы = Новый Соответствие;
МесяцыВозврата = Новый Массив;
Для Счетчик = 1 По 12 Цикл
Представление = Формат(Дата(2000, Счетчик, 1), "ДФ='ММММ'");
СписокМесяцев.Добавить(Счетчик, Представление);
Представление = Формат(Дата(2000, Счетчик, 1), "ДФ='МММ'");
СписокМесяцев.Добавить(Счетчик, Представление);
КонецЦикла;
Для Каждого ЭлементСписка Из СписокМесяцев Цикл
Если ВРег(Текст) = ВРег(Лев(ЭлементСписка.Представление, СтрДлина(Текст))) Тогда
Месяцы[ЭлементСписка.Значение] = 0;
КонецЕсли;
КонецЦикла;
Для Каждого Элемент Из Месяцы Цикл
МесяцыВозврата.Добавить(Элемент.Ключ);
КонецЦикла;
Возврат МесяцыВозврата;
КонецФункции
&НаКлиенте
Процедура ПродолжитьИзменениеМесяцаГрафика()
Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", ЭтотОбъект);
ПараметрыПериода = Новый Структура("УстановленныйПериод,РежимВыбораПериода", Объект.МесяцГрафика, "Месяц");
ОткрытьФорму("Документ.УстановкаГрафиковРаботы.Форма.ФормаВыборПериода", ПараметрыПериода, ЭтотОбъект, , , , Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораПериода(Результат, ДопПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Объект.МесяцГрафика = Результат;
МесяцРегистрацииСтрокой = Формат(Объект.МесяцГрафика, "ДФ='ММММ гггг'");
МесяцРегистрацииСтрокойПриИзменении();
КонецПроцедуры
&НаКлиенте
Процедура ЗадатьВопросПриИзмененииДаты()
Обработчик = Новый ОписаниеОповещения("ОчиститьРасписаниеСотрудниковПослеЗакрытияВопроса", ЭтотОбъект);
ТекстВопроса = НСтр("ru = 'При изменении месяца будет утеряно нынешнее расписание сотрудников. Продолжить?'");
ПоказатьВопрос(Обработчик, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ОчиститьРасписаниеСотрудниковПослеЗакрытияВопроса(Результат, Параметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ПродолжитьИзменениеМесяцаГрафика();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьПроизводственныйКалендарь(ГодВыбора)
Объект.ПроизводственныйКалендарь = Неопределено;
ПроизводственныйГрафик.Очистить();
Календарь = ПолучитьКалендарьНаСервере(ГодВыбора);
Если Календарь <> Неопределено Тогда
Объект.ПроизводственныйКалендарь = Календарь;
Иначе
Сообщить("Отсутствует производственный календарь за " + ГодВыбора + " год.");
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Функция ЕстьДубльСотрудника(Сотрудник, ИдентификаторТекущейСтроки)
Для Каждого СтрокаТЧ Из Объект.Сотрудники Цикл
Если СтрокаТЧ.Сотрудник = Сотрудник И СтрокаТЧ.ПолучитьИдентификатор() <> ИдентификаторТекущейСтроки Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
&НаКлиенте
Процедура ПослеЗаписиДанныхФормыРасписаниеРаботы(Результат, ДопПараметры) Экспорт
Если Результат <> Неопределено Тогда
ПослеЗаписиДанныхФормыРасписаниеРаботыНаСервере(Результат, ДопПараметры);
КонецЕсли;
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункцииСервер
&НаСервереБезКонтекста
Функция ПолучитьКалендарьНаСервере(Знач ГодВыбора)
Возврат Документы.УстановкаГрафиковРаботы.ПолучитьКалендарь(ГодВыбора);
КонецФункции
&НаСервереБезКонтекста
Функция ПолучитьСписокЗначенийКалендарейНаСервере(Знач ГодВыбора)
Возврат Документы.УстановкаГрафиковРаботы.ПолучитьСписокЗначенийКалендарей(ГодВыбора);
КонецФункции
&НаСервере
Процедура ПроизводственныйКалендарьПриИзмененииНаСервере()
Если НЕ ЗначениеЗаполнено(Объект.ПроизводственныйКалендарь) Тогда
СделатьОсновныеЭлементыФормыНедоступными();
Сообщить("Заполните производственный график");
Иначе
СделатьОсновныеЭлементыФормыДоступными();
ЗагрузитьТаблицуПроизводственногоКалендаря();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СделатьОсновныеЭлементыФормыНедоступными()
Элементы.Сотрудники.Доступность = Ложь;
Элементы.ДанныеОВремени.Доступность = Ложь;
Элементы.ЗаполнитьПоПроизводственномуГрафику.Доступность = Ложь;
КонецПроцедуры
&НаСервере
Процедура СделатьОсновныеЭлементыФормыДоступными()
Элементы.Сотрудники.Доступность = Истина;
Элементы.ДанныеОВремени.Доступность = Истина;
Элементы.ЗаполнитьПоПроизводственномуГрафику.Доступность = Истина;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДанныеОВремени()
Для Каждого СтрСотрудник Из Объект.Сотрудники Цикл
ДобавитьКолонкуСотрудника(СтрСотрудник.Сотрудник);
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ДобавитьКолонкуСотрудника(Сотрудник)
Если ЗначениеЗаполнено(Сотрудник) Тогда
ИмяКолонки = ВернутьУникальноеИмяКолонкиСотрудника(Сотрудник);
РекРодителя = ПолучитьРеквизиты("ДанныеОВремени");
НаличиеРеквизита = Ложь;
Для Каждого ТекРек Из РекРодителя Цикл
Если ТекРек.Имя = ИмяКолонки Тогда
НаличиеРеквизита = Истина;
КонецЕсли;
КонецЦикла;
Если НЕ НаличиеРеквизита Тогда
ЗаголовокКолонки = ВернутьФамилиюИИнициалы(Сотрудник.Наименование);
НовыеРеквизиты = Новый Массив;
НовыйРеквизит = Новый РеквизитФормы(ИмяКолонки, Новый ОписаниеТипов("Строка"), "ДанныеОВремени", ЗаголовокКолонки, Ложь);
НовыеРеквизиты.Добавить(НовыйРеквизит);
ИзменитьРеквизиты(НовыеРеквизиты);
ТаблицаФормы = Элементы.ДанныеОВремени;
НоваяКолонка = Элементы.Добавить(ИмяКолонки, Тип("ПолеФормы"), ТаблицаФормы);
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
НоваяКолонка.ПутьКДанным = "ДанныеОВремени." + ИмяКолонки;
НоваяКолонка.Заголовок = ЗаголовокКолонки;
КонецЕсли;
ДобавитьСоответствиеИмениКолонкиИСотрудника(ИмяКолонки, Сотрудник);
ЗадатьФорматТЧДанныеОВремени();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ДобавитьСоответствиеИмениКолонкиИСотрудника(ИмяКолонки, Сотрудник)
Отбор = Новый Структура("Сотрудник, ИмяКолонки", Сотрудник, ИмяКолонки);
НайденныеСтроки = Объект.СоответствиеКолонокСотрудников.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() = 0 Тогда
НовоеСоответствие = Объект.СоответствиеКолонокСотрудников.Добавить();
НовоеСоответствие.ИмяКолонки = ИмяКолонки;
НовоеСоответствие.Сотрудник = Сотрудник;
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПолучитьСотрудникаПоИмениКолонки(ИмяКолонки)
Отбор = Новый Структура("ИмяКолонки", ИмяКолонки);
НайденныеСтроки = Объект.СоответствиеКолонокСотрудников.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() > 0 Тогда
Возврат НайденныеСтроки[0].Сотрудник;
КонецЕсли;
Возврат Справочники.Сотрудники.ПустаяСсылка();
КонецФункции
&НаСервере
Функция ПолучитьИмяКолонкиПоСотруднику(Сотрудник)
Отбор = Новый Структура("Сотрудник", Сотрудник);
НайденныеСтроки = Объект.СоответствиеКолонокСотрудников.НайтиСтроки(Отбор);
Если НайденныеСтроки.Количество() > 0 Тогда
Возврат НайденныеСтроки[0].ИмяКолонки;
КонецЕсли;
Возврат "";
КонецФункции
&НаСервере
Процедура УдалитьСотрудникаИзГрафикаРаботыСотрудников(Сотрудник)
Если ЗначениеЗаполнено(Сотрудник) Тогда
Отбор = Новый Структура("Сотрудник", Сотрудник);
НайденныеСтроки = Объект.ГрафикРаботыСотрудников.НайтиСтроки(Отбор);
Для Каждого Строка Из НайденныеСтроки Цикл
Объект.ГрафикРаботыСотрудников.Удалить(Строка);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура УдалитьКолонкуСотрудников(Сотрудник)
Если ЗначениеЗаполнено(Сотрудник) Тогда
ИмяКолонки = ВернутьУникальноеИмяКолонкиСотрудника(Сотрудник);
ИмяРодителя = "ДанныеОВремени";
ИмяУдаляемогоРеквизита = ИмяРодителя + "." + ИмяКолонки;
МассивУдаляемыхРеквизитов = Новый Массив;
РекРодителя = ПолучитьРеквизиты(ИмяРодителя);
Для Каждого ТекРек Из РекРодителя Цикл
Если ТекРек.Имя = ИмяКолонки Тогда
МассивУдаляемыхРеквизитов.Добавить(ИмяУдаляемогоРеквизита);
КонецЕсли;
КонецЦикла;
Если МассивУдаляемыхРеквизитов.Количество() > 0 Тогда
ИзменитьРеквизиты(, МассивУдаляемыхРеквизитов);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура УдалитьСотрудникаИзСоответствиеКолонокСотрудников(Сотрудник)
Если ЗначениеЗаполнено(Сотрудник) Тогда
НомерСтроки = Объект.СоответствиеКолонокСотрудников.Количество() - 1;
Пока НомерСтроки >= 0 Цикл
Если Объект.СоответствиеКолонокСотрудников[НомерСтроки].Сотрудник = Сотрудник Тогда
Объект.СоответствиеКолонокСотрудников.Удалить(НомерСтроки);
КонецЕсли;
НомерСтроки = НомерСтроки - 1;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ВернутьФамилиюИИнициалы(ФИО)
МассивСлов = СтрРазделить(СокрЛП(ФИО), " ");
Если МассивСлов.Количество() = 3 Тогда
Возврат МассивСлов[0] + " " + Лев(МассивСлов[1], 1) + "." + Лев(МассивСлов[2], 1) + ".";
Иначе
Возврат СтрСоединить(МассивСлов, " ");
КонецЕсли;
КонецФункции
&НаСервере
Функция ВернутьУникальноеИмяКолонкиСотрудника(Сотрудник)
ЧастьУИД = Сред(Строка(СтрЗаменить(Сотрудник.УникальныйИдентификатор(), "-", "_")), 1, 8);
Возврат "С_" + Сотрудник.Код + "_" + ЧастьУИД;
КонецФункции
&НаСервере
Функция ВернутьГодПроизводственногоКалендаря()
Возврат Объект.ПроизводственныйКалендарь.Год;
КонецФункции
&НаСервере
Процедура ЗагрузитьТаблицуПроизводственногоКалендаря()
ДатаВыбора = Объект.МесяцГрафика;
ПроизводственныйКалендарь = Объект.ПроизводственныйКалендарь;
Если НЕ ЗначениеЗаполнено(ПроизводственныйКалендарь) Тогда
Сообщить("Заполните производственный календарь");
Возврат;
КонецЕсли;
ПроизводственныйГрафик.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДанныеПК.Дата КАК Дата,
| ДЕНЬНЕДЕЛИ(ДанныеПК.Дата) КАК ДеньНедели,
| ДанныеПК.Год КАК Год,
| ДанныеПК.ВидДня КАК ВидДня,
| ДанныеПК.ПроизводственныйКалендарь.Ссылка КАК ПроизводственныйКалендарьСсылка
|ПОМЕСТИТЬ ВТ_ДанныеПК
|ИЗ
| РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеПК
|ГДЕ
| ДанныеПК.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, МЕСЯЦ) И КОНЕЦПЕРИОДА(КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ), ДЕНЬ)
| И ДанныеПК.ПроизводственныйКалендарь = &ПроизводственныйКалендарь
|;
|
|ВЫБРАТЬ
| ВЫБОР
| КОГДА Расписание.ВремяНачала ЕСТЬ NULL ТОГДА НЕОПРЕДЕЛЕНО
| ИНАЧЕ Расписание.ВремяНачала
| КОНЕЦ КАК ВремяНачала,
| ВЫБОР
| КОГДА Расписание.ВремяОкончания ЕСТЬ NULL ТОГДА НЕОПРЕДЕЛЕНО
| ИНАЧЕ Расписание.ВремяОкончания
| КОНЕЦ КАК ВремяОкончания,
| ВТ_ДанныеПК.Дата КАК Дата,
| ВТ_ДанныеПК.ДеньНедели КАК ДеньНедели,
| ВТ_ДанныеПК.ВидДня КАК ВидДня
|ИЗ
| ВТ_ДанныеПК КАК ВТ_ДанныеПК
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ГрафикРаботы.РасписаниеРаботы КАК Расписание
| ПО ВТ_ДанныеПК.ПроизводственныйКалендарьСсылка = Расписание.Ссылка.Ссылка
| И ВТ_ДанныеПК.ДеньНедели = Расписание.НомерДня
|УПОРЯДОЧИТЬ ПО
| Дата, ДеньНедели, ВремяНачала";
Запрос.УстановитьПараметр("Дата", ДатаВыбора);
Запрос.УстановитьПараметр("ПроизводственныйКалендарь", ПроизводственныйКалендарь);
ПроизводственныйГрафик.Загрузить(Запрос.Выполнить().Выгрузить());
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоПроизводственномуГрафикуНаСервере()
Если Объект.Сотрудники.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Объект.ГрафикРаботыСотрудников.Очистить();
Для Каждого СтрокаСотрудник Из Объект.Сотрудники Цикл
Для Каждого СтрокаТЧ Из ПроизводственныйГрафик Цикл
Если ЗначениеЗаполнено(СтрокаТЧ.ВремяНачала) И ЗначениеЗаполнено(СтрокаТЧ.ВремяОкончания) Тогда
НоваяСтрока = Объект.ГрафикРаботыСотрудников.Добавить();
НоваяСтрока.Сотрудник = СтрокаСотрудник.Сотрудник;
НоваяСтрока.ВремяНачала = СтрокаТЧ.ВремяНачала;
НоваяСтрока.ВремяОкончания = ?(СтрокаТЧ.ВремяОкончания = Дата(1, 1, 1, 0, 0, 0), Дата(1, 1, 1, 23, 59, 0), СтрокаТЧ.ВремяОкончания);
НоваяСтрока.Дата = СтрокаТЧ.Дата;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоПроизводственномуГрафикуСотрудникаНаСервере(Сотрудник)
Отбор = Новый Структура("Сотрудник", Сотрудник);
НайденныеСтроки = Объект.ГрафикРаботыСотрудников.НайтиСтроки(Отбор);
Для Каждого Строка Из НайденныеСтроки Цикл
Объект.ГрафикРаботыСотрудников.Удалить(Строка);
КонецЦикла;
Для Каждого СтрокаТЧ Из ПроизводственныйГрафик Цикл
Если ЗначениеЗаполнено(СтрокаТЧ.ВремяНачала) И ЗначениеЗаполнено(СтрокаТЧ.ВремяОкончания) Тогда
НоваяСтрока = Объект.ГрафикРаботыСотрудников.Добавить();
НоваяСтрока.Сотрудник = Сотрудник;
НоваяСтрока.ВремяНачала = СтрокаТЧ.ВремяНачала;
НоваяСтрока.ВремяОкончания = ?(СтрокаТЧ.ВремяОкончания = Дата(1, 1, 1, 0, 0, 0), Дата(1, 1, 1, 23, 59, 0), СтрокаТЧ.ВремяОкончания);
НоваяСтрока.Дата = СтрокаТЧ.Дата;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ОтрисоватьТаблицуДанныеОВремени()
ТЗГрафикРаботыСотрудников = Объект.ГрафикРаботыСотрудников.Выгрузить();
Если ТЗГрафикРаботыСотрудников.Количество() = 0 И Объект.Сотрудники.Количество() = 0 Тогда
ДанныеОВремени.Очистить();
Возврат;
КонецЕсли;
СохраненнаяДата = Неопределено;
Если ТекущаяСтрокаТаблицыДанныеОВремени <> Неопределено
И ТипЗнч(ТекущаяСтрокаТаблицыДанныеОВремени) = Тип("Структура")
И ТекущаяСтрокаТаблицыДанныеОВремени.Свойство("Дата") Тогда
СохраненнаяДата = ТекущаяСтрокаТаблицыДанныеОВремени.Дата;
КонецЕсли;
ТЗТаблицаДатМесяца = Новый ТаблицаЗначений;
ТЗТаблицаДатМесяца.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата"));
ДатаДляТаблицы = НачалоМесяца(Объект.МесяцГрафика);
ДатаСледующегоМесяца = НачалоДня(ДобавитьМесяц(ДатаДляТаблицы, 1));
Пока ДатаДляТаблицы < ДатаСледующегоМесяца Цикл
ТЗТаблицаДатМесяца.Добавить().Дата = ДатаДляТаблицы;
ДатаДляТаблицы = КонецДня(ДатаДляТаблицы) + 1;
КонецЦикла;
ТЗТаблицаДатМесяца.Сортировать("Дата Возр");
ДанныеОВремени.Очистить();
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ ТаблицаДатМесяца.Дата КАК Дата ПОМЕСТИТЬ ВТТаблицаДатМесяца ИЗ &ТаблицаДатМесяца КАК ТаблицаДатМесяца;
|ВЫБРАТЬ ТаблицаСотрудников.Сотрудник КАК Сотрудник, ТаблицаСотрудников.ВремяНачала КАК ВремяНачала, ТаблицаСотрудников.ВремяОкончания КАК ВремяОкончания, ТаблицаСотрудников.Дата КАК Дата ПОМЕСТИТЬ ВТТаблицаСотрудников ИЗ &ТаблицаСотрудников КАК ТаблицаСотрудников;
|ВЫБРАТЬ ВТТаблицаДатМесяца.Дата КАК Дата, ВТТаблицаСотрудников.Сотрудник КАК Сотрудник, ВТТаблицаСотрудников.ВремяНачала КАК ВремяНачала, ВТТаблицаСотрудников.ВремяОкончания КАК ВремяОкончания ИЗ ВТТаблицаДатМесяца КАК ВТТаблицаДатМесяца ЛЕВОЕ СОЕДИНЕНИЕ ВТТаблицаСотрудников КАК ВТТаблицаСотрудников ПО ВТТаблицаДатМесяца.Дата = ВТТаблицаСотрудников.Дата УПОРЯДОЧИТЬ ПО Дата, Сотрудник, ВремяНачала";
Запрос.УстановитьПараметр("ТаблицаСотрудников", ТЗГрафикРаботыСотрудников);
Запрос.УстановитьПараметр("ТаблицаДатМесяца", ТЗТаблицаДатМесяца);
Выборка = Запрос.Выполнить().Выбрать();
СтрокиПоДатам = Новый Соответствие;
Пока Выборка.Следующий() Цикл
ТекущаяДатаВыборки = Выборка.Дата;
ДниМесяцаСтр = Формат(ТекущаяДатаВыборки, "ДФ='dd ddd'");
Если СтрокиПоДатам.Получить(ТекущаяДатаВыборки) <> Неопределено Тогда
МассивСтрок = СтрокиПоДатам[ТекущаяДатаВыборки];
Иначе
МассивСтрок = Новый Массив;
НоваяСтрока = ДанныеОВремени.Добавить();
НоваяСтрока.Дата = ТекущаяДатаВыборки;
НоваяСтрока.ДниМесяца = ДниМесяцаСтр;
НайденныеСтроки = ПроизводственныйГрафик.НайтиСтроки(Новый Структура("Дата", ТекущаяДатаВыборки));
НоваяСтрока.ВидДня = ?(НайденныеСтроки.Количество() > 0, НайденныеСтроки[0].ВидДня, Неопределено);
МассивСтрок.Добавить(НоваяСтрока);
СтрокиПоДатам.Вставить(ТекущаяДатаВыборки, МассивСтрок);
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Выборка.Сотрудник) Тогда
Продолжить;
КонецЕсли;
ИмяКолонки = ПолучитьИмяКолонкиПоСотруднику(Выборка.Сотрудник);
Интервал = ?(Формат(Выборка.ВремяНачала, "ДФ=ЧЧ:мм") = "", "00:00", Формат(Выборка.ВремяНачала, "ДФ=ЧЧ:мм")) + " - " + ?(Формат(Выборка.ВремяОкончания, "ДФ=ЧЧ:мм") = "", "00:00", Формат(Выборка.ВремяОкончания, "ДФ=ЧЧ:мм")) + " (" + ДниМесяцаСтр + ")";
СтрокаДляЗаписи = Неопределено;
Для Каждого СтрокаДанных Из МассивСтрок Цикл
Если ПустаяСтрока(СтрокаДанных[ИмяКолонки]) Тогда
СтрокаДляЗаписи = СтрокаДанных;
Прервать;
КонецЕсли;
КонецЦикла;
Если СтрокаДляЗаписи = Неопределено Тогда
СтрокаДляЗаписи = ДанныеОВремени.Добавить();
СтрокаДляЗаписи.ВидДня = ?(НайденныеСтроки.Количество() > 0, НайденныеСтроки[0].ВидДня, Неопределено);
СтрокаДляЗаписи.Дата = ТекущаяДатаВыборки;
МассивСтрок.Добавить(СтрокаДляЗаписи);
КонецЕсли;
СтрокаДляЗаписи[ИмяКолонки] = Интервал;
КонецЦикла;
Если СохраненнаяДата <> Неопределено Тогда
Для Каждого СтрокаДанных Из ДанныеОВремени Цикл
Если СохраненнаяДата = СтрокаДанных.Дата Тогда
Элементы.ДанныеОВремени.ТекущаяСтрока = СтрокаДанных.ПолучитьИдентификатор();
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
УстановитьУсловноеОформлениеДанныеОВремени();
КонецПроцедуры
&НаСервере
Процедура УстановитьУсловноеОформлениеДанныеОВремени()
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(245, 251, 255));
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДанныеОВремени.ВидДня");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
СписокВидовДней = Новый СписокЗначений;
СписокВидовДней.Добавить(Перечисления.ВидыДнейПроизводственногоКалендаря.Суббота);
СписокВидовДней.Добавить(Перечисления.ВидыДнейПроизводственногоКалендаря.Воскресенье);
ЭлементОтбора.ПравоеЗначение = СписокВидовДней;
ЭлементОтбора.Использование = Истина;
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ДанныеОВремени");
// Праздники
ЭлементОформленияПраздник = УсловноеОформление.Элементы.Добавить();
ЭлементОформленияПраздник.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(255, 225, 232));
ЭлементОтбораПраздник = ЭлементОформленияПраздник.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораПраздник.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДанныеОВремени.ВидДня");
ЭлементОтбораПраздник.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораПраздник.ПравоеЗначение = Перечисления.ВидыДнейПроизводственногоКалендаря.Праздник;
ЭлементОтбораПраздник.Использование = Истина;
ПолеОформленияПраздник = ЭлементОформленияПраздник.Поля.Элементы.Добавить();
ПолеОформленияПраздник.Поле = Новый ПолеКомпоновкиДанных("ДанныеОВремени");
// Нерабочие
ЭлементОформленияНерабочий = УсловноеОформление.Элементы.Добавить();
ЭлементОформленияНерабочий.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(240, 240, 240));
ЭлементОтбораНерабочий = ЭлементОформленияНерабочий.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбораНерабочий.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДанныеОВремени.ВидДня");
ЭлементОтбораНерабочий.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбораНерабочий.ПравоеЗначение = Перечисления.ВидыДнейПроизводственногоКалендаря.Нерабочий;
ЭлементОтбораНерабочий.Использование = Истина;
ПолеОформленияНерабочий = ЭлементОформленияНерабочий.Поля.Элементы.Добавить();
ПолеОформленияНерабочий.Поле = Новый ПолеКомпоновкиДанных("ДанныеОВремени");
КонецПроцедуры
&НаСервере
Процедура ЗадатьФорматТЧДанныеОВремени()
Элементы.ДанныеОВремени.РастягиватьПоВертикали = Истина;
Элементы.ДанныеОВремени.РастягиватьПоГоризонтали = Истина;
Элементы.ДанныеОВремени.Ширина = 100;
Элементы.ДанныеОВремени.ПодчиненныеЭлементы.ДанныеОВремениГруппаКолонок.РастягиватьПоВертикали = Истина;
Элементы.ДанныеОВремени.ПодчиненныеЭлементы.ДанныеОВремениГруппаКолонок.РастягиватьПоГоризонтали = Ложь;
КоллекцияЭлементов = Элементы.ДанныеОВремени.ПодчиненныеЭлементы;
Для Индекс = 1 По КоллекцияЭлементов.Количество() - 1 Цикл
КоллекцияЭлементов[Индекс].ТолькоПросмотр = Истина;
КоллекцияЭлементов[Индекс].РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
КоллекцияЭлементов[Индекс].ГоризонтальноеПоложениеВШапке = ГоризонтальноеПоложениеЭлемента.Центр;
КоллекцияЭлементов[Индекс].ГоризонтальноеПоложение = ГоризонтальноеПоложениеЭлемента.Центр;
КонецЦикла;
КоллекцияЭлементовГруппы = Элементы.ДанныеОВремени.ПодчиненныеЭлементы.ДанныеОВремениГруппаКолонок.ПодчиненныеЭлементы;
Для Индекс = 0 По КоллекцияЭлементовГруппы.Количество() - 1 Цикл
КоллекцияЭлементовГруппы[Индекс].ТолькоПросмотр = Истина;
КоллекцияЭлементовГруппы[Индекс].РежимРедактирования = РежимРедактированияКолонки.Непосредственно;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ПослеЗаписиДанныхФормыРасписаниеРаботыНаСервере(Результат, ДопПараметры)
КоллекцияСотрудников = Результат.КоллекцияСотрудников;
ГрафикРаботыПоКонкретномуСотруднику = Результат.ГрафикРаботыПоКонкретномуСотруднику;
ДатаРедактирования = Результат.ДатаРедактирования;
Для Индекс = 0 По КоллекцияСотрудников.Количество() - 1 Цикл
Отбор = Новый Структура("Сотрудник, Дата", КоллекцияСотрудников[Индекс].Значение, ДатаРедактирования);
НайденныеСтроки = Объект.ГрафикРаботыСотрудников.НайтиСтроки(Отбор);
Для Каждого Строка Из НайденныеСтроки Цикл
Объект.ГрафикРаботыСотрудников.Удалить(Строка);
КонецЦикла;
КонецЦикла;
НайденныеСтроки = ГрафикРаботыПоКонкретномуСотруднику.НайтиСтроки(Новый Структура("Дата", ДатаРедактирования));
Для Каждого Строка Из НайденныеСтроки Цикл
НоваяСтрока = Объект.ГрафикРаботыСотрудников.Добавить();
НоваяСтрока.Сотрудник = Строка.Сотрудник;
НоваяСтрока.Дата = Строка.Дата;
НоваяСтрока.ВремяНачала = Строка.ВремяНачала;
НоваяСтрока.ВремяОкончания = Строка.ВремяОкончания;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура ОчиститьГрафикРаботыСотрудников()
Объект.ГрафикРаботыСотрудников.Очистить();
ОтрисоватьТаблицуДанныеОВремени();
КонецПроцедуры
#КонецОбласти
```