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

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

При разработке в системе 1С:Предприятие 8.3 часто возникает задача, когда из одной формы необходимо открыть другую и отобразить в ней данные, полученные в результате выполнения запроса. Это может быть вывод информации в табличное поле, связанное с реквизитом типа «ТаблицаЗначений», или же формирование отчета в табличном документе. Давайте рассмотрим подробнее, как эффективно решить эту задачу, используя различные подходы и механизмы платформы.

В начале обсудим основные способы передачи данных между формами, так как именно этот этап является ключевым для последующей работы с данными в открываемой форме.

1. Передача данных между формами в 1С:Предприятие

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

  1. Передача через параметры при открытии формы: Этот метод является наиболее распространенным и удобным для передачи небольших и средних объемов данных. При вызове метода ОткрытьФорму() мы можем передать структурированные данные вторым параметром. Эти данные становятся доступными в открываемой форме.
  2. Использование временного хранилища: Этот подход становится особенно актуальным, когда объем передаваемых данных значителен или если данные должны быть доступны на сервере без избыточной передачи через клиентскую часть. Результат запроса сначала помещается во временное хранилище, и только адрес этого хранилища передается в открываемую форму.
  3. Обратная передача данных с помощью метода Оповестить(): Хотя этот метод не используется для инициализации открываемой формы, он важен для понимания полного цикла взаимодействия форм. Он позволяет закрывающейся форме передать информацию форме-владельцу.

Подробнее о передаче через параметры

Когда мы открываем новую форму, мы можем передать ей структуру с параметрами. Эти параметры будут доступны в открываемой форме в событии ПриСозданииНаСервере. Мы создадим новую структуру, заполним ее необходимыми значениями (например, результатом запроса или ссылкой на него) и передадим вторым параметром в метод ОткрытьФорму().

Пример кода для формы-источника (клиентский контекст):


&НаКлиенте
Процедура ОткрытьФормуСДанными(Команда)
    // Выполняем запрос на сервере и получаем выгруженную ТаблицуЗначений
    ТаблицаЗначенийЗапроса = ВыполнитьЗапросНаСервере();
    
    // Создаем структуру параметров
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ДанныеДляОтображения", ТаблицаЗначенийЗапроса);
    
    // Открываем новую форму, передавая параметры
    ОткрытьФорму("Обработка.МояОбработкаСТаблицей.Форма.Форма", ПараметрыФормы);
КонецПроцедуры

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

Обратите внимание, что выполнение запроса на сервере необходимо, поэтому мы вынесли его в серверную функцию ВыполнитьЗапросНаСервере(), которая возвращает ТаблицуЗначений.

В открываемой форме (например, в модуле формы МояОбработкаСТаблицей.Форма.Форма), мы получим эти параметры в обработчике события ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартныеПараметры)
    Если СтандартныеПараметры.Свойство("ДанныеДляОтображения") Тогда
        // ТаблицаНаФорме - это реквизит формы типа ТаблицаЗначений,
        // привязанный к табличному полю на форме.
        ТаблицаНаФорме = СтандартныеПараметры.ДанныеДляОтображения;
    КонецЕсли;
КонецПроцедуры

Использование временного хранилища

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

Пример для формы-источника (клиентский контекст):


&НаКлиенте
Процедура ОткрытьФормуСДаннымиЧерезХранилище(Команда)
    // Выполняем запрос на сервере и помещаем результат во временное хранилище
    АдресХранилища = ПоместитьДанныеВоВременноеХранилищеНаСервере();
    
    // Создаем структуру параметров с адресом хранилища
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("АдресДанныхВХранилище", АдресХранилища);
    
    // Открываем новую форму, передавая адрес хранилища
    ОткрытьФорму("Обработка.МояОбработкаСТаблицей.Форма.Форма", ПараметрыФормы);
КонецПроцедуры

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

В открываемой форме, в обработчике ПриСозданииНаСервере, мы получаем адрес и извлекаем данные:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартныеПараметры)
    Если СтандартныеПараметры.Свойство("АдресДанныхВХранилище") Тогда
        АдресХранилища = СтандартныеПараметры.АдресДанныхВХранилище;
        // Получаем ТаблицуЗначений из временного хранилища
        ТаблицаДанных = ПолучитьИзВременногоХранилища(АдресХранилища);
        
        Если ТаблицаДанных <> Неопределено Тогда
            // ТаблицаНаФорме - это реквизит формы типа ТаблицаЗначений
            ТаблицаНаФорме = ТаблицаДанных;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

2. Выгрузка результата запроса в табличное поле на форме

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

Для управляемых форм

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

  1. На сервере выполняем запрос.
  2. Выгружаем его результат в объект ТаблицаЗначений.
  3. Присваиваем эту ТаблицуЗначений реквизиту формы, который связан с табличным полем.

Критически важно, чтобы названия и типы колонок реквизита формы типа ТаблицаЗначений (если они определены заранее) совпадали с колонками результата запроса. Если колонки не определены, платформа создаст их автоматически при присвоении.

Пример кода (серверный контекст, после получения данных как описано выше):


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

Если ваше табличное поле является динамическим списком, то для вывода данных запроса в него применяются совершенно другие механизмы. Динамические списки оптимизированы для работы с большими объемами данных и используют систему компоновки данных. В этом случае мы будем использовать методы ПолучитьИсполняемуюСхемуКомпоновкиДанных() и ПолучитьИсполняемыеНастройкиКомпоновкиДанных() динамического списка для формирования макета компоновки и вывода данных, а не напрямую присваивать ТаблицуЗначений.

Для обычных форм

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


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

3. Выгрузка результата запроса в табличный документ на форме

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

  1. Создаем реквизит формы типа ТабличныйДокумент (например, РезультатОтчета).
  2. На сервере выполняем запрос.
  3. Используем методы объекта ТабличныйДокумент для заполнения его данными.

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


&НаСервере
Процедура ЗаполнитьТабличныйДокументНаСервере(РезультатЗапросаВыгруженный)
    // РезультатОтчета - это реквизит формы типа ТабличныйДокумент
    РезультатОтчета.Очистить();
    
    // Предполагаем, что РезультатЗапросаВыгруженный - это ТаблицаЗначений
    
    // Выводим заголовки колонок
    НомерСтроки = 1;
    НомерКолонки = 1;
    Для Каждого Колонка Из РезультатЗапросаВыгруженный.Колонки Цикл
        ОбластьЗаголовка = РезультатОтчета.Область(НомерСтроки, НомерКолонки);
        ОбластьЗаголовка.Текст = Колонка.Имя;
        ОбластьЗаголовка.Объединить(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
        НомерКолонки = НомерКолонки + 1;
    КонецЦикла;
    
    // Выводим данные
    НомерСтроки = НомерСтроки + 1; // Начинаем выводить данные со следующей строки после заголовков
    Для Каждого СтрокаТЗ Из РезультатЗапросаВыгруженный Цикл
        НомерКолонки = 1;
        Для Каждого КолонкаТЗ Из РезультатЗапросаВыгруженный.Колонки Цикл
            ОбластьДанных = РезультатОтчета.Область(НомерСтроки, НомерКолонки);
            ЗначениеКолонки = СтрокаТЗ[КолонкаТЗ.Имя];
            ОбластьДанных.Текст = Строка(ЗначениеКолонки);
            ОбластьДанных.Объединить(НомерСтроки, НомерКолонки, НомерСтроки, НомерКолонки);
            НомерКолонки = НомерКолонки + 1;
        КонецЦикла;
        НомерСтроки = НомерСтроки + 1;
    КонецЦикла;
    
    // После заполнения, если табличный документ не отображается автоматически,
    // на клиенте можно вызвать:
    // Элементы.РезультатОтчета.Обновить(); 
    // Если ТабличныйДокумент был создан как Новый ТабличныйДокумент
    // и не привязан к реквизиту формы, его можно показать:
    // ТаблДок.Показать(); 
КонецПроцедуры

Обратите внимание, что для более сложного и отформатированного вывода данных в табличный документ обычно используются макеты и механизм системы компоновки данных. Мы можем получить макет формы или внешней обработки (например, Макет = ПолучитьМакет("МойМакетОтчета");), затем использовать его области для форматированного вывода заголовков, данных и итогов. Представленный выше пример является базовым и предназначен для быстрого вывода без сложного форматирования, но дает общее представление о принципе.

Важные нюансы и рекомендации

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

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

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

← На главную