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