При разработке внешних отчетов по кадрам программисты часто сталкиваются с ситуацией, когда стаж на предприятии (с момента приема) выводится верно, а общий, страховой или любой другой вид стажа рассчитывается с ошибками или вовсе не отображается. Попытки решить эту задачу «в лоб» через написание огромных конструкций ВЫБОР КОГДА и использование функции РАЗНОСТЬДАТ в запросе обычно приводят к созданию нечитаемого и трудноотлаживаемого кода, который к тому же не учитывает специфику учета в 1С.
В этой статье мы подробно разберем, почему ручной расчет в запросе — это тупиковый путь, и выясним, как использовать штатные механизмы конфигураций (на примере 1С:ЗУП 3.1) для получения корректного результата.
Давайте проанализируем ситуацию. В типовых конфигурациях (ЗУП 3.1, ERP 2.5, КА 2.5) данные о стаже хранятся в регистре сведений СтажиФизическихЛиц. Но важно понимать, что там записывается не текущий стаж, а точка отсчета: количество лет, месяцев и дней на определенную дату.
Основные причины ошибок при попытке написать свой запрос:
РАЗНОСТЬДАТ между приемом и текущей датой даст только стаж внутри компании.РАЗНОСТЬДАТ(..., МЕСЯЦ) в 1С работает по принципу разницы границ периодов, что не всегда совпадает с кадровыми правилами подсчета.Рассмотрим, как решить проблему правильно, используя программные интерфейсы 1С.
Если вы разрабатываете отчет на базе Системы компоновки данных (СКД), наиболее правильным способом будет использование механизмов, заложенных в конфигурацию. В ЗУП 3.1 существуют специальные функции, которые можно вызвать прямо в вычисляемых полях или выражениях компоновки.
Проанализируем работу с общим модулем ЗарплатаКадрыСоставВыражений. Этот модуль предназначен для того, чтобы в полях СКД можно было получать сложные данные без написания тяжелых запросов. Для вывода стажа текстом (например, «5 лет, 2 месяца, 10 дней») можно использовать вызов функции, которая сама обратится к нужным регистрам и выполнит расчет на дату отчета.
Для реализации этого метода выполним следующие шаги:
СтажТекстом.Пример обращения к типовым механизмам в СКД может выглядеть так (в зависимости от версии конфигурации):
ЗарплатаКадрыСоставВыражений.СтажФизическогоЛицаТекст(ФизическоеЛицо, ВидСтажа, &ДатаОтчета)
Если отчет «обычный» (не СКД) или вам нужно получить стаж в виде чисел (количество месяцев или дней) для дальнейших расчетов, следует использовать программный интерфейс общего модуля КадровыйУчет.
Разберем алгоритм работы с функцией РассчитатьСтажиФизическихЛиц. Она удобна тем, что позволяет рассчитать данные сразу по списку сотрудников на нужную дату. Рассмотрим пример кода, который можно разместить в модуле объекта отчета:
// Подготовим таблицу сотрудников, для которых нужен расчет
ТаблицаСотрудников = Новый ТаблицаЗначений;
ТаблицаСотрудников.Колонки.Добавить("ФизическоеЛицо", Новый ОписаниеТипов("СправочникСсылка.ФизическиеЛица"));
ТаблицаСотрудников.Колонки.Добавить("ВидСтажа", Новый ОписаниеТипов("СправочникСсылка.ВидыСтажа"));
// Заполняем таблицу данными из вашего запроса
НоваяСтрока = ТаблицаСотрудников.Добавить();
НоваяСтрока.ФизическоеЛицо = СсылкаНаФизЛицо;
НоваяСтрока.ВидСтажа = Справочники.ВидыСтажа.ОбщийСтаж;
// Вызываем типовой метод расчета
ПараметрыРасчета = КадровыйУчет.ПараметрыРасчетаСтажа();
ПараметрыРасчета.ДатаРасчета = Объект.ДатаОтчета;
ПараметрыРасчета.ФизическиеЛицаВидыСтажа = ТаблицаСотрудников;
РезультатРасчета = КадровыйУчет.РассчитатьСтажиФизическихЛиц(ПараметрыРасчета);
В переменной РезультатРасчета вы получите таблицу, где для каждого физического лица будет указано общее количество лет, месяцев и дней. Это исключает любые ошибки ручного вычисления.
Как справедливо заметили участники обсуждения на форуме, лучший способ понять, почему ваш код не работает — это посмотреть на работающий аналог. В конфигурации ЗУП 3.1 есть типовой отчет СтажиСотрудников.
Выясним, как он устроен:
РАЗНОСТЬДАТ. Вместо этого там используются временные таблицы и связи, которые подготавливают данные для программного вывода.ПриКомпоновкеРезультата, где программно дозаполняются данные о стаже через вызов кадровых функций.Если вы всё же вынуждены использовать запрос (например, в очень специфическом внешнем источнике), давайте проанализируем, как минимизировать ошибки.
Вместо того чтобы пытаться посчитать всё одной формулой, разделите задачу на этапы в Пакете запросов:
РегистрСведений.СтажиФизическихЛиц количество лет, месяцев и дней, а также дату, на которую эти данные были актуальны (ДатаОтсчета).ТекущиеКадровыеДанныеСотрудников.Однако помните: запрос никогда не будет на 100% точным при расчете стажа в 1С, так как он не видит периоды исключения (например, прогулы или отпуска по уходу за ребенком, которые могут не входить в определенные виды стажа). Только использование функций общего модуля КадровыйУчет гарантирует юридическую чистоту расчета.
Если у вас «неправильно выводится стаж», выполните следующие действия:
Во-первых, откажитесь от сложных математических вычислений внутри текста запроса. Это делает отчет неподдерживаемым.
Во-вторых, проверьте, заполнены ли данные в регистре Стажи физических лиц для тех сотрудников, по которым выводится неверное значение.
В-третьих, используйте вычисляемые поля СКД с обращением к функциям ЗарплатаКадрыСоставВыражений или вызывайте методы модуля КадровыйУчет в коде обработки результата отчета.
Следуя этим правилам, вы получите надежный отчет, который будет работать корректно даже при изменении законодательства или обновлении платформы.