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

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

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

Постановка задачи

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

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

Способ 1. Модификация Менеджера расчета зарплаты (Прямой метод)

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

Основная логика расчета сосредоточена в обработке МенеджерРасчетаЗарплаты. Однако, в отличие от старых версий, данные здесь обрабатываются пакетами таблиц значений.

1. Создание показателя

Для начала необходимо добавить сам показатель в справочник ПоказателиРасчетаЗарплаты. Чтобы к нему можно было обращаться из кода по имени (без поиска по наименованию, что ненадежно), лучше всего:

  1. Добавить предопределенный элемент в справочник ПоказателиРасчетаЗарплаты через конфигуратор.
  2. Если конфигурация на поддержке и вы используете расширение, можно создать элемент в режиме Предприятия, а ссылку на него хранить в константе или искать по уникальному идентификатору (но предопределенный элемент надежнее).

2. Точка входа в код

В модуле объекта обработки МенеджерРасчетаЗарплаты нас интересует процедура, отвечающая за подготовку данных перед расчетом. Обратим внимание на методы (для более глубокого понимания контекста рекомендуем изучить справочник методов конфигурации Зарплата и кадры 3.1):

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

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

Примерный алгоритм внедрения нашего кода (псевдокод для понимания логики):


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

Важные нюансы:

Способ 2. Программная генерация документов "Данные для расчета зарплаты" (Рекомендуемый)

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

Этот метод безопасен при обновлениях, позволяет видеть историю значений показателя и использует типовой механизм запросов ЗУП при расчете зарплаты.

Алгоритм реализации:

  1. Настройка показателя: Создаем показатель в пользовательском режиме. Настраиваем его как "Вводится единовременно документом ввода данных для расчета зарплаты" (или накапливаемый, если нужно суммировать значения).
  2. Создание шаблона: В справочнике ШаблоныВводаИсходныхДанных создаем шаблон, в котором отмечаем наш показатель. Это обязательно, так как документы ввода данных создаются на основании шаблонов.
  3. Написание обработки или регламентного задания: Создаем механизм, который будет запускаться перед расчетом зарплаты (например, ночью или по кнопке). Стоит отметить, что если ваша задача ограничивается разовыми выплатами, может подойти простая загрузка сотрудников и сумм в табличную часть документа «Разовое начисление», но для регулярных сложных показателей нужен именно нижеописанный подход.

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


Процедура ЗаполнитьНашПоказательПрограммно(МесяцРасчета)
    
    // Получаем шаблон ввода данных
    ШаблонСсылка = Справочники.ШаблоныВводаИсходныхДанных.НайтиПоНаименованию("НашШаблонДляРасчета");
    
    // Создаем новый документ
    Док = Документы.ДанныеДляРасчетаЗарплаты.СоздатьДокумент();
    Док.Дата = КонецМесяца(МесяцРасчета);
    Док.Месяц = НачалоМесяца(МесяцРасчета);
    Док.Организация = Справочники.Организации.НайтиПоКоду("001"); // Пример
    Док.ШаблонВводаИсходныхДанных = ШаблонСсылка;
    
    // Заполняем табличную часть (имя ТЧ зависит от настроек шаблона, часто это "ЗначенияПоказателей")
    // В реальной задаче здесь будет запрос к данным для получения значений
    МассивСотрудников = ПолучитьСотрудниковДляРасчета();
    
    Для Каждого ДанныеСотрудника Из МассивСотрудников Цикл
        
        НоваяСтрока = Док.ЗначенияПоказателей.Добавить();
        НоваяСтрока.Сотрудник = ДанныеСотрудника.Сотрудник;
        
        // Вычисляем значение по нашему алгоритму
        Значение = РассчитатьСложныйПоказатель(ДанныеСотрудника.Сотрудник, МесяцРасчета);
        
        // Имя колонки с показателем генерируется динамически в шаблоне, 
        // обычно оно совпадает с идентификатором показателя (или можно найти через метаданные)
        // Предположим, имя колонки "val1" или идентично имени показателя
        ИмяКолонкиПоказателя = "Знач_" + СтрЗаменить(ШаблонСсылка.Показатели[0].Показатель.УникальныйИдентификатор(), "-", ""); 
        // Лучше посмотреть точное имя колонки в отладчике при создании документа вручную
        
        Попытка
             НоваяСтрока[ИмяКолонкиПоказателя] = Значение;
        Исключение
             // Обработка ошибки определения имени колонки
        КонецПопытки;
        
    КонецЦикла;
    
    Док.Записать(РежимЗаписиДокумента.Проведение);
    
КонецПроцедуры

Преимущества этого подхода:

Резюме

Если вам необходимо реализовать сложный расчетный показатель в ЗУП 3.1:

Вариант А (Для гуру и экстремалов): Через расширение вклиниться в МенеджерРасчетаЗарплаты.ЗаполнитьЗначенияПоказателейНачислений(), предварительно добавив предопределенный показатель. Это позволяет избежать создания лишних документов, но повышает риски при обновлениях.

Вариант Б (Рекомендуемый стандарт): Написать внешнюю обработку или регламентное задание, которое программно создает и проводит документы ДанныеДляРасчетаЗарплаты по заранее созданному шаблону. Это соответствует идеологии ЗУП 3.1, обеспечивает прозрачность учета и безопасность обновлений.

← На главную