Как правильно рассчитать и вывести стаж сотрудников во внешнем отчете 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке внешних отчетов по кадрам программисты часто сталкиваются с ситуацией, когда стаж на предприятии (с момента приема) выводится верно, а общий, страховой или любой другой вид стажа рассчитывается с ошибками или вовсе не отображается. Попытки решить эту задачу «в лоб» через написание огромных конструкций ВЫБОР КОГДА и использование функции РАЗНОСТЬДАТ в запросе обычно приводят к созданию нечитаемого и трудноотлаживаемого кода, который к тому же не учитывает специфику учета в 1С.

В этой статье мы подробно разберем, почему ручной расчет в запросе — это тупиковый путь, и выясним, как использовать штатные механизмы конфигураций (на примере 1С:ЗУП 3.1) для получения корректного результата.

Почему расчет стажа через обычный запрос работает некорректно?

Давайте проанализируем ситуацию. В типовых конфигурациях (ЗУП 3.1, ERP 2.5, КА 2.5) данные о стаже хранятся в регистре сведений СтажиФизическихЛиц. Но важно понимать, что там записывается не текущий стаж, а точка отсчета: количество лет, месяцев и дней на определенную дату.

Основные причины ошибок при попытке написать свой запрос:

  1. Не учитывается «входящий» остаток: Общий стаж сотрудника складывается из того, что он наработал до приема в вашу организацию (записано в регистре), и того, что он наработал у вас. Простое использование РАЗНОСТЬДАТ между приемом и текущей датой даст только стаж внутри компании.
  2. Сложность календарной арифметики: Месяцы имеют разную длительность (28, 29, 30, 31 день). Функция РАЗНОСТЬДАТ(..., МЕСЯЦ) в 1С работает по принципу разницы границ периодов, что не всегда совпадает с кадровыми правилами подсчета.
  3. Високосные годы: Ошибки в один-два дня часто возникают из-за некорректной обработки февраля в самописных формулах.

Рассмотрим, как решить проблему правильно, используя программные интерфейсы 1С.

Способ №1: Использование программных представлений в СКД

Если вы разрабатываете отчет на базе Системы компоновки данных (СКД), наиболее правильным способом будет использование механизмов, заложенных в конфигурацию. В ЗУП 3.1 существуют специальные функции, которые можно вызвать прямо в вычисляемых полях или выражениях компоновки.

Проанализируем работу с общим модулем ЗарплатаКадрыСоставВыражений. Этот модуль предназначен для того, чтобы в полях СКД можно было получать сложные данные без написания тяжелых запросов. Для вывода стажа текстом (например, «5 лет, 2 месяца, 10 дней») можно использовать вызов функции, которая сама обратится к нужным регистрам и выполнит расчет на дату отчета.

Для реализации этого метода выполним следующие шаги:

  1. В схеме компоновки данных перейдем на закладку Вычисляемые поля.
  2. Добавим новое поле, назовем его СтажТекстом.
  3. В колонке «Выражение» пропишем вызов функции типового модуля.

Пример обращения к типовым механизмам в СКД может выглядеть так (в зависимости от версии конфигурации):

ЗарплатаКадрыСоставВыражений.СтажФизическогоЛицаТекст(ФизическоеЛицо, ВидСтажа, &ДатаОтчета)

Способ №2: Использование типовых функций кадрового учета

Если отчет «обычный» (не СКД) или вам нужно получить стаж в виде чисел (количество месяцев или дней) для дальнейших расчетов, следует использовать программный интерфейс общего модуля КадровыйУчет.

Разберем алгоритм работы с функцией РассчитатьСтажиФизическихЛиц. Она удобна тем, что позволяет рассчитать данные сразу по списку сотрудников на нужную дату. Рассмотрим пример кода, который можно разместить в модуле объекта отчета:


// Подготовим таблицу сотрудников, для которых нужен расчет
ТаблицаСотрудников = Новый ТаблицаЗначений;
ТаблицаСотрудников.Колонки.Добавить("ФизическоеЛицо", Новый ОписаниеТипов("СправочникСсылка.ФизическиеЛица"));
ТаблицаСотрудников.Колонки.Добавить("ВидСтажа", Новый ОписаниеТипов("СправочникСсылка.ВидыСтажа"));

// Заполняем таблицу данными из вашего запроса
НоваяСтрока = ТаблицаСотрудников.Добавить();
НоваяСтрока.ФизическоеЛицо = СсылкаНаФизЛицо;
НоваяСтрока.ВидСтажа = Справочники.ВидыСтажа.ОбщийСтаж;

// Вызываем типовой метод расчета
ПараметрыРасчета = КадровыйУчет.ПараметрыРасчетаСтажа();
ПараметрыРасчета.ДатаРасчета = Объект.ДатаОтчета;
ПараметрыРасчета.ФизическиеЛицаВидыСтажа = ТаблицаСотрудников;

РезультатРасчета = КадровыйУчет.РассчитатьСтажиФизическихЛиц(ПараметрыРасчета);

В переменной РезультатРасчета вы получите таблицу, где для каждого физического лица будет указано общее количество лет, месяцев и дней. Это исключает любые ошибки ручного вычисления.

Способ №3: Анализ типового отчета «Стажи сотрудников»

Как справедливо заметили участники обсуждения на форуме, лучший способ понять, почему ваш код не работает — это посмотреть на работающий аналог. В конфигурации ЗУП 3.1 есть типовой отчет СтажиСотрудников.

Выясним, как он устроен:

  1. Найдем отчет в дереве конфигурации или через «Все функции».
  2. Откроем его основную схему компоновки данных.
  3. Обратим внимание на набор данных. В нем вы не увидите гигантских формул РАЗНОСТЬДАТ. Вместо этого там используются временные таблицы и связи, которые подготавливают данные для программного вывода.
  4. Основной секрет кроется в Модуле объекта отчета. Там часто используется процедура ПриКомпоновкеРезультата, где программно дозаполняются данные о стаже через вызов кадровых функций.

Рекомендации по исправлению вашего запроса

Если вы всё же вынуждены использовать запрос (например, в очень специфическом внешнем источнике), давайте проанализируем, как минимизировать ошибки.

Вместо того чтобы пытаться посчитать всё одной формулой, разделите задачу на этапы в Пакете запросов:

  1. ВТ_ДанныеРегистра: Выберите из РегистрСведений.СтажиФизическихЛиц количество лет, месяцев и дней, а также дату, на которую эти данные были актуальны (ДатаОтсчета).
  2. ВТ_РаботаВКомпании: Получите дату приема из ТекущиеКадровыеДанныеСотрудников.
  3. ВТ_ИтоговыйРасчет: Сложите периоды. Помните, что 12 месяцев должны превратиться в 1 год, а 30 дней (по кадровым правилам) — в 1 месяц.

Однако помните: запрос никогда не будет на 100% точным при расчете стажа в 1С, так как он не видит периоды исключения (например, прогулы или отпуска по уходу за ребенком, которые могут не входить в определенные виды стажа). Только использование функций общего модуля КадровыйУчет гарантирует юридическую чистоту расчета.

Резюме

Если у вас «неправильно выводится стаж», выполните следующие действия:

Во-первых, откажитесь от сложных математических вычислений внутри текста запроса. Это делает отчет неподдерживаемым.
Во-вторых, проверьте, заполнены ли данные в регистре Стажи физических лиц для тех сотрудников, по которым выводится неверное значение.
В-третьих, используйте вычисляемые поля СКД с обращением к функциям ЗарплатаКадрыСоставВыражений или вызывайте методы модуля КадровыйУчет в коде обработки результата отчета.

Следуя этим правилам, вы получите надежный отчет, который будет работать корректно даже при изменении законодательства или обновлении платформы.

← На главную