При работе в оперативных базах данных пользователи часто сталкиваются с необходимостью быстрого визуального анализа информации. Например, в списке контрагентов было бы очень удобно выделять цветом тех партнеров, у которых есть просроченная задолженность, превышен лимит кредита или заблокирована отгрузка. При этом крайне желательно реализовать такое оформление без внесения изменений в основную конфигурацию, чтобы не усложнять последующие обновления системы. Рассмотрим, как решить эту задачу в различных версиях платформы 1С:Предприятие.
В современных конфигурациях 1С на управляемых формах (например, в «1С:Управление нашей фирмой», «1С:ERP», «1С:Комплексная автоматизация» или «1С:Управление торговлей 11») каждый пользователь может самостоятельно настроить расцветку списка без программирования. Разберем по шагам, как это сделать:
Просрочка со значением Равно Истина или поле СуммаДолга со значением Больше 100 000.Важное ограничение метода: этот способ доступен только в том случае, если реквизит, по которому мы делаем проверку (например, статус или наличие долга), уже выведен в динамический список в качестве колонки. Если нужного поля в списке изначально нет, пользователю придется обратиться к программисту.
Если нам необходимо добавить в динамический список новые данные для раскраски (например, соединить таблицу контрагентов с остатками по регистру взаиморасчетов) и при этом сохранить конфигурацию на стандартной поддержке, идеальным инструментом станет расширение конфигурации. Проанализируем, как реализовать эту задачу программно в расширении:
Создадим расширение и заимствуем в него форму списка контрагентов. Затем в модуле формы программно опишем добавление условного оформления в обработчике события ПриСозданииНаСервере. Посмотрим на практический пример кода:
&НаСервере
Процедура Расшир_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
// Добавим элемент условного оформления программно
НовыйЭлемент = Список.УсловноеОформление.Элементы.Добавить();
// Зададим оформление: цвет фона — нежно-красный
НовыйЭлемент.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоРозовый);
// Зададим условие отбора: если колонка "ЕстьПросрочка" равна Истина
ЭлементОтбора = НовыйЭлемент.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ЕстьПросрочка");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;
ЭлементОтбора.Использование = Истина;
// Укажем, какие именно поля мы хотим красить (например, только Наименование)
ОформляемоеПоле = НовыйЭлемент.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("Наименование");
ОформляемоеПоле.Использование = Истина;
КонецПроцедуры
Этот метод гарантирует, что при обновлении основной конфигурации ваши доработки не затрутся, а визуальное оформление будет стабильно работать у всех пользователей информационной базы.
В устаревших конфигурациях, работающих на обычных формах (таких как «Управление торговлей 10.3», «Управление производственным предприятием 1.3»), механизм динамических списков устроен совершенно иначе. В них отсутствует пользовательское условное оформление и нет расширений в их современном понимании. Здесь для визуализации строк табличного поля используются два ключевых события: ПриВыводеСтроки и ПриПолученииДанных.
Выясним причину, почему событие ПриПолученииДанных является более приоритетным и архитектурно правильным. Событие ПриВыводеСтроки срабатывает отдельно для каждой строки, отображаемой на экране. Если в этом событии выполнять запросы к базе данных (например, получать остаток долга по контрагенту), это приведет к критическому снижению производительности — система будет делать по одному запросу на каждую строчку при любой прокрутке списка.
Событие ПриПолученииДанных, напротив, отрабатывает один раз для всей порции данных, которая выводится на экран (обычно около 30–40 строк). Это позволяет нам получить данные пакетным запросом быстро и без зависания интерфейса. Рассмотрим пример реализации такой раскраски в модуле формы списка контрагентов:
Процедура СправочникСписокПриПолученииДанных(Элемент, ОформленияСтрок)
// Создаем массив для сбора уникальных ссылок контрагентов, видимых на экране
МассивКонтрагентов = Новый Массив;
СоответствиеОформлений = Новый Соответствие;
Для Каждого СтрокаОформления Из ОформленияСтрок Цикл
ДанныеСтроки = СтрокаОформления.ДанныеСтроки;
Если ДанныеСтроки <> Неопределено Тогда
СсылкаКонтрагента = ДанныеСтроки.Ссылка;
МассивКонтрагентов.Добавить(СсылкаКонтрагента);
СоответствиеОформлений.Вставить(СсылкаКонтрагента, СтрокаОформления);
КонецЕсли;
КонецЦикла;
Если МассивКонтрагентов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Выполняем один быстрый пакетный запрос по видимым контрагентам
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВзаиморасчетыОстатки.ДоговорКонтрагента.Владелец КАК Контрагент,
| ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток КАК Долг
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки(, ДоговорКонтрагента.Владелец В (&МассивКонтрагентов)) КАК ВзаиморасчетыОстатки";
Запрос.УстановитьПараметр("МассивКонтрагентов", МассивКонтрагентов);
Выборка = Запрос.Выполнить().Выбрать();
// Раскрашиваем строки на основе полученных остатков
Пока Выборка.Следующий() Цикл
Если Выборка.Долг > 0 Тогда
ТекущееОформление = СоответствиеОформлений.Получить(Выборка.Контрагент);
Если ТекущееОформление <> Неопределено Тогда
// Установим цвет фона для строки должника
ТекущееОформление.ЦветФона = Новый Цвет(255, 225, 225); // Светло-красный
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Независимо от версии платформы (обычные или управляемые формы), выполнение сложных расчетов задолженности непосредственно при открытии списков всегда создает нагрузку на сервер. Если база данных большая, динамический список может начать ощутимо «тормозить».
Чтобы избежать этой проблемы, применим архитектурно верный паттерн оптимизации:
СтатусыКонтрагентов. В качестве измерения укажем Контрагент, а в качестве ресурсов — нужные нам признаки (например, ЕстьПросрочка типа Булево или ТекущийСтатус типа Строка).В результате динамическому списку не придется каждый раз обращаться к сложным виртуальным таблицам остатков и рассчитывать просрочку «на лету» — он будет мгновенно считывать уже готовое булево значение из регистра сведений. Это обеспечит молниеносное открытие списков даже при сотнях тысяч записей в базе данных.
Если вам категорически запрещено вносить любые изменения в конфигурацию (даже через расширения), но пользователи требуют готовый инструмент с раскраской, вы можете создать внешнюю обработку. На этой обработке размещается табличное поле, полностью имитирующее список контрагентов с необходимыми кнопками навигации. В модуле этой внешней формы вы вольны реализовать любую логику раскраски (через условное оформление или события вывода данных). Пользователи смогут запускать эту обработку через стандартное меню Файл — Открыть или подключить ее в раздел дополнительных отчетов и обработок.
Мы подробно разобрали различные способы раскраски элементов в списках 1С. Для управляемых форм наиболее предпочтительным и простым решением является стандартное Условное оформление (настраиваемое пользователем либо программно через расширение). Для обычных форм в старых конфигурациях, таких как УТ 10.3, следует использовать оптимизированный обработчик ПриПолученииДанных. А для баз с высокой нагрузкой лучшим решением станет предварительный расчет данных с записью во вспомогательный регистр сведений.