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

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

При разработке отчетов в Системе Компоновки Данных (СКД) начинающие программисты часто сталкиваются с ситуацией, когда запрос прекрасно работает в Консоли запросов для управляемых форм, но при запуске отчета в режиме "Предприятие" выдает ошибку: "Несоответствие типов (Параметр номер '1')" — для отладки и тестирования удобнее использовать универсальную консоль запросов и консоль СКД. В этой статье мы подробно разберем причины возникновения этой ошибки на примере соединения товарных запасов с ценами, проанализируем архитектурные ошибки запроса и составим правильный алгоритм решения.

Суть проблемы и анализ исходного кода

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


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

При выполнении этого кода возникает ошибка несоответствия типов в параметре номер 1. Давайте разберем, почему это происходит и какие еще критические ошибки допущены в этом запросе.

Причина 1: Неверная работа с параметрами виртуальной таблицы

Сообщение об ошибке "Несоответствие типов (Параметр номер '1')" прямо указывает на то, что в первый параметр одной из виртуальных таблиц передается значение неверного типа. Часто такие проблемы выявляются при использовании инструментов анализа конфигураций, отчетов и обработок на наличие ошибок.

Давайте посмотрим на синтаксис виртуальной таблицы РегистрСведений.СрезПоследних. Она принимает параметры в следующем порядке:

  1. Период (Тип: Дата) — момент времени, на который нужно получить срез.
  2. Условие — отбор по измерениям.

В СКД есть механизм автозаполнения параметров. Если в настройках компоновки данных (на закладке "Параметры") у вас создан параметр "Период" с типом СтандартныйПериод (содержащий дату начала и дату окончания), а в запросе параметр для виртуальной таблицы не указан явно, СКД может попытаться подставить туда доступное значение.

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

Ошибка автора: Автор пытался исправить ситуацию, прописав &НачалоПериода, &КонецПериода внутри скобок СрезПоследних. Это вызвало синтаксическую ошибку, так как таблица ожидает только одну дату в первом параметре.

Причина 2: Декартово произведение таблиц (Критическая ошибка)

Помимо ошибки с типами, в запросе используется устаревший и опасный метод соединения таблиц — неявное соединение через запятую в секции ИЗ.


ИЗ
    Таблица1,
    Таблица2
ГДЕ
    Таблица1.Поле = Таблица2.Поле

В языке запросов 1С (как и в стандартном SQL) такая конструкция сначала создает Декартово произведение. Это значит, что каждая строка первой таблицы соединяется с каждой строкой второй таблицы. Это серьезно влияет на производительность, а вопросы оптимизации отчетов с набором данных показывают, что такие запросы могут привести к критическим нагрузкам — выявить подобные проблемы на сервере поможет монитор производительности и анализа неоптимальных запросов.

Это приводит к:

Правильное решение: Пошаговая инструкция

Чтобы исправить ошибку и оптимизировать запрос, нам нужно выполнить два действия: использовать явное соединение и корректно передать параметр периода.

Шаг 1. Используем ЛЕВОЕ СОЕДИНЕНИЕ

В отчетах по остаткам нам важно видеть товар, даже если на него не установлена цена. Для этого идеально подходит оператор ЛЕВОЕ СОЕДИНЕНИЕ. Главной таблицей будет таблица остатков, а таблицу цен мы будем "присоединять" к ней.

Шаг 2. Корректно задаем параметры периода

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

Рассмотрим итоговый правильный текст запроса:


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

Разбор ключевых изменений

  1. Явное указание параметра в Срезе Последних:

    Обратите внимание на конструкцию СрезПоследних(&КонецПериода, ...). Мы явно сказали системе: "Дай мне цены, актуальные на момент окончания отчета". Теперь СКД не будет пытаться подставить туда непонятные значения, и ошибка "Несоответствие типов" исчезнет.

  2. Использование ЛЕВОЕ СОЕДИНЕНИЕ:

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

  3. Обработка NULL:

    Добавлена функция ЕСТЬNULL(..., 0). Это хорошая практика. Если соединение не нашло цену, пользователь увидит в отчете "0", а не пустую ячейку.

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

После исправления текста запроса, зайдите на вкладку "Параметры" в схеме компоновки данных. Убедитесь в следующем:

Соблюдение этих правил гарантирует стабильную работу отчета и корректное отображение данных без ошибок несоответствия типов.

← На главную