Почему табличная часть формы в 1С не передается в запрос и как это исправить?

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

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

Понимаем разницу: данные формы против объекта

Первое, что необходимо усвоить — это различие между типом данных на форме и полноценным объектом в базе данных. Когда мы создаем РеквизитФормы, платформа 1С создает специальный тип ДанныеФормыКоллекция. Этот тип оптимизирован для передачи через интернет, работы в веб-клиенте и отображения в интерфейсе. Он не является ТаблицейЗначений в классическом серверном понимании.

Запрос 1С ожидает на вход структуру, которая хранится в памяти сервера или базе данных. Тип ДанныеФормыКоллекция не имеет тех методов доступа, которые нужны движку запросов. Именно поэтому платформа «ругается» при попытке передать его как параметр.

Решение 1: использование метода РеквизитФормыВОбъект

Самый простой и понятный способ превратить данные формы в объект, с которым умеет работать сервер — это метод РеквизитФормыВОбъект. Этот метод создает временный серверный объект, из которого можно получить полноценную табличную часть. Рассмотрим, как это реализовать на практике:


&НаСервере
Процедура ВыполнитьЗапросПоТаблице()
    // Получаем объект обработки или документа из данных формы
    ОбъектОбработки = РеквизитФормыВОбъект("Объект");
    ТЧ = ОбъектОбработки.ТабличнаяЧасть;
    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ &ТЧ КАК ТЧ";
    Запрос.УстановитьПараметр("ТЧ", ТЧ);
    // Теперь запрос отработает корректно
    Результат = Запрос.Выполнить().Выгрузить();
КонецПроцедуры

Этот способ позволяет работать с данными максимально просто, однако помните, что при очень больших объемах данных (десятки и сотни тысяч строк) преобразование может занимать ресурсы сервера.

Решение 2: явная выгрузка в ТаблицуЗначений

Если мы не хотим преобразовывать весь объект, мы можем воспользоваться методом Выгрузить. Этот метод создает стандартную серверную ТаблицуЗначений из коллекции данных формы. Это решение считается классическим для процедур НаСервере:


&НаСервере
Процедура ОбработатьДанныеФормы()
    // Выгружаем коллекцию в ТЗ, которая является понятным типом для запроса
    ДанныеДляЗапроса = Объект.ТабличнаяЧасть.Выгрузить();
    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ * ИЗ &Таблица КАК Таблица";
    Запрос.УстановитьПараметр("Таблица", ДанныеДляЗапроса);
    Результат = Запрос.Выполнить();
КонецПроцедуры

Когда стоит изменить архитектуру

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

  1. Вынос логики в серверные модули: не делайте тяжелые вычисления в формах. Создайте процедуру в серверном модуле, которая сама читает данные из базы (а не с формы), обрабатывает их и записывает результат.
  2. Использование фоновых заданий: при работе с Big Data выполнение кода в фоновом режиме позволит не блокировать интерфейс пользователя и эффективно распределять ресурсы сервера.
  3. Работа с временными таблицами: если вы импортируете данные из прайс-листов или внешних файлов, загружайте их сразу в регистры сведений или временные таблицы БД, минуя визуальное отображение в табличной части формы.

Таким образом, разделение на ДанныеФормы и Объект — это не недостаток платформы, а инструмент обеспечения производительности и безопасности работы в тонком и веб-клиенте. Понимая эти архитектурные особенности, мы можем писать быстрый и стабильный код, используя подходящие методы для каждого конкретного случая.

← На главную