При разработке прикладных решений в платформе 1С:Предприятие 8.3 часто возникает задача передачи табличных данных между клиентом и сервером. Сложность заключается в том, что таблица значений может содержать как примитивные типы данных (числа, строки, даты, булево), так и ссылочные объекты информационной базы (ссылки на справочники, документы, перечисления). Разберем доступные и эффективные способы решения этой задачи.
Распространенное заблуждение заключается в том, что платформа не умеет штатно преобразовывать ссылки в формат JSON. Начиная с платформы 8.3, объект СериализаторXDTO предоставляет метод ЗаписатьJSON, который автоматически сериализует как саму таблицу значений, так и все содержащиеся в ней ссылочные типы данных.
Рассмотрим, как выполнить сериализацию таблицы значений в строку JSON:
// Формирование строки JSON из ТаблицыЗначений
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ТаблицаЗначений);
СтрокаJSON = ЗаписьJSON.Закрыть();
При этом подходе платформа автоматически добавляет в структуру JSON служебные маркеры типов (например, #type и #value) и сохраняет уникальные идентификаторы ссылок. На стороне сервера восстановить исходную таблицу значений с сохранением всех ссылочных объектов можно с помощью парного метода:
// Восстановление ТаблицыЗначений из строки JSON на сервере
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
ТаблицаЗначенийСервер = СериализаторXDTO.ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Важный момент: при десериализации данных со ссылочными типами необходимо использовать именно СериализаторXDTO.ПрочитатьJSON, а не стандартный метод ПрочитатьJSON. Стандартный метод вернет объект типа Структура или Соответствие, тогда как сериализатор XDTO воссоздаст полноценные объекты ссылок 1С.
Если требуется получить чистый, легко читаемый JSON без служебных метаданных XDTO или передать данные во внешнюю систему, оптимальным решением является преобразование таблицы значений в массив структур. Каждая строка таблицы преобразуется в отдельную структуру, где ключами выступают имена колонок.
Разберем по шагам реализацию преобразования:
ЗаписьJSON.Посмотрим на пример программного кода:
МассивСтрок = Новый Массив;
Для Каждого Стр Из ТаблицаЗначений Цикл
СтруктураСтроки = Новый Структура;
Для Каждого Колонка Из ТаблицаЗначений.Колонки Цикл
Значение = Стр[Колонка.Имя];
// При необходимости преобразуем ссылку в строку GUID
Если ЗначениеЗаполнено(Значение) И ОбщегоНазначенияКлиентСервер.ЭтоСсылка(ТипЗнч(Значение)) Тогда
СтруктураСтроки.Вставить(Колонка.Имя, Строка(Значение.УникальныйИдентификатор()));
Иначе
СтруктураСтроки.Вставить(Колонка.Имя, Значение);
КонецЕсли;
КонецЦикла;
МассивСтрок.Добавить(СтруктураСтроки);
КонецЦикла;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивСтрок);
РезультатJSON = ЗаписьJSON.Закрыть();
Если цель заключается исключительно в передаче данных между контекстами клиента и сервера внутри сеанса 1С (без необходимости интеграции со сторонними сервисами), преобразование в JSON или XML часто является избыточным. Наиболее производительный способ — использование механизма временного хранилища.
Проанализируем пример передачи данных:
// На клиенте (в толстом клиенте или обычном приложении)
АдресХранилища = ПоместитьВоВременноеХранилище(ТаблицаЗначений, УникальныйИдентификатор);
// Передаем только строку адреса в серверную процедуру
ВыполнитьОбработкуНаСервере(АдресХранилища);
На сервере значение извлекается одной строкой:
// В серверном контексте
ТаблицаЗначений = ПолучитьИзВременногоХранилища(АдресХранилища);
УдалитьИзВременногоХранилища(АдресХранилища);
Механизм временного хранилища выполняет передачу во внутреннем бинарном формате платформы, что исключает накладные расходы на формирование, передачу и разбор текстовых данных.
Выясним причину возможных ошибок при работе с табличными данными в разных режимах работы приложения:
ТаблицаЗначений полностью доступен в контексте клиента. Его можно сериализовать в JSON, передавать во временное хранилище или напрямую передавать параметром в серверные вызовы.ТаблицаЗначений на клиенте недоступен. Данные таблицы формы представлены объектом ДанныеФормыКоллекция. Для преобразования коллекции формы в таблицу значений необходимо использовать серверный метод ДанныеФормыВЗначение:
&НаСервере
Процедура ОбработатьДанныеФормыНаСервере()
ТаблицаЗначений = ДанныеФормыВЗначение(Объект.ТабличнаяЧасть1, Тип("ТаблицаЗначений"));
// Дальнейшая работа с объектом ТаблицаЗначений
КонецПроцедуры
Подведем итог и выберем оптимальный вариант под конкретные задачи:
ПоместитьВоВременноеХранилище.СериализаторXDTO.ЗаписатьJSON.