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

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

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

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

Почему изменения в подписке на проведение документа могут не сохраняться

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

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

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

Вариант 1. Использование флага Записывать и явная запись

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


Процедура ПриПроведенииУвольнения(Источник, Отказ, РежимПроведения)
    
    // Получаем набор записей из коллекции движений документа
    НаборПлановыхНачислений = Источник.Движения.ПлановыеНачисления;
    
    // Выгружаем движения в таблицу значений для удобной обработки
    ТаблицаДвижений = НаборПлановыхНачислений.Выгрузить();
    
    // Допустим, нам нужно изменить дату окончания начисления для определенных строк
    Для Каждого СтрокаДвижения Из ТаблицаДвижений Цикл
        Если СтрокаДвижения.Начисление = НужноеНачисление Тогда
            СтрокаДвижения.ДействуетДо = КонецМесяца(ДобавитьМесяц(Источник.ДатаУвольнения, 1));
            СтрокаДвижения.Используется = Истина;
            СтрокаДвижения.УдалитьИспользуетсяПоОкончании = Истина;
        КонецЕсли;
    КонецЦикла;
    
    // Загружаем измененную таблицу обратно в движения
    НаборПлановыхНачислений.Загрузить(ТаблицаДвижений);
    
    // КРИТИЧЕСКИ ВАЖНО: устанавливаем флаг записи и вызываем метод Записать()
    НаборПлановыхНачислений.Записывать = Истина;
    НаборПлановыхНачислений.Записать(Истина); // Истина - параметр замещения существующих записей
    
КонецПроцедуры

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

Вариант 2. Подписка на событие ПередЗаписью регистра (Рекомендуемый)

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

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

Рассмотрим пример реализации такой подписки. В качестве Источник здесь будет выступать РегистрСведенийНаборЗаписей.ПлановыеНачисления.


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

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

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

Нюансы работы с регистрами состояний

При корректировке регистра ПлановыеНачисления важно помнить, что в ЗУП 3.1 право на начисление проверяется в комплексе. Проанализируем смежные регистры:

Если ваша задача — выплатить что-то сотруднику после увольнения, рассмотрите возможность использования механизмов «Прочие доходы» или настройки начисления, которое не требует наличия действующего трудового договора в периоде расчета. Если же вы программно продлеваете начисление, рассмотрите необходимость аналогичной правки в регистрах, отвечающих за состояние занятости, иначе Расчет Зарплаты просто «не увидит» ваше начисление.

Заключение

Подведем итоги. Для гарантированного изменения движений в ЗУП 3.1 мы рекомендуем использовать подписку на событие регистра сведений ПередЗаписью. Это позволяет избежать конфликтов с типовым механизмом ЗаписьДвиженийПоУчетам и гарантирует сохранение данных. Если же вы используете подписку на документ, обязательно проверяйте флаг Записывать и при необходимости вызывайте метод Записать(Истина), чтобы зафиксировать изменения в базе данных.

← На главную