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