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

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

При разработке в управляемом приложении 1С программисты часто сталкиваются с ошибкой "Неверные параметры" при попытке передать таблицу значений в запрос в качестве параметра. Типичный сценарий выглядит так: в форме или обработке есть реквизит типа "Таблица значений", мы пытаемся поместить его во временную таблицу в запросе, но система отказывается выполнять код. Рассмотрим подробнее, почему возникает эта ошибка и как её исправить.

Выясняем причину: разница между Таблицей значений и Коллекцией формы

Основная причина кроется в особенностях клиент-серверной архитектуры управляемых форм. Реквизит формы с типом "Таблица значений" на самом деле не является классическим объектом ТаблицаЗначений. На сервере и клиенте этот реквизит представлен типом ДанныеФормыКоллекция.

Платформа 1С спроектирована так, что СУБД не умеет напрямую работать с объектами типа ДанныеФормыКоллекция. В параметрах запроса для построения временной таблицы должна передаваться исключительно чистая, типизированная ТаблицаЗначений. Попытка передать туда коллекцию формы напрямую как раз и вызывает ошибку "Неверные параметры".

Решение 1. Получение чистой таблицы значений

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

  1. Метод Выгрузить(). Если нам нужно просто получить копию данных из реквизита в виде таблицы значений, проще всего вызвать метод Выгрузить(). Он преобразует коллекцию данных формы в стандартную таблицу значений.
    
    // Предположим, ТЗФормы — это реквизит формы (ДанныеФормыКоллекция)
    ТаблицаДляЗапроса = ТЗФормы.Выгрузить();
    
  2. Функция РеквизитФормыВЗначение(). В тех случаях, когда требуется преобразовать весь объект (например, саму обработку со всеми ее реквизитами и табличными частями) во внутренний объект базы данных, используется стандартная функция платформы:
    
    ОбъектЗначение = РеквизитФормыВЗначение("Объект");
    ТаблицаДляЗапроса = ОбъектЗначение.ИмяВашейТабличнойЧасти.Выгрузить();
    

Решение 2. Правильная работа с временными таблицами в запросе

Вторая частая ошибка — это создание двух независимых объектов запроса без явного связывания их контекста. Если вы создаете временную таблицу в одном объекте Запрос, а затем пытаетесь выбрать из нее данные в другом объекте Запрос, вы получите ошибку, так как временная таблица уничтожается сразу после завершения работы первого запроса.

Проанализируем два правильных архитектурных подхода к работе с временными таблицами.

Вариант А: Использование пакетного запроса (рекомендуется)

Это самый простой и лаконичный способ. Мы объединяем помещение данных во временную таблицу и последующую выборку в один пакетный запрос, разделяя инструкции символом точки с запятой (;).


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

// Преобразуем коллекцию формы в настоящую Таблицу Значений
ТаблицаПараметр = Объект.ТЗ.Выгрузить(); 

Запрос.УстановитьПараметр("ТаблицаПараметр", ТаблицаПараметр);
РезультатЗапроса = Запрос.Выполнить();

Вариант Б: Использование Менеджера временных таблиц

Если логика программы требует разделения запросов во времени или в разных процедурах, необходимо использовать специальный объект МенеджерВременныхТаблиц. Он позволяет хранить временные таблицы между выполнениями разных запросов.


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

// Первый запрос: помещаем данные во временную таблицу
Запрос1 = Новый Запрос;
Запрос1.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос1.Текст = 
"ВЫБРАТЬ
|    ВременныйИсточник.Заказ КАК Заказ
|ПОМЕСТИТЬ ВТ_Заказы
|ИЗ
|    &ТаблицаПараметр КАК ВременныйИсточник";

ТаблицаПараметр = Объект.ТЗ.Выгрузить();
Запрос1.УстановитьПараметр("ТаблицаПараметр", ТаблицаПараметр);
Запрос1.Выполнить();

// Второй запрос: обращаемся к созданной временной таблице
Запрос2 = Новый Запрос;
Запрос2.МенеджерВременныхТаблиц = МенеджерВТ; // Важно передать тот же менеджер!
Запрос2.Текст = 
"ВЫБРАТЬ
|    ВТ_Заказы.Заказ КАК Заказ
|ИЗ
|    ВТ_Заказы КАК ВТ_Заказы";

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

Важные требования к передаваемой таблице значений

Помимо приведения типов данных формы, необходимо соблюдать правила платформы и СУБД для работы с временными таблицами:

← На главную