Как настроить условное оформление динамического списка для всех пользователей в 1С?

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

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

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

---

Способ 1. Административный перенос настроек через БСП (без программирования)

Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП) (к таким относятся практически все современные типовые решения: 1С:ERP, 1С:УТ, 1С:КА, 1С:БП, 1С:ЗУП и др.), вы можете воспользоваться встроенным административным механизмом копирования настроек. Этот способ не требует работы в конфигураторе и отлично подходит, когда задачу нужно решить оперативно.

Проанализируем пошагово процесс настройки и переноса оформления:

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

Важные особенности и ограничения данного способа:

---

Способ 2. Программное условное оформление через расширение (Рекомендуемый метод)

Для того чтобы условное оформление работало "железно", автоматически применялось для всех существующих и вновь создаваемых пользователей и не могло быть случайно удалено, лучшим решением является использование механизма расширений конфигурации. При этом крайне не рекомендуется менять форму визуально в самом расширении, так как при обновлении основной конфигурации разработчики могут переименовать или удалить элементы формы, что приведет к конфликтам.

Вместо интерактивного изменения формы мы применим программное добавление правил условного оформления в коде расширения. Это безопасно, надежно и полностью контролируемо.

Рассмотрим подробнее пошаговую реализацию этого метода:

  1. Создайте новое расширение конфигурации (если его еще нет) или откройте существующее. Убедитесь, что у расширения сняты флажки "Безопасный режим" и "Защита от опасных действий", если планируется сложная серверная логика (для базового оформления это не всегда обязательно, но желательно).
  2. Добавьте в расширение форму списка интересующего вас документа или журнала документов.
  3. Перейдите в модуль добавленной формы и создайте обработчик события ПриСозданииНаСервере с типом вызова &После (&After). Это позволит выполнить наш код сразу после того, как отработает стандартная инициализация формы в основной конфигурации.

Давайте посмотрим на пример программного кода, который решает задачу выделения строк:


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

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

---

Способ 3. Использование события "ПриПолученииДанныхНаСервере" для сложных условий

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

Выясним причину эффективности этого метода: платформа передает в данный обработчик только ту порцию данных, которая непосредственно отображается на экране монитора пользователя в текущий момент (обычно от 15 до 45 строк). Мы можем перехватить этот массив строк, выполнить один быстрый пакетный запрос к базе данных и раскрасить нужные ячейки программно "на лету".

Рассмотрим пример реализации такого подхода:


&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
    
    // Создаем массив для сбора идентификаторов отображаемых документов
    МассивСсылок = Новый Массив;
    Для Каждого СтрокаСписка Из Строки Цикл
        МассивСсылок.Добавить(СтрокаСписка.Ключ);
    КонецЦикла;
    
    // Выполняем пакетный запрос для получения связанных данных (например, остаток долга по договору)
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ВзаиморасчетыОстатки.Договор КАК Договор,
        |	ВзаиморасчетыОстатки.СуммаОстаток КАК Долг
        |ИЗ
        |	РегистрНакопления.Взаиморасчеты.Остатки(, Договор В (&МассивСсылок)) КАК ВзаиморасчетыОстатки";
    
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    ТаблицаДолгов = Запрос.Выполнить().Выгрузить();
    ТаблицаДолгов.Индексировать("Договор");
    
    // Обходим выводимые строки и устанавливаем оформление
    Для Каждого СтрокаСписка Из Строки Цикл
        ДанныеСтроки = СтрокаСписка.Значение;
        
        // Ищем соответствие по ключевому полю
        СтрокаДолга = ТаблицаДолгов.Найти(СтрокаСписка.Ключ, "Договор");
        Если СтрокаДолга <> Неопределено И СтрокаДолга.Долг > 100000 Тогда
            // Раскрашиваем ячейку "Договор" в красный цвет, если долг превышает лимит
            ОформлениеКолонки = ДанныеСтроки.Оформление["Договор"];
            ОформлениеКолонки.ЦветФона = WebЦвета.СветлоКоралловый;
            ОформлениеКолонки.Шрифт = Новый Шрифт(ОформлениеКолонки.Шрифт, , , Истина); // Делаем текст жирным
        КонецЕсли;
    	
    КонецЦикла;
    
КонецПроцедуры

Предупреждение по оптимизации производительности: Событие ПриПолученииДанныхНаСервере вызывается очень часто — при каждом скроллинге, изменении размеров формы или интерактивном обновлении. Внутри этого обработчика категорически запрещено выполнять запросы в цикле! Любое обращение к базе данных должно происходить один раз за вызов процедуры, пакетом по всем переданным ключам строк из параметра Строки.

---

Сравнение подходов: что выбрать в реальной работе?

Давайте сопоставим рассмотренные варианты по ключевым критериям, чтобы вы могли принять оптимальное решение для своей задачи:

  1. Административное копирование через БСП:
    • Сложность реализации: Низкая (проводится в пользовательском режиме за 2 минуты).
    • Автоматизация для новых пользователей: Нет (требуется повторный запуск администратором).
    • Влияние на обновление системы: Отсутствует.
    • Область применения: Простые условия оформления, небольшое число пользователей, редкие кадровые изменения.
  2. Программное оформление через расширение (ПриСозданииНаСервере):
    • Сложность реализации: Средняя (требуется базовое понимание встроенного языка и СКД).
    • Автоматизация для новых пользователей: Полная (настройки применяются на уровне ядра системы для всех без исключения).
    • Влияние на обновление системы: Минимальное (код в расширении не мешает обновлению основной конфигурации).
    • Область применения: Рекомендуемый стандарт для большинства задач автоматизации оформления списков.
  3. Использование события ПриПолученииДанныхНаСервере:
    • Сложность реализации: Высокая (требует написания оптимальных запросов и контроля производительности).
    • Автоматизация для новых пользователей: Полная.
    • Влияние на обновление системы: Минимальное.
    • Область применения: Сложные динамические условия, завязанные на обособленные регистры накопления или внешние веб-сервисы.

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

← На главную