Как убрать модифицированность (звездочку) формы документа после проведения в 1С 7.7?

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

При работе в среде 1С:Предприятие 7.7 (особенно в типовой конфигурации «Торговля и Склад» с документами типа ЧекККМ) разработчики часто сталкиваются с неприятной особенностью интерфейса: после успешной записи или проведения документа в заголовке его формы продолжает отображаться символ звездочки «*». Этот символ указывает на то, что форма якобы изменена (модифицирована) и требует сохранения.

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

В этой статье мы подробно разберем, почему возникает эта проблема на платформе 1С 7.7, проанализируем внутреннее поведение системы и рассмотрим несколько эффективных способов решения задачи.

Выясняем причину: почему форма остается «грязной»?

Давайте проанализируем поведение платформы. В отличие от версии 1С 8.x, где у формы есть прямое свойство ЭтаФорма.Модифицированность, которое можно легко прочитать или принудительно установить в Ложь, в версии 7.7 управление состоянием изменения формы скрыто глубже. Платформа автоматически взводит флаг модифицированности при соблюдении любого из следующих условий:

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

Посмотрим на пример кода, предоставленный автором темы:


Если ИмяКнопки="Записать" Тогда
    
    Если ВидОперации = Перечисление.ВидыОперацийЧекККМ.Чек Тогда // продажа
        Комментарий="ЧЕК/Сумма: "+Формат(Итог("Сумма"),"Ч.2");
    Иначе     
        Комментарий="ЧЕК НА ВОЗВРАТ/Сумма: -"+Формат(Итог("Сумма"),"Ч.2");
    КонецЕсли;
    
    Записать();

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


Способ 1. Корректировка логики изменения реквизитов (Архитектурное решение)

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

Давайте перенесем логику автозаполнения комментариев и служебных полей в предопределенную процедуру модуля формы ПриЗаписи(). Эта процедура вызывается платформой автоматически в контексте транзакции записи.

Разберем по шагам, как это реализовать:

  1. Откроем модуль формы документа ЧекККМ.
  2. Найдем или создадим предопределенную процедуру ПриЗаписи().
  3. Перенесем туда логику формирования служебных реквизитов:

Процедура ПриЗаписи()
    // Процедура вызывается платформой ДО физической записи в базу данных
    Если ВидОперации = Перечисление.ВидыОперацийЧекККМ.Чек Тогда
        Комментарий = "ЧЕК/Сумма: " + Формат(Итог("Сумма"), "Ч.2");
    Иначе     
        Комментарий = "ЧЕК НА ВОЗВРАТ/Сумма: -" + Формат(Итог("Сумма"), "Ч.2");
    КонецЕсли;
КонецПроцедуры

При таком подходе в обработчике кнопки нам достаточно будет просто вызвать команду Записать(). Платформа сама выполнит процедуру ПриЗаписи(), обновит реквизит Комментарий, запишет документ в базу данных и вернет форме состояние «не изменена» (без звездочки).


Способ 2. Ревизия свойств элементов формы в Конфигураторе

Если программный код чист, но звездочка все равно появляется, нам необходимо проверить свойства элементов управления на самой форме документа.

Выполним следующие действия в Конфигураторе:

  1. Откроем форму документа ЧекККМ.
  2. Последовательно изучим свойства всех элементов управления, которые выводят расчетные или текстовые данные (например, общая сумма, скидки, статус подключения фискального регистратора, состояние чека).
  3. В окне свойств каждого такого элемента перейдем на вкладку «Дополнительно» (или «Свойства» в зависимости от типа элемента).
  4. Найдем флаг «Изменяет данные». Если этот флаг установлен для элемента, который не связан напрямую с реквизитом документа, а хранит лишь вспомогательное значение, его необходимо снять.

Когда этот флаг снят, любые программные присвоения вида ИмяВспомогательногоЭлемента = "Активен" в коде формы перестанут влиять на признак модифицированности документа.


Способ 3. Транзакционный хак (Сброс модифицированности силами платформы)

В практике разработки под 1С 7.7 существует знаменитый и очень эффективный «обходной маневр», позволяющий сбросить звездочку модифицированности формы без фактической перезаписи данных. Мы можем использовать особенность работы транзакций в сочетании с интерактивным контекстом формы.

Рассмотрим следующий шаблон кода, который можно встроить в обработчик кнопки проведения после выполнения основного метода Провести():


// ... Здесь выполняется проведение документа ...
Если Проведен() = 1 Тогда
    // Запускаем транзакционный хак для сброса модифицированности формы
    НачатьТранзакцию();
    Записать();
    ОтменитьТранзакцию();
КонецЕсли;

Проанализируем ситуацию и выясним, почему этот прием работает:

  1. Метод НачатьТранзакцию() открывает транзакцию базы данных.
  2. Метод Записать() производит запись изменений. Платформа видит, что документ успешно сохранен, и сбрасывает внутренний флаг модифицированности формы (звездочка пропадает).
  3. Вызов ОтменитьТранзакцию() мгновенно откатывает запись в базе данных назад. Но важно понимать: физически документ уже был сохранен на предыдущих шагах алгоритма, поэтому данные в СУБД не пострадают.
  4. При этом отмена транзакции базы данных не возвращает форме признак модифицированности! Интерфейсная часть платформы «считает», что запись прошла успешно, и визуальная звездочка исчезает навсегда.

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


Способ 4. Использование внешней компоненты FormEx

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

Компонента FormEx предоставляет объект РасширениеФормы, у которого есть прямой метод для управления модифицированностью.

Посмотрим на пример реализации:


// Создаем объект расширения формы
Сервис = СоздатьОбъект("Сервис");
РасширениеФормы = СоздатьОбъект("РасширениеФормы");
РасширениеФормы.УстановитьФорму(Форма);

// Сбрасываем флаг модифицированности одной строкой
РасширениеФормы.СбросМодифицированности();

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

Резюме

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

← На главную