Как устранить ошибку вызова конструктора запроса по таблице значений при изменении режима совместимости 1С?

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

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

Разбор причины ошибки

Основная причина заключается в том, что платформа 1С ужесточила требования к работе с внешними источниками данных. Если раньше 1С могла «догадаться» о типах данных в вашей таблице значений, то в новых версиях платформы строгая типизация стала обязательной. Кроме того, при использовании конструкции ПОМЕСТИТЬ в запросе, сложные выражения и разыменования через точку (обращение к реквизитам объектов через ВЫРАЗИТЬ) при первом обращении к таблице часто вызывают сбои.

Шаг 1: Обязательная типизация таблицы значений

Первым делом проанализируем, как формируется таблица значений в коде. Если вы просто создали таблицу методом Добавить, платформа не знает, какие данные в ней хранятся, что и приводит к ошибке при обращении к полям в запросе. Нам необходимо принудительно задать типы данных для каждой колонки с помощью объекта ОписаниеТипов.

Рассмотрим, как правильно типизировать колонки перед тем, как передать таблицу в запрос:


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

МассивТиповУпаковка = Новый Массив;
МассивТиповУпаковка.Добавить(Тип("СправочникСсылка.УпаковкиЕдиницыИзмерения"));
ОписаниеТипаУпаковка = Новый ОписаниеТипов(МассивТиповУпаковка);

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура", ОписаниеТипаНоменклатура);
ТЗ.Колонки.Добавить("Упаковка", ОписаниеТипаУпаковка);
ТЗ.Колонки.Добавить("КоличествоУпаковок", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));

Шаг 2: Упрощение структуры запроса

Если после типизации ошибка сохраняется, значит, запрос перегружен логикой в первом пакете. Платформа 1С в новых режимах совместимости требует, чтобы первый этап выполнения запроса был «чистым». Не пытайтесь производить вычисления, округления или использовать ВЫРАЗИТЬ непосредственно в пакете, где данные помещаются во временную таблицу.

Разделим наш запрос на два последовательных этапа:

  1. Пакет №1: Просто помещаем данные из таблицы значений во временную таблицу ВТ_Исходная без каких-либо преобразований.
  2. Пакет №2: Выполняем все необходимые соединения, вычисления и выражения ВЫРАЗИТЬ уже над временной таблицей.

Пример правильной структуры запроса:


// Пакет 1: Помещение данных в чистом виде
ВЫБРАТЬ
    ТЗ.Номенклатура,
    ТЗ.Упаковка,
    ТЗ.КоличествоУпаковок
ПОМЕСТИТЬ ВТ_Исходная
ИЗ &ТЗ КАК ТЗ
;

// Пакет 2: Выполняем сложные вычисления
ВЫБРАТЬ
    ВТ.Номенклатура,
    ВЫРАЗИТЬ(ВТ.Номенклатура КАК Справочник.Номенклатура).Наименование КАК Наименование,
    ВТ.КоличествоУпаковок * 10 КАК Количество
ИЗ ВТ_Исходная КАК ВТ

Почему нельзя использовать сложные выражения при ПОМЕСТИТЬ

Попытка обращения через точку (разыменование выражений) к данным, пришедшим извне, в первом же запросе ПОМЕСТИТЬ — это «тяжелая» операция для движка 1С в новых версиях платформы. Когда вы используете ВЫРАЗИТЬ прямо в первом пакете, платформа пытается транслировать это в SQL-запрос, не имея точной информации о структуре исходной таблицы. Это и вызывает падение конструктора или ошибку исполнения.

Практические советы для разработчика

Следуя этим рекомендациям, вы сможете успешно адаптировать ваш код под новые версии платформы 1С и избежать проблем с режимами совместимости. Совместная работа с типизацией и поэтапная обработка данных — залог стабильной работы ваших запросов!

← На главную