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

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

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

Разбираем проблему: процедура против функции

Рассмотрим ситуацию, описанную автором темы. Изначально код выглядел так: на клиенте вызывается серверная процедура, которая выполняет запрос. Проблема заключается в том, что Процедура по своей сути не возвращает результат. Она выполняет действия, но «молчит» по завершении. Чтобы получить данные обратно на клиенте, нам необходимо использовать Функцию.

Давайте проанализируем правильный подход к написанию кода для получения данных:


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

&НаСервереБезКонтекста
Функция ПолучитьМассивНаСервере()
    // Выполняем запрос или вычисления
    МассивРезультатов = Новый Массив;
    
    // ПРИМЕР: ЗАПРОС_С_ОБРАБОТКОЙ_РЕЗУЛЬТАТА
    // Здесь мы формируем массив или структуру
    МассивРезультатов.Добавить(100);
    МассивРезультатов.Добавить(200);
    
    Возврат МассивРезультатов; // Ключевое слово для передачи данных обратно
КонецФункции

Почему нельзя просто передать Таблицу Значений?

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

Если ваша задача — передать многомерный массив или таблицу, мы должны преобразовать её в типы, доступные на клиенте. К ним относятся:

Рассмотрим пример, как превратить результат запроса в массив структур, который «поймет» клиентская часть:


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

Использование реквизитов формы для больших объемов данных

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

Разберем алгоритм работы через контекст формы:

  1. Создаем на форме реквизит (например, СписокЧисел) с типом ТаблицаЗначений (в редакторе формы).
  2. На сервере заполняем этот реквизит.
  3. Используем метод ЗначениеВРеквизитФормы, если мы работали с «чистым» объектом ТЗ, или просто обращаемся к реквизиту напрямую.

Пример работы в контексте формы:


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

Оптимизация: Контекстный или бесконтекстный вызов?

Обратите внимание на директивы компиляции. В советах форума упоминается &НаСервереБезКонтекста. Выясним причину, почему это важно:

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

Где лучше проводить вычисления?

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

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

Резюме для разработчика

Для успешной передачи результата на клиент придерживайтесь следующих правил:

Следуя этим шагам, вы создадите надежную и быструю систему взаимодействия между клиентской и серверной частью вашего приложения.

← На главную