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

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

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

Анализ частых ошибок в коде

Проанализируем исходный фрагмент кода, чтобы выяснить причины возможных сбоев платформы:

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

Способ 1. Загрузка результата в табличную часть объекта

Рассмотрим основной вариант, когда у внешней обработки создана собственная табличная часть (например, ДокументыКОбработке), которая вынесена на управляемую форму. В контексте управляемой формы эта коллекция доступна через свойство Объект.ИмяТабличнойЧасти и имеет тип ДанныеФормыКоллекция.

Чтобы быстро поместить строки запроса в табличную часть, используем метод Загрузить(). При этом имена колонок в тексте запроса должны строго совпадать с именами реквизитов табличной части обработки.

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


&НаСервере
Процедура ЗаполнитьТабличнуюЧастьНаСервере()

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   РеализацияТоваровУслуг.Ссылка КАК РеализацияТиУ,
        |   СчетФактураВыданныйДокументыОснования.Ссылка КАК СчетФактураВыданный
        |ИЗ
        |   Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
        |   ЛЕВОЕ СОЕДИНЕНИЕ Документ.СчетФактураВыданный.ДокументыОснования КАК СчетФактураВыданныйДокументыОснования
        |       ПО СчетФактураВыданныйДокументыОснования.ДокументОснование = РеализацияТоваровУслуг.Ссылка
        |ГДЕ
        |   РеализацияТоваровУслуг.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
        |   И РеализацияТоваровУслуг.Проведен = &Проведен
        |   И РеализацияТоваровУслуг.Организация = &Организация
        |   И РеализацияТоваровУслуг.Контрагент В (&Контрагент)";

    Запрос.УстановитьПараметр("ДатаНачала", Объект.Период.ДатаНачала);
    Запрос.УстановитьПараметр("ДатаОкончания", Объект.Период.ДатаОкончания);
    Запрос.УстановитьПараметр("Проведен", Объект.Проведенные);
    Запрос.УстановитьПараметр("Организация", Объект.Организация);
    Запрос.УстановитьПараметр("Контрагент", Объект.Контрагент);

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

    // Загружаем полученную таблицу значений в табличную часть обработки
    Объект.ДокументыКОбработке.Загрузить(ТаблицаРезультата);

КонецПроцедуры

Обратите внимание: вызов метода Загрузить() полностью очищает существующие строки в табличной части перед добавлением новых данных.

Способ 2. Построчное добавление данных без полной перезаписи

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


&НаСервере
Процедура ДополнитьТабличнуюЧастьНаСервере()

    Запрос = Новый Запрос;
    Запрос.Текст = "..."; // Текст запроса с псевдонимами, совпадающими с именами колонок ТЧ
    
    // Установка параметров
    // ...

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

    Для Каждого СтрокаТЗ Из ТаблицаРезультата Цикл
        НоваяСтрока = Объект.ДокументыКОбработке.Добавить();
        ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаТЗ);
    КонецЦикла;

КонецПроцедуры

Такой подход обеспечивает гибкость: можно добавить условия проверки перед добавлением, пересчитать суммы или заполнить вычисляемые поля, которых нет в исходном запросе.

Способ 3. Вывод в произвольный реквизит формы типа «ТаблицаЗначений»

Если табличная часть создана не в объекте обработки, а добавлена непосредственно на вкладке «Реквизиты» формы с типом данных ТаблицаЗначений, прямое присвоение или метод Загрузить() использовать нельзя. В управляемых формах для таких таблиц платформа создает прокси-объект ДанныеФормыКоллекция.

Для переноса данных из серверной таблицы значений в реквизит формы используем встроенную процедуру ЗначениеВРеквизитФормы:


&НаСервере
Процедура ЗаполнитьРеквизитФормыНаСервере()

    Запрос = Новый Запрос;
    Запрос.Текст = "...";
    
    ТаблицаРезультата = Запрос.Выполнить().Выгрузить();

    // Переносим данные из ТаблицыЗначений в реквизит формы "ТаблицаНаФорме"
    ЗначениеВРеквизитФормы(ТаблицаРезультата, "ТаблицаНаФорме");

КонецПроцедуры

Особенности клиент-серверного взаимодействия

Важно помнить об ограничениях работы с коллекциями в 1С 8.3:

  1. Объект ТаблицаЗначений доступен исключительно на стороне сервера. Передавать его как возвращаемое значение функции на тонкий клиент нельзя — платформа выдаст ошибку сериализации.
  2. Все операции по выполнению запроса и заполнению данных формы следует выполнять в процедуре с директивой компиляции &НаСервере. На клиенте остается лишь привязать вызов этой процедуры к кнопке или команде формы.
← На главную