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