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

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

При разработке отчетов в системе компоновки данных (СКД) в формате кросс-таблиц (где присутствуют и строки, и динамические колонки) программисты регулярно сталкиваются с двумя неочевидными проблемами. Первая — как обратиться к значению ресурса из предыдущей колонки (например, получить остаток или курс за предыдущий день). Вторая — как программно или интерактивно оформить (или очистить) горизонтальные итоги в колонке «Итого», если стандартное условное оформление СКД для общих итогов упорно отказывается работать.

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

Часть 1. Получение значения из предыдущей колонки (горизонтальной группировки)

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

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

Синтаксис функции выглядит следующим образом:

ВычислитьВыражение(Выражение, Группировка, ОбластьВычисления, Начало, Конец)

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


ЕстьNull(ВычислитьВыражение("Сумма(ИмяРесурса)", "ИмяГруппировкиКолонок", , "Предыдущая", "Предыдущая"), 0)

Проанализируем ключевые параметры этого выражения подробнее:

  1. Первый параметр ("Сумма(ИмяРесурса)") — это выражение, которое мы хотим вычислить. Обратите внимание, что имя ресурса обязательно должно быть обернуто в агрегатную функцию (например, Сумма, Максимум, Среднее).
  2. Второй параметр ("ИмяГруппировкиКолонок") — критически важный параметр. Здесь мы передаем строковое имя нашей группировки колонок (например, "ПериодДень" или "Номенклатура"), заданное в настройках СКД на вкладке «Структура». Именно этот параметр заставляет систему двигаться по горизонтали, а не по строкам.
  3. Третий параметр (ОбластьВычисления) — оставляем пустым (пропускаем), так как расчет происходит в пределах текущей группировки.
  4. Четвертый и пятый параметры ("Предыдущая", "Предыдущая") — указывают границы расчета. В данном случае мы берем строго одну предыдущую колонку.
  5. Функция ЕстьNull(..., 0) — необходима для обработки первой колонки отчета. Поскольку у самого первого дня (или первой колонки) нет предыдущей, функция вернет Null. Чтобы избежать пустых ячеек в отчете, мы заменяем их на нули или любое другое дефолтное значение.

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

Часть 2. Почему не работает стандартное условное оформление горизонтальных итогов?

Перейдем ко второй проблеме. Допустим, перед нами стоит задача: очистить или скрыть значение ресурса в итоговой колонке («Общие итоги» справа), но только для определенных строк (например, для показателя «Остаток на начало дня», так как суммировать начальные остатки за разные дни в общем итоге методологически неверно).

Интуитивно разработчики пытаются решить это через стандартное Условное оформление в СКД:

Однако при формировании отчета выясняется, что оформление не применяется к правой колонке итогов. Почему так происходит? Дело в архитектурной особенности платформы 1С: область использования условного оформления «В общем итоге» в понимании СКД относится исключительно к вертикальным итогам (расположенным в самом низу таблицы). Горизонтальные же итоги (колонка «Итого» справа) система считает частью обычной группировки строк, поэтому стандартный отбор для итогов здесь не срабатывает.

Если применить оформление ко всей строке, то очистятся данные и в самих колонках по дням, что нам категорически не подходит.

Часть 3. Пошаговое решение: метод «Вычисляемое поле-маркер»

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

Рассмотрим пошагово, как реализовать этот алгоритм:

Шаг 1. Создание вычисляемого поля

Перейдем на вкладку «Вычисляемые поля» нашей схемы компоновки данных. Добавим новую строку со следующими параметрами:

Шаг 2. Раздельный расчет ресурса

Теперь перейдем на вкладку «Ресурсы». Нам нужно добавить поле ОбластьИтогов в список ресурсов дважды с разными выражениями расчета для разных группировок. Это ключевой момент схемы!

Добавим первую строку ресурса:

Добавим вторую строку ресурса:

Благодаря такой настройке, при выводе обычных ячеек на пересечении строк и колонок ресурс ОбластьИтогов будет принимать значение "ОбычнаяЯчейка". Но как только СКД начнет рассчитывать и выводить колонку горизонтального общего итога, значение ресурса изменится на "ГоризонтальныйИтог".

Шаг 3. Настройка условного оформления

Теперь мы можем легко настроить точечное условное оформление. Перейдем на вкладку «Настройки», выберем вкладку «Условное оформление» и добавим новое правило:

  1. Оформление: установите свойство Текст равным пустой строке "" (или настройте любой другой визуал: цвет фона, шрифт).
  2. Условие: добавьте два условия (соединение И):
    • ОбластьИтогов Равно "ГоризонтальныйИтог"
    • ВидОборотов Равно "Остаток на начало дня" (условие по вашей аналитике строк, если очистка нужна выборочно).
  3. Оформляемые поля: выберите ресурс, значение которого нужно очистить в итогах.
  4. Область использования: оставьте значение по умолчанию — Везде.

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

Часть 4. Альтернативные методы решения

Если метод с полем-маркером по каким-то причинам вам не подходит, проанализируем еще два альтернативных варианта решения проблемы с горизонтальными итогами.

Исключение итогов на уровне настроек ресурсов

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

Программная постобработка в модуле объекта

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


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Инициализируем схему, настройки и компоновщик макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    // Проводим компоновку
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
    
    // Выводим результат в табличный документ
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    // Программный обход ячеек для очистки горизонтального итога
    Для НомерСтроки = 1 По ДокументРезультат.ВысотаТаблицы Цикл
        // Ищем строку с нужным нам показателем
        ТекстГруппировки = ДокументРезультат.Область(НомерСтроки, 1).Текст;
        Если ТекстГруппировки = "Остаток на начало дня" Тогда
            // Очищаем ячейку в последней колонке (где находится итог)
            ШиринаТаблицы = ДокументРезультат.ШиринаТаблицы;
            ДокументРезультат.Область(НомерСтроки, ШиринаТаблицы).Текст = "";
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры

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

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

← На главную