При работе с классическими конфигурациями на базе Обычных форм разработчики часто сталкиваются с задачей визуального выделения строк табличной части. Особую сложность вызывает сценарий, когда логика раскраски должна быть реализована во внешней обработке заполнения ТЧ. В этой статье мы подробно разберем, почему нельзя «раскрасить» строки напрямую из обработки, и изучим несколько эффективных способов решения этой задачи.
Для начала проанализируем архитектуру обычного приложения. Внешняя обработка заполнения табличной части взаимодействует непосредственно с Объектом документа. Она может изменять данные в строках, добавлять новые записи или удалять существующие. Однако визуальное отображение (цвет текста, фон, шрифт) — это свойство не данных, а Элемента Управления (в данном случае — ТабличногоПоля на форме).
События оформления в обычных формах работают по принципу «ленивой отрисовки». Цвета назначаются только в тот момент, когда строка выводится на экран монитора. Поэтому, чтобы реализовать раскраску из внешней обработки, нам нужно передать некий «сигнал» или условие из обработки в форму документа, где специальные обработчики событий применят нужное оформление.
Рассмотрим самый простой и надежный вариант, который упоминали участники форума. Он заключается в добавлении в табличную часть документа специального служебного реквизита. Выясним, как это работает по шагам:
Товары реквизит СлужебныйЦвет (тип: Число или Строка).ПриВыводеСтроки для табличного поля.Проанализируем пример кода для обработчика в форме документа:
Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Если ДанныеСтроки.СлужебныйЦвет = 1 Тогда
ОформлениеСтроки.ЦветФона = Новый Цвет(255, 200, 200); // Розовый
ИначеЕсли ДанныеСтроки.СлужебныйЦвет = 2 Тогда
ОформлениеСтроки.ЦветФона = Новый Цвет(200, 255, 200); // Светло-зеленый
КонецЕсли;
КонецПроцедуры
Преимущество: Это решение работает всегда, даже после закрытия и повторного открытия документа, так как данные о цвете хранятся в базе данных.
Недостаток: Требуется изменение метаданных конфигурации, что не всегда допустимо.
Если изменять структуру документа нельзя, мы можем воспользоваться объектом ДополнительныеСвойства, который есть у любого документа (объекта). Рассмотрим этот изящный метод программирования.
Внешняя обработка может поместить в ДополнительныеСвойства документа таблицу значений или соответствие, где ключом будет номер строки или ссылка на товар, а значением — желаемый цвет. Посмотрим на реализацию:
В коде внешней обработки заполнения:
// В обработке заполнения ТЧ
ОбъектДокумент = Параметры.Объект; // Получаем объект документа
ТаблицаЦветов = Новый ТаблицаЗначений;
ТаблицаЦветов.Колонки.Добавить("КлючСвязи");
ТаблицаЦветов.Колонки.Добавить("Цвет");
// Заполняем таблицу по вашей логике
НоваяСтрока = ТаблицаЦветов.Добавить();
НоваяСтрока.КлючСвязи = НужнаяСтрокаТЧ.НомерСтроки;
НоваяСтрока.Цвет = WebЦвета.Золотой;
ОбъектДокумент.ДополнительныеСвойства.Вставить("ПравилаРаскраски", ТаблицаЦветов);
Затем в форме документа в событии ПриВыводеСтроки мы обращаемся к этим свойствам:
Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
// Пытаемся получить таблицу из свойств объекта документа
ТаблицаЦветов = ДокументОбъект.ДополнительныеСвойства.Найти("ПравилаРаскраски");
Если ТаблицаЦветов <> Неопределено Тогда
СтрокаНастроек = ТаблицаЦветов.Найти(ДанныеСтроки.НомерСтроки, "КлючСвязи");
Если СтрокаНастроек <> Неопределено Тогда
ОформлениеСтроки.ЦветФона = СтрокаНастроек.Цвет;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный момент: После того как внешняя обработка отработала, необходимо вызвать ЭлементыФормы.Товары.Обновить(), чтобы заставить форму перерисовать строки с учетом новых данных в ДополнительныеСвойства.
Если строк в таблице очень много (тысячи), использование ПриВыводеСтроки может привести к замедлению интерфейса, так как код выполняется для каждой строки отдельно. Разберем более эффективный метод — ПриПолученииДанных.
Это событие срабатывает один раз для всей видимой области строк. Мы можем получить данные для всей пачки строк одним запросом или одним обращением к коллекции. Проанализируем пример использования этого события совместно с данными из внешней обработки:
Процедура ТоварыПриПолученииДанных(Элемент, ОформленияСтрок)
ТаблицаЦветов = ДокументОбъект.ДополнительныеСвойства.Найти("ПравилаРаскраски");
Если ТаблицаЦветов = Неопределено Тогда
Возврат;
КонецЕсли;
Для Каждого ОформлениеСтроки Из ОформленияСтрок Цикл
// Ищем данные по ключу (например, по ссылке на номенклатуру или индексу)
ТекущиеДанные = ОформлениеСтроки.ДанныеСтроки;
СтрокаНастроек = ТаблицаЦветов.Найти(ТекущиеДанные.НомерСтроки, "КлючСвязи");
Если СтрокаНастроек <> Неопределено Тогда
ОформлениеСтроки.ЦветФона = СтрокаНастроек.Цвет;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В ходе обсуждения на форуме возник вопрос об использовании Расширений конфигурации. Важно понимать, что в режиме Обычного приложения возможности расширений сильно ограничены. В отличие от управляемых форм, вы не можете просто добавить аннотацию &После к процедуре ПриВыводеСтроки в расширении.
Чтобы изменить поведение формы обычного приложения через расширение, вам придется заимствовать форму целиком. Это означает, что при обновлении основной конфигурации изменения в оригинальной форме не попадут в вашу расширенную версию автоматически. Поэтому использование расширений для раскраски в ОФ считается менее предпочтительным, чем доработка модуля оригинальной формы.
Мы выяснили, что напрямую из внешней обработки «покрасить» таблицу нельзя, так как оформление — это задача формы. Однако мы можем успешно реализовать эту задачу, следуя алгоритму:
ДополнительныеСвойства.ПриВыводеСтроки или ПриПолученииДанных, который считывает метки и меняет ОформлениеСтроки.ЦветФона.Обновить() для табличного поля после завершения работы внешней обработки.Такой системный подход позволит вам создавать интерактивные и удобные интерфейсы даже в устаревших конфигурациях 1С, обеспечивая пользователям наглядность при работе с документами.