При работе с платформой 1С:Предприятие 8 часто возникает ситуация, когда необходимо передать ТаблицуЗначений в качестве параметра в запрос для объединения данных или создания временной таблицы. Однако, если колонка ТаблицыЗначений заполнена значением Неопределено, платформа выдает ошибку: «Тип не может быть выбран в запросе». Это происходит потому, что при помещении данных во временную таблицу СУБД требует четкой типизации, а Неопределено не является конкретным типом данных.
Когда мы передаем таблицу в МенеджерВременныхТаблиц, платформа пытается создать физическую таблицу в базе данных. Для колонок, содержащих только Неопределено или NULL, система не может подобрать соответствующий тип данных в SQL (например, VARCHAR, INT или DATETIME). В результате процесс выполнения запроса прерывается.
Чтобы избежать этой ошибки, нам необходимо программно подготовить ТаблицуЗначений, назначив каждой колонке корректное описание типа. Рассмотрим пошаговый алгоритм решения этой задачи.
Мы можем создать функцию, которая проходит по всем колонкам исходной таблицы, определяет их типы и создает новую ТаблицуЗначений с жестко заданными описаниями типов.
Функция ПолучитьТипизированнуюТаблицу(ТекТаблица)
Ответ = Новый ТаблицаЗначений;
Для Каждого Колонка из ТекТаблица.Колонки Цикл
СписокТипов = Новый Массив;
Для Каждого Тип из Колонка.ТипЗначения.Типы() Цикл
Если Тип = Тип("Null") Тогда
Продолжить;
КонецЕсли;
СписокТипов.Добавить(Тип);
КонецЦикла;
// Если типы не определены, назначаем стандартный тип
Если СписокТипов.Количество() = 0 Тогда
СписокТипов.Добавить(Тип("Строка"));
// Можно добавить и другие типы, если это требуется
КонецЕсли;
ОписаниеСоставногоТипа = Новый ОписаниеТипов(СписокТипов);
Ответ.Колонки.Добавить(Колонка.Имя, ОписаниеСоставногоТипа);
КонецЦикла;
Для Каждого Стр из ТекТаблица Цикл
ЗаполнитьЗначенияСвойств(Ответ.Добавить(), Стр);
КонецЦикла;
Возврат Ответ;
КонецФункции
Второй эффективный способ — это предварительная обработка данных с помощью запроса, который принудительно преобразует Неопределено в конкретное значение или тип. Рассмотрим пример использования оператора ЕСТЬNULL или конструкции ВЫБОР.
// Пример преобразования данных перед передачей в основной запрос
ТекстЗапроса =
"ВЫБРАТЬ
| ЕСТЬNULL(Данные.Поле1, ""Неопределено"") КАК Поле1
|ПОМЕСТИТЬ ВТ_Очищенная
|ИЗ &ТЗ КАК Данные";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ТЗ", ИсходнаяТЗ);
Результат = Запрос.Выполнить().Выгрузить();
Строка для пустых колонок всегда задавайте квалификатор длины. Это предотвратит создание полей неограниченной длины, по которым невозможно построение индексов и группировок. Используйте Новый КвалификаторыСтроки(1024).СправочникСсылка.Номенклатура и СправочникСсылка.Контрагенты), всегда включайте все эти типы в ОписаниеТипов. Даже если сейчас в колонке только Неопределено, наличие типов в описании позволит базе данных корректно выделить место под составной тип.Неопределено не нужна для логики запроса, самым быстрым и «чистым» решением будет просто удалить её из ТаблицыЗначений перед передачей в параметр запроса.ВЫРАЗИТЬ(Поле КАК Тип), если вы подозреваете, что в данных могут быть неопределенные или несовместимые типы. Это помогает платформе заранее понять структуру данных.Применяя данные подходы, вы сможете избавиться от ошибок типизации и обеспечить стабильную работу механизмов временных таблиц в ваших отчетах и обработках.