Как эффективно работать с JSON в 1С 7.7: создание и разбор данных без встроенных инструментов?

Программист 1С v7.7 Торговля и дистрибуция
← К списку

Работа с форматом JSON в 1С 7.7 может показаться непростой задачей, учитывая отсутствие встроенных механизмов для его обработки, которые доступны в более поздних версиях платформы. Однако, не стоит отчаиваться! Мы вместе разберем несколько проверенных подходов, которые позволят нам успешно создавать и парсить JSON-структуры, используя как стандартные объекты 1С 7.7, так и внешние компоненты.

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

1. Формирование JSON-строки с использованием стандартных объектов 1С 7.7

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

Подготовка данных с помощью объекта СписокЗначений

Объект СписокЗначений является очень гибким инструментом в 1С 7.7, позволяющим создавать как простые списки, так и имитировать структуры с ключами (при использовании второго параметра метода ДобавитьЗначение). Мы можем использовать его для построения иерархических JSON-объектов и массивов.

  1. Создание простого JSON-объекта:

    Начнем с простого примера, где нам нужно создать JSON-объект с несколькими парами "ключ-значение". Мы будем использовать один СписокЗначений, где каждый элемент будет представлять собой пару "значение-ключ".

    
    Процедура СобратьПростойJSON()
        // Создаем основной СписокЗначений, который будет корневым JSON-объектом
        СЗ = СоздатьОбъект("СписокЗначений");
    
        // Добавляем элементы в СписокЗначений, указывая ключ вторым параметром
        СЗ.ДобавитьЗначение("001", "set_code");
        СЗ.ДобавитьЗначение("НекоеЗначение", "description");
        СЗ.ДобавитьЗначение(12345, "quantity");
    
        // Предполагаем, что функция ЗначениеВJSON() доступна и преобразует
        // СписокЗначений в JSON-строку.
        JSONСтрока = ЗначениеВJSON(СЗ);
    
        // Теперь переменная JSONСтрока содержит нашу JSON-структуру
        // Например: {"set_code":"001", "description":"НекоеЗначение", "quantity":12345}
    КонецПроцедуры
    

    В этом примере мы видим, как каждый вызов ДобавитьЗначение() с двумя параметрами формирует элемент JSON-объекта, где второй параметр становится ключом, а первый — его значением.

  2. Создание JSON-объекта с вложенным массивом объектов:

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

    
    Процедура СобратьСложныйJSON()
        // Создаем основной СписокЗначений, представляющий корневой JSON-объект
        СЗ = СоздатьОбъект("СписокЗначений");
    
        // Создаем отдельные СпискиЗначений для каждого вложенного объекта в массиве "items"
        СзИт1 = СоздатьОбъект("СписокЗначений");
        СзИт1.ДобавитьЗначение("W", "marketplace");
        СзИт1.ДобавитьЗначение(1223423, "article");
        СзИт1.ДобавитьЗначение("3243243", "article_post");
        СзИт1.ДобавитьЗначение(3242354435, "barcode");
    
        СзИт2 = СоздатьОбъект("СписокЗначений");
        СзИт2.ДобавитьЗначение("O", "marketplace");
        СзИт2.ДобавитьЗначение(234324324, "article");
        СзИт2.ДобавитьЗначение("КОД-Н2", "article_post");
        СзИт2.ДобавитьЗначение(3243234, "barcode");
    
        // Создаем СписокЗначений, который будет представлять JSON-массив
        // Он будет содержать вложенные объекты (СзИт1, СзИт2)
        СзМассивЭлементов = СоздатьОбъект("СписокЗначений");
        СзМассивЭлементов.ДобавитьЗначение(СзИт1); // Добавляем первый вложенный объект
        СзМассивЭлементов.ДобавитьЗначение(СзИт2); // Добавляем второй вложенный объект
    
        // Добавляем основные элементы в корневой JSON-объект
        СЗ.ДобавитьЗначение("001", "set_code");
        // Вторым элементом корневого объекта будет наш массив
        СЗ.ДобавитьЗначение(СзМассивЭлементов, "items");
    
        // Повторим операцию для создания второго корневого объекта, если это массив объектов
        // Это демонстрирует, как мы можем добавить еще один такой же блок
        // СЗ.ДобавитьЗначение("002", "set_code");
        // СЗ.ДобавитьЗначение(СзМассивЭлементов, "items"); // Здесь мы повторно используем тот же массив
    
        // Сериализуем итоговую структуру
        JSONСтрока = ЗначениеВJSON(СЗ);
    
        // JSONСтрока будет содержать структуру, аналогичную:
        // {
        //   "set_code": "001",
        //   "items": [
        //     {"marketplace": "W", "article": 1223423, "article_post": "3243243", "barcode": 3242354435},
        //     {"marketplace": "O", "article": 234324324, "article_post": "КОД-Н2", "barcode": 3243234}
        //   ]
        // }
    КонецПроцедуры
    

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

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

2. Использование внешних компонентов для обработки JSON (MSScriptControl.ScriptControl)

Для более сложной работы с JSON, особенно при необходимости парсинга входящих JSON-строк или обработки больших объемов данных, стандартных средств 1С 7.7 может быть недостаточно. В таких случаях мы рекомендуем обратить внимание на использование внешних COM-объектов, таких как MSScriptControl.ScriptControl.

Почему MSScriptControl.ScriptControl?

Объект MSScriptControl.ScriptControl позволяет нам выполнять JavaScript (JScript) код непосредственно из 1С. Поскольку JSON является подмножеством JavaScript, это дает нам мощный инструмент для работы с ним:

Разбираем по шагам работу с MSScriptControl.ScriptControl:

  1. Инициализация ScriptControl:

    Первым делом нам необходимо создать экземпляр объекта MSScriptControl.ScriptControl. Мы можем добавить его в глобальный контекст или использовать локально в процедурах.

    
    // Пример создания объекта
    Перем ScriptCtrl;
    
    Процедура ИнициализироватьScriptControl()
        Попытка
            ScriptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl");
            ScriptCtrl.Language = "JScript"; // Указываем, что будем использовать JScript
        Исключение
            Сообщить("Ошибка инициализации MSScriptControl.ScriptControl: " + ОписаниеОшибки());
            Возврат;
        КонецПопытки;
    КонецПроцедуры
    
  2. Добавление вспомогательных функций (при необходимости):

    Для удобства работы, особенно при парсинге, можно добавить в ScriptControl собственные JavaScript-функции. Например, для безопасного парсинга JSON.

    
    // Пример добавления функции для парсинга JSON
    Процедура ДобавитьФункцииJSON()
        ИнициализироватьScriptControl(); // Убедимся, что ScriptCtrl создан
        Если ScriptCtrl.Язык = "JScript" Тогда
            ScriptCtrl.AddCode("
                function parseJsonSafe(jsonString) {
                    try {
                        return JSON.parse(jsonString);
                    } catch (e) {
                        return null; // Возвращаем null в случае ошибки парсинга
                    }
                }
                function stringifyJson(obj) {
                    return JSON.stringify(obj);
                }
            ");
        КонецЕсли;
    КонецПроцедуры
    
  3. Парсинг JSON-строки:

    После инициализации и добавления необходимых функций, мы можем передать JSON-строку для парсинга. Результатом будет JavaScript-объект, с которым мы можем работать через методы ScriptControl.

    
    Процедура РазобратьJSONСтроку(JSONТекст)
        Если ScriptCtrl.Пусто() Тогда
            ДобавитьФункцииJSON();
        КонецЕсли;
    
        // Выполняем JavaScript-функцию parseJsonSafe
        JSОбъект = ScriptCtrl.Run("parseJsonSafe", JSONТекст);
    
        Если JSОбъект = Неопределено Тогда
            Сообщить("Ошибка парсинга JSON-строки.");
            Возврат;
        КонецЕсли;
    
        // Теперь мы можем получать значения из JSОбъекта
        // Например, получить значение по ключу "set_code"
        Попытка
            SetCode = ScriptCtrl.Eval("JSОбъект.set_code");
            Сообщить("SetCode: " + SetCode);
        Исключение
            Сообщить("Ключ 'set_code' не найден или ошибка доступа.");
        КонецПопытки;
    
        // Для получения элементов массива или вложенных объектов
        // потребуется более сложная логика, возможно, с использованием
        // вспомогательных функций JScript для обхода структуры.
        // Например, можно написать JScript функцию, которая преобразует
        // JS-объект в строку, а затем разобрать ее в 1С.
    КонецПроцедуры
    

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

3. Работа с большими JSON-файлами и специализированные инструменты (1csqllite)

При работе с очень большими JSON-файлами (например, сотни килобайт или мегабайты), мы можем столкнуться с ограничениями по памяти в 1С 7.7. В отличие от 1С 8.3.6+, где есть потоковые объекты для чтения JSON, в 1С 7.7 такие механизмы отсутствуют. Полная загрузка большого JSON-файла в память 1С может привести к сбоям или крайне медленной работе.

Когда стандартные подходы не справляются

Если MSScriptControl.ScriptControl начинает давать сбои при объеме данных 500+ КБ (как упоминалось в исходной теме), это является сигналом к поиску более специализированных решений.

Представляем 1csqllite

Одним из мощных внешних компонентов, который может помочь в этой ситуации, является 1csqllite. Это внешняя компонента, позволяющая работать с базами данных SQLite, но также имеющая функционал для эффективного парсинга больших JSON-файлов.

Гибридный подход для больших файлов

Учитывая особенности 1csqllite (плоская таблица на выходе), мы можем использовать гибридный подход:

  1. Первичный разбор больших файлов: Используем 1csqllite для быстрого и эффективного парсинга всего JSON-файла в плоскую ТаблицаЗначений.
  2. Обработка вложенных структур: Если нам нужна иерархическая структура из вложенных элементов, которые уже были "сглажены" в таблице, мы можем извлекать эти подстроки и затем использовать MSScriptControl.ScriptControl для их повторного парсинга в иерархический СписокЗначений.

Этот подход позволяет нам совместить высокую производительность 1csqllite для общего разбора с гибкостью MSScriptControl для работы с конкретными вложенными структурами, избегая при этом переполнения памяти 1С.

Дополнительные рекомендации и особенности

Мы рассмотрели несколько эффективных способов работы с JSON в 1С 7.7, от формирования структур с помощью стандартных объектов до использования мощных внешних компонентов для парсинга и обработки больших объемов данных. Выбирайте подход, который наилучшим образом соответствует вашим задачам и объему обрабатываемых данных. Удачи в вашей работе!

← К списку