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

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

Рассмотрим распространенную ситуацию, с которой сталкиваются разработчики при проектировании интерфейсов в 1С. Задача кажется тривиальной: необходимо дать пользователю возможность выбрать несколько строк в документе (например, в «Реализации товаров и услуг») и распечатать только их. Для этого мы добавляем колонку с флажком «Печатать».

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

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

Почему устанавливается модифицированность?

Для начала поймем механику платформы. Когда мы добавляем колонку реквизита формы в таблицу, связанную с объектом (Объект.Товары), платформа воспринимает строку таблицы как единое целое.

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

Попытка сбросить этот флаг «в лоб» внутри события ПриИзменении часто не срабатывает, так как платформа может обновлять состояние модифицированности после завершения обработки события.

Рассмотрим три способа решения этой проблемы: от «хитрых» интерфейсных приемов до архитектурно правильных подходов.

Способ 1: Эмуляция флажка через картинку (Рекомендуемый)

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

Суть метода: Вместо элемента управления «Поле флажка» мы используем «Поле картинки». Клик по картинке не переводит строку в режим редактирования данных, а просто вызывает событие нажатия, в котором мы программно меняем данные и картинку.

Алгоритм реализации:

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

Рассмотрим пример кода обработчика:


&НаКлиенте
Процедура ТоварыВыбраноДляПечатиВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    // Отменяем стандартную обработку, чтобы не входить в режим редактирования
    СтандартнаяОбработка = Ложь;
    
    // Получаем текущие данные строки
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Инвертируем значение булево (было Ложь -> стало Истина, и наоборот)
    ТекущиеДанные.ВыбраноДляПечати = НЕ ТекущиеДанные.ВыбраноДляПечати;
    
    // Визуально картинка сменится автоматически, если настроена КартинкаЗначений
    // или можно управлять индексом картинки вручную, если поле числовое.
    
КонецПроцедуры

Результат: Пользователь кликает по иконке, она меняется, данные в реквизите формы обновляются, но платформа не фиксирует начало редактирования строки. Свойство Модифицированность остается Ложь.

Способ 2: Использование стандартного выделения строк (Архитектурный)

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

Пользователи могут выделять строки стандартными средствами операционной системы:

В команде печати мы можем просто проверить свойство таблицы ВыделенныеСтроки. Если массив не пустой, печатаем только выделенное. Если пустой — печатаем всё.

Рассмотрим пример реализации команды печати:


&НаКлиенте
Процедура ПечатьВыделенного(Команда)
    
    МассивВыделенныхСтрок = Элементы.Товары.ВыделенныеСтроки;
    
    ПараметрыПечати = Новый Структура;
    ПараметрыПечати.Вставить("ОтборСтрок", МассивВыделенныхСтрок);
    
    // Передаем параметры в процедуру печати
    // Важно: в самой процедуре печати на сервере нужно будет обработать этот массив
    // и отфильтровать табличную часть перед выводом в макет.
    УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(...); 
    
КонецПроцедуры

Преимущества:

  1. Не загромождает интерфейс лишними колонками.
  2. Не вызывает модифицированность формы (выделение — это состояние интерфейса, а не данных).
  3. Использует привычные паттерны поведения (Ctrl/Shift).

Способ 3: Сброс модифицированности через Обработчик Ожидания

Если вы все же хотите использовать стандартный флажок (Checkbox) и редактирование, но хотите принудительно гасить «звездочку», делать это нужно правильно.

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

Решение — вынести сброс флага «в будущее» с помощью метода ПодключитьОбработчикОжидания.


&НаКлиенте
Процедура ТоварыПечататьПриИзменении(Элемент)
    // Запускаем сброс флага с минимальной задержкой
    ПодключитьОбработчикОжидания("СброситьМодифицированность", 0.1, Истина);
КонецПроцедуры

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

Внимание! Это опасный метод. Если пользователь изменит количество товара, а затем нажмет галочку «Печатать», данный код сбросит признак модифицированности для всего документа. При закрытии формы система не предложит сохранить изменения, и введенное количество будет потеряно. Используйте этот метод только если вы уверены в логике контроля данных.

Особенности работы с БСП (Библиотека Стандартных Подсистем)

Если вы используете стандартную подсистему «Печать», помните, что большинство команд печати БСП спроектированы так, чтобы брать данные из базы данных, а не с формы. Это сделано для обеспечения консистентности данных.

Именно поэтому при нажатии «Печать» программа просит записать документ: ей нужно, чтобы ваши галочки попали в базу, откуда их прочитает менеджер печати.

Чтобы печатать «с формы» без записи:

  1. Вам придется реализовать собственную команду печати (тип использования ВызовКлиентскогоМетода).
  2. В этой команде вы должны программно сформировать структуру данных на основе коллекции Объект.Товары (данные формы) и передать её на сервер.
  3. На сервере метод формирования печатной формы должен уметь принимать не только Ссылка, но и готовые данные (ТаблицуЗначений).

Резюме

Проблема с модифицированностью при установке служебных галочек — это нормальное поведение платформы 1С. Для решения задачи выборочной печати лучше всего подходят:

Оба этих метода позволяют пользователю взаимодействовать с таблицей без перевода формы в состояние «Данные изменены».

← На главную