Как выделить договоры в отчете СКД на основе внешней таблицы значений?

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

Часто при разработке отчетов на системе компоновки данных (СКД) возникает ситуация, когда логика определения «особенных» данных слишком сложна для реализации внутри одного запроса. Например, вам нужно подсветить в отчете договоры, по которым нарушена последовательность документов. Сама проверка последовательности может выполняться отдельным сложным алгоритмом или запросом к специализированным таблицам, результатом которого становится обычная Таблица значений. Рассмотрим детально, как связать эти внешние данные с основным отчетом СКД и настроить визуальное выделение нужных строк.

Метод 1: Передача массива договоров в параметр СКД

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

Во-первых, нам необходимо подготовить саму схему СКД. В конструкторе на закладке «Параметры» создадим новый параметр, назовем его СписокНарушенныхДоговоров. В качестве типа данных выберем «Список значений» или просто оставим без ограничения типа, чтобы передать массив.

Во-вторых, настроим «Условное оформление» в настройках отчета:

  1. Перейдем на закладку «Настройки», далее — «Условное оформление».
  2. Добавим новый элемент оформления.
  3. В поле «Оформление» выберем «Цвет фона» (например, светло-красный).
  4. В поле «Условие» укажем: Договор В &СписокНарушенныхДоговоров.
  5. В поле «Оформляемые поля» выберем поле Договор или оставим пустым, чтобы подсветить всю строку.

Теперь проанализируем программную часть. В модуле отчета, перед выводом, нам нужно заполнить этот параметр данными из нашей таблицы значений:


// Получаем массив договоров из колонки ТЗ
МассивДоговоров = ТЗ_Нарушения.ВыгрузитьКолонку("Договор");

// Устанавливаем параметр в компоновщике настроек
ПараметрСКД = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("СписокНарушенныхДоговоров");
Если ПараметрСКД <> Неопределено Тогда
    ПараметрСКД.Значение = МассивДоговоров;
    ПараметрСКД.Использование = Истина;
КонецЕсли;

Метод 2: Использование внешнего набора данных (Dataset-Object)

Если данных много или вам нужно не просто подсветить строку, а вывести рядом дополнительные сведения из вашей таблицы значений, используем механизм Набора данных - объект. Посмотрим, как это реализовать.

В схеме СКД добавим новый «Набор данных - объект» и назовем его ТаблицаНарушений. В нем создадим поле ДоговорНарушение (тип — Ссылка на справочник Договоры) и поле ЭтоНарушение (тип — Булево).

Затем перейдем на закладку «Связи наборов данных». Свяжем наш основной запрос и этот объект по полю Договор. Источником будет основной запрос, приемником — ТаблицаНарушений.

Важный нюанс: Чтобы СКД выполнила соединение и применила оформление, поле ЭтоНарушение должно присутствовать в выбранных полях компоновщика или использоваться в настройках. Иначе оптимизатор СКД может просто проигнорировать этот набор данных. В условном оформлении теперь достаточно прописать условие: ЭтоНарушение Равно Истина.

Программный вывод при таком подходе будет выглядеть так:


ВнешниеДанные = Новый Структура;
ВнешниеДанные.Вставить("ТаблицаНарушений", МояТЗ_С_Договорами);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеДанные, ДанныеРасшифровки);

Метод 3: Вычисляемое поле и функция общего модуля

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

Сначала создадим в общем модуле (например, РаботаСДоговорамиСервер) функцию, доступную для вызова с сервера:


Функция ПроверитьНаличиеДоговораВНарушениях(ДоговорСсылка) Экспорт
    // Здесь может быть обращение к кэшированному массиву или временному хранилищу
    Возврат СписокНарушений.Найти(ДоговорСсылка) <> Неопределено;
КонецФункции

В СКД на закладке «Вычисляемые поля» добавим поле СтатусНарушения. В выражении пропишем вызов нашей функции:

РаботаСДоговорамиСервер.ПроверитьНаличиеДоговораВНарушениях(Договор)

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

Метод 4: Работа через Менеджер временных таблиц

Если ваш отчет СКД базируется на запросе, мы можем внедрить внешнюю таблицу значений прямо в «тело» компоновки через Менеджер временных таблиц. Проанализируем, как это сделать программно.

Перед тем как компоновать результат, создадим менеджер и поместим туда ТЗ:


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

// Передаем менеджер в настройки СКД
КомпоновщикНастроек.ПараметрыДанных.УстановитьЗначениеПараметра("МенеджерВТ", МенеджерВТ);

В самом запросе СКД нам нужно будет прописать левое соединение с этой временной таблицей ВТ_Нарушения. Если связь есть (поле не NULL), значит, договор требует подсветки. Это самый быстрый способ с точки зрения СУБД для обработки больших массивов данных.

Особенности для «Универсального отчета»

Поскольку в вопросе упоминался Универсальный отчет, важно помнить, что он программно формирует схему компоновки. Чтобы внедрить в него свою логику, лучше всего использовать расширение или переопределить процедуру ПриКомпоновкеРезультата в модуле отчета. Там вы сможете динамически добавить элементы УсловноеОформление, используя вышеописанные методы передачи данных через параметры или внешние наборы.

Используя один из предложенных подходов, вы сможете гибко управлять визуализацией данных в СКД, даже если критерии для этой визуализации рассчитываются за пределами основного запроса отчета.

← На главную