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