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