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