Как программно вызвать обработчик события формы При изменении сотрудника из внешней обработки

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

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

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

Способ 1. Использование расширения и экспортной обертки

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

Разберем этот процесс по шагам:

  1. Создадим расширение для конфигурации.
  2. Добавим в расширение форму документа Увольнение.
  3. В модуле формы расширения создадим новую экспортную процедуру-обертку.

Пример кода в модуле формы расширения:


&НаСервере
Процедура пвОбновитьДанныеФормыЭкспорт() Экспорт
    // Вызываем внутреннюю процедуру типовой формы
    СотрудникПриИзмененииНаСервере(); 
КонецПроцедуры

Однако этот метод имеет существенный недостаток: для его работы требуется наличие открытой формы документа (контекста ЭтаФорма). Если ваша обработка работает в фоновом задании или просто создает сотни документов в цикле без открытия окон, этот метод не подойдет.

Способ 2. Поиск программного интерфейса (API) в общих модулях

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

Рассмотрим подробнее структуру модулей. Вместо того чтобы пытаться «дернуть» событие формы, нам следует найти процедуру в общем модуле, которую вызывает сама форма. Чаще всего такие процедуры находятся в модулях:

Обычно существует метод, принимающий ДокументОбъект или структуру данных. Проанализируем пример вызова такой логики:


// В вашей обработке
НовыйДокумент = Документы.Увольнение.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = ВыбраннаяОрганизация;
НовыйДокумент.Сотрудник = ВыбранныйСотрудник;

// Ищем экспортный метод для заполнения параметров увольнения
ПараметрыЗаполнения = УвольнениеФормы.ПараметрыЗаполнения(НовыйДокумент);
УвольнениеФормы.ЗаполнитьПоСотруднику(НовыйДокумент, ПараметрыЗаполнения);

Этот подход является наиболее правильным, так как он не зависит от интерфейса и работает непосредственно с данными объекта.

Способ 3. Использование механизма ДополнительныеСвойства

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

В коде обработки мы пишем:


ОбъектДок = Документы.Увольнение.СоздатьДокумент();
ОбъектДок.Сотрудник = НужныйСотрудник;
// Устанавливаем специальный флаг
ОбъектДок.ДополнительныеСвойства.Вставить("ПерезаполнитьПриПрограммномСоздании", Истина);
ОбъектДок.Записать();

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

Способ 4. Перенос логики в модуль менеджера

Проанализируем ситуацию, когда типового API недостаточно. В этом случае хорошей практикой считается создание собственного метода в расширении в модуле менеджера документа. Мы можем скопировать код из СотрудникПриИзменении, но адаптировать его так, чтобы он работал не с реквизитами формы, а с реквизитами ДокументОбъект.

Посмотрим на пример такой адаптации:

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

Важный нюанс: при работе с ЗУП 3.1 помните, что многие расчеты (например, средний заработок) выполняются асинхронно или требуют актуальных данных в регистрах. После заполнения объекта программно, обязательно убедитесь, что вы вызвали процедуры актуализации данных, иначе документ запишется с «нулевыми» суммами.

Резюме

Вызывать события формы напрямую из обработки — это путь, ведущий к нестабильной работе системы и привязке к экранным формам, которых нет при фоновом выполнении. Рекомендуется всегда искать экспортные методы в общих модулях Увольнение.... Если же разработчики конфигурации не предусмотрели API, используйте расширение для создания собственного экспортного метода в модуле менеджера или объекта, который будет отвечать за полное заполнение документа «под ключ».

← На главную