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