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