Как правильно использовать таблицу значений в запросе 1С и исправить ошибку «Таблица не найдена»

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

При изучении механизмов работы с временными таблицами в 1С начинающие разработчики часто сталкиваются с ситуацией, когда запрос не «видит» переданную в него таблицу значений (ТЗ). Ошибка «{(5, 1)}: Таблица не найдена "ТЗ"» обычно означает, что синтаксический анализатор запроса не понимает, откуда взять данные: из параметра, из существующей в базе таблицы или из временной таблицы, созданной ранее.

В этой статье мы подробно разберем, как правильно передавать внешние данные (ТЗ) в запрос, как создавать на их основе временные таблицы и как избежать типичных ошибок при написании кода.

Разбор типичной ошибки: почему запрос не видит ТЗ

Проанализируем ситуацию, представленную автором темы. В его коде создается объект ТаблицаЗначений, заполняется данными из DBF-файла, а затем делается попытка использовать её в запросе. Основная ошибка заключалась в следующем фрагменте кода:


Запрос.Текст = "ВЫБРАТЬ
               |    ТабЗначКодыПоставщика.НоменклатураНаша КАК НоменклатураНаша
               |ПОМЕСТИТЬ ВТ_1
               |ИЗ
               |    ТЗ КАК ТабЗначКодыПоставщика";

В языке запросов 1С слово ТЗ (без амперсанда &) воспринимается системой как имя физической таблицы в базе данных (например, справочника или регистра). Так как таблицы с именем «ТЗ» в метаданных нет, система выдает ошибку. Чтобы запрос понял, что данные нужно взять из переданного параметра, перед именем переменной обязательно должен стоять символ &.

Решение 1: Использование параметров запроса

Рассмотрим первый способ исправления. Для того чтобы запрос мог работать с внешней таблицей значений, её необходимо передать через метод УстановитьПараметр. Выясним причину ошибки: в коде автора параметр назывался «ТабЗначКодыПоставщика», а в тексте запроса он пытался обратиться к «ТЗ».

Шаг 1. Правильно заполним таблицу значений с указанием типов колонок. Это критически важно для работы временных таблиц.


ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("НоменклатураНаша", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
// ... добавление остальных колонок

Шаг 2. Передадим ТЗ в запрос и обратимся к ней через символ &.


Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ВнешняяТЗ", ТЗ); // Указываем имя параметра
Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Коды ИЗ &ВнешняяТЗ КАК ВнешняяТЗ"; 
Запрос.Выполнить();

Решение 2: Использование пакетных запросов (рекомендуемый способ)

Наиболее эффективный и современный подход в 1С — это использование пакетных запросов. Пакетный запрос позволяет в одном тексте сначала поместить данные из ТЗ во временную таблицу, а затем сразу же использовать её для соединений или выборок. Это избавляет от необходимости вручную создавать МенеджерВременныхТаблиц в коде, если временные таблицы не нужны за пределами этого конкретного запроса.

Разберем пример реализации пакетного запроса:


Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДанныеИзФайла", ТЗ);

Запрос.Текст = 
    "ВЫБРАТЬ
    |    Данные.НоменклатураНаша КАК НоменклатураНаша,
    |    Данные.КодПоставщика КАК КодПоставщика
    |ПОМЕСТИТЬ ВТ_Поставщики
    |ИЗ
    |    &ДанныеИзФайла КАК Данные
    |;
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТ_Поставщики.НоменклатураНаша,
    |    ВТ_Поставщики.КодПоставщика
    |ИЗ
    |    ВТ_Поставщики КАК ВТ_Поставщики";

Выборка = Запрос.Выполнить().Выбрать();

Обратите внимание на символ ; между частями запроса — он разделяет пакеты. Во втором пакете мы уже не используем амперсанд &, так как ВТ_Поставщики — это уже созданная временная таблица, а не параметр.

Важные нюансы при работе с таблицами значений в запросах

Проанализируем дополнительные технические моменты, которые часто становятся причиной ошибок при профессиональной разработке:

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

Оптимизация чтения внешних файлов

Рассмотрим ситуацию с чтением DBF, которую привел автор вопроса. Он сначала полностью выгружает данные из файла в ТаблицаЗначений, а затем передает её в запрос. При работе с файлами огромного размера (сотни тысяч строк) это может привести к переполнению оперативной памяти на стороне сервера.

В таких случаях рекомендуется:

Подводя итог, можно сказать: для успешного решения задачи «Таблица не найдена» необходимо убедиться, что вы обращаетесь к параметру через &, а все колонки вашей ТЗ имеют правильные типы данных. Использование пакетных запросов сделает ваш код чище и понятнее для других разработчиков.

← На главную