Почему при вызове вопроса пользователю в обработчике «ПослеЗаписи» 1С сообщает, что данные были изменены?

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

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

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

Анализ причины проблемы

Проанализируем сценарий, при котором возникает эта проблема:

  1. Пользователь нажимает кнопку «ОК» («Записать, провести и закрыть»).
  2. Платформа выполняет запись и проведение документа.
  3. Вызывается обработчик события формы ПослеЗаписи.
  4. Внутри обработчика выполняется синхронный (модальный) вызов функции Вопрос().
  5. После ответа пользователя платформой предпринимается попытка закрыть форму, но выводится диалог о несохраненных данных.

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

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

Решение 1. Переход на немодальный метод «ПоказатьВопрос»

Наиболее эффективный и правильный способ решения проблемы — использование асинхронного метода ПоказатьВопрос вместе со специальным объектом ОписаниеОповещения. Это позволяет не прерывать основной поток выполнения платформы: обработчик ПослеЗаписи завершается мгновенно, а форма закрывается штатно без лишних вопросов.

Рассмотрим пример реализации асинхронного вопроса в модуле обычной формы документа:


Процедура ПослеЗаписи(Отказ)
    
    // Формируем описание оповещения для обработки ответа пользователя
    Оповещение = Новый ОписаниеОповещения("СоздатьЗаявкуНаДоставкуЗавершение", ЭтаФорма);
    
    // Вызываем немодальный диалог
    ПоказатьВопрос(Оповещение, "Создать автоматически ""Заявку на доставку""?", РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да);

КонецПроцедуры

Процедура СоздатьЗаявкуНаДоставкуЗавершение(Результат, Параметры) Экспорт

    Если Результат <> КодВозвратаДиалога.Да Тогда
        Возврат;
    КонецЕсли;

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

КонецПроцедуры

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

Решение 2. Перенос вопроса в событие «ПередЗаписью»

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

В таком случае, если пользователь отказывается от действия или отменяет операцию, мы можем установить флаг Отказ = Истина и предотвратить проведение документа еще до начала транзакции.

Решение 3. Использование явных реквизитов формы или флажков

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

  1. Добавляем на форму документа реквизит типа Булево (например, СоздатьЗаявкуНаДоставку).
  2. Пользователь взводит флажок на форме перед нажатием кнопки «ОК».
  3. В событии ПослеЗаписи проверяем значение флага и создаем необходимый документ без вызова модальных окон.

Этот вариант делает поведение системы полностью предсказуемым и избавляет пользователя от необходимости отвечать на всплывающие вопросы при каждой записи документа.

← На главную