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