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