Как изменить вывод значений в поле отчета СКД в зависимости от настроек пользователя?

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

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

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

Ограничения платформы и почему нельзя переписывать значения в ячейках

Проанализируем механику работы СКД. Поток данных в системе компоновки является строго однонаправленным:

  1. Выполнение запроса и получение источников данных.
  2. Инициализация и обработка процессором компоновки данных.
  3. Вывод результатов процессором вывода в табличный документ.

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

Вариант 1. Использование параметров компоновки и логики в запросе

Рассмотрим наилучший по производительности вариант — перенос условий расчета прямо в текст запроса схемы компоновки данных с использованием параметра &УчитыватьВыходные.

Посмотрим на пример реализации запроса:


ВЫБРАТЬ
	Взаиморасчеты.Контрагент КАК Контрагент,
	ВЫБОР
		КОГДА &УчитыватьВыходные ТОГДА
			Взаиморасчеты.ДнейПросрочкиКалендарных
		ИНАЧЕ
			Взаиморасчеты.ДнейПросрочкиРабочих
	КОНЕЦ КАК ДниПросрочки
ИЗ
	РегистрНакопления.Взаиморасчеты КАК Взаиморасчеты

Разберем по шагам, как настроить передачу пользовательского значения в этот параметр:

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

Вариант 2. Использование вычисляемых полей и функций общих модулей

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

  1. Переходим на закладку Вычисляемые поля в схеме компоновки данных.
  2. Добавляем новое поле ДниПросрочки.
  3. В колонке Выражение указываем вызов функции общего модуля, передавая даты и параметр настройки:

    УчетВзаиморасчетовСервер.РассчитатьДни(ДатаНачала, ДатаОкончания, &УчитыватьВыходные)

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


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

Вариант 3. Динамическая подмена выбранных полей

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

В процедуре ПриКомпоновкеРезультата мы анализируем пользовательские настройки и подменяем поля в структуре компоновщика:


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

КонецПроцедуры

Сводная рекомендация

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

← На главную