Как получить суммы начислений в разрезе должностей с учетом переводов и сотрудников ГПХ в 1С ЗУП 3.1?

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

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

Суть проблемы: Необходимость интервальной кадровой истории и учет ГПХ

Основная сложность заключается в том, что регистр накопления "НачисленияУдержанияПоСотрудникам" хранит данные за определенный период (обычно месяц), а регистр сведений "КадроваяИсторияСотрудников" хранит актуальные кадровые данные на определенную дату. Если сотрудник в течение месяца был переведен с одной должности на другую, простая выборка "среза последних" на конец месяца или даже на начало месяца не покажет полной картины. Нам необходимо знать, какая должность была у сотрудника в каждый конкретный день (или месяц) начисления.

Дополнительный вызов – это сотрудники по договорам ГПХ. Для них, как правило, отсутствуют записи в регистре "КадроваяИсторияСотрудников", так как они не являются штатными сотрудниками. Следовательно, прямое соединение с этим регистром приведет к исключению ГПХ-шников из отчета.

Давайте разберем по шагам, как построить такой запрос, преодолевая указанные сложности.

Шаг 1: Получаем данные по начислениям

Начнем с получения основных данных по начислениям. Нам потребуется регистр накопления НачисленияУдержанияПоСотрудникам. Виртуальная таблица Обороты этого регистра позволяет получить суммы начислений за заданный период. Мы группируем данные по сотруднику и периоду (приводим его к началу месяца, чтобы агрегировать начисления за месяц), а также исключаем специфические виды начислений/удержаний, такие как НДФЛ.

Рассмотрим структуру запроса для получения начислений:


ВЫБРАТЬ
    НачисленияУдержанияПоСотрудникамОбороты.Сотрудник КАК Сотрудник,
    СУММА(НачисленияУдержанияПоСотрудникамОбороты.СуммаОборот) КАК СуммаОборот,
    НАЧАЛОПЕРИОДА(НачисленияУдержанияПоСотрудникамОбороты.Период, МЕСЯЦ) КАК Период
ПОМЕСТИТЬ втНачисления
ИЗ
    РегистрНакопления.НачисленияУдержанияПоСотрудникам.Обороты(
        &НачалоПериода,
        &КонецПериода,
        День,
        НЕ НачислениеУдержание ССЫЛКА ПланВидовРасчета.Удержания
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛ)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛКЗачету)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛЗачтено)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НФДЛДивиденды)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛСПревышения)
    ) КАК НачисленияУдержанияПоСотрудникамОбороты
// ГДЕ НачисленияУдержанияПоСотрудникамОбороты.Сотрудник = &Сотрудник // Если нужен отчет по одному сотруднику
СГРУППИРОВАТЬ ПО
    НАЧАЛОПЕРИОДА(НачисленияУдержанияПоСотрудникамОбороты.Период, МЕСЯЦ),
    НачисленияУдержанияПоСотрудникамОбороты.Сотрудник
;

В этом запросе:

  1. Мы используем НАЧАЛОПЕРИОДА(НачисленияУдержанияПоСотрудникамОбороты.Период, МЕСЯЦ) для того, чтобы все начисления за один календарный месяц агрегировались к одной дате – началу этого месяца.
  2. В условиях на виртуальную таблицу Обороты мы исключаем виды начислений и удержаний, которые не должны попадать в итоговую сумму (в данном случае НДФЛ и некоторые удержания).
  3. Строка // ГДЕ НачисленияУдержанияПоСотрудникамОбороты.Сотрудник = &Сотрудник закомментирована, так как обычно такие отчеты строятся по всем сотрудникам или группе. Если нужен отчет по конкретному сотруднику, эту строку можно раскомментировать.

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

Шаг 2: Формируем интервальную кадровую историю

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

Существует несколько подходов к формированию интервальной кадровой истории:

Метод 1: Ручное построение интервальной истории (более универсальный, но сложный)

Этот метод предполагает, что мы самостоятельно вычисляем даты начала и окончания действия каждой кадровой записи. Для каждой записи в РегистрСведений.КадроваяИсторияСотрудников Период является датой начала действия. Дата окончания действия для текущей записи — это день, предшествующий дате начала следующей записи, или конец отчетного периода, если текущая запись последняя.

Давайте посмотрим на запрос, который может сформировать такую историю:


ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    КадроваяИсторияСотрудников.Период КАК ДатаНачала,
    ЕСТЬNULL(
        (ВЫБРАТЬ МИНИМУМ(ВложенныйЗапрос.Период) ИЗ РегистрСведений.КадроваяИсторияСотрудников КАК ВложенныйЗапрос
         ГДЕ ВложенныйЗапрос.Сотрудник = КадроваяИсторияСотрудников.Сотрудник
         И ВложенныйЗапрос.Период > КадроваяИсторияСотрудников.Период) - 1,
        &КонецПериода
    ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Должность КАК Должность,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
ПОМЕСТИТЬ втКадроваяИсторияИнтервальная
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
ГДЕ
    КадроваяИсторияСотрудников.Период <= &КонецПериода
    И ЕСТЬNULL(
        (ВЫБРАТЬ МИНИМУМ(ВложенныйЗапрос.Период) ИЗ РегистрСведений.КадроваяИсторияСотрудников КАК ВложенныйЗапрос
         ГДЕ ВложенныйЗапрос.Сотрудник = КадроваяИсторияСотрудников.Сотрудник
         И ВложенныйЗапрос.Период > КадроваяИсторияСотрудников.Период) - 1,
        &КонецПериода
    ) >= &НачалоПериода
;

Здесь мы:

  1. Используем вложенный запрос для поиска следующей по Периоду записи для того же сотрудника.
  2. МИНИМУМ(ВложенныйЗапрос.Период) - 1 дает нам дату окончания текущего интервала.
  3. Если следующей записи нет (то есть это последняя кадровая запись), то ЕСТЬNULL подставляет &КонецПериода отчета.
  4. Условие в ГДЕ отсекает записи, которые полностью выходят за пределы нашего отчетного периода.

Эта временная таблица втКадроваяИсторияИнтервальная будет содержать для каждого сотрудника интервалы дат, в течение которых действовала определенная должность и подразделение.

Метод 2: Использование Представлений СКД (рекомендовано для ЗУП 3.1)

Разработчики 1С для ЗУП 3.1 предоставили специальные "Представления" для системы компоновки данных (СКД), которые значительно упрощают получение кадровых данных, учитывая всю сложность их хранения. Одно из таких представлений – Представления_СрезПоследних_КадроваяИсторияСотрудников. Оно позволяет получить срез последних кадровых данных на каждую дату в заданном диапазоне, что идеально подходит для нашей задачи.

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

Если бы мы использовали представление, запрос для получения кадровых данных мог бы выглядеть так (с упрощениями для примера):


ВЫБРАТЬ
    КадроваяИстория.Сотрудник КАК Сотрудник,
    КадроваяИстория.Период КАК Период,
    КадроваяИстория.Должность КАК Должность,
    КадроваяИстория.Подразделение КАК Подразделение
ПОМЕСТИТЬ втКадроваяИсторияПоПериодам
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(
        &КонецПериода,
        Сотрудник В (ВЫБРАТЬ Сотрудник ИЗ втНачисления) // Или конкретный список сотрудников
    ) КАК КадроваяИстория
;

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

Более продвинутый вариант с использованием генерации дат для получения среза на каждый месяц:


ВЫБРАТЬ
    КадроваяИсторияСрез.Сотрудник КАК Сотрудник,
    НАЧАЛОПЕРИОДА(Даты.ДатаМесяца, МЕСЯЦ) КАК Период,
    КадроваяИсторияСрез.Должность КАК Должность,
    КадроваяИсторияСрез.Подразделение КАК Подразделение
ПОМЕСТИТЬ втКадроваяИсторияМесячная
ИЗ
    (ВЫБРАТЬ
        ДОБАВИТЬКДАТЕ(&НачалоПериода, МЕСЯЦ, Числа.Номер) КАК ДатаМесяца
    ИЗ
        (ВЫБРАТЬ РАЗЛИЧНЫЕ
            РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, МЕСЯЦ) + 1 КАК КоличествоМесяцев
        ПОМЕСТИТЬ втКоличествоМесяцев) КАК Числа
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Числа
        ПО Числа.Номер <= КоличествоМесяцев
        // Генерация таблицы чисел для ДОБАВИТЬКДАТЕ - это упрощенный подход
        // В реальных условиях лучше использовать таблицу с числами или более сложные методы
    ) КАК Даты
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(
        Даты.ДатаМесяца,
        Сотрудник В (ВЫБРАТЬ Сотрудник ИЗ втНачисления)
    ) КАК КадроваяИсторияСрез
    ПО ИСТИНА // Соединение по всем строкам, затем отфильтруем
;

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

Мы рекомендуем использовать подход с явным вычислением интервалов (Метод 1), так как он дает точную интервальную историю, которая позволяет корректно связать начисления с должностями в любой день периода.

Шаг 3: Объединяем начисления с интервальной кадровой историей

Теперь, когда у нас есть временная таблица с начислениями (втНачисления) и временная таблица с интервальной кадровой историей (втКадроваяИсторияИнтервальная, полученная Методом 1), мы можем их соединить. Ключевым здесь будет ЛЕВОЕ СОЕДИНЕНИЕ и условие, что период начисления попадает в интервал действия кадровой записи.

Почему ЛЕВОЕ СОЕДИНЕНИЕ? Потому что нам необходимо сохранить все записи из таблицы начислений, даже если для какого-либо сотрудника (например, ГПХ) не найдется соответствующей записи в кадровой истории. В этом случае поля должности и подразделения из правой таблицы будут NULL, что мы обработаем на следующем шаге.

Условие соединения будет следующим:


...
ИЗ
    втНачисления КАК втНачисления
    ЛЕВОЕ СОЕДИНЕНИЕ втКадроваяИсторияИнтервальная КАК втКадроваяИстория
    ПО
        втНачисления.Сотрудник = втКадроваяИстория.Сотрудник
        И втНачисления.Период МЕЖДУ втКадроваяИстория.ДатаНачала И втКадроваяИстория.ДатаОкончания
...

Использование МЕЖДУ крайне важно, поскольку оно позволяет корректно сопоставить месячный период начисления с интервалом действия должности. Если бы мы использовали простое равенство по Период, мы бы упустили все начисления, где период кадровой истории не совпадал бы точно с месяцем начисления, что особенно критично при переводах в середине месяца.

Шаг 4: Обработка сотрудников по договорам ГПХ

Как мы уже выяснили, для сотрудников по ГПХ, скорее всего, не будет записей в РегистрСведений.КадроваяИсторияСотрудников. Благодаря ЛЕВОМУ СОЕДИНЕНИЮ их начисления сохранятся в итоговой выборке, но поля Должность и Подразделение будут иметь значение NULL.

Чтобы сделать отчет более информативным, мы можем заменить эти NULL-значения на более осмысленные строки, например, "Сотрудник ГПХ" или "Без должности". Для этого используем функцию ЕСТЬNULL() или оператор ВЫБОР КОГДА в секции ВЫБРАТЬ финального запроса.

Пример использования ЕСТЬNULL:


ВЫБРАТЬ
    втНачисления.Период КАК ПериодНачисления,
    втНачисления.Сотрудник КАК Сотрудник,
    ЕСТЬNULL(втКадроваяИстория.Должность, "Сотрудник ГПХ") КАК Должность,
    ЕСТЬNULL(втКадроваяИстория.Подразделение, "Без подразделения") КАК Подразделение,
    втНачисления.СуммаОборот КАК СуммаНачисления
ИЗ
    втНачисления КАК втНачисления
    ЛЕВОЕ СОЕДИНЕНИЕ втКадроваяИсторияИнтервальная КАК втКадроваяИстория
    ПО
        втНачисления.Сотрудник = втКадроваяИстория.Сотрудник
        И втНачисления.Период МЕЖДУ втКадроваяИстория.ДатаНачала И втКадроваяИстория.ДатаОкончания
// ГРУППИРОВКА ПО ВСЕМ ПОЛЯМ, ЕСЛИ НЕТ АГРЕГИРУЮЩИХ ФУНКЦИЙ
СГРУППИРОВАТЬ ПО
    втНачисления.Период,
    втНачисления.Сотрудник,
    ЕСТЬNULL(втКадроваяИстория.Должность, "Сотрудник ГПХ"),
    ЕСТЬNULL(втКадроваяИстория.Подразделение, "Без подразделения"),
    втНачисления.СуммаОборот
;

Это позволит включить всех сотрудников в отчет и заполнить недостающие кадровые данные для ГПХ-шников. Важно помнить, что если вы используете агрегирующие функции (например, СУММА()), то поля, для которых вы используете ЕСТЬNULL(), также должны быть включены в секцию СГРУППИРОВАТЬ ПО.

Альтернативный подход для ГПХ: Объединение запросов (ОБЪЕДИНИТЬ ВСЕ)

Если требуется более сложное поведение для ГПХ (например, получение их "должности" из других источников, не связанных с кадровой историей, или если данные для ГПХ должны быть представлены в особом формате), можно использовать подход с ОБЪЕДИНИТЬ ВСЕ. Это означает, что мы создаем два отдельных запроса:

  1. Первый запрос: для штатных сотрудников, где мы используем жесткое соединение с кадровой историей по интервалам.
  2. Второй запрос: для сотрудников ГПХ, где мы можем получить их "должность" из договора ГПХ или просто указать "Сотрудник ГПХ" по умолчанию.

Затем результаты этих двух запросов объединяются с помощью ОБЪЕДИНИТЬ ВСЕ.

Пример структуры:


// Запрос для штатных сотрудников
ВЫБРАТЬ
    втНачисления.Период КАК ПериодНачисления,
    втНачисления.Сотрудник КАК Сотрудник,
    втКадроваяИстория.Должность КАК Должность,
    втКадроваяИстория.Подразделение КАК Подразделение,
    втНачисления.СуммаОборот КАК СуммаНачисления
ИЗ
    втНачисления КАК втНачисления
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ втКадроваяИсторияИнтервальная КАК втКадроваяИстория
    ПО
        втНачисления.Сотрудник = втКадроваяИстория.Сотрудник
        И втНачисления.Период МЕЖДУ втКадроваяИстория.ДатаНачала И втКадроваяИстория.ДатаОкончания
ГДЕ
    НЕ втКадроваяИстория.Сотрудник ССЫЛКА Справочник.Сотрудники.СотрудникПоДоговоруГПХ // Условие для определения штатных
    И втНачисления.Сотрудник ССЫЛКА Справочник.Сотрудники // Убеждаемся, что это сотрудник, а не ГПХ

ОБЪЕДИНИТЬ ВСЕ

// Запрос для сотрудников ГПХ
ВЫБРАТЬ
    втНачисленияГПХ.Период КАК ПериодНачисления,
    втНачисленияГПХ.Сотрудник КАК Сотрудник,
    "Сотрудник ГПХ" КАК Должность, // Или выбираем из другого источника
    "Без подразделения" КАК Подразделение, // Или выбираем из другого источника
    втНачисленияГПХ.СуммаОборот КАК СуммаНачисления
ИЗ
    втНачисления КАК втНачисленияГПХ
ГДЕ
    втНачисленияГПХ.Сотрудник ССЫЛКА Справочник.Сотрудники.СотрудникПоДоговоруГПХ // Условие для определения ГПХ
;

Этот подход дает больше гибкости, но может быть более сложным в реализации и отладке.

Финальный консолидированный запрос (пример)

Давайте соберем все рассмотренные шаги в один запрос, используя метод интервальной кадровой истории и ЕСТЬNULL для ГПХ-шников.


////////////////////////////////////////////////////////////
// Временная таблица 1: Начисления
////////////////////////////////////////////////////////////
ВЫБРАТЬ
    НачисленияУдержанияПоСотрудникамОбороты.Сотрудник КАК Сотрудник,
    СУММА(НачисленияУдержанияПоСотрудникамОбороты.СуммаОборот) КАК СуммаОборот,
    НАЧАЛОПЕРИОДА(НачисленияУдержанияПоСотрудникамОбороты.Период, МЕСЯЦ) КАК Период
ПОМЕСТИТЬ втНачисления
ИЗ
    РегистрНакопления.НачисленияУдержанияПоСотрудникам.Обороты(
        &НачалоПериода,
        &КонецПериода,
        День,
        НЕ НачислениеУдержание ССЫЛКА ПланВидовРасчета.Удержания
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛ)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛКЗачету)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛЗачтено)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НФДЛДивиденды)
        И НачислениеУдержание <> ЗНАЧЕНИЕ(Перечисление.ВидыОсобыхНачисленийИУдержаний.НДФЛСПревышения)
    ) КАК НачисленияУдержанияПоСотрудникамОбороты
СГРУППИРОВАТЬ ПО
    НАЧАЛОПЕРИОДА(НачисленияУдержанияПоСотрудникамОбороты.Период, МЕСЯЦ),
    НачисленияУдержанияПоСотрудникамОбороты.Сотрудник
;

////////////////////////////////////////////////////////////
// Временная таблица 2: Интервальная кадровая история
////////////////////////////////////////////////////////////
ВЫБРАТЬ
    КадроваяИсторияСотрудников.Сотрудник КАК Сотрудник,
    КадроваяИсторияСотрудников.Период КАК ДатаНачала,
    ЕСТЬNULL(
        (ВЫБРАТЬ МИНИМУМ(ВложенныйЗапрос.Период) ИЗ РегистрСведений.КадроваяИсторияСотрудников КАК ВложенныйЗапрос
         ГДЕ ВложенныйЗапрос.Сотрудник = КадроваяИсторияСотрудников.Сотрудник
         И ВложенныйЗапрос.Период > КадроваяИсторияСотрудников.Период) - 1,
        &КонецПериода
    ) КАК ДатаОкончания,
    КадроваяИсторияСотрудников.Должность КАК Должность,
    КадроваяИсторияСотрудников.Подразделение КАК Подразделение
ПОМЕСТИТЬ втКадроваяИсторияИнтервальная
ИЗ
    РегистрСведений.КадроваяИсторияСотрудников КАК КадроваяИсторияСотрудников
ГДЕ
    КадроваяИсторияСотрудников.Период <= &КонецПериода
    И ЕСТЬNULL(
        (ВЫБРАТЬ МИНИМУМ(ВложенныйЗапрос.Период) ИЗ РегистрСведений.КадроваяИсторияСотрудников КАК ВложенныйЗапрос
         ГДЕ ВложенныйЗапрос.Сотрудник = КадроваяИсторияСотрудников.Сотрудник
         И ВложенныйЗапрос.Период > КадроваяИсторияСотрудников.Период) - 1,
        &КонецПериода
    ) >= &НачалоПериода
;

////////////////////////////////////////////////////////////
// Основной запрос: Объединение и финальная выборка
////////////////////////////////////////////////////////////
ВЫБРАТЬ
    втНачисления.Период КАК ПериодНачисления,
    втНачисления.Сотрудник КАК Сотрудник,
    ЕСТЬNULL(втКадроваяИстория.Должность, ЗНАЧЕНИЕ(Справочник.Должности.ПустаяСсылка)) КАК Должность,
    ЕСТЬNULL(втКадроваяИстория.Подразделение, ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)) КАК Подразделение,
    втНачисления.СуммаОборот КАК СуммаНачисления
ИЗ
    втНачисления КАК втНачисления
    ЛЕВОЕ СОЕДИНЕНИЕ втКадроваяИсторияИнтервальная КАК втКадроваяИстория
    ПО
        втНачисления.Сотрудник = втКадроваяИстория.Сотрудник
        И втНачисления.Период МЕЖДУ втКадроваяИстория.ДатаНачала И втКадроваяИстория.ДатаОкончания
СГРУППИРОВАТЬ ПО
    втНачисления.Период,
    втНачисления.Сотрудник,
    ЕСТЬNULL(втКадроваяИстория.Должность, ЗНАЧЕНИЕ(Справочник.Должности.ПустаяСсылка)),
    ЕСТЬNULL(втКадроваяИстория.Подразделение, ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)),
    втНачисления.СуммаОборот
;

В этом финальном запросе мы используем ЗНАЧЕНИЕ(Справочник.Должности.ПустаяСсылка) и ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка) вместо строковых значений "Сотрудник ГПХ" или "Без подразделения". Это более корректно с точки зрения работы с объектами 1С, так как позволяет сохранять тип данных полей Должность и Подразделение как ссылки на соответствующие справочники, даже для ГПХ-шников, для которых реальные значения отсутствуют. Если для отчета нужны именно строковые представления, то можно использовать ЕСТЬNULL(Представление(втКадроваяИстория.Должность), "Сотрудник ГПХ").

Важные аспекты и рекомендации

  1. Производительность: Запросы с вычислением интервалов и вложенными запросами могут быть достаточно ресурсоемкими, особенно на больших базах данных. Обязательно тестируйте запрос на реальных данных и при необходимости оптимизируйте его (например, добавьте индексы, если это возможно, или ограничьте период выборки).
  2. Параметры: Использование параметров &НачалоПериода и &КонецПериода позволяет гибко управлять отчетным периодом.
  3. Особенности ЗУП 3.1: В ЗУП 3.1 для кадрового учета используются не только регистры сведений, но и специальные функции программного интерфейса (например, КадровыйУчет.КадровыеДанныеСотрудников()), которые могут упростить получение некоторых данных и являются более устойчивыми к изменениям в конфигурации. При возможности, рассмотрите их использование, особенно если вы разрабатываете отчет на СКД.
  4. Точность интервалов: Мы использовали НАЧАЛОПЕРИОДА(..., МЕСЯЦ) для начислений, что подразумевает, что должность актуальна на весь месяц. Если требуется дневная точность (например, если начисления могут быть внутримесячными и привязаны к конкретным дням перевода), то Период начислений не нужно приводить к началу месяца, а втКадроваяИсторияИнтервальная должна быть построена с максимальной точностью.

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

← На главную