Как исправить ошибку «Несоответствие типов параметр (1)» при использовании СрезПоследних в СКД?

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

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

Анализ причины возникновения ошибки

Давайте проанализируем ситуацию. В обычном запросе 1С мы передаем параметры напрямую, например, РегистрСведений.Цены.СрезПоследних(&Период). Однако СКД — это не просто механизм выполнения запросов, это сложная надстройка, которая самостоятельно управляет текстом запроса перед его отправкой на сервер СУБД. Когда мы помещаем запрос с виртуальной таблицей в СКД, система пытается сопоставить параметры, указанные в тексте, с параметрами на закладке Параметры схемы компоновки.

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

Решение 1: Использование расширения языка запросов СКД

Самый эффективный и правильный способ решения — использование фигурных скобок {}. Это специальный синтаксис СКД, который позволяет системе гибко управлять параметрами. Посмотрим на пример правильного оформления соединения таблиц:


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

Разберем, что дают фигурные скобки вокруг параметра &ДатаСреза:

  1. Явное указание для СКД: Мы сообщаем системе компоновки, что управление этим параметром берет на себя механизм расширения языка запросов.
  2. Безопасность типов: Если параметр не заполнен пользователем, СКД просто проигнорирует его, и виртуальная таблица вернет актуальные данные на текущий момент, не вызывая ошибку СУБД.
  3. Приоритет компоновщика: Это позволяет избежать конфликтов, если включено Автозаполнение наборов данных.

Решение 2: Настройка параметров на соответствующей закладке

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

  1. Перейдем на закладку Параметры в СКД.
  2. Найдем параметр, который используется в виртуальной таблице (например, Период или НачДата).
  3. Если у вас есть общий параметр периода (тип СтандартныйПериод), то в поле Выражение для параметра виртуальной таблицы нужно прописать: &СтандартныйПериод.ДатаНачала или &СтандартныйПериод.ДатаОкончания.
  4. Убедитесь, что тип данных параметра установлен как Дата.

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

Решение 3: Получение цены на дату каждого документа (Связи наборов данных)

Иногда ошибка возникает из-за попытки сделать невозможное в рамках одного запроса. Если нам нужно получить цену не на одну общую дату отчета, а на дату каждого документа в списке (коррелированный запрос), то использование параметра в ЛЕВОЕ СОЕДИНЕНИЕ внутри одного запроса не сработает должным образом для каждой строки.

Рассмотрим по шагам, как это реализовать через механизмы СКД:

  1. Создадим Набор данных 1 (запрос), который выбирает документы и их даты.
  2. Создадим Набор данных 2 (запрос), который выбирает данные из РегистрСведений.Цены.СрезПоследних(&ПериодДлЦен, ).
  3. Перейдем на закладку Связи наборов данных.
  4. Укажем в качестве источника связи Набор данных 1, а в качестве приемника — Набор данных 2.
  5. В колонке Параметры для связи укажем наш параметр ПериодДлЦен и свяжем его с полем Дата из первого набора.

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

Дополнительные рекомендации

Выясним еще одну деталь: иногда полезно проверить, какой именно итоговый запрос генерирует СКД. Это можно сделать в отладчике, исследовав объект МакетКомпоновки. Путь в отладке: МакетКомпоновки.НаборыДанных.ИмяВашегоНабора.Запрос. Там вы увидите реальный текст с подставленными значениями, что поможет понять, на каком этапе происходит искажение типа данных.

Также важно помнить про Границу. Если вам нужно получить остатки или цены строго на конец секунды документа, включая его собственные движения, используйте в выражениях параметров функцию КОНЕЦПЕРИОДА(&Дата, "ДЕНЬ") или создавайте объект Граница, иначе данные за последнюю секунду периода могут не попасть в выборку.

Подводя итог, можно сказать, что использование фигурных скобок {(&Дата)} — это золотой стандарт при работе с виртуальными таблицами в СКД. Это избавляет от большинства проблем с типизацией и делает ваш отчет более устойчивым к изменениям настроек пользователем.

← На главную