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