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

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

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

Попытка прописать в выражении параметра или в тексте запроса конструкцию вида ВЫРАЗИТЬ(&Ссылка КАК Документ.ЗаказПоставщику).Дата либо &Ссылка.Дата часто приводит к синтаксической ошибке, возврату пустой даты (NULL) или некорректной работе отчета. Проанализируем, почему возникает эта проблема и какими способами ее можно решить.

Выясним причину проблемы и ограничения платформы

Разберем, почему обычные обращения через точку или функции приведения типов не работают в параметрах периода виртуальных таблиц:

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

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


ВЫБРАТЬ
	ЦеныСрезПоследних.Период,
	ЦеныСрезПоследних.Номенклатура,
	ЦеныСрезПоследних.Цена
ИЗ
	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, 
		Регистратор.Дата = НАЧАЛОПЕРИОДА(ВЫРАЗИТЬ(&СсылкаДок КАК Документ.УстановкаЦенНоменклатуры).Дата, ДЕНЬ)
	) КАК ЦеныСрезПоследних

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

Способ 1. Использование связей наборов данных в СКД (рекомендуемый)

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

Рассмотрим порядок настроек по шагам:

  1. Создадим Набор данных 1 (Запрос) для получения шапки документа и его даты:
    
    ВЫБРАТЬ
    	Заказ.Ссылка КАК Ссылка,
    	Заказ.Дата КАК ДатаДокумента
    ИЗ
    	Документ.ЗаказПоставщику КАК Заказ
    ГДЕ
    	Заказ.Ссылка = &Ссылка
    
  2. Создадим Набор данных 2 (Запрос) для работы с виртуальной таблицей, где в параметрах используется отдельный параметр даты:
    
    ВЫБРАТЬ
    	Продажи.АналитикаУчетаНоменклатуры.Номенклатура КАК Номенклатура,
    	Продажи.КоличествоОборот КАК КоличествоОборот
    ИЗ
    	РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Продажи
    
  3. Перейдем на вкладку «Связи наборов данных» и добавим новую связь:
    • Источник связи: Набор данных 1
    • Приемник связи: Набор данных 2
    • Выражение источника: ДатаДокумента
    • Параметр: НачалоПериода (или КонецПериода)

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

Способ 2. Программная установка параметра в модуле отчета

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

Рассмотрим алгоритм реализации в модуле объекта отчета в процедуре ПриКомпоновкеРезультата:

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

Способ 3. Использование временных таблиц в запросе

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

Разберем пример такого запроса:


ВЫБРАТЬ
	ЗаказТовары.Номенклатура КАК Номенклатура,
	ЗаказТовары.Ссылка.Дата КАК ДатаДок
ПОМЕСТИТЬ ВТ_Заказ
ИЗ
	Документ.ЗаказПоставщику.Товары КАК ЗаказТовары
ГДЕ
	ЗаказТовары.Ссылка = &Ссылка
;

ВЫБРАТЬ
	ВТ_Заказ.Номенклатура КАК Номенклатура,
	ВТ_Заказ.ДатаДок КАК ДатаДок,
	ПродажиОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
	ВТ_Заказ КАК ВТ_Заказ
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ВыручкаИСебестоимостьПродаж.Обороты(&НачалоПериода, &КонецПериода, , ) КАК ПродажиОбороты
		ПО ВТ_Заказ.Номенклатура = ПродажиОбороты.АналитикаУчетаНоменклатуры.Номенклатура

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

← На главную