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

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

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

Почему прямая подстановка не работает?

Важно понимать архитектуру 1С: параметры виртуальных таблиц вычисляются до того, как запрос начнет считывать данные из таблиц базы данных. Виртуальная таблица — это механизм оптимизации, который «закрывается» на конкретные границы периодов еще на этапе формирования SQL-запроса к СУБД. Поле ДатаОбработки, в свою очередь, существует только внутри выборки справочника ИЗАФ. Таким образом, на момент обращения к виртуальной таблице, значения ДатаОбработки еще просто не существуют в оперативной памяти запроса. Это фундаментальное ограничение платформы.

Метод 1: Использование связей наборов данных

Это самый профессиональный и методологически верный способ решения задачи. Вместо одного «монструозного» запроса мы разделяем логику на два набора данных:

  1. Набор данных 1: Запрос к таблице Справочник.ИЗАФ, в котором мы получаем список номенклатуры и поле ДатаОбработки.
  2. Набор данных 2: Запрос к виртуальной таблице ТоварыНаСкладахОстаткиИОбороты, где параметр Период мы оставляем пустым или задаем как общий параметр отчета.

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

Метод 2: Программная установка параметров в модуле

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

В событии ПриКомпоновкеРезультата мы можем перехватить настройки компоновки и программно установить значения параметров:


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

Этот подход дает максимальную гибкость, но требует поддержки кода при изменении структуры отчета.

Метод 3: Вычисление разности дат через вычисляемые поля

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

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

Итоги и рекомендации

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

← На главную