Как распарсить и загрузить JSON в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В платформе 1С:Предприятие 7.7 отсутствует нативная поддержка формата JSON, в отличие от старших версий платформы 1С 8. При этом интеграции с современными веб-сервисами, маркетплейсами и внешними базами данных требуют регулярного приема и разбора данных в этом стандарте. Рассмотрим доступные и эффективные способы парсинга JSON в среде 1С 7.7, разберем готовый программный код на базе системных скриптов, а также проанализируем узкие места и альтернативные варианты реализации.

Особенности и сложности работы с JSON в 1С 7.7

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

  1. Проблема кодировок: Стандарт JSON базируется на кодировке UTF-8, тогда как платформа 1С 7.7 по умолчанию работает с кодировкой Windows-1251 (ANSI). При прямом чтении файла через стандартный объект Текст кириллические символы превращаются в нечитаемые символы («кракозябры»). Кроме того, строки могут содержать экранированные Unicode-последовательности вида \uXXXX.
  2. Ограничения стандартных коллекций: Базовый объект СписокЗначений позволяет хранить вложенные структуры, однако он не предназначен для быстрой выборки и поиска по составным ключам. Стандартная ТаблицаЗначений также осуществляет поиск методом полного перебора, что создает задержки при обработке массивов с тысячами записей.
  3. Разрядность окружения: Платформа 1С 7.7 является 32-битным приложением, что накладывает ограничения на объем потребляемой оперативной памяти при загрузке многомегабайтных пакетов данных.

Решение через MSScriptControl (JScript) с выгрузкой в СписокЗначений

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

Разберем по шагам реализацию данного механизма. Сначала подготовим инициализирующий код, который внедряет вспомогательные функции JScript для безопасного обхода структуры данных:


Перем JSON_ctrl;

Процедура JSON_Init()
    Если ПустоеЗначение(JSON_ctrl) = 0 Тогда
        Возврат;
    КонецЕсли;
    
    JSON_ctrl = СоздатьОбъект("MSScriptControl.ScriptControl");
    JSON_ctrl.Language = "jscript";
    
    код = "
    | function parseJSON(strJSON) {
    |     var tmpFunc = (new Function('return(' + strJSON + ');'))();
    |     return(tmpFunc);
    | }
    |
    | function aGet(Array, index) {
    |     return(Array[index]);
    | }
    |
    | function oKey(Obj, index) {
    |     var size = 0, key;
    |     for (key in Obj) {
    |         if (size == index) break;
    |         if (Obj.hasOwnProperty(key)) size++;
    |     }
    |     return(key);
    | }
    |
    | function oValueByKey(Obj, key) {
    |     return(Obj[key]);
    | }
    |
    | function oSize(Obj) {
    |     var size = 0, key;
    |     for (key in Obj) {
    |         if (Obj.hasOwnProperty(key)) size++;
    |     }
    |     return(size);
    | }
    |
    | function eType(Element) {
    |     if (Element instanceof Array) {
    |         return('array');
    |     } else if (Object.prototype.toString.call(Element) === '[object Array]') {
    |         return('array');
    |     } else {
    |         return(typeof(Element));
    |     }
    | }
    |";
    JSON_ctrl.AddCode(код);
КонецПроцедуры

Теперь рассмотрим рекурсивную функцию jsonВСписок, которая преобразует разобранный JScript-объект в иерархию стандартных объектов СписокЗначений платформы 1С 7.7:


Функция jsonВСписок(obj)
    сп = СоздатьОбъект("СписокЗначений");
    ТипОбъекта = JSON_ctrl.run("eType", obj);
    
    Если ТипОбъекта = "object" Тогда
        КоличествоЭлементов = JSON_ctrl.run("oSize", obj);
        Для н = 0 По КоличествоЭлементов - 1 Цикл
            Ключ = JSON_ctrl.run("oKey", obj, н);
            Значение = JSON_ctrl.run("oValueByKey", obj, Ключ);
            ТипЗнач = JSON_ctrl.run("eType", Значение);
            
            Если Найти("number, string, boolean", ТипЗнач) > 0 Тогда
                сп.ДобавитьЗначение(Значение, Ключ);
            ИначеЕсли Найти("object, array", ТипЗнач) > 0 Тогда
                сп.ДобавитьЗначение(jsonВСписок(Значение), Ключ);
            КонецЕсли;
        КонецЦикла;
        
    ИначеЕсли ТипОбъекта = "array" Тогда
        Для н = 0 По obj.length - 1 Цикл
            Значение = JSON_ctrl.run("aGet", obj, н);
            ТипЗнач = JSON_ctrl.run("eType", Значение);
            
            Если Найти("number, string, boolean", ТипЗнач) > 0 Тогда
                сп.ДобавитьЗначение(Значение, СокрЛП(Строка(н)));
            ИначеЕсли Найти("object, array", ТипЗнач) > 0 Тогда
                сп.ДобавитьЗначение(jsonВСписок(Значение), СокрЛП(Строка(н)));
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
    Возврат сп;
КонецФункции

Функция сз_FromJSON(стр) Экспорт
    JSON_Init();
    obj = JSON_ctrl.run("parseJSON", стр);
    сз = jsonВСписок(obj);
    Возврат сз;
КонецФункции

Подводные камни использования MSScriptControl

Обратим внимание на нюансы эксплуатации данного подхода в промышленной среде:

  1. Регистрация библиотеки в 64-битных ОС: MSScriptControl.ScriptControl — это 32-битный компонент. В современных версиях Windows он может отсутствовать в реестре. Для корректной работы требуется выполнить ручную регистрацию библиотеки msscript.ocx через команду regsvr32 %windir%\SysWOW64\msscript.ocx.
  2. Ошибки парсинга при наличии переносов строк: Конструкция new Function('return(' + strJSON + ');') чувствительна к неэкранированным символам перевода каретки и табуляции в значениях полей. Перед отправкой строки в parseJSON необходимо экранировать служебные символы.

Альтернативные подходы к обработке JSON

Если производительности или возможностей скрипт-контрола недостаточно, проанализируем другие надежные инструменты:

  1. Парсинг через объект htmlfile (MSHTML):
    Вместо MSScriptControl можно подключить COM-объект htmlfile. Данный компонент эмулирует браузерное окружение и поддерживает вызов нативного метода JSON.parse(), что обеспечивает более высокую скорость и безопасность при разборе текста по сравнению с eval.
  2. Чтение кодировки UTF-8 через ADODB.Stream:
    Если JSON поступает из файла, категорически не рекомендуется читать его через объект Текст. Используем объект ADODB.Stream, задав свойство кодировки utf-8. Это позволит считать файл без искажения кириллицы и передать готовую ANSI-строку на вход парсеру.
  3. Выгрузка в объект ИндексированнаяТаблица (библиотека 1С++):
    Если результирующие данные представляют собой массив однотипных объектов (например, строки накладной или каталог номенклатуры), перенос данных во вложенные списки значений усложняет дальнейшую работу. Оптимально переписать функцию обхода так, чтобы результат помещался в объект ИндексированнаяТаблица из надстройки 1С++. Это обеспечит построение составных индексов и мгновенный поиск элементов по ключам без последовательного сканирования строк.
  4. Специализированные внешние компоненты (ВК) и .NET-мосты:
    Для тяжелых пакетов JSON (размером в десятки и сотни мегабайт) целесообразно использовать готовые C++ внешние компоненты либо подключение CLR/.NET-библиотек. Они осуществляют разбор данных в скомпилированном машинном коде, исключая накладные расходы COM-интерфейсов и снижая нагрузку на память процесса 1cv7s.exe.
← На главную