Почему документ становится модифицированным при открытии и как правильно использовать событие ПриВыводеСтроки

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

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

Разберем детально, как работают обработчики отрисовки строк ПриВыводеСтроки и ПриПолученииДанных, влияет ли визуальное оформление на признак модифицированности и как локализовать истинную причину изменения данных объекта.

Влияет ли визуальное оформление строк на модифицированность объекта

Рассмотрим типовой сценарий: в процедуре ТоварыПриВыводеСтроки разработчик настраивает отображение ячеек или всей строки в зависимости от условий:


Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Настройка отображения пиктограммы
    ОформлениеСтроки.Ячейки.ИзменениеВЦене.ОтображатьКартинку = Истина;
    ОформлениеСтроки.Ячейки.ИзменениеВЦене.ИндексКартинки = 0;
    
    // Выделение текста цветом
    Если ДанныеСтроки.Сумма > 100000 Тогда
        ОформлениеСтроки.ЦветТекста = WebЦвета.Кирпичный;
    КонецЕсли;
    
КонецПроцедуры

Важно понимать: манипуляции со свойствами объекта ОформлениеСтроки (такими как ЦветФона, ЦветТекста, Шрифт, ОтображатьКартинку, ИндексКартинки), а также управление свойствами колонок формы (например, КолонкаТаблицы.Видимость = Ложь;) никогда не изменяют признак Модифицированность документа. Данные свойства относятся исключительно к визуальному представлению на клиенте и не затрагивают данные самого объекта в оперативной памяти.

Основные причины нежелательной установки признака модифицированности

Если после открытия документа метод ЭтотОбъект.Модифицированность() возвращает Истина, причину следует искать в изменении данных, а не в оформлении. Проанализируем типичные ошибки:

  1. Программное заполнение реквизитов формы, связанных с объектом: если поле ввода на форме связано с реквизитом через свойство «Данные», то любое прямое присвоение значения (например, подстановка значения по умолчанию в обработчике ПриОткрытии) автоматически помечает объект как измененный.
  2. Сортировка данных через коллекцию объекта: вызов метода ЭтотОбъект.Товары.Сортировать(...) физически перестраивает строки в табличной части объекта и взводит модифицированность. Для визуального упорядочивания следует настраивать порядок в самом элементе управления ТабличноеПоле.
  3. Автоматические пересчеты и автозаполнение: типовые алгоритмы инициализации (подстановка основного договора, пересчет сумм по курсу валюты при смене даты) часто меняют реквизиты документа до действий пользователя.
  4. Изменение реквизитов в событиях строк: случайная запись значения непосредственно в ДанныеСтроки.Реквизит = Значение; внутри обработчиков отрисовки табличной части.

Пошаговый алгоритм поиска и устранения проблемы

Разберем по шагам, как выявить конкретное место в коде, устанавливающее признак модифицированности:

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

Оптимизация: выбор между ПриВыводеСтроки и ПриПолученииДанных

Рассмотрим разницу в производительности при оформлении табличных полей на обычных формах:

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

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


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

Особенности работы на управляемых формах

Выясним, как аналогичная задача решается в современном интерфейсе 1С 8.3 на управляемых формах. В управляемом интерфейсе события ПриВыводеСтроки и ПриПолученииДанных отсутствуют.

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

← На главную