Как исправить ошибку «Невозможно определить поле для записи результата» в запросе 1С?

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

При составлении сложных запросов с расчетом итоговых показателей разработчики нередко сталкиваются с синтаксической ошибкой: «Невозможно определить поле для записи результата». Ошибка указывает на строку в секции ИТОГИ, где выполняется приведение типов с помощью функции ВЫРАЗИТЬ() или вычисление сложных математических выражений. Рассмотрим подробнее, почему возникает данная ситуация и как правильно организовать текст запроса.

Посмотрим на пример кода, вызывающего ошибку:


Запрос.Текст = "ВЫБРАТЬ
|    ЗначениеСв,
|    Номенклатура,
|    КоличествоПродаж,
|    ЦенаРеализации
|ИЗ
|    ТЧ КАК т1
|ИТОГИ
|    ВЫРАЗИТЬ(СУММА(КоличествоПродаж) КАК ЧИСЛО(15, 3)),
|    ВЫРАЗИТЬ(СРЕДНЕЕ(ЦенаРеализации) КАК ЧИСЛО(15, 3))
|ПО
|    ЗначениеСв ИЕРАРХИЯ,
|    Номенклатура";

При выполнении такого запроса платформа 1С выдает исключение при вызове метода Выполнить(), указывая на строку с ВЫРАЗИТЬ(СУММА(...)).

Выясним причину возникновения ошибки

Проанализируем принципы работы механизма итогов в платформе 1С:

  1. Назначение секции ИТОГИ: Данная секция предназначена для агрегации уже выбранных в секции ВЫБРАТЬ полей и записи итоговых данных в соответствующие колонки результирующей выборки.
  2. Невозможность автоматического сопоставления: Когда в секции ИТОГИ пишется конструкция ВЫРАЗИТЬ(СУММА(...) КАК ...) без явного псевдонима, платформа не может однозначно связать это выражение ни с одним полем из списка ВЫБРАТЬ.
  3. Автоматическое наследование типов: Платформа 1С самостоятельно определяет тип и разрядность итоговых полей на основании детальных записей, поэтому явное приведение типов в секции ИТОГИ избыточно и синтаксически не поддерживается в таком виде.
  4. Несоответствие списка полей: Если агрегируемое поле или выражение отсутствует в секции ВЫБРАТЬ, платформа выдаст ошибку о невозможности расчета итогов.

Способ 1. Перенос приведения типов в секцию ВЫБРАТЬ

Разберем основной и самый надежный способ решения проблемы. Если требуется ограничить разрядность или точность чисел, конструкцию ВЫРАЗИТЬ() необходимо применить в основном списке полей выборки либо на этапе помещения данных во временную таблицу. В секции ИТОГИ следует оставить только вызов агрегатных функций (СУММА, СРЕДНЕЕ, МАКСИМУМ и др.).

Перепишем запрос следующим образом:


Запрос.Текст = "ВЫБРАТЬ
|    ЗначениеСв,
|    Номенклатура,
|    ЦеноваяГруппа,
|    ВЫРАЗИТЬ(КоличествоПродаж КАК ЧИСЛО(15, 3)) КАК КоличествоПродаж,
|    ВЫРАЗИТЬ(ЦенаРеализации КАК ЧИСЛО(15, 3)) КАК ЦенаРеализации,
|    ВЫРАЗИТЬ(ПолнаяСебестоимость КАК ЧИСЛО(15, 3)) КАК ПолнаяСебестоимость,
|    ВЫРАЗИТЬ(Прибыль КАК ЧИСЛО(15, 3)) КАК ПрибыльЕдиницы,
|    ВЫРАЗИТЬ(СуммаПрибыль КАК ЧИСЛО(15, 3)) КАК СуммаПрибыль,
|    КоличествоПродажПлан КАК КоличествоПланПродаж,
|    СуммаПрибыльПлан,
|    Рентабельность
|ИЗ
|    ТЧ КАК т1
|ИТОГИ
|    МАКСИМУМ(ЦеноваяГруппа),
|    СУММА(КоличествоПродаж),
|    СРЕДНЕЕ(ЦенаРеализации),
|    СРЕДНЕЕ(ПолнаяСебестоимость),
|    СРЕДНЕЕ(ПрибыльЕдиницы),
|    СУММА(СуммаПрибыль),
|    СУММА(КоличествоПланПродаж),
|    СУММА(СуммаПрибыльПлан),
|    СУММА(Рентабельность)
|ПО
|    ЗначениеСв ИЕРАРХИЯ,
|    Номенклатура";

Способ 2. Задание типов колонок в исходной ТаблицеЗначений

Если источником данных для временной таблицы является объект ТаблицаЗначений, передаваемый в качестве параметра, правильнее всего задать типы данных колонок еще до выполнения запроса. Для числовых полей необходимо указать объект КвалификаторыЧисла с требуемой длиной и точностью.

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


КвалификаторЧисла = Новый КвалификаторыЧисла(15, 3);
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("Число"));
ОписаниеТипаЧисло = Новый ОписаниеТипов(МассивТипов, , , КвалификаторЧисла);

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("КоличествоПродаж", ОписаниеТипаЧисло);
ТЗ.Колонки.Добавить("ЦенаРеализации", ОписаниеТипаЧисло);

При таком подходе отпадает необходимость использовать ВЫРАЗИТЬ() как во временных таблицах, так и в секции выборки — платформа сразу создаст поля нужной разрядности.

Способ 3. Вычисляемые поля с псевдонимами в секции ИТОГИ

Если в итогах требуется рассчитать сложный показатель (например, средневзвешенное значение или процент), выражению в секции ИТОГИ обязательно присваивается псевдоним, который предварительно должен быть объявлен в списке ВЫБРАТЬ.

Посмотрим на пример расчета рентабельности на уровне итогов:


Запрос.Текст = "ВЫБРАТЬ
|    Номенклатура,
|    СуммаВыручки,
|    СуммаСебестоимости,
|    0 КАК РентабельностьПроцент
|ИЗ
|    Продажи КАК Продажи
|ИТОГИ
|    СУММА(СуммаВыручки),
|    СУММА(СуммаСебестоимости),
|    ВЫБОР
|        КОГДА СУММА(СуммаСебестоимости) = 0 ТОГДА 0
|        ИНАЧЕ (СУММА(СуммаВыручки) - СУММА(СуммаСебестоимости)) / СУММА(СуммаСебестоимости) * 100
|    КОНЕЦ КАК РентабельностьПроцент
|ПО
|    Номенклатура";

Таким образом, для устранения ошибки достаточно следовать правилу: все преобразования типов и подготовка полей выполняются в секции ВЫБРАТЬ, а в секцию ИТОГИ передаются агрегатные операции с обязательной привязкой к существующим колонкам выборки.

← На главную