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