Как передать запись регистра сведений с сервера на клиент в управляемом приложении

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

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

Почему нельзя передать объект напрямую?

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

Способ 1. Использование структур и массивов

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

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


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

Преимущество этого метода в том, что на клиенте мы получаем легкий объект, к полям которого можно обращаться через точку: ДанныеЗаписи.ИмяПоля.

Способ 2. Использование Ключа записи

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

Разберем по шагам процесс открытия формы записи с сервера на клиент:

  1. На сервере формируем отбор.
  2. Создаем ключ записи.
  3. Передаем этот ключ на клиент.
  4. На клиенте используем ОткрытьФорму, передавая ключ в параметрах.

Пример кода для открытия формы:


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

Способ 3. Синхронизация с реквизитами формы

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

Рассмотрим, как это работает: мы создаем на сервере объект (менеджер записи или набор), считываем данные, а затем одной командой "пробрасываем" их в реквизиты формы. После завершения серверного вызова данные автоматически станут доступны на клиенте через обращение к ЭтаФорма.ИмяРеквизита.

Способ 4. Временное хранилище

Если нам необходимо передать большой объем данных (например, весь набор записей или результат сложного запроса), использование структур может быть неэффективным из-за нагрузки на сеть. В этом случае целесообразно использовать Временное хранилище.

Алгоритм действий следующий:

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

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

Выводы и рекомендации

Подводя итог, выбор метода зависит от вашей конкретной задачи:

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

← На главную