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