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