При ведении кадрового учета в крупных организациях часто возникает задача планирования отпусков для большого количества сотрудников. Типовой механизм 1С:ЗУП 3.1 «Контроль остатков отпусков» отлично справляется со своей задачей при ручном вводе, однако при загрузке данных из внешних файлов (например, Excel) на сотни строк стандартные проверки могут работать медленно или требовать дополнительной автоматизации. Рассмотрим, как реализовать эффективную проверку суммарного количества дней отпуска, чтобы оно не превышало установленный лимит (например, 28 дней), и как оптимизировать этот процесс для разработчика.
Основная сложность заключается в том, что сотрудник может делить отпуск на несколько частей. Например, 14 дней летом и 14 дней зимой. Программа должна не просто проверять каждую строку по отдельности, а суммировать все дни по конкретному сотруднику в рамках документа ГрафикОтпусков или за определенный период планирования. При этом важно учитывать, что стандартный лимит в 28 дней — это база, но существуют дополнительные отпуска (за вредность, ненормированный рабочий день, северные надбавки), которые увеличивают этот порог.
Прежде чем приступать к программированию в 1С, проанализируем самый простой способ, предложенный участниками обсуждения. Если данные подготавливаются в Excel, логично добавить механизмы контроля непосредственно в файл загрузки. Разберем по шагам, как это реализовать:
СУММЕСЛИ (SUMIF), чтобы посчитать общее количество дней по каждому сотруднику в списке.Этот метод позволяет подавать в систему уже «чистые» данные, минимизируя нагрузку на сервер 1С.
Если проверка должна выполняться внутри 1С при нажатии кнопки «Записать» или в процессе загрузки, нам необходимо программно сгруппировать данные. Проанализируем ситуацию: в документе ГрафикОтпусков данные хранятся в табличной части. Чтобы проверить суммарное количество дней по каждому сотруднику, используем метод Свернуть.
Рассмотрим алгоритм реализации:
Свернуть, указав колонки для группировки (Сотрудник) и колонки для суммирования (КоличествоДней).Пример кода для реализации такой проверки:
// Выгружаем данные из табличной части в ТЗ
ТЗ_Отпуска = Объект.ОстаткиОтпусков.Выгрузить();
// Сворачиваем по сотруднику, суммируя дни
ТЗ_Отпуска.Свернуть("Сотрудник", "КоличествоДней");
Для Каждого СтрокаТЗ Из ТЗ_Отпуска Цикл
// Здесь получаем лимит сотрудника (например, 28 или из регистра)
ДопустимыйЛимит = 28;
Если СтрокаТЗ.КоличествоДней > ДопустимыйЛимит Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "У сотрудника " + СтрокаТЗ.Sотрудник + " превышен лимит отпуска: " + СтрокаТЗ.КоличествоДней;
Сообщение.Сообщить();
КонецЕсли;
КонецЦикла;
При проверке 300 и более сотрудников обращение к функциям расчета остатков в цикле будет крайне медленным. Выясним причину: каждый вызов функции расчета остатка инициирует отдельный запрос к базе данных. Чтобы ускорить процесс, проанализируем использование временных таблиц в запросах.
Правильный подход заключается в следующем:
ПлановыеЕжегодныеОтпуска или регистром накопления ФактическиеОтпуска.Это позволит сократить время проверки с нескольких минут до долей секунды. В запросе важно учитывать Период, так как право на отпуск привязано к рабочему году сотрудника, а не к календарному.
При реализации контроля программным способом, обязательно учтем следующие моменты, чтобы не заблокировать работу пользователям:
Чтобы не снимать конфигурацию с поддержки, рекомендуется внедрять данную логику через Расширение. Мы можем создать процедуру-обработчик ПередЗаписью для документа ГрафикОтпусков. Это позволит автоматически прерывать запись документа, если проверка не пройдена, и выводить пользователю подробный протокол ошибок со списком сотрудников-нарушителей.
Таким образом, мы рассмотрели комплексный подход к решению задачи: от простых формул в Excel до оптимизированных запросов в коде 1С. Выбор конкретного метода зависит от частоты загрузки данных и требований к строгости контроля в вашей организации.