diff --git a/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/CommonModules/ПС_ТабелиСервер/Module.bsl b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/CommonModules/ПС_ТабелиСервер/Module.bsl
new file mode 100644
index 0000000..bb3aea4
--- /dev/null
+++ b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/CommonModules/ПС_ТабелиСервер/Module.bsl
@@ -0,0 +1,561 @@
+// Серверные функции для работы с табелем учёта рабочего времени.
+// Перенесены из модуля формы обработки ПС_ЗагрузкаТабеляУчётаРабочегоВремениИзEXCEL.
+
+#Область СлужебныеПроцедурыИФункции
+
+// Поиск элементов справочника ВидыИспользованияРабочегоВремени по наименованию.
+// Используется как замена прямого обращения к реквизитам формы обработки.
+// Имена элементов зафиксированы в проекте и не подлежат изменению.
+
+Функция ВидВремениЯвкаСГЗ()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Явка (СГЗ)", Истина);
+КонецФункции
+
+Функция ВидВремениЯвкаПД()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Явка (ПД)", Истина);
+КонецФункции
+
+Функция ВидВремениЯвкаОМС()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Явка (ОМС)", Истина);
+КонецФункции
+
+Функция ВидВремениПраздникиСГЗ()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Праздники (СГЗ)", Истина);
+КонецФункции
+
+Функция ВидВремениПраздникиПД()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Праздники (ПД)", Истина);
+КонецФункции
+
+Функция ВидВремениПраздникиОМС()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Праздники (ОМС)", Истина);
+КонецФункции
+
+Функция ВидВремениПраздникиБезПовышеннойОплатыСГЗ()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Праздники без повышенной оплаты (СГЗ)", Истина);
+КонецФункции
+
+Функция ВидВремениПраздникиБезПовышеннойОплатыПД()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Праздники без повышенной оплаты (ПД)", Истина);
+КонецФункции
+
+Функция ВидВремениПраздникиБезПовышеннойОплатыОМС()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Праздники без повышенной оплаты (ОМС)", Истина);
+КонецФункции
+
+Функция ВидВремениРаботаНочныеЧасыСГЗ()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Работа ночные часы (СГЗ)", Истина);
+КонецФункции
+
+Функция ВидВремениРаботаНочныеЧасыПД()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Работа ночные часы (ПД)", Истина);
+КонецФункции
+
+Функция ВидВремениРаботаНочныеЧасыОМС()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Работа ночные часы (ОМС)", Истина);
+КонецФункции
+
+Функция ВидВремениСверхурочныеСГЗ()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Сверхурочные (СГЗ)", Истина);
+КонецФункции
+
+Функция ВидВремениСверхурочныеПД()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Сверхурочные (ПД)", Истина);
+КонецФункции
+
+Функция ВидВремениСверхурочныеОМС()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Сверхурочные (ОМС)", Истина);
+КонецФункции
+
+Функция ВидВремениСверхурочныеБезПовышеннойОплатыСГЗ()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Сверхурочные без повышенной оплаты (СГЗ)", Истина);
+КонецФункции
+
+Функция ВидВремениСверхурочныеБезПовышеннойОплатыПД()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Сверхурочные без повышенной оплаты (ПД)", Истина);
+КонецФункции
+
+Функция ВидВремениСверхурочныеБезПовышеннойОплатыОМС()
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НайтиПоНаименованию("Сверхурочные без повышенной оплаты (ОМС)", Истина);
+КонецФункции
+
+// Статьи финансирования — ищем предопределённые элементы.
+Функция СтатьяФинансированияСГЗ()
+ Возврат Справочники.СтатьиФинансированияЗарплата.НайтиПоНаименованию("СГЗ", Истина);
+КонецФункции
+
+Функция СтатьяФинансированияПД()
+ Возврат Справочники.СтатьиФинансированияЗарплата.НайтиПоНаименованию("ПД", Истина);
+КонецФункции
+
+Функция СтатьяФинансированияОМС()
+ Возврат Справочники.СтатьиФинансированияЗарплата.НайтиПоНаименованию("ОМС", Истина);
+КонецФункции
+
+#КонецОбласти
+
+#Область ПолучениеВидовВремени
+
+// Возвращает элемент справочника ВидыИспользованияРабочегоВремени для вида «Явка»
+// по текущей статье финансирования (СГЗ / ПД / ОМС).
+//
+// Параметры:
+// СтатьяФинансирования - CatalogRef.СтатьиФинансированияЗарплата
+//
+// Возвращаемое значение:
+// CatalogRef.ВидыИспользованияРабочегоВремени
+//
+Функция ВидВремениЯвка(СтатьяФинансирования) Экспорт
+ Если СтатьяФинансирования = СтатьяФинансированияСГЗ() Тогда
+ Возврат ВидВремениЯвкаСГЗ();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияПД() Тогда
+ Возврат ВидВремениЯвкаПД();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияОМС() Тогда
+ Возврат ВидВремениЯвкаОМС();
+ КонецЕсли;
+КонецФункции
+
+// Возвращает элемент справочника для вида «Болезнь».
+Функция ВидВремениБолезнь() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.Болезнь;
+КонецФункции
+
+Функция ВидВремениВыходныеДни() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ВыходныеДни;
+КонецФункции
+
+Функция ВидВремениДополнительныйОтпуск() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ДополнительныйОтпуск;
+КонецФункции
+
+Функция ВидВремениКомандировка() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.Командировка;
+КонецФункции
+
+Функция ВидВремениКормлениеРебенка() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.КормлениеРебенка;
+КонецФункции
+
+Функция ВидВремениНеявкиПоНевыясненнымПричинам() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НеявкиПоНевыясненнымПричинам;
+КонецФункции
+
+Функция ВидВремениНеоплачиваемыйОтпускПоРазрешениюРаботодателя() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.НеоплачиваемыйОтпускПоРазрешениюРаботодателя;
+КонецФункции
+
+Функция ВидВремениОтстранениеОтРаботыБезОплаты() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОтстранениеОтРаботыБезОплаты;
+КонецФункции
+
+Функция ВидВремениОтстранениеОтРаботыСОплатой() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОтстранениеОтРаботыСОплатой;
+КонецФункции
+
+Функция ВидВремениОплачиваемыеНерабочиеДни() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОплачиваемыеНерабочиеДни;
+КонецФункции
+
+Функция ВидВремениОсновнойОтпуск() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОсновнойОтпуск;
+КонецФункции
+
+Функция ВидВремениОтпускНаОбучение() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОтпускНаОбучение;
+КонецФункции
+
+Функция ВидВремениОтпускПоБеременностиИРодам() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОтпускПоБеременностиИРодам;
+КонецФункции
+
+Функция ВидВремениОтпускПоУходуЗаРебенком() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОтпускПоУходуЗаРебенком;
+КонецФункции
+
+// В исходном коде модуля формы эта функция возвращает ОтпускПоУходуЗаРебенком —
+// копируем как есть (так зафиксировано в проекте).
+Функция ВидВремениДополнительныеВыходныеДниОплачиваемые() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ОтпускПоУходуЗаРебенком;
+КонецФункции
+
+Функция ВидВремениПовышениеКвалификации() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.ПовышениеКвалификации;
+КонецФункции
+
+Функция ВидВремениПраздники(СтатьяФинансирования) Экспорт
+ Если СтатьяФинансирования = СтатьяФинансированияСГЗ() Тогда
+ Возврат ВидВремениПраздникиСГЗ();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияПД() Тогда
+ Возврат ВидВремениПраздникиПД();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияОМС() Тогда
+ Возврат ВидВремениПраздникиОМС();
+ КонецЕсли;
+КонецФункции
+
+Функция ВидВремениПраздникиБезПовышеннойОплаты(СтатьяФинансирования) Экспорт
+ Если СтатьяФинансирования = СтатьяФинансированияСГЗ() Тогда
+ Возврат ВидВремениПраздникиБезПовышеннойОплатыСГЗ();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияПД() Тогда
+ Возврат ВидВремениПраздникиБезПовышеннойОплатыПД();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияОМС() Тогда
+ Возврат ВидВремениПраздникиБезПовышеннойОплатыОМС();
+ КонецЕсли;
+КонецФункции
+
+Функция ВидВремениПрогулы() Экспорт
+ Возврат Справочники.ВидыИспользованияРабочегоВремени.Прогулы;
+КонецФункции
+
+Функция ВидВремениРаботаНочныеЧасы(СтатьяФинансирования) Экспорт
+ Если СтатьяФинансирования = СтатьяФинансированияСГЗ() Тогда
+ Возврат ВидВремениРаботаНочныеЧасыСГЗ();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияПД() Тогда
+ Возврат ВидВремениРаботаНочныеЧасыПД();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияОМС() Тогда
+ Возврат ВидВремениРаботаНочныеЧасыОМС();
+ КонецЕсли;
+КонецФункции
+
+Функция ВидВремениСверхурочные(СтатьяФинансирования) Экспорт
+ Если СтатьяФинансирования = СтатьяФинансированияСГЗ() Тогда
+ Возврат ВидВремениСверхурочныеСГЗ();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияПД() Тогда
+ Возврат ВидВремениСверхурочныеПД();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияОМС() Тогда
+ Возврат ВидВремениСверхурочныеОМС();
+ КонецЕсли;
+КонецФункции
+
+Функция ВидВремениСверхурочныеБезПовышеннойОплаты(СтатьяФинансирования) Экспорт
+ Если СтатьяФинансирования = СтатьяФинансированияСГЗ() Тогда
+ Возврат ВидВремениСверхурочныеБезПовышеннойОплатыСГЗ();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияПД() Тогда
+ Возврат ВидВремениСверхурочныеБезПовышеннойОплатыПД();
+ ИначеЕсли СтатьяФинансирования = СтатьяФинансированияОМС() Тогда
+ Возврат ВидВремениСверхурочныеБезПовышеннойОплатыОМС();
+ КонецЕсли;
+КонецФункции
+
+#КонецОбласти
+
+#Область КлассификацияВидовВремени
+
+// Возвращает код финансирования ("СГЗ"/"ПД"/"ОМС") для указанного вида времени.
+// Для неденежных видов (болезнь, отпуск и т.п.) возвращает Неопределено.
+Функция ФинансированиеПоВидуВремени(ВидВремени) Экспорт
+ Если ВидВремени = ВидВремениЯвкаСГЗ()
+ ИЛИ ВидВремени = ВидВремениРаботаНочныеЧасыСГЗ()
+ ИЛИ ВидВремени = ВидВремениПраздникиСГЗ()
+ ИЛИ ВидВремени = ВидВремениПраздникиБезПовышеннойОплатыСГЗ()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеСГЗ()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеБезПовышеннойОплатыСГЗ() Тогда
+ Возврат "СГЗ";
+ ИначеЕсли ВидВремени = ВидВремениЯвкаПД()
+ ИЛИ ВидВремени = ВидВремениРаботаНочныеЧасыПД()
+ ИЛИ ВидВремени = ВидВремениПраздникиПД()
+ ИЛИ ВидВремени = ВидВремениПраздникиБезПовышеннойОплатыПД()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеПД()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеБезПовышеннойОплатыПД() Тогда
+ Возврат "ПД";
+ ИначеЕсли ВидВремени = ВидВремениЯвкаОМС()
+ ИЛИ ВидВремени = ВидВремениРаботаНочныеЧасыОМС()
+ ИЛИ ВидВремени = ВидВремениПраздникиОМС()
+ ИЛИ ВидВремени = ВидВремениПраздникиБезПовышеннойОплатыОМС()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеОМС()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеБезПовышеннойОплатыОМС() Тогда
+ Возврат "ОМС";
+ Иначе
+ Возврат Неопределено;
+ КонецЕсли;
+КонецФункции
+
+Функция ВидВремениЯвкаПринадлежитФинансированию(ВидВремени) Экспорт
+ Возврат ВидВремени = ВидВремениЯвкаСГЗ()
+ ИЛИ ВидВремени = ВидВремениЯвкаПД()
+ ИЛИ ВидВремени = ВидВремениЯвкаОМС();
+КонецФункции
+
+Функция ВидВремениПраздникиПринадлежит(ВидВремени) Экспорт
+ Возврат ВидВремени = ВидВремениПраздникиСГЗ()
+ ИЛИ ВидВремени = ВидВремениПраздникиПД()
+ ИЛИ ВидВремени = ВидВремениПраздникиОМС()
+ ИЛИ ВидВремени = ВидВремениПраздникиБезПовышеннойОплатыСГЗ()
+ ИЛИ ВидВремени = ВидВремениПраздникиБезПовышеннойОплатыПД()
+ ИЛИ ВидВремени = ВидВремениПраздникиБезПовышеннойОплатыОМС();
+КонецФункции
+
+Функция ВидВремениНочныеПринадлежит(ВидВремени) Экспорт
+ Возврат ВидВремени = ВидВремениРаботаНочныеЧасыСГЗ()
+ ИЛИ ВидВремени = ВидВремениРаботаНочныеЧасыПД()
+ ИЛИ ВидВремени = ВидВремениРаботаНочныеЧасыОМС();
+КонецФункции
+
+Функция ВидВремениСверхурочныеПринадлежит(ВидВремени) Экспорт
+ Возврат ВидВремени = ВидВремениСверхурочныеСГЗ()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеПД()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеОМС()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеБезПовышеннойОплатыСГЗ()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеБезПовышеннойОплатыПД()
+ ИЛИ ВидВремени = ВидВремениСверхурочныеБезПовышеннойОплатыОМС()
+ ИЛИ ВидВремени = ВидВремениКормлениеРебенка()
+ ИЛИ ВидВремени = ВидВремениПовышениеКвалификации();
+КонецФункции
+
+// Возвращает буквенное обозначение вида времени (для UI/Excel-формата).
+Функция БукваПоВидуВремени(ВидВремени) Экспорт
+ Если ВидВремени = ВидВремениБолезнь() Тогда
+ Возврат "Б";
+ ИначеЕсли ВидВремени = ВидВремениВыходныеДни() Тогда
+ Возврат "В";
+ ИначеЕсли ВидВремени = ВидВремениОсновнойОтпуск() Тогда
+ Возврат "О";
+ ИначеЕсли ВидВремени = ВидВремениДополнительныйОтпуск() Тогда
+ Возврат "ОД";
+ ИначеЕсли ВидВремени = ВидВремениКомандировка() Тогда
+ Возврат "К";
+ ИначеЕсли ВидВремени = ВидВремениПрогулы() Тогда
+ Возврат "П";
+ ИначеЕсли ВидВремени = ВидВремениНеявкиПоНевыясненнымПричинам() Тогда
+ Возврат "НН";
+ ИначеЕсли ВидВремени = ВидВремениОтпускНаОбучение() Тогда
+ Возврат "ОУ";
+ ИначеЕсли ВидВремени = ВидВремениОтпускПоБеременностиИРодам() Тогда
+ Возврат "Р";
+ ИначеЕсли ВидВремени = ВидВремениОтпускПоУходуЗаРебенком() Тогда
+ Возврат "ОР";
+ ИначеЕсли ВидВремени = ВидВремениНеоплачиваемыйОтпускПоРазрешениюРаботодателя() Тогда
+ Возврат "ОЗ";
+ ИначеЕсли ВидВремени = ВидВремениОтстранениеОтРаботыБезОплаты() Тогда
+ Возврат "НБ";
+ ИначеЕсли ВидВремени = ВидВремениОтстранениеОтРаботыСОплатой() Тогда
+ Возврат "НО";
+ Иначе
+ Возврат "";
+ КонецЕсли;
+КонецФункции
+
+#КонецОбласти
+
+#Область ОбратноеПреобразование
+
+// Классифицирует записи дня для обратной загрузки из табеля в ТЧ формы.
+//
+// Параметры:
+// ЗаписиДня - Массив из Структура (ключи "ВидВремени", "Часы")
+//
+// Возвращаемое значение:
+// Структура с ключами "Основная", "Ночные", "Сверхурочные".
+// Каждое значение — Структура("Часы, Буква, ВидВремени") или Неопределено.
+//
+Функция КлассифицироватьДень(ЗаписиДня) Экспорт
+ Результат = Новый Структура("Основная, Ночные, Сверхурочные", Неопределено, Неопределено, Неопределено);
+
+ ЧасыПраздничных = 0;
+ ЧасыЯвки = 0;
+ ЧасыНочных = 0;
+ ЧасыСверхурочных = 0;
+ ВидВремениПраздничных = Неопределено;
+ ВидВремениЯвки = Неопределено;
+ ВидВремениНочных = Неопределено;
+ ВидВремениСверхурочных = Неопределено;
+ ПервыйНеденежный = Неопределено;
+
+ Для Каждого Запись Из ЗаписиДня Цикл
+ ВидВремени = Запись.ВидВремени;
+ Часы = Запись.Часы;
+
+ Если ВидВремениЯвкаПринадлежитФинансированию(ВидВремени) Тогда
+ ЧасыЯвки = ЧасыЯвки + Часы;
+ Если ВидВремениЯвки = Неопределено Тогда
+ ВидВремениЯвки = ВидВремени;
+ КонецЕсли;
+ ИначеЕсли ВидВремениПраздникиПринадлежит(ВидВремени) Тогда
+ ЧасыПраздничных = ЧасыПраздничных + Часы;
+ Если ВидВремениПраздничных = Неопределено Тогда
+ ВидВремениПраздничных = ВидВремени;
+ КонецЕсли;
+ ИначеЕсли ВидВремениНочныеПринадлежит(ВидВремени) Тогда
+ ЧасыНочных = ЧасыНочных + Часы;
+ Если ВидВремениНочных = Неопределено Тогда
+ ВидВремениНочных = ВидВремени;
+ КонецЕсли;
+ ИначеЕсли ВидВремениСверхурочныеПринадлежит(ВидВремени) Тогда
+ ЧасыСверхурочных = ЧасыСверхурочных + Часы;
+ Если ВидВремениСверхурочных = Неопределено Тогда
+ ВидВремениСверхурочных = ВидВремени;
+ КонецЕсли;
+ ИначеЕсли ПервыйНеденежный = Неопределено Тогда
+ ПервыйНеденежный = Новый Структура("Часы, Буква, ВидВремени", Часы, БукваПоВидуВремени(ВидВремени), ВидВремени);
+ КонецЕсли;
+ КонецЦикла;
+
+ Если ЧасыПраздничных > 0 Тогда
+ Результат.Основная = Новый Структура("Часы, Буква, ВидВремени", ЧасыПраздничных, "РП", ВидВремениПраздничных);
+ ИначеЕсли ЧасыЯвки > 0 Тогда
+ Результат.Основная = Новый Структура("Часы, Буква, ВидВремени", ЧасыЯвки, "Ф", ВидВремениЯвки);
+ ИначеЕсли ПервыйНеденежный <> Неопределено Тогда
+ Результат.Основная = ПервыйНеденежный;
+ КонецЕсли;
+
+ Если ЧасыНочных > 0 Тогда
+ Результат.Ночные = Новый Структура("Часы, Буква, ВидВремени", ЧасыНочных, "Н", ВидВремениНочных);
+ КонецЕсли;
+
+ Если ЧасыСверхурочных > 0 Тогда
+ Результат.Сверхурочные = Новый Структура("Часы, Буква, ВидВремени", ЧасыСверхурочных, "С", ВидВремениСверхурочных);
+ КонецЕсли;
+
+ Возврат Результат;
+КонецФункции
+
+// Возвращает Истина, если во всех 31 колонках ЧасовN строки значение <= 0.
+Функция СтрокаПустаяПоЧасам(СтрокаТЧ) Экспорт
+ Для НомерДня = 1 По 31 Цикл
+ Если СтрокаТЧ["Часов" + НомерДня] > 0 Тогда
+ Возврат Ложь;
+ КонецЕсли;
+ КонецЦикла;
+ Возврат Истина;
+КонецФункции
+
+// Группирует часы по буквенным кодам и формирует строку вида "Я 7, Б 10".
+Функция РассчитатьВремяИтог(СтрокаТЧ) Экспорт
+ ГруппировкаЧасов = Новый Соответствие;
+ Для НомерДня = 1 По 31 Цикл
+ Часы = СтрокаТЧ["Часов" + НомерДня];
+ Если Часы = 0 Тогда
+ Продолжить;
+ КонецЕсли;
+ Буква = СтрокаТЧ["Время" + НомерДня + "Буква"];
+ Если Буква = "" Тогда
+ Продолжить;
+ КонецЕсли;
+ ТекущаяСумма = ГруппировкаЧасов[Буква];
+ Если ТекущаяСумма = Неопределено Тогда
+ ТекущаяСумма = 0;
+ КонецЕсли;
+ ГруппировкаЧасов.Вставить(Буква, ТекущаяСумма + Часы);
+ КонецЦикла;
+
+ Результат = "";
+ Для Каждого КЗ Из ГруппировкаЧасов Цикл
+ Если Результат <> "" Тогда
+ Результат = Результат + ", ";
+ КонецЕсли;
+ Результат = Результат + КЗ.Ключ + " " + Формат(КЗ.Значение, "ЧРД=.; ЧГ=");
+ КонецЦикла;
+ Возврат Результат;
+КонецФункции
+
+#КонецОбласти
+
+#Область Валидация
+
+// Проверяет, есть ли в записях дня другие виды времени, отличные от указанного.
+Функция ЕстьНесовместимыеВидыВремени(Сотрудник, НомерДня, ТаблицаДня, ВидВремени) Экспорт
+ НесовместимыеВидыВремениНайдены = Ложь;
+ СписокНесовместимыхВидовВремени = "";
+ Для каждого СтрокаТаблицыДня Из ТаблицаДня Цикл
+ Если СтрокаТаблицыДня.ВидВремени <> ВидВремени Тогда
+ Если СписокНесовместимыхВидовВремени = "" Тогда
+ СписокНесовместимыхВидовВремени = Строка(СтрокаТаблицыДня.ВидВремени);
+ Иначе
+ СписокНесовместимыхВидовВремени = СписокНесовместимыхВидовВремени + ", " + Строка(СтрокаТаблицыДня.ВидВремени);
+ КонецЕсли;
+ НесовместимыеВидыВремениНайдены = Истина;
+ КонецЕсли;
+ КонецЦикла;
+ Возврат НесовместимыеВидыВремениНайдены;
+КонецФункции
+
+#КонецОбласти
+
+#Область ПоискСотрудников
+
+// Возвращает табельный номер (поле Код) для указанного сотрудника.
+Функция ТабельныйНомерСотрудникаБД(Сотрудник) Экспорт
+ Возврат Сотрудник.Код;
+КонецФункции
+
+// Получает последнюю кадровую историю сотрудника.
+Функция КадровыеДанные(Сотрудник, ДатаПолученияКадровыхДанных) Экспорт
+ СтруктураПоискаКадровыхДанных = Новый Структура("Сотрудник", Сотрудник);
+ Возврат РегистрыСведений.КадроваяИсторияСотрудников.ПолучитьПоследнее(ДатаПолученияКадровыхДанных, СтруктураПоискаКадровыхДанных);
+КонецФункции
+
+// Возвращает пустую структуру данных сотрудника (используется как фабрика).
+Функция СтруктураДанныхСотрудника() Экспорт
+ Возврат Новый Структура("Сотрудник,Должность,НаименованиеДолжностиДляТабеля,ДолжностьПоШтатномуРасписанию,Подразделение,ВидЗанятости,КоличествоСтавок," +
+ "ПредставлениеСотрудника,ПредставлениеДолжности,ПредставлениеПодразделения,Обработан",
+ Справочники.Сотрудники.ПустаяСсылка(),
+ Справочники.Должности.ПустаяСсылка(), "",
+ Справочники.ШтатноеРасписание.ПустаяСсылка(),
+ Справочники.ПодразделенияОрганизаций.ПустаяСсылка(),
+ "",
+ 0,
+ "", "", "",
+ Ложь);
+КонецФункции
+
+#КонецОбласти
+
+#Область ФильтрацияСотрудников
+
+// Проверяет, есть ли сотрудник в списке совместителей (по физическому лицу).
+Функция СотрудникВСпискеСовместителей(Сотрудник, СписокСовместителей) Экспорт
+ Результат = Ложь;
+ Попытка
+ Если СписокСовместителей.Количество() > 0 Тогда
+ Если Сотрудник.ФизическоеЛицо = СписокСовместителей[0].Сотрудник.ФизическоеЛицо Тогда
+ Результат = Истина;
+ КонецЕсли;
+ КонецЕсли;
+ Исключение
+ КонецПопытки;
+ Возврат Результат;
+КонецФункции
+
+#КонецОбласти
+
+#Область ПоискТабеля
+
+// Ищет ссылку на сохранённый табель по ключевым реквизитам через РС ПС_ЗагруженныеТабеля.
+// Возвращает последнюю по дате загрузки редакцию.
+Функция НайтиСсылкуНаТабель(Организация, Подразделение, НаименованиеПодразделения, ПериодРегистрации) Экспорт
+ Если НЕ ЗначениеЗаполнено(Организация)
+ ИЛИ НЕ ЗначениеЗаполнено(Подразделение)
+ ИЛИ ПустаяСтрока(НаименованиеПодразделения)
+ ИЛИ НЕ ЗначениеЗаполнено(ПериодРегистрации) Тогда
+ Возврат Документы.ТабельУчетаРабочегоВремени.ПустаяСсылка();
+ КонецЕсли;
+
+ Запрос = Новый Запрос;
+ Запрос.Текст =
+ "ВЫБРАТЬ
+ | ПС_ЗагруженныеТабеляСрезПоследних.ТабельУчетаРабочегоВремени КАК ТабельУчетаРабочегоВремени
+ |ИЗ
+ | РегистрСведений.ПС_ЗагруженныеТабеля.СрезПоследних(
+ | &ПериодРегистрации,
+ | Организация = &Организация
+ | И НаименованиеПодразделенияПоТабелю = &НаименованиеПодразделения
+ | И ПериодВводаДанныхОВремени = &ПериодВводаДанныхОВремени
+ | И СтруктурноеПодразделение = &СтруктурноеПодразделение) КАК ПС_ЗагруженныеТабеляСрезПоследних
+ |УПОРЯДОЧИТЬ ПО
+ | ПС_ЗагруженныеТабеляСрезПоследних.ДатаЗагрузки УБЫВ";
+ Запрос.УстановитьПараметр("Организация", Организация);
+ Запрос.УстановитьПараметр("СтруктурноеПодразделение", Подразделение);
+ Запрос.УстановитьПараметр("НаименованиеПодразделения", НаименованиеПодразделения);
+ Запрос.УстановитьПараметр("ПериодВводаДанныхОВремени", Перечисления.ПериодыВводаДанныхОВремени.ТекущийМесяц);
+ Запрос.УстановитьПараметр("ПериодРегистрации", НачалоМесяца(ПериодРегистрации));
+
+ РезультатЗапроса = Запрос.Выполнить();
+ Если РезультатЗапроса.Пустой() Тогда
+ Возврат Документы.ТабельУчетаРабочегоВремени.ПустаяСсылка();
+ КонецЕсли;
+
+ Выборка = РезультатЗапроса.Выбрать();
+ Выборка.Следующий();
+ Возврат Выборка.ТабельУчетаРабочегоВремени;
+КонецФункции
+
+#КонецОбласти
diff --git a/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/CommonModules/ПС_ТабелиСервер/ПС_ТабелиСервер.mdo b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/CommonModules/ПС_ТабелиСервер/ПС_ТабелиСервер.mdo
new file mode 100644
index 0000000..896d048
--- /dev/null
+++ b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/CommonModules/ПС_ТабелиСервер/ПС_ТабелиСервер.mdo
@@ -0,0 +1,8 @@
+
+
+ ПС_ТабелиСервер
+ true
+ true
+ true
+ DuringSession
+
diff --git a/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/Configuration/Configuration.mdo b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/Configuration/Configuration.mdo
index 84479b1..df4c7ed 100644
--- a/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/Configuration/Configuration.mdo
+++ b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/Configuration/Configuration.mdo
@@ -77,6 +77,7 @@
CommonModule.УчетРабочегоВремениРасширенный
CommonModule.ПС_ЗагрузкаДанныхИзExcel_Описание
CommonModule.ПС_КартаДанных
+ CommonModule.ПС_ТабелиСервер
Catalog.Организации
Catalog.ПодразделенияОрганизаций
Catalog.Пользователи
diff --git a/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/DataProcessors/ПС_ЗагрузкаТабеляУчётаРабочегоВремениИзEXCEL/Forms/Форма/Module.bsl b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/DataProcessors/ПС_ЗагрузкаТабеляУчётаРабочегоВремениИзEXCEL/Forms/Форма/Module.bsl
index 38145be..01c88b4 100644
--- a/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/DataProcessors/ПС_ЗагрузкаТабеляУчётаРабочегоВремениИзEXCEL/Forms/Форма/Module.bsl
+++ b/101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/DataProcessors/ПС_ЗагрузкаТабеляУчётаРабочегоВремениИзEXCEL/Forms/Форма/Module.bsl
@@ -3515,7 +3515,7 @@
Возврат;
КонецЕсли;
- СсылкаНаТабель = Ждать НайтиСсылкуНаТабельАсинх();
+ СсылкаНаТабель = НайтиСсылкуНаТабельАсинх();
Если НЕ ЗначениеЗаполнено(СсылкаНаТабель) Тогда
Возврат;
КонецЕсли;
@@ -3555,7 +3555,7 @@
// Проход Б: полная обратная загрузка данных табеля в табличные части формы.
&НаКлиенте
Асинх Процедура ЗагрузитьДанныеТабеляВФорму(СсылкаНаТабель)
- Ждать ЗаполнитьТабличныеЧастиИзТабеляНаСервере(СсылкаНаТабель);
+ ЗаполнитьТабличныеЧастиИзТабеляНаСервере(СсылкаНаТабель);
ОпределитьВидимостьСтраниц();
@@ -3722,6 +3722,16 @@
КонецЕсли;
КонецФункции
+&НаСервере
+Функция СтрокаПустаяПоЧасам(СтрокаТЧ)
+ Для НомерДня = 1 По 31 Цикл
+ Если СтрокаТЧ["Часов" + НомерДня] > 0 Тогда
+ Возврат Ложь;
+ КонецЕсли;
+ КонецЦикла;
+ Возврат Истина;
+КонецФункции
+
&НаСервере
Функция КлассифицироватьДень(ЗаписиДня)
Результат = Новый Структура("Основная, Ночные, Сверхурочные", Неопределено, Неопределено, Неопределено);
@@ -3784,16 +3794,6 @@
Возврат Результат;
КонецФункции
-&НаСервере
-Функция СтрокаПустаяПоЧасам(СтрокаТЧ)
- Для НомерДня = 1 По 31 Цикл
- Если СтрокаТЧ["Часов" + НомерДня] > 0 Тогда
- Возврат Ложь;
- КонецЕсли;
- КонецЦикла;
- Возврат Истина;
-КонецФункции
-
&НаСервере
Функция ВидВремениЯвкаПринадлежитФинансированию(ВидВремени)
Возврат ВидВремени = ВидВремениЯвкаСГЗ
@@ -3895,57 +3895,16 @@
// Серверная обёртка для вызова с клиента без контекста формы.
&НаСервереБезКонтекста
Функция НайтиСсылкуНаТабельНаСервере(Организация, Подразделение, НаименованиеПодразделения, ПериодРегистрации)
- Возврат НайтиСсылкуНаТабель(Организация, Подразделение, НаименованиеПодразделения, ПериодРегистрации);
+ Возврат ПС_ТабелиСервер.НайтиСсылкуНаТабель(Организация, Подразделение, НаименованиеПодразделения, ПериодРегистрации);
КонецФункции
&НаКлиенте
-Асинх Функция НайтиСсылкуНаТабельАсинх()
- Возврат Ждать НайтиСсылкуНаТабельНаСервере(
+Функция НайтиСсылкуНаТабельАсинх()
+ Возврат НайтиСсылкуНаТабельНаСервере(
Объект.Организация,
Объект.Подразделение,
Объект.НаименованиеПодразделения,
Объект.ПериодРегистрации);
КонецФункции
-// Поиск ссылки на табель по ключевым реквизитам.
-// Источник: РС ПС_ЗагруженныеТабеля.СрезПоследних (последняя редакция по ДатаЗагрузки).
-// Возвращает DocumentRef.ТабельУчетаРабочегоВремени или пустую ссылку.
-&НаСервереБезКонтекста
-Функция НайтиСсылкуНаТабель(Организация, Подразделение, НаименованиеПодразделения, ПериодРегистрации)
- Если НЕ ЗначениеЗаполнено(Организация)
- ИЛИ НЕ ЗначениеЗаполнено(Подразделение)
- ИЛИ ПустаяСтрока(НаименованиеПодразделения)
- ИЛИ НЕ ЗначениеЗаполнено(ПериодРегистрации) Тогда
- Возврат Документы.ТабельУчетаРабочегоВремени.ПустаяСсылка();
- КонецЕсли;
-
- Запрос = Новый Запрос;
- Запрос.Текст =
- "ВЫБРАТЬ
- | ПС_ЗагруженныеТабеляСрезПоследних.ТабельУчетаРабочегоВремени КАК ТабельУчетаРабочегоВремени
- |ИЗ
- | РегистрСведений.ПС_ЗагруженныеТабеля.СрезПоследних(
- | &ПериодРегистрации,
- | Организация = &Организация
- | И НаименованиеПодразделенияПоТабелю = &НаименованиеПодразделения
- | И ПериодВводаДанныхОВремени = &ПериодВводаДанныхОВремени
- | И СтруктурноеПодразделение = &СтруктурноеПодразделение) КАК ПС_ЗагруженныеТабеляСрезПоследних
- |УПОРЯДОЧИТЬ ПО
- | ПС_ЗагруженныеТабеляСрезПоследних.ДатаЗагрузки УБЫВ";
- Запрос.УстановитьПараметр("Организация", Организация);
- Запрос.УстановитьПараметр("СтруктурноеПодразделение", Подразделение);
- Запрос.УстановитьПараметр("НаименованиеПодразделения", НаименованиеПодразделения);
- Запрос.УстановитьПараметр("ПериодВводаДанныхОВремени", Перечисления.ПериодыВводаДанныхОВремени.ТекущийМесяц);
- Запрос.УстановитьПараметр("ПериодРегистрации", НачалоМесяца(ПериодРегистрации));
-
- РезультатЗапроса = Запрос.Выполнить();
- Если РезультатЗапроса.Пустой() Тогда
- Возврат Документы.ТабельУчетаРабочегоВремени.ПустаяСсылка();
- КонецЕсли;
-
- Выборка = РезультатЗапроса.Выбрать();
- Выборка.Следующий();
- Возврат Выборка.ТабельУчетаРабочегоВремени;
-КонецФункции
-