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