Как реализовать раскраску строк в журнале документов по нажатию кнопки в обычных формах 1С

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Постановка задачи и анализ механизмов оформления

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

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

  1. ПриВыводеСтроки — вызывается для каждой отдельной строки в момент её отрисовки на экране.
  2. ПриПолученииДанных — вызывается один раз для всей порции данных, которая отображается в текущий момент.

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

Вариант 1: Простая реализация через флаг состояния

Этот метод предложил автор темы, и он является наиболее понятным для быстрой реализации. Суть заключается в использовании переменной модуля формы, которая служит индикатором активности оформления.

Разберем алгоритм действий:

  1. Объявим переменную ИспользоватьРаскраску в начале модуля формы.
  2. В процедуре ПриОткрытии установим её значение в Ложь.
  3. Создадим кнопку на форме и в её обработчике будем менять значение переменной и обновлять визуальное состояние списка.

Проанализируем пример кода для кнопки:


Перем ИспользоватьРаскраску;

Процедура ПриОткрытии()
    ИспользоватьРаскраску = Ложь;
КонецПроцедуры

Процедура ДействияФормыРаскрасить(Кнопка)
    // Инвертируем значение флага
    ИспользоватьРаскраску = Не ИспользоватьРаскраску;
    
    // Инициируем перерисовку видимых строк списка
    ЭлементыФормы.ЖурналДокументовСписок.ОбновитьСтроки();
КонецПроцедуры

Теперь нам нужно внедрить условие в обработчик события ПриВыводеСтроки. Важно помнить, что оформление применяется только тогда, когда наш флаг установлен в значение Истина.


Процедура ЖурналДокументовСписокПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    Если ИспользоватьРаскраску Тогда
        // Проверяем наше условие (например, сумма документа > 100 000)
        Если ДанныеСтроки.СуммаДокумента > 100000 Тогда
            ОформлениеСтроки.ЦветФона = Новый Цвет(255, 230, 230); // Светло-красный
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Вариант 2: Оптимизация производительности через ПриПолученииДанных

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

Проанализируем более профессиональный подход с использованием ПриПолученииДанных. Это событие получает коллекцию ОформленияСтрок, что позволяет нам выполнить один запрос для всех отображаемых документов сразу.


Процедура ЖурналДокументовСписокПриПолученииДанных(Элемент, ОформленияСтрок)
    Если Не ИспользоватьРаскраску Тогда
        Возврат;
    КонецЕсли;

    // Собираем ссылки на все видимые документы в массив
    МассивСсылок = Новый Массив;
    Для Каждого Оформление Из ОформленияСтрок Цикл
        МассивСсылок.Добавить(Оформление.ДанныеСтроки.Ссылка);
    КонецЦикла;

    // Выполняем ОДИН запрос для получения данных по всем строкам
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   ДополнительныеСведения.Объект КАК Ссылка,
    |   ДополнительныеСведения.Значение КАК Статус
    |ИЗ
    |   РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
    |ГДЕ
    |   ДополнительныеСведения.Объект В(&МассивСсылок)";
    
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    ТаблицаРезультатов = Запрос.Выполнить().Выгрузить();

    // Применяем оформление, сопоставляя данные из запроса с оформлениями строк
    Для Каждого Оформление Из ОформленияСтрок Цикл
        СтрокаДанных = ТаблицаРезультатов.Найти(Оформление.ДанныеСтроки.Ссылка, "Ссылка");
        Если СтрокаДанных <> Неопределено И СтрокаДанных.Статус = Справочники.СтатусыДокументов.Критичный Тогда
            Оформление.ЦветФона = ЦветаСтиля.ЦветОтрицательногоПоказателя;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Использование кэширования для мгновенного отклика

Чтобы сделать работу пользователя еще более комфортной, рассмотрим технику кэширования. Если данные для раскраски не меняются каждую секунду, мы можем рассчитать их один раз в момент нажатия кнопки и сохранить в объекте Соответствие.

Разберем этот алгоритм:

  1. При нажатии кнопки "Раскрасить" мы обходим весь список (или его видимую часть) и формируем Соответствие, где Ключ — это Ссылка документа, а Значение — Цвет.
  2. В процедуре ПриВыводеСтроки мы просто берем готовый цвет из кэша по ключу.

Посмотрим на пример кода:


Перем КэшЦветов; // Тип Соответствие

Процедура ДействияФормыРаскрасить(Кнопка)
    ИспользоватьРаскраску = Не ИспользоватьРаскраску;
    
    Если ИспользоватьРаскраску Тогда
        КэшЦветов = Новый Соответствие;
        // Здесь может быть логика заполнения кэша запросом по всему списку
        // или по текущим условиям фильтрации
    КонецЕсли;
    
    ЭлементыФормы.ЖурналДокументовСписок.ОбновитьСтроки();
КонецПроцедуры

Процедура ЖурналДокументовСписокПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    Если ИспользоватьРаскраску И КэшЦветов <> Неопределено Тогда
        НайденныйЦвет = КэшЦветов.Получить(ДанныеСтроки.Ссылка);
        Если НайденныйЦвет <> Неопределено Тогда
            ОформлениеСтроки.ЦветФона = НайденныйЦвет;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Тонкости визуального оформления

При реализации раскраски важно учитывать не только техническую часть, но и удобство пользователя. Рассмотрим несколько советов по оформлению:

Подведем итоги

Мы выяснили, что даже в "старых" обычных формах можно реализовать гибкое и производительное оформление. Основные моменты, которые стоит запомнить:

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

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

← На главную