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