Как передать результат запроса с сервера на клиент в 1С

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

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

Метод 1: Использование реквизита формы (ДанныеФормыКоллекция)

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

На уровне платформы такой реквизит на сервере представлен типом ДанныеФормыКоллекция. Этот тип данных «умеет» перемещаться между сервером и клиентом. Разберем пример кода, который загружает результат запроса в такой реквизит:


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

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

Метод 2: Преобразование в массив структур

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

Структура и Массив — это универсальные типы, которые доступны и на сервере, и на клиенте. Рассмотрим функцию, которая автоматизирует процесс конвертации:


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

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

Метод 3: Использование временного хранилища

Рассмотрим ситуацию, когда данных экстремально много, и мы не хотим передавать их по сети в текущем вызове. Мы можем сохранить результат запроса в специальную область памяти сервера и передать на клиент только адрес этой области (строку).

Разберем алгоритм работы с ПоместитьВоВременноеХранилище:

  1. На сервере выполняем запрос и выгружаем его в ТаблицуЗначений.
  2. Вызываем функцию ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор).
  3. Передаем полученный адрес (строку) на клиент.
  4. Когда на клиенте (в другом серверном вызове) нам понадобятся эти данные, мы извлекаем их по адресу.

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

Этот метод идеален, если данные нужны для последующей серверной обработки, но инициирует эту обработку клиент. Передавать саму таблицу на клиент в этом случае вообще не требуется.

Метод 4: Быстрая передача через JSON

Для оптимизации передачи данных в современных версиях платформы (8.3.6 и выше) можно использовать JSON-сериализацию. Передача одной длинной строки (JSON) часто работает быстрее, чем передача массива из множества мелких структур, так как уменьшается количество обращений к подсистеме маршалинга (упаковки) данных.

Посмотрим на пример реализации:


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

На клиенте мы можем использовать объект ЧтениеJSON, чтобы превратить эту строку обратно в массив структур, либо передать её «как есть» в JavaScript (если работаем в веб-клиенте или с полем HTML-документа).

Сравнение методов и рекомендации

Проанализируем, какой метод выбрать в зависимости от условий задачи:

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

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

← На главную