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