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

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

При разработке в среде 1С:Предприятие 8.3 часто возникает задача сохранения сложных данных (например, структуры, соответствия или массива) в один текстовый реквизит. Особенно остро этот вопрос встает при адаптации типовых конфигураций (например, 1С:УНФ, 1С:БП или 1С:КА) через механизм расширений, когда мы ограничены в возможности добавлять новые реквизиты в таблицы базы данных. В таких случаях программисты часто используют "халявные" текстовые поля неограниченной длины (например, поле Содержание в табличной части запасов или товаров), упаковывая туда целый набор пользовательских колонок.

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

Почему стоит отказаться от метода ЗначениеВСтрокуВнутр()

Исторически в системе 1С:Предприятие существовал простой метод ЗначениеВСтрокуВнутр() (и парный ему ЗначениеИзСтрокиВнутр()). Он позволял сериализовать практически любой объект базы данных или коллекции в системную строку. Однако в современной разработке использовать его крайне не рекомендуется по следующим причинам:

  1. Закрытый формат данных. Строка, полученная этим методом, имеет недокументированный внутренний формат платформы 1С. В случае обновления платформы формат может незначительно измениться, что приведет к невозможности прочитать ранее сохраненные данные.
  2. Отсутствие поддержки на клиенте. Этот метод не работает в веб-клиенте и накладывает жесткие ограничения на архитектуру управляемого приложения.
  3. Потеря читаемости. Данные внутри такой строки невозможно проанализировать или скорректировать сторонними средствами (например, при интеграции или отладке).

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

Решение №1: Сериализация в формат JSON на клиенте (Рекомендуемый способ)

Использование формата JSON — это современный стандарт для работы с коллекциями данных в 1С. Главное преимущество данного подхода заключается в том, что сериализация и десериализация JSON полностью поддерживаются на стороне клиента (в тонком и веб-клиентах). Это позволяет мгновенно упаковывать данные интерактивных колонок при изменении строк табличной части без единого серверного вызова, сохраняя высокую отзывчивость интерфейса.

Проанализируем два варианта реализации этого метода в зависимости от версии вашей платформы.

Вариант А: Для платформы 1С:Предприятие 8.3.23 и выше

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

Код для упаковки структуры в строку на клиенте:


// Формируем структуру с данными колонок
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("СкидкаПроцент", 15);
СтруктураДанных.Вставить("СпецУсловие", Истина);
СтруктураДанных.Вставить("КомментарийМенеджера", "Срочная доставка");

// Укладываем структуру в строку JSON одним методом
СтрокаРеквизита = ЗаписатьЗначениеJSON(СтруктураДанных);

Код для распаковки строки обратно в структуру:


// Восстанавливаем структуру из сохраненной строки
Если Не ПустаяСтрока(СтрокаРеквизита) Тогда
    СтруктураДанных = ПрочитатьЗначениеJSON(СтрокаРеквизита);
    // Теперь мы можем обратиться к свойствам: СтруктураДанных.СкидкаПроцент
КонецЕсли;

Вариант Б: Для версий платформы от 8.3.6 до 8.3.22

Если вы работаете на более ранних релизах платформы 1С 8.3, то для работы с JSON потребуется классический синтаксис с использованием специализированных объектов ЗаписьJSON и ЧтениеJSON.

Код для упаковки структуры на клиенте:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

// Записываем структуру в поток JSON
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);

// Получаем итоговую строку
СтрокаРеквизита = ЗаписьJSON.Закрыть();

Код для распаковки структуры на клиенте:


ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаРеквизита);

// Считываем структуру из потока
СтруктураДанных = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

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

Решение №2: Использование ХранилищаЗначения и XML-сериализации

Еще один рабочий способ заключается в оборачивании нашей структуры в объект ХранилищеЗначения с последующим его преобразованием в XML-строку. Этот метод часто используется разработчиками "по старой памяти", но он имеет один существенный недостаток.

Важное ограничение: Конструктор объекта ХранилищеЗначения доступно только на сервере. Это означает, что при каждом изменении данных в строке табличной части вам придется выполнять вызов сервера (даже если он будет безконтекстным). При медленном интернет-соединении или высокой нагрузке на сервер это приведет к заметным "микрофризам" интерфейса для конечного пользователя.

Давайте посмотрим на программную реализацию этого метода. Код упаковки структуры на сервере:


&НаСервереБезКонтекста
Функция УпаковатьСтруктуруВСтроку(Знач СтруктураДанных) Экспорт
    
    // Помещаем структуру в ХранилищеЗначения
    Хранилище = Новый ХранилищеЗначения(СтруктураДанных);
    
    // Сериализуем хранилище в строку XML
    Возврат XMLСтрока(Хранилище);
    
КонецФункции

Код восстановления структуры из XML-строки на сервере:


&НаСервереБезКонтекста
Функция РаспаковатьСтруктуруИзСтроки(Знач СтрокаXML) Экспорт
    
    Если ПустаяСтрока(СтрокаXML) Тогда
        Возврат Новый Структура;
    КонецЕсли;
    
    // Восстанавливаем ХранилищеЗначения из XML-строки
    Хранилище = XMLЗначение(Тип("ХранилищеЗначения"), СтрокаXML);
    
    // Извлекаем саму структуру
    Возврат Хранилище.Получить();
    
КонецФункции

Этот способ надежен с точки зрения сохранения сложных типов данных 1С (которые JSON может не поддерживать напрямую, например, ссылки на элементы справочников или перечисления), но платой за эту универсальность становится необходимость постоянных обращений к серверу. Для отслеживания таких ссылок в сериализованных данных подойдёт подсистема для поддержки ссылочной целостности в реквизитах типа ХранилищеЗначений.

Решение №3: Готовые методы в конфигурациях на базе БСП

Если вы ведете разработку в типовой конфигурации (например, УНФ, ERP или Бухгалтерия), то в вашем распоряжении уже есть Библиотека Стандартных Подсистем (БСП). Разработчики БСП предусмотрели готовые общие модули для сериализации данных, чтобы избавить вас от необходимости писать вспомогательный код вручную.

Для быстрого сворачивания структуры вы можете использовать функции серверных общих модулей общего назначения:


// Сериализация структуры силами БСП
СтрокаРеквизита = ОбщегоНазначения.ЗначениеВСтрокуJSON(СтруктураДанных);

// Обратная десериализация силами БСП
СтруктураДанных = ОбщегоНазначения.ЗначениеИзСтрокиJSON(СтрокаРеквизита);

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

Подведем итоги и выберем оптимальный вариант

Выяснив сильные и слабые стороны каждого подхода, мы можем составить простую рекомендацию:

← На главную