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