Как загрузить и обработать большой файл JSON в 1С 7.7

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

Работа с современными форматами обмена данными, такими как JSON, в среде 1С:Предприятие 7.7 всегда сопряжена с определенными трудностями. Платформа создавалась в эпоху доминирования XML и текстовых файлов фиксированной длины, поэтому встроенных средств для парсинга JSON в ней нет. Когда объем данных достигает значительных размеров (например, 10–12 МБ), стандартные подходы через MSScriptControl начинают вызывать падение системы или работают неприемлемо долго. В этой статье мы подробно разберем, как эффективно решить задачу загрузки «тяжелых» JSON-файлов, избежав утечек памяти и обеспечив высокую скорость обработки.

Проблема 1: Ограничения MSScriptControl и падение платформы

Рассмотрим ситуацию, когда при попытке передать большую строку в объект MSScriptControl.ScriptControl платформа 1С 7.7 просто закрывается без объяснения причин. Это происходит из-за ограничений на передачу данных через COM-интерфейс и особенностей выделения памяти под строки в движке JScript. Проанализируем типичный ошибочный сценарий: программист считывает файл в переменную 1С, а затем пытается выполнить ScriptControl.Eval(СтрокаСДанными). При объеме в 10 МБ строка дублируется в памяти несколько раз, что приводит к критической ошибке.

Чтобы избежать этой ситуации, мы применим стратегию «чтения внутри скрипта». Вместо того чтобы передавать мегабайты текста из 1С в ScriptControl, мы передадим только путь к файлу, а чтение и парсинг доверим самому объекту JScript.

Разберем по шагам реализацию этого метода:


Функция РаспарситьJSON(ПутьКФайлу)
    Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
    Скрипт.Language = "JScript";
    
    // Добавляем вспомогательный код на JavaScript
    ТекстСкрипта = "
    |function parseJSONFile(path) {
    |    var fso = new ActiveXObject('Scripting.FileSystemObject');
    |    var ts = fso.OpenTextFile(path, 1);
    |    var str = ts.ReadAll();
    |    ts.Close();
    |    // Используем JSON.parse вместо eval для безопасности и скорости
    |    // Если JSON.parse недоступен (старая ОС), используем eval
    |    try {
    |        return JSON.parse(str);
    |    } catch(e) {
    |        return eval('(' + str + ')');
    |    }
    |}";
    
    Скрипт.AddCode(ТекстСкрипта);
    ОбъектJSON = Скрипт.Run("parseJSONFile", ПутьКФайлу);
    Возврат ОбъектJSON;
КонецФункции

Этот подход значительно стабильнее, так как 1С 7.7 выступает лишь в роли координатора, не перегоняя через свои внутренние буферы огромные строковые значения.

Проблема 2: Кодировка UTF-8 и кириллица

Большинство JSON-файлов приходят в кодировке UTF-8. 1С 7.7 работает с кодировкой Windows-1251. Если просто прочитать файл, вместо русских букв мы получим нечитаемые символы («кракозябры»). Рассмотрим, как можно решить эту проблему.

Самый простой, но медленный способ — посимвольный перебор строки на языке 1С. Рассмотрим этот алгоритм для понимания логики процесса:


Функция ПреобразоватьИзУТФ8(Стр)
    Длина = СтрДлина(Стр);
    Итог = "";
    Н = 1;
    Пока Н <= Длина Цикл
        Знак = Сред(Стр, Н, 1);
        Код = КодСимв(Знак);
        Если Код < 128 Тогда
            Итог = Итог + Знак;
        ИначеЕсли Код >= 192 Тогда
            Н = Н + 1;
            Знак2 = Сред(Стр, Н, 1);
            Код2 = КодСимв(Знак2);
            Если Код = 208 Тогда
                Если Код2 = 129 Тогда Итог = Итог + "Ё";
                Иначе Итог = Итог + Симв(КодСимв("А") + Код2 - 144);
                КонецЕсли;
            ИначеЕсли Код = 209 Тогда
                Если Код2 = 145 Тогда Итог = Итог + "ё";
                Иначе Итог = Итог + Симв(КодСимв("р") + Код2 - 128);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        Н = Н + 1;
    КонецЦикла;
    Возврат Итог;
КонецФункции

Важное замечание: Для файлов размером в 11 МБ такой перебор будет работать крайне долго (десятки минут). Проанализируем более производительный вариант с использованием объекта ADODB.Stream, который выполняет перекодировку на уровне системных библиотек мгновенно:


Функция ПрочитатьФайлВ1251(Путь)
    Stream = СоздатьОбъект("ADODB.Stream");
    Stream.Type = 2; // Text
    Stream.Charset = "utf-8";
    Stream.Open();
    Stream.LoadFromFile(Путь);
    Текст = Stream.ReadText();
    Stream.Close();
    Возврат Текст;
КонецФункции

Проблема 3: Скорость обработки сложных структур

Если файл успешно прочитан и распарсен в объект JScript, перед нами встает задача — как вытащить из него данные в 1С? Обращение к свойствам объекта через точку Объект.Property работает, но если в файле тысячи элементов, это будет медленно.

Рассмотрим альтернативное решение — использование внешней компоненты 1sqlite. Она позволяет загрузить JSON во временную базу данных SQLite прямо в памяти и работать с ним с помощью SQL-запросов. Это «термоядерный» по скорости метод. Выясним, как это реализовать:

  1. Загружаем библиотеку 1sqlite.dll.
  2. Создаем базу данных в памяти (:memory:).
  3. Используем расширение json1 для разбора текста.

Посмотрим на пример SQL-запроса, который выберет данные из вложенного массива JSON:


SELECT
    json_extract(value, '$.id') as ID,
    json_extract(value, '$.title') as Title
FROM json_each(?)

Здесь json_each — это функция, которая разворачивает массив JSON в плоскую таблицу. Скорость обработки файла в 11 МБ при таком подходе составит секунды, а не десятки минут.

Рекомендации по выбору инструмента

Подведем итог и выберем оптимальный инструмент в зависимости от условий задачи:

Используя приведенные выше методы, мы сможем эффективно интегрировать старые системы на базе 1С 7.7 с современными веб-сервисами и API, не опасаясь больших объемов данных.

← На главную