Как настроить предупреждение о сохранении изменений при закрытии формы в 1С?

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

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

Анализ проблемы: почему возникает ошибка при попытке вызвать предупреждение?

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

Проанализируем код, который привел к ошибке:


Процедура ПриЗакрытии()
    Модифицировать = Истина;
КонецПроцедуры

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

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

Как автоматически работает свойство «Модифицированность»?

Давайте подробнее разберем, как платформа 1С управляет данным свойством по умолчанию. Если вы размещаете на форме стандартные реквизиты объекта (например, базовые реквизиты справочника Контрагенты или документа), вам вообще не нужно писать код для контроля их изменения.

  1. Как только пользователь редактирует любое поле, связанное с основным реквизитом объекта, платформа автоматически устанавливает для формы Модифицированность = Истина.
  2. В заголовке формы появляется символ снежинки (*), сигнализирующий о наличии несохраненных данных.
  3. При попытке закрыть форму крестиком или клавишей Esc, 1С самостоятельно перехватит событие и покажет стандартный диалог с предложением сохранить данные.

Ручное присвоение Модифицированность = Истина требуется только тогда, когда мы работаем с независимыми (вспомогательными) реквизитами формы. То есть с данными, которые хранятся «внутри формы» и не связаны напрямую с реквизитами объекта базы данных, но их изменение все равно критично для бизнес-логики.

Выбор правильного обработчика: ПередЗакрытием или ПриЗакрытии?

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

Если мы хотим вмешаться в процесс закрытия, проанализируем работу обработчика ПередЗакрытием. Именно он предназначен для проверок перед тем, как окно исчезнет.


&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
    Если ЭтаФорма.Модифицированность Тогда
        // Здесь можно реализовать свою логику проверки
    КонецЕсли;
КонецПроцедуры

Параметр Отказ позволяет нам прервать действие. Если установить Отказ = Истина, форма останется открытой на экране.

Современный подход в 1С: отказ от модальных окон

Разберем важный нюанс современных версий платформы (начиная с 1С v8.3.8). Сейчас платформа ориентирована на работу в веб-клиенте, где запрещены синхронные (модальные) окна. Мы больше не можем просто вызвать метод Вопрос() прямо внутри обработчика закрытия, остановить выполнение кода и ждать ответа пользователя.

Если нам нужно задать нестандартный вопрос о сохранении при закрытии, посмотрим на современный асинхронный паттерн с использованием Библиотеки стандартных подсистем (БСП):

  1. В процедуре ПередЗакрытием мы проверяем наше условие. Если есть несохраненные данные, мы принудительно отменяем стандартное закрытие: Отказ = Истина.
  2. Затем вызываем асинхронный диалог для пользователя. В БСП для этого есть отличный метод ОбщегоНазначенияКлиент.ПоказатьПодтверждениеЗакрытияФормы().
  3. Платформа выводит пользователю вопрос. Форма при этом не заблокирована наглухо, браузер не зависает.
  4. После того как пользователь нажал кнопку (например, «Да, сохранить»), срабатывает отдельная процедура — обработчик оповещения.
  5. В этом обработчике мы программно сохраняем данные, сбрасываем флаг (Модифицированность = Ложь) и снова вызываем метод закрытия формы — ЭтаФорма.Закрыть(). В этот раз, так как флаг сброшен, форма закроется без лишних вопросов.

Как закрыть измененную форму без сохранения и лишних вопросов?

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

Решить это очень просто. Перед тем как вызвать метод закрытия, нам достаточно «обмануть» платформу, обнулив признак изменения. Рассмотрим пример:


&НаКлиенте
Процедура ЗакрытьБезСохранения()
    // Сбрасываем признак модифицированности
    ЭтаФорма.Модифицированность = Ложь;
    
    // Теперь форма закроется тихо, без предупреждений
    ЭтаФорма.Закрыть();
КонецПроцедуры

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

← На главную