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