Как сделать так, чтобы 1С запрашивала сохранение документа только при реальном редактировании

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

Часто пользователи сталкиваются с раздражающей ситуацией: они открывают документ в 1С просто для того, чтобы просмотреть данные («поглазеть»), ничего в нем не меняют, но при попытке закрыть форму нажатием на «крестик» программа настойчиво спрашивает: «Сохранить изменения?». Это не только замедляет работу, но и вводит в заблуждение, заставляя пользователя сомневаться — не изменил ли он что-то случайно. В этой статье мы подробно разберем, почему так происходит, как найти «виновника» в коде и как правильно настроить поведение формы в обычных и управляемых приложениях.

Разберем причину: что такое модифицированность?

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

Проблема «ложного» сохранения чаще всего кроется в процедурах ПриОткрытии или ПередОткрытием. Если в этих обработчиках прописано прямое присвоение значений реквизитам объекта, форма помечается как измененная в ту же секунду, когда пользователь ее открыл.

Шаг 1: Поиск проблемного участка через отладчик

Прежде чем что-то исправлять, нам нужно точно выяснить, какая строка кода «пачкает» объект. Для этого проанализируем ситуацию с помощью конфигуратора и встроенного отладчика.

  1. Откроем модуль формы документа, который ведет себя некорректно.
  2. Найдем процедуру ПриОткрытии (или ПриСозданииНаСервере для управляемых форм).
  3. Установим точку останова в самом начале процедуры (клавиша F9).
  4. Запустим сеанс отладки и откроем злополучный документ.
  5. Когда выполнение программы остановится, откроем окно Табло и впишем туда выражение Модифицированность (для обычных форм) или ЭтаФорма.Модифицированность (для управляемых).
  6. Будем пошагово проходить код, нажимая F10, и внимательно следить, после какой строки значение в табло изменится с Ложь на Истина.

Как правило, виновником оказывается код вида:


Если ДоговорСбытаСКоторогоСписываем.Пустая() Тогда
    ЗаполнятьИзРезерва = Ложь; // Здесь взводится флаг модифицированности!
КонецЕсли;

Шаг 2: Правильное присвоение значений

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


// Неправильно:
Объект.Статус = Справочники.Статусы.Просмотрен;

// Правильно:
Если Объект.Статус <> Справочники.Статусы.Просмотрен Тогда
    Объект.Статус = Справочники.Статусы.Просмотрен;
КонецЕсли;

Этот простой прием позволяет сохранить «чистоту» формы, если данные фактически не поменялись.

Шаг 3: Перенос логики в правильные события

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

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

Шаг 4: Принудительный сброс модифицированности

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

Посмотрим на пример кода для обычной формы:


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

Важно: этот метод называют «костылем», так как он может скрыть реальные изменения, если вы случайно сбросите флаг после того, как пользователь уже начал что-то вводить. Используйте его осторожно и только в самом конце инициализации формы.

Шаг 5: Использование режима «Только просмотр»

Если ваша задача — разделить пользователей на тех, кто правит, и тех, кто «глазеет», самым элегантным решением будет установка свойства ТолькоПросмотр. В этом режиме 1С полностью игнорирует любые изменения данных в контексте модифицированности формы.

Проанализируем ситуацию из примера: если пользователю с определенной ролью (например, «ПЭО») нельзя редактировать документ, лучше не закрывать доступность полей по отдельности, а установить свойство всей форме:


Если РольДоступна("ПросмотрДанных") И НЕ РольДоступна("ПолныеПрава") Тогда
    ЭтаФорма.ТолькоПросмотр = Истина;
КонецЕсли;

В режиме ТолькоПросмотр = Истина любые изменения реквизитов в коде не приведут к появлению «звездочки» в заголовке и запроса на сохранение. Документ просто закроется.

Особенности для управляемых форм (1С 8.3)

В управляемом приложении (платформа 8.3) работа с данными разделена между сервером и клиентом. Для корректного решения проблемы «лишнего сохранения» рекомендуется:

  1. Использовать обработчик ПриЧтенииНаСервере. Это идеальное место для заполнения расчетных данных формы, которые не должны влиять на ее модифицированность сразу после открытия. Данные, измененные в этом обработчике, платформа воспринимает как «исходные».
  2. Если изменение данных происходит в ПриСозданииНаСервере, не забудьте в конце вызвать ЭтаФорма.Модифицированность = Ложь;, если эти изменения не должны инициировать сохранение.

Выяснив причину и локализовав проблемный код, вы сможете сделать работу пользователей гораздо комфортнее, избавив их от бесконечных и бессмысленных нажатий на кнопку «Нет» в диалоге сохранения.

← На главную