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

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

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

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

---

1. Глубокий технический анализ: почему СУБД не видит таблицу?

Когда платформа 1С выполняет запрос, содержащий инструкцию ПОМЕСТИТЬ ИмяВременнойТаблицы, физически на стороне СУБД (например, в MS SQL Server, PostgreSQL) создается реальная временная таблица (в базе данных tempdb или аналогичном системном хранилище). Чтобы СУБД знала о ее существовании при выполнении последующих запросов, платформа 1С использует связующий механизм — Менеджер временных таблиц (МВТ).

Если во втором запросе вы пытаетесь обратиться к временной таблице через конструкцию ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаДоп КАК ТаблицаДоп, а система выдает ошибку «Таблица не найдена», это может происходить по одной из следующих причин:

  1. Менеджер временных таблиц не инициализирован. Переменная, которая должна хранить МВТ, была просто объявлена через ключевое слово Перем, но ей не было присвоено значение Новый МенеджерВременныхТаблиц.
  2. Разрыв контекста запросов. Первый запрос (который создавал таблицу) и второй запрос (который ее читает) используют разные объекты Запрос, у которых не связан менеджер временных таблиц.
  3. Потеря контекста при вызове процедур. Менеджер временных таблиц был передан на сторону клиента или уничтожен сборщиком мусора при выходе из процедуры, где создавалась таблица. Данные ВТ существуют ровно столько, сколько живет сам объект МВТ в оперативной памяти сервера.
  4. Пропуск шага генерации таблицы. Алгоритм, который должен был заполнить и поместить таблицу ТаблицаДоп, просто не выполнился из-за логической ошибки (например, не заполнена исходная таблица значений или не установлена настройка интеграции).

---

2. Пошаговая отладка: ищем причину в режиме конфигуратора

Давайте разберем по шагам, как локализовать место возникновения ошибки с помощью встроенного отладчика 1С. Многие начинающие разработчики совершают ошибку: они ставят точку останова, видят окно ошибки и не знают, куда смотреть дальше. Действовать нужно системно. Для интерактивной проверки и анализа выполнения запросов также подойдёт консоль запросов с поддержкой пакетных запросов и временных таблиц.

Шаг 1. Анализ Менеджера временных таблиц

Установим точку останова непосредственно перед выполнением проблемного запроса (на строке Запрос.Выполнить()). Вызовем окно оценки выражений с помощью горячих клавиш Shift + F9 (или «Табло») и проверим состояние менеджера временных таблиц:

  1. Вычислим выражение Запрос.МенеджерВременныхТаблиц. Если результатом вычисления является Неопределено, значит, в коде вообще не задан контейнер для хранения временных таблиц.
  2. Если менеджер определен (тип значения МенеджерВременныхТаблиц), проверим коллекцию его таблиц с помощью выражения: Запрос.МенеджерВременныхТаблиц.Таблицы.
  3. Раскроем эту коллекцию. Каждая строка там представляет собой описание существующей временной таблицы. Нам нужно убедиться, присутствует ли там таблица с именем ТаблицаДоп. Если список пуст или нужной таблицы там нет, значит, она не была создана ранее.

Шаг 2. Поиск места создания таблицы

Если таблицы в менеджере нет, нам нужно понять, где она должна была создаться. Используем глобальный поиск по конфигурации или по текущему модулю (Ctrl + F) со следующими поисковыми фразами:

Важный нюанс: часто разработчики собирают тексты запросов динамически, складывая строки. В таком случае прямой поиск фразы ПОМЕСТИТЬ ТаблицаДоп может не дать результатов. Попробуйте поискать только имя таблицы ТаблицаДоп в кавычках или переменную, в которую может выгружаться эта таблица перед помещением в запрос.

---

3. Практические варианты исправления кода

Давайте рассмотрим конкретные программные сценарии решения проблемы в зависимости от того, как спроектирована логика вашей обработки.

Вариант А. Правильная инициализация Менеджера временных таблиц

Если в вашей обработке используются два последовательных запроса, очень важно явно инициализировать и связать их через один менеджер. Рассмотрим пример правильного кода:


// 1. Создаем единый менеджер временных таблиц
МенеджерВТ = Новый МенеджерВременныхТаблиц;

// 2. Инициализируем первый запрос, который создаст таблицу
Запрос1 = Новый Запрос;
Запрос1.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос1.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка КАК Ссылка,
    |	Номенклатура.Код КАК Код
    |ПОМЕСТИТЬ ТаблицаДоп
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.ЭтоГруппа = ЛОЖЬ";

// Выполняем первый запрос. ТаблицаДоп теперь физически создана в СУБД 
// и зарегистрирована в объекте МенеджерВТ
Запрос1.Выполнить();

// 3. Инициализируем второй (основной) запрос
Запрос2 = Новый Запрос;
// Передаем тот же самый менеджер во второй запрос!
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос2.Текст = 
    "ВЫБРАТЬ
    |	ТаблицаДоп.Ссылка КАК Ссылка,
    |	ТаблицаДоп.Код КАК Код
    |ИЗ
    |	ТаблицаДоп КАК ТаблицаДоп";

// Теперь этот запрос выполнится без ошибок
Результат = Запрос2.Выполнить().Выгрузить();

Вариант Б. Передача внешней Таблицы Значений в качестве временной таблицы

В практике интеграций (например, при выгрузке каталога товаров на маркетплейсы вроде Onliner) часто требуется сопоставить иерархию категорий 1С с категориями внешней площадки. Данные сопоставления хранятся в памяти в виде Таблицы Значений. Прямо соединить Таблицу Значений с базой данных в запросе невозможно — её нужно сначала принудительно «залить» в СУБД.

Проанализируем пример, как правильно передать готовую Таблицу Значений в качестве временной таблицы запроса:


// Предположим, у нас есть заполненная Таблица Значений "ТЗ_Сопоставление"
// с колонками: СтруктураЭлемент (СправочникСсылка) и СтруктураПодЭлемент (СправочникСсылка)

МенеджерВТ = Новый МенеджерВременныхТаблиц;

ЗапросПодготовки = Новый Запрос;
ЗапросПодготовки.МенеджерВременныхТаблиц = МенеджерВТ;

// Передаем ТЗ как параметр запроса
ЗапросПодготовки.УстановитьПараметр("ВнешняяТаблица", ТЗ_Сопоставление);

// Описываем типы колонок во временной таблице
ЗапросПодготовки.Текст = 
    "ВЫБРАТЬ
    |	ВнешнийИсточник.СтруктураЭлемент КАК СтруктураЭлемент,
    |	ВнешнийИсточник.СтруктураПодЭлемент КАК СтруктураПодЭлемент
    |ПОМЕСТИТЬ ТаблицаДоп
    |ИЗ
    |	&ВнешняяТаблица КАК ВнешнийИсточник";

// Заполняем ВТ "ТаблицаДоп" данными нашей ТЗ
ЗапросПодготовки.Выполнить();

// Теперь основной запрос сможет использовать эту таблицу
ЗапросОсновной = Новый Запрос;
ЗапросОсновной.МенеджерВременныхТаблиц = МенеджерВТ;
ЗапросОсновной.Текст = 
    "ВЫБРАТЬ
    |	ВложенныйЗапрос.Ссылка КАК СтруктураЭлемент,
    |	ВЫБОР
    |		КОГДА ТаблицаДоп.СтруктураПодЭлемент ЕСТЬ NULL
    |			ТОГДА ВложенныйЗапрос.Ссылка
    |		ИНАЧЕ ТаблицаДоп.StructureПодЭлемент
    |	КОНЕЦ КАК СтруктураПодЭлемент
    |ИЗ
    |	Справочник.СтруктураНоменклатуры КАК ВложенныйЗапрос
    |	ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаДоп КАК ТаблицаДоп
    |	ПО ВложенныйЗапрос.Ссылка = ТаблицаДоп.СтруктураЭлемент";

РезультатЗапроса = ЗапросОсновной.Выполнить().Выгрузить();

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

Чтобы избежать путаницы с передачей менеджеров временных таблиц между разными объектами запросов, в 1С крайне рекомендуется использовать конструкцию Пакетного запроса. Пакетный запрос объединяет создание временных таблиц и получение итоговых данных в рамках одной транзакции и одного текста запроса. Части запроса разделяются символом точки с запятой ;. Для оптимизации работы с временными таблицами в сложных пакетах можно использовать обработку для расстановки инструкций уничтожения временных таблиц.

Рассмотрим, как выглядит лаконичный и защищенный от потери контекста пакетный запрос:


Запрос = Новый Запрос;
// При использовании пакета в рамках одного объекта Запрос
// Менеджер временных таблиц создается автоматически внутри платформы!

Запрос.Текст = 
    "ВЫБРАТЬ
    |	Сопоставление.Ссылка1 КАК СтруктураЭлемент,
    |	Сопоставление.Ссылка2 КАК СтруктураПодЭлемент
    |ПОМЕСТИТЬ ТаблицаДоп
    |ИЗ
    |	РегистрСведений.СопоставлениеКатегорий КАК Сопоставление
    |;
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |	ВложенныйЗапрос.Ссылка КАК СтруктураЭлемент,
    |	ВЫБОР
    |		КОГДА ТаблицаДоп.СтруктураПодЭлемент ЕСТЬ NULL
    |			ТОГДА ВложенныйЗапрос.Ссылка
    |		ИНАЧЕ ТаблицаДоп.СтруктураПодЭлемент
    |	КОНЕЦ КАК СтруктураПодЭлемент
    |ИЗ
    |	Справочник.СтруктураНоменклатуры КАК ВложенныйЗапрос
    |	ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаДоп КАК ТаблицаДоп
    |	ПО ВложенныйЗапрос.Ссылка = ТаблицаДоп.СтруктураЭлемент";

// Выполняем весь пакет за один раз
РезультатыПакета = Запрос.ВыполнитьПакет();

// РезультатыПакета[0] - это результат создания ВТ
// РезультатыПакета[1] - это результат нашего основного выборщика
ТаблицаРезультат = РезультатыПакета[1].Выгрузить();

---

4. Специфика интеграции «ВыгрузкаОнлайнер»

Проанализируем контекст ошибки конкретно для обработки «ВыгрузкаОнлайнер2017». Ошибка происходит при попытке связать структуру номенклатуры 1С со вспомогательной таблицей соответствия категорий (ТаблицаДоп). Поле ОбъединятьСтруктуры говорит о том, что в обработке реализована возможность группировки нескольких веток категорий вашего склада в одну категорию на маркетплейсе.

Если данная обработка раньше работала, а теперь выдает ошибку, велика вероятность, что:

Для исправления ситуации обязательно проверьте, заполнены ли настройки категорий на форме обработки перед тем, как нажимать кнопку выгрузки в XML.

← На главную