Как в 1С рассчитать стаж сотрудника в годах, месяцах и днях?

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

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

Методологические особенности расчета стажа

Прежде чем приступать к написанию кода, проанализируем правила, по которым работает кадровик. В отличие от обычной математики, где разница между 1-м и 2-м числом составляет 1 день, в трудовом законодательстве день увольнения является рабочим днем. Это означает, что если сотрудник работал с 01.01.2023 по 31.01.2023, он отработал ровно один полный месяц (31 день), а не 30 дней.

Важный нюанс: при расчете стажа к разности дат практически всегда нужно добавлять один день, либо использовать КонецДня для даты окончания. Если этого не сделать, при сложении множества коротких периодов работы (например, по договорам ГПХ) итоговый стаж может «похудеть» на несколько недель за счет потери одного дня в каждом периоде.

Использование типовой функции РазобратьРазностьДат

В конфигурациях, построенных на базе 1С:ЗУП 2.5 или старых версиях БСП, существует крайне полезная процедура РазобратьРазностьДат. Посмотрим, как она работает. Процедура принимает две даты и возвращает результат в переменные, переданные по ссылке.

Разберем пример вызова в коде:


// Инициализируем переменные для получения результата
Лет = 0;
Месяцев = 0;
Дней = 0;

// Дата начала и дата окончания периода
Дата1 = ТекущаяСтрока.ДатаНачала;
Дата2 = ТекущаяСтрока.ДатаОкончания;

// Вызываем типовую функцию (обычно находится в ОбщегоНазначения или ОбщегоНазначенияКлиентСервер)
ОбщегоНазначения.РазобратьРазностьДат(Дата2, Дата1, Лет, Месяцев, Дней);

// Теперь переменные Лет, Месяцев и Дней содержат рассчитанные значения

Почему функция может «не работать»? Если вы заметили, что функция возвращает только дни, а года и месяцы остаются нулевыми, проверьте порядок следования аргументов. В большинстве реализаций первым параметром должна идти большая дата (дата окончания), а вторым — меньшая (дата начала). Также убедитесь, что переменные Лет, Месяцев и Дней инициализированы числом 0 перед вызовом.

Современный подход в 1С:ЗУП 3.1 и БСП

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

Рассмотрим ситуацию, когда нам нужно рассчитать стаж программно через запрос, как это предлагается в типовых решениях. Проанализируем пример использования временных таблиц для расчета стажа:


МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;

// Формируем описание данных для расчета
Запрос.Текст = 
"ВЫБРАТЬ
|   &ФизическоеЛицо КАК ФизическоеЛицо,
|   &Период КАК Дата,
|   &ВидСтажа КАК ВидСтажа
|ПОМЕСТИТЬ ВТИсходныеДанные";

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

// Используем метод КадровыйУчет.СоздатьВТСтажиСотрудников
// Эта функция автоматически рассчитает данные на основании учетных данных системы
КадровыйУчет.СоздатьВТСтажиСотрудников(Запрос.МенеджерВременныхТаблиц);

// Извлекаем результат
Запрос.Текст = "ВЫБРАТЬ РазмерМесяцев, РазмерДней ИЗ ВТСтажиСотрудников";
Выборка = Запрос.Выполнить().Выбрать();

Этот метод удобен тем, что он учитывает все введенные в систему сведения о предыдущих местах работы сотрудника, которые хранятся в соответствующих регистрах сведений.

Как правильно суммировать несколько периодов стажа?

Если ваша задача — создать калькулятор, в который пользователь вручную вводит несколько строк с периодами «Дата начала — Дата окончания», то простое сложение лет, месяцев и дней каждой строки даст математическую ошибку. Выясним почему.

Согласно правилам подсчета страхового стажа (Постановление Правительства РФ №1015), расчет производится следующим образом:

  1. Сначала вычисляется разница по каждому периоду в днях.
  2. К каждому периоду добавляется 1 день (день увольнения).
  3. Все дни суммируются в общую копилку.
  4. Итоговое количество дней переводится в месяцы и годы по правилу: 30 дней = 1 месяц, 12 месяцев = 1 год.

Это критически важно, так как в календаре есть месяцы по 28 и 31 день, но для суммируемого стажа используется фиксированный знаменатель 30. Посмотрим на пример кода для суммирования:


ОбщееКоличествоДней = 0;
Для Каждого СтрокаПериода Из ТаблицаМестРаботы Цикл
    // Считаем разницу в днях и добавляем 1 день (день увольнения)
    ДнейВПериоде = (СтрокаПериода.ДатаОкончания - СтрокаПериода.ДатаНачала) / 86400 + 1;
    ОбщееКоличествоДней = ОбщееКоличествоДней + ДнейВПериоде;
КонецЦикла;

// Переводим в годы, месяцы, дни по правилам ФСС
ИтогоЛет = Цел(ОбщееКоличествоДней / (30 * 12));
ОстатокДней = ОбщееКоличествоДней % (30 * 12);
ИтогоМесяцев = Цел(ОстатокДней / 30);
ИтогоДней = ОстатокДней % 30;

Красивое представление стажа для пользователя

Мало просто посчитать цифры, нужно вывести их пользователю в понятном виде, например: «5 лет, 2 месяца и 11 дней». В системе 1С для этого часто используется механизм склонения представлений объектов. Если вы работаете с БСП, обратите внимание на функцию СклонениеПредставленийОбъектов.ФормироватьПредставлениеПериодаДатами.

Если же вы пишете решение «с нуля», не забудьте про правильные окончания. Разберем логику:

Для реализации такой логики в 1С удобно использовать функцию ПредставлениеПериода или написать простую функцию с использованием оператора % (остаток от деления), чтобы определять последнюю цифру числа и подставлять нужное слово из массива.

Резюме и рекомендации

Подведем итоги нашего анализа. Для реализации качественного калькулятора стажа рекомендуем придерживаться следующего алгоритма:

  1. Всегда уточняйте у заказчика (бухгалтера или кадровика), нужно ли добавлять 1 день к периоду. В 99% случаев в РФ это необходимо.
  2. Если конфигурация типовая (ЗУП, КА, ERP), старайтесь использовать функцию ОбщегоНазначенияКлиентСервер.РазностьДатВГодахМесяцахДнях. Она наиболее корректно обрабатывает календарные сложности.
  3. При расчете суммарного стажа по нескольким местам работы сначала приводите всё к дням, а затем делите на 30 и 12, чтобы соответствовать законодательным нормам.
  4. Для отображения результата на форме используйте КонецДня для даты окончания, чтобы пользователь видел корректные границы периода.

Соблюдение этих простых правил позволит вам избежать претензий со стороны расчетчиков зарплаты и обеспечит точность данных в кадровых отчетах вашей системы.

← На главную