Почему возникает ошибка при использовании секции {ГДЕ} в Построителе отчета 1С и как её исправить?

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

При разработке отчетов на базе объекта ПостроительОтчета разработчики часто сталкиваются с ошибкой выполнения запроса вида: «Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов». Подобная проблема возникает при попытке передать готовое булево выражение с параметрами внутрь фигурных скобок секции {ГДЕ}.

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

Причина возникновения ошибки

Рассмотрим, как объект ПостроительОтчета обрабатывает расширения языка запросов (конструкции в фигурных скобках {...}). Механизм построителя отчета предназначен для динамического изменения текста запроса на основе настроек пользователя (полей отбора, группировок, порядков).

Когда пользователь добавляет отбор в интерфейсе, построитель отчета берет выражение, указанное в секции {ГДЕ ...}, и автоматически достраивает к нему оператор сравнения и создаваемый параметр (например, = &Параметр1).

Если в запросе написать логическое условие целиком:


{ГДЕ
    (ОборудованиеВРемонтеОстаткиИОбороты.Регистратор.Дата >= &НачалоПериода) КАК ПолеПериода}

То при активизации отбора построитель трансформирует это выражение в следующий некорректный вид:


(ОборудованиеВРемонтеОстаткиИОбороты.Регистратор.Дата >= &НачалоПериода) = &Параметр3

Платформа пытается сравнить результат булевого выражения (Регистратор.Дата >= &НачалоПериода) с параметром отбора, что вызывает ошибку несовместимости типов в СУБД.

Правильное составление запроса для Построителя отчета

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

  1. Параметры виртуальной таблицы: Указываются в фигурных скобках в параметрах самой виртуальной таблицы. Построитель отчета автоматически подставит значение из коллекции Параметры, если параметр с таким именем там присутствует.
  2. Поля секции {ГДЕ}: В секции {ГДЕ} указываются только имена полей без каких-либо операторов сравнения (>=, =, <=) и логических условий.

Проанализируем правильный вариант написания запроса:


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

Передача параметров и управление отбором в коде BSL

При передаче значений из элементов отбора формы в параметры построителя отчета важно учитывать, что ПостроительОтчета.Отбор.ИмяПоля возвращает объект типа ЭлементОтбора, а не само значение. Для получения значения необходимо обращаться к свойству Значение элемента отбора, предварительно проверив флаг Использование.

Рассмотрим пример кода установки параметров периода:


// Установка параметров виртуальной таблицы
ПостроительОтчетаОбъект.Параметры.Вставить("НачалоПериода", НачалоДня(ДатаНачала));
ПостроительОтчетаОбъект.Параметры.Вставить("КонецПериода", КонецДня(ДатаОкончания));

// Если значение выбирается из пользовательского отбора на форме:
ЭлементОтбора = ПостроительОтчетаОбъект.Отбор.Найти("ДатаРегистратора");
Если ЭлементОтбора <> Неопределено И ЭлементОтбора.Использование Тогда
    // Задаем параметр на основе выбранного значения отбора
    ПостроительОтчетаОбъект.Параметры.Вставить("НачалоПериода", ЭлементОтбора.Значение);
КонецЕсли;

// Выполнение запроса и формирование отчета
ПостроительОтчетаОбъект.Выполнить();

Подведем итог: Для предотвращения ошибок в ПостроительОтчета никогда не указывайте логические условия и операторы сравнения внутри секции {ГДЕ}. Передавайте границы периода через параметры виртуальных таблиц {(&НачалоПериода)}, а в секции {ГДЕ} объявляйте только доступные для фильтрации поля.

← На главную