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

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

При переходе с обычных форм платформы «1С:Предприятие 8.2» на управляемые формы разработчики часто сталкиваются с ошибками при попытке программно получить и заполнить строки табличной части. Старые конструкции вроде прямого обращения к элементам формы на сервере больше не работают из-за разделения клиентского интерфейса и серверных данных.

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

Анализ типичных ошибок: почему код из обычных форм не работает

В обычном интерфейсе разработчики часто обращались к данным через визуальный элемент управления: ЭлементыФормы.ТабличнаяЧасть.Значение. В управляемом приложении концепция полностью изменилась:

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

Решение 1. Заполнение строк через основной реквизит «Отчет» в цикле

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

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


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

Обратите внимание: перед заполнением рекомендуется вызывать метод Очистить(), чтобы при повторном формировании отчета данные не дублировались.

Решение 2. Быстрая загрузка таблицы значений (без обхода в цикле)

Построчный обход выборки через Пока ... Цикл с вызовом метода Добавить() работает медленно, если запрос возвращает сотни или тысячи строк. В платформе 1С коллекция данных формы (ДанныеФормыКоллекция) поддерживает встроенный метод Загрузить().

Рассмотрим, как оптимизировать код и загрузить все строки в одну операцию:

  1. В тексте запроса назначаем псевдонимы колонок (через оператор КАК) так, чтобы они в точности совпадали с именами колонок табличной части отчета.
  2. Выгружаем результат запроса в таблицу значений методом Выгрузить().
  3. Передаем готовую таблицу значений в метод Загрузить() нужной табличной части.

Посмотрим на практическую реализацию:


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

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

Особый случай: заполнение произвольного реквизита формы

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


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

Рекомендации по разработке отчетов в управляемом интерфейсе

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

  1. Объем контекста формы. Все строки, загруженные в реквизит Отчет, передаются по сети между сервером и клиентом при каждом контекстном серверном вызове. Если таблица содержит тысячи записей, форма начнет работать с заметными задержками.
  2. Использование Системы компоновки данных (СКД). Стандартный и наиболее правильный способ создания отчетов в 1С — использование СКД. Компоновка данных берет на себя формирование макета, расчет итогов, расшифровку полей и пользовательские настройки без необходимости вручную писать код заполнения таблиц.
  3. Вывод в табличный документ. Если требуется нестандартный макет, вывод данных обычно организуют в ТабличныйДокумент (поле табличного документа на форме). Это позволяет не перегружать контекст формы массивами строк табличных частей.
← На главную