Как из запроса в 1С убрать сторнированные часы и записи перерасчетов

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

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

Причина появления дублей и сторно в запросе

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

Способ 1: Фильтрация по «магическому числу» ИдентификаторСтроки

Самый простой и эффективный способ в современных конфигурациях 1С основан на особенностях работы платформы с идентификаторами строк. Рассмотрим подробнее, как система нумерует записи:

  1. Записи основной табличной части: Идентификатор строки всегда меньше 1 000 000.
  2. Записи перерасчетов и автоматических корректировок: Платформа присваивает им идентификаторы, начиная с 1 000 000 и выше.

Выясним, как применить это в коде. Достаточно добавить условие в блок ГДЕ вашего запроса. Это позволит отсечь все «служебные» записи, которые не были введены пользователем вручную в основную ТЧ.


ВЫБРАТЬ
    Начисления.Сотрудник КАК Сотрудник,
    Начисления.Результат КАК Результат,
    Начисления.ОтработаноЧасов КАК ОтработаноЧасов
ИЗ
    РегистрРасчета.Начисления КАК Начисления
ГДЕ
    Начисления.ИдентификаторСтроки < 1000000
    И Начисления.ПериодРегистрации МЕЖДУ &НачПериода И &КонПериода

Важный нюанс: Не пытайтесь вставить это условие внутрь оператора сравнения в соединении (JOIN), как это иногда делают новички. Это должно быть либо самостоятельное условие в ГДЕ, либо четко отделенное условие связи.

Способ 2: Соединение с табличными частями документов

Если вам нужно гарантированно получить только те строки, которые видит пользователь в конкретной табличной части «Начисления», мы можем использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ регистра с данными документа-регистратора. Рассмотрим этот метод на примере документа «Увольнение».

Разберем по шагам логику построения запроса:

  1. Сначала выберем все данные из регистра во временную таблицу.
  2. Затем соединим эту таблицу с табличной частью Начисления документа-основания по двум полям: Регистратор (ссылка на документ) и ИдентификаторСтроки.

// Помещаем данные регистра во временную таблицу
ВЫБРАТЬ
    Начисления.Сотрудник,
    Начисления.Регистратор,
    Начисления.ИдентификаторСтроки,
    Начисления.Результат
ПОМЕСТИТЬ ВТ_ДанныеРегистра
ИЗ
    РегистрРасчета.Начисления КАК Начисления
ГДЕ
    Начисления.ПериодРегистрации МЕЖДУ &НачПериода И &КонПериода;

////////////////////////////////////////////////////////////////////////////////
// Фильтруем данные через внутреннее соединение с ТЧ документа
ВЫБРАТЬ
    ВТ.Сотрудник,
    ВТ.Результат,
    ВТ.Регистратор
ИЗ
    ВТ_ДанныеРегистра КАК ВТ
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.Увольнение.Начисления КАК ТЧ_Увольнение
    ПО ВТ.Регистратор = ТЧ_Увольнение.Ссылка
    И ВТ.ИдентификаторСтроки = ТЧ_Увольнение.ИдентификаторСтрокиВидаРасчета

Такой подход позволяет исключить любые записи, которых нет в визуальной таблице «Начисления» документа, включая все скрытые движения, порожденные механизмом перерасчетов.

Способ 3: Использование признака Сторно и группировка данных

Иногда простого исключения по идентификатору недостаточно, особенно если в документе «Отпуск» данные разбиваются по периодам (например, переходящий отпуск). В этом случае возникают дубли строк, которые кажутся одинаковыми.

Проанализируем ситуацию с полем Сторно. В регистре расчета есть стандартный реквизит Сторно (булево). Казалось бы, достаточно поставить фильтр ГДЕ Сторно = ЛОЖЬ. Однако это ловушка: если программа сначала сторнировала старый оклад (минус), а потом начислила новый (плюс) в рамках перерасчета, то фильтр по ЛОЖЬ уберет минус, но оставит плюс, что приведет к завышению итоговой суммы.

Вместо использования ВЫБРАТЬ РАЗЛИЧНЫЕ, которое не всегда корректно отрабатывает при наличии скрытых различий в полях времени, мы рекомендуем использовать группировку. Посмотрим на пример правильной структуры запроса:


ВЫБРАТЬ
    Начисления.Сотрудник КАК Сотрудник,
    Начисления.ВидРасчета КАК ВидРасчета,
    СУММА(ЕСТЬNULL(Начисления.ОтработаноЧасов, 0)) КАК ОтработаноЧасов,
    СУММА(Начисления.Результат) КАК Результат
ИЗ
    РегистрРасчета.Начисления КАК Начисления
ГДЕ
    Начисления.ИдентификаторСтроки < 1000000
СГРУППИРОВАТЬ ПО
    Начисления.Сотрудник,
    Начисления.ВидРасчета

Как бороться с дублями в документах «Отпуск»

В документах типа «Отпуск» или «Командировка» начисления часто разбиваются на несколько строк, если период действия начисления охватывает разные календарные месяцы. Чтобы избежать дублей, при которых одна и та же сумма или часы выводятся дважды, необходимо:

Резюмируя, наиболее надежным и универсальным методом для разработчика 1С является фильтрация по ИдентификаторСтроки < 1000000. Это позволяет не привязываться к конкретным типам документов (Увольнение, Отпуск, Больничный) и автоматически отсекать все данные, порожденные механизмом автоматического исправления прошлых периодов.

← На главную