При разработке сложных отчетов в Системе Компоновки Данных (СКД) часто возникает ситуация, когда требуется вычислить показатели относительно даты, которая сама является полем в выборке (например, ДатаОбработки конкретного заказа). Многие разработчики сталкиваются с ошибкой, пытаясь подставить имя поля в параметр виртуальной таблицы ОстаткиИОбороты. Давайте разберем, почему это происходит и как правильно решить эту задачу.
Важно понимать архитектуру 1С: параметры виртуальных таблиц вычисляются до того, как запрос начнет считывать данные из таблиц базы данных. Виртуальная таблица — это механизм оптимизации, который «закрывается» на конкретные границы периодов еще на этапе формирования SQL-запроса к СУБД. Поле ДатаОбработки, в свою очередь, существует только внутри выборки справочника ИЗАФ. Таким образом, на момент обращения к виртуальной таблице, значения ДатаОбработки еще просто не существуют в оперативной памяти запроса. Это фундаментальное ограничение платформы.
Это самый профессиональный и методологически верный способ решения задачи. Вместо одного «монструозного» запроса мы разделяем логику на два набора данных:
Справочник.ИЗАФ, в котором мы получаем список номенклатуры и поле ДатаОбработки.ТоварыНаСкладахОстаткиИОбороты, где параметр Период мы оставляем пустым или задаем как общий параметр отчета.После этого на вкладке Связи наборов данных мы устанавливаем связь между ними по полям Номенклатура и Склад. В настройках связи мы можем указать параметр (например, Период для второго набора), и привязать его значение к полю ДатаОбработки из первого набора. Таким образом, СКД сама «развернет» запрос для каждой строки, передавая нужное значение даты.
Если логика отчета слишком специфична или требует сложной предобработки, можно вмешаться в процесс формирования отчета через модуль объекта. Рассмотрим, как это выглядит:
В событии ПриКомпоновкеРезультата мы можем перехватить настройки компоновки и программно установить значения параметров:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Получаем значение параметра из формы или вычисляем его
ДатаДляРасчета = ...;
// Устанавливаем параметр в схему компоновки
Параметр = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ДатаНачала"));
Если Параметр <> Неопределено Тогда
Параметр.Значение = ДатаДляРасчета;
Параметр.Использование = Истина;
КонецЕсли;
// Выполняем компоновку вручную
...
КонецПроцедуры
Этот подход дает максимальную гибкость, но требует поддержки кода при изменении структуры отчета.
Если вам нужно просто отобразить «количество дней с даты обработки», не обязательно пытаться заставить виртуальную таблицу считать это внутри себя. Вы можете:
ДатаОбработки.Вычисляемые поля создать новое поле КоличествоДней.РАЗНОСТЬДАТ(&ТекущаяДата, ДатаОбработки, ДЕНЬ).Этот способ позволяет избежать проблем с производительностью виртуальных таблиц, так как все расчеты будут проводиться уже после получения данных из базы, на уровне движка СКД.
Мы проанализировали ситуацию и выяснили, что попытка «скормить» поле запроса в параметр виртуальной таблицы приводит к ошибкам логики. Для решения задачи всегда стремитесь к использованию связей наборов данных — это позволяет системе 1С оптимизировать план запроса автоматически. Если же задача требует динамической логики, которая не укладывается в визуальный конструктор, используйте ПриКомпоновкеРезультата, но помните, что это усложняет сопровождение отчета в будущем.