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

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

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

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

Анализ причины проблемы: Сотрудник vs Физическое лицо

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

Когда в настройках расчетного листка устанавливается отбор по полю Подразделение, система фильтрует именно записи справочника Сотрудники. В результате:

  1. Основной сотрудник попадает в отчет, так как его подразделение совпадает с фильтром.
  2. Сотрудник-совместитель отсекается, так как он числится в другом подразделении.
  3. Итоговый расчетный листок выводит данные только по одной должности, что вводит расчетчика в заблуждение относительно общей суммы начислений и удержаний физлица.

Рассмотрим подробнее способы обхода этого ограничения.

Решение №1: Использование штатных возможностей в новых релизах

Прежде чем приступать к программированию, проверим версию вашей конфигурации. Начиная с релизов 3.1.18.246 и выше, фирма «1С» добавила штатную опцию, которая решает эту проблему. В настройках отчета (вкладка Настройки — Расширенный — Дополнительные настройки) появился флаг Выводить отчет по всем рабочим местам сотрудника.

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

Решение №2: Программная подмена отбора через расширение

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

Разберем алгоритм действий по шагам:

  1. Создадим новое расширение и добавим в него общий модуль ЗарплатаКадрыОтчеты.
  2. Найдем процедуру ПриКомпоновкеРезультатаРасчетныйЛисток и обернем ее в метод &Вместо или используем &Перед.
  3. Внутри процедуры нам нужно прочитать пользовательские настройки компоновщика. Если пользователь установил отбор по полю Подразделение, мы должны:
    • Получить выбранное подразделение.
    • Выполнить запрос к регистру сведений ТекущиеКадровыеДанныеСотрудников, чтобы найти все Физические лица, работающие в этом подразделении на дату отчета.
    • Отключить или удалить стандартный отбор по Подразделение.
    • Добавить новый отбор по полю ФизическоеЛицо, передав туда список найденных лиц.

Рассмотрим пример кода, который реализует эту логику в расширении:


&Вместо("ПриКомпоновкеРезультатаРасчетныйЛисток")
Процедура Ист_ПриКомпоновкеРезультатаРасчетныйЛисток(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Получаем текущие настройки отчета
    Настройки = ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки();
    
    // Ищем отбор по подразделению
    ЭлементОтбораПодразделение = Неопределено;
    Для Каждого Элемент Из Настройки.Отбор.Элементы Цикл
        Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") 
            И Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Подразделение") Тогда
            ЭлементОтбораПодразделение = Элемент;
            Прервать;
        КонецЕсли;
    КонецЦикла;

    Если ЭлементОтбораПодразделение <> Неопределено И ЭлементОтбораПодразделение.Использование Тогда
        // 1. Находим всех физлиц в этом подразделении
        СписокФизЛиц = ПолучитьСписокФизЛицПодразделения(ЭлементОтбораПодразделение.ПравоеЗначение);
        
        // 2. Отключаем отбор по подразделению, чтобы не резало совместителей
        ЭлементОтбораПодразделение.Использование = Ложь;
        
        // 3. Добавляем отбор по списку ФизЛиц
        НовыйОтбор = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ФизическоеЛицо");
        НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
        НовыйОтбор.ПравоеЗначение = СписокФизЛиц;
        НовыйОтбор.Использование = Истина;
        
        // Загружаем модифицированные настройки обратно
        ЭтотОбъект.КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
    КонецЕсли;

КонецПроцедуры

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

Решение №3: Работа с шаблонами запросов в модуле «ЗарплатаКадрыОбщие»

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

Если вы опытный разработчик, вы можете модифицировать формирование временной таблицы ВТДанныеСотрудников. Необходимо изменить условие связи так, чтобы при попадании основного сотрудника в выборку, система автоматически добавляла в таблицу всех его «двойников» (внутренних совместителей) по полю ФизическоеЛицо. Посмотрите на глобальный поиск по строке ОбщиеЗапросы_НачисленияУдержания — именно там описываются шаблоны, из которых собирается итоговый текст запроса для расчетных листков.

Важный момент: Постобработка запроса здесь не подходит, так как данные уже будут отсечены на этапе первичной выборки из регистров расчета. Нужно менять именно условия вхождения сотрудников в пакет запросов СКД.

Рекомендации для релиза 3.1.14

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

  1. Сохраните типовой отчет РасчетныйЛисток на диск.
  2. В модуле объекта внешнего отчета найдите блок формирования данных.
  3. В тексте запроса (который обычно передается в процедуру ЗарплатаКадрыОтчеты.ПриКомпоновкеРезультатаРасчетныйЛисток) вручную ослабьте условия по подразделению в секции ГДЕ.

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

Резюме

Для решения задачи мы рекомендуем:

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

← На главную