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

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

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

Почему на клиенте недоступны запросы и таблицы значений?

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

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

Все тяжелые вычисления, запросы к базе данных и работа с бизнес-логикой должны происходить исключительно на сервере.

Работа с табличными частями через реквизит Объект

Рассмотрим подробнее, как получить доступ к табличной части документа или справочника на сервере. Когда мы открываем форму сущности, все её данные помещаются в специальный реквизит формы — Объект (имеющий тип ДанныеФормыСтруктура).

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

  1. Создайте запрос и получите таблицу значений с результатами.
  2. Обратитесь к табличной части формы через реквизит Объект.
  3. Используйте метод Загрузить для заполнения данными.

Посмотрим на практический пример реализации этого алгоритма:


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

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

Преобразование данных формы в прикладные объекты (и обратно)

Проанализируем ситуацию, когда нам требуется вызвать метод самого прикладного объекта (например, процедуру расчета цен или проведение, описанную в модуле документа), а не просто заполнить поля. На клиенте и в контексте формы метод ПолучитьОбъект() не работает.

Для связи экранных данных формы с реальными объектами базы данных в памяти сервера используются специальные методы-взаимопреобразователи:

Разберем по шагам, как это реализовать в коде:


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

Передача таблиц данных с сервера на клиент без привязки к форме

Что делать, если результат запроса (таблицу) не нужно выводить на форму, а требуется обработать алгоритмами на клиенте? Как мы уже выяснили, передавать ТаблицуЗначений напрямую нельзя. Решением является её преобразование в разрешенные типы данных — Массив и Структуру.

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

В типовых конфигурациях на базе БСП (Библиотеки Стандартных Подсистем) для этого есть готовая функция. Рассмотрим пример ее использования:


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

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

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

Особенности использования глобальных переменных

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

Понимание этих базовых механизмов позволяет писать чистый, производительный и надежный код в среде управляемых форм 1С 8.3 без использования костылей и неоправданно сложных конструкций.

← На главную