При разработке на управляемых формах 1С часто возникает задача: дать пользователю возможность отметить галочками определенные строки в табличной части документа (например, для выборочной печати), но при этом не изменять признак модифицированности самого документа. Разберем по шагам, почему прямое добавление колонки не работает, и рассмотрим подробнее несколько надежных способов решения этой задачи.
Самая первая мысль, которая приходит в голову — добавить новый реквизит (колонку с типом Булево) прямо в табличную часть документа в реквизите формы Объект. Однако при таком подходе мы сталкиваемся с архитектурной особенностью платформы 1С.
Проанализируем ситуацию: когда мы добавляем реквизит в коллекцию данных Объект (который является основным реквизитом формы), он автоматически подчиняется правилам этого объекта. У основного реквизита установлено свойство СохраняемыеДанные. Это означает, что любое интерактивное изменение в этой таблице (даже установка служебной галочки) воспринимается платформой как изменение данных документа. Платформа попытается заблокировать объект и установит признак модифицированности (появится "звездочка" в заголовке формы). Если пользователь случайно нажмет "Записать", служебная колонка сохранится, либо возникнет ошибка, если в метаданных такой колонки нет.
Выясним причину: штатно разорвать связь между служебной колонкой внутри данных объекта и флагом модифицированности невозможно. Поэтому нам необходимо использовать альтернативные подходы.
Посмотрим на самый правильный с точки зрения стандартов интерфейса 1С способ. Вместо создания визуальной колонки с флажками, мы можем использовать встроенный в платформу механизм выделения строк.
В управляемых формах пользователи могут выделять несколько строк с помощью зажатых клавиш Ctrl или Shift и кликов мышью. Чтобы получить список строк, которые выделил пользователь для печати, достаточно обратиться к свойству ВыделенныеСтроки элемента формы.
Рассмотрим пример кода для команды печати:
&НаКлиенте
Процедура ПечатьВыделенныхСтрок(Команда)
МассивВыделенныхСтрок = Элементы.ИмяВашейТаблицы.ВыделенныеСтроки;
Если МассивВыделенныхСтрок.Количество() = 0 Тогда
Сообщить("Выделите строки для печати!");
Возврат;
КонецЕсли;
// Передаем массив идентификаторов на сервер для обработки
СформироватьПечатнуюФормуНаСервере(МассивВыделенныхСтрок);
КонецПроцедуры
Этот метод не требует изменения структуры данных, не добавляет лишних элементов на форму и гарантирует, что признак модифицированности останется нетронутым.
Если заказчик жестко требует наличия визуальных флажков или цветового выделения строк, разберем решение с использованием условного оформления.
Суть метода заключается в том, что мы храним идентификаторы выбранных строк в отдельном служебном массиве на форме, а табличную часть раскрашиваем в зависимости от наличия идентификатора строки в этом массиве.
ОтмеченныеСтроки с типом СписокЗначений или Массив (не связанный с объектом).Выбор (двойной клик) или добавим кнопку "Отметить строку".УсловноеОформление формы: если идентификатор строки находится в списке ОтмеченныеСтроки, меняем цвет фона строки или выводим специальную картинку-галочку в первой колонке.Поскольку мы работаем с независимым реквизитом формы, модифицированность документа не меняется.
Если строк много и логика отбора сложная, вынесем эту задачу в отдельное окно. Это полностью изолирует процесс отбора от самого документа.
Создадим служебную общую форму (или форму обработки). На этой форме разместим реквизит типа ТаблицаЗначений. При нажатии на кнопку "Печать" в документе, мы программно выгружаем нужные колонки из табличной части документа в эту независимую ТЗ и добавляем к ней колонку Отметка (тип Булево).
&НаСервере
Функция ПодготовитьДанныеДляВыбора()
ТЗ = Объект.Товары.Выгрузить();
ТЗ.Колонки.Добавить("Отметка", Новый ОписаниеТипов("Булево"));
// Заполняем ТЗ и помещаем во временное хранилище или передаем на форму
Возврат ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор);
КонецФункции
Пользователь работает в новом окне: ставит галочки, делает отборы, и затем нажимает "Распечатать". Документ при этом остается в исходном состоянии.
Рассмотрим вариант, который обсуждался на форуме, но который следует применять с осторожностью. Суть заключается в том, чтобы перехватывать события изменения нашего флажка и принудительно снимать флаг измененности документа.
В событии ПередНачаломИзменения мы запоминаем текущее состояние свойства Модифицированность. А в событии ПриИзменении флажка — восстанавливаем его обратно (устанавливаем в Ложь, если документ до этого не был изменен).
Недостаток этого метода в том, что в сложных формах со множеством перекрестных проверок и подписок на события, этот механизм может дать сбой. Платформа 1С может повести себя непредсказуемо, что приведет к расхождению данных на форме и в базе. Поэтому, используйте этот подход только в крайнем случае, отдавая предпочтение методам с множественным выделением или условным оформлением.