Как добавить реквизит формы для табличной части документа без изменения модифицированности?

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

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

Почему нельзя просто добавить реквизит в Объект?

Самая первая мысль, которая приходит в голову — добавить новый реквизит (колонку с типом Булево) прямо в табличную часть документа в реквизите формы Объект. Однако при таком подходе мы сталкиваемся с архитектурной особенностью платформы 1С.

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

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

Способ 1: Использование множественного выделения строк

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

В управляемых формах пользователи могут выделять несколько строк с помощью зажатых клавиш Ctrl или Shift и кликов мышью. Чтобы получить список строк, которые выделил пользователь для печати, достаточно обратиться к свойству ВыделенныеСтроки элемента формы.

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


&НаКлиенте
Процедура ПечатьВыделенныхСтрок(Команда)
    
    МассивВыделенныхСтрок = Элементы.ИмяВашейТаблицы.ВыделенныеСтроки;
    
    Если МассивВыделенныхСтрок.Количество() = 0 Тогда
        Сообщить("Выделите строки для печати!");
        Возврат;
    КонецЕсли;
    
    // Передаем массив идентификаторов на сервер для обработки
    СформироватьПечатнуюФормуНаСервере(МассивВыделенныхСтрок);
    
КонецПроцедуры

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

Способ 2: Имитация отметки через Условное оформление

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

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

  1. Создадим реквизит формы ОтмеченныеСтроки с типом СписокЗначений или Массив (не связанный с объектом).
  2. В таблице формы создадим событие Выбор (двойной клик) или добавим кнопку "Отметить строку".
  3. При выборе строки мы программно добавляем ее идентификатор в наш список (или удаляем, если он там уже есть).
  4. Настроим УсловноеОформление формы: если идентификатор строки находится в списке ОтмеченныеСтроки, меняем цвет фона строки или выводим специальную картинку-галочку в первой колонке.

Поскольку мы работаем с независимым реквизитом формы, модифицированность документа не меняется.

Способ 3: Отдельная форма с Таблицей Значений (ТЗ)

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

Создадим служебную общую форму (или форму обработки). На этой форме разместим реквизит типа ТаблицаЗначений. При нажатии на кнопку "Печать" в документе, мы программно выгружаем нужные колонки из табличной части документа в эту независимую ТЗ и добавляем к ней колонку Отметка (тип Булево).


&НаСервере
Функция ПодготовитьДанныеДляВыбора()
    ТЗ = Объект.Товары.Выгрузить();
    ТЗ.Колонки.Добавить("Отметка", Новый ОписаниеТипов("Булево"));
    // Заполняем ТЗ и помещаем во временное хранилище или передаем на форму
    Возврат ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор);
КонецФункции

Пользователь работает в новом окне: ставит галочки, делает отборы, и затем нажимает "Распечатать". Документ при этом остается в исходном состоянии.

Способ 4: Программное управление признаком модифицированности (Не рекомендуется)

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

В событии ПередНачаломИзменения мы запоминаем текущее состояние свойства Модифицированность. А в событии ПриИзменении флажка — восстанавливаем его обратно (устанавливаем в Ложь, если документ до этого не был изменен).

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

← На главную