Как исправить ошибку «Плохой тип переменной» при парсинге JSON в 1С 7.7?

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

При интеграции платформы 1С:Предприятие 7.7 со сторонними веб-сервисами, интернет-магазинами или государственными информационными системами разработчики часто сталкиваются с необходимостью разбора файлов формата JSON. Поскольку в устаревшей платформе 1С 7.7 нет встроенных нативных средств для работы с JSON, стандартным решением является использование внешнего OLE-объекта MSScriptControl.ScriptControl для выполнения JavaScript-кода.

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

Причина ошибки «Плохой тип переменной»

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


// Пример ошибочного вызова
РезультатРазбора = сз_FromJSON(Текст);

Внутри функции разбора выполняется обращение к COM-объекту:


obj = JSON_ctrl.run("parseJSON", стр); // Здесь падает с ошибкой "Плохой тип переменной"

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

Компонента MSScriptControl.ScriptControl — это внешняя библиотека Microsoft Windows, которая общается с 1С на уровне универсальных типов данных (строка, число, дата, булево). Она совершенно ничего не знает о внутреннем устройстве объекта Текст платформы 1С. Когда мы пытаемся передать этот объект в метод run() скрипт-контроля, OLE-интерфейс выдает ошибку несоответствия типов.

Решение: Построчное преобразование объекта в текстовую строку

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


// 1. Создаем объект "Текст" и загружаем файл с диска
ТекстФайлаОбъект = СоздатьОбъект("Текст");
ТекстФайлаОбъект.Открыть(КаталогФС + ФайлФС);

// 2. Считываем содержимое в обычную строковую переменную 1С
СтрокаJSON = "";
Для Ном = 1 По ТекстФайлаОбъект.КоличествоСтрок() Цикл
    СтрокаJSON = СтрокаJSON + ТекстФайлаОбъект.ПолучитьСтроку(Ном) + РазделительСтрок;
EndЦикл;

// 3. Теперь передаем в парсер именно строковое значение
РезультатРазбора = сз_FromJSON(СтрокаJSON);

Такой подход полностью решает проблему несовместимости типов переменных при передаче данных в среду JavaScript.

Проблема переполнения памяти при передаче длинных строк

Решая проблему передачи типов, мы можем столкнуться со следующим ограничением платформы 1С 7.7. При передаче очень длинной строки (размером более 1–2 Мегабайт) из 1С в COM-объект MSScriptControl программа может аварийно завершить работу (вылететь без сообщений об ошибках). Это связано с механизмами выделения памяти под BSTR-строки при COM-взаимодействии.

Для стабильной работы с большими файлами JSON рекомендуется использовать один из двух обходных путей:

  1. Дробление строки (Chunking): Мы можем объявить переменную внутри окружения JavaScript, а затем передавать ее в JS по небольшим частям (например, блоками по 100 000 символов) с помощью метода Eval().
  2. Чтение файла напрямую из JavaScript: Чтобы вообще исключить передачу тяжелых данных между 1С и COM, чтение файла переносят на сторону скрипта. Для этого внутри JS-кода инициализируют объект ADODB.Stream (который отлично поддерживает кодировку UTF-8) или Scripting.FileSystemObject, считывают файл силами операционной системы и сразу же парсят его.

Посмотрим на пример реализации чтения UTF-8 файла силами JavaScript внутри скрипт-контроля:


// Добавляем функцию чтения UTF-8 файла в JS-контекст
JS_Код = "
|function parseJSONFromFile(filePath) {
|    var stream = new ActiveXObject('ADODB.Stream');
|    stream.Type = 2; // Текстовый режим
|    stream.Charset = 'utf-8';
|    stream.Open();
|    stream.LoadFromFile(filePath);
|    var text = stream.ReadText();
|    stream.Close();
|    return JSON.parse(text);
|}";
JSON_ctrl.AddCode(JS_Код);

// Вызываем чтение и разбор файла без передачи строки из 1С
Результат = JSON_ctrl.Run("parseJSONFromFile", КаталогФС + ФайлФС);

Альтернатива №1: Использование объекта htmlfile

Важным нюансом является то, что библиотека MSScriptControl является устаревшей и 32-битной. В современных 64-битных версиях операционных систем Windows (Windows 10 / 11, Windows Server) она часто не зарегистрирована по умолчанию в системе. Чтобы не заниматься регистрацией сторонних библиотек на компьютерах пользователей, можно использовать стандартный системный объект htmlfile, который присутствует в любой Windows.

Объект htmlfile использует под капотом движок Internet Explorer (MSHTML) и позволяет выполнять код JavaScript. Рассмотрим пример парсинга с его помощью:


// Функция разбора JSON через объект htmlfile
Функция РазобратьJSON_HTML(СтрокаJSON)
    HTML = СоздатьОбъект("htmlfile");
    // Включаем поддержку современного режима рендеринга и скриптов
    HTML.write("<meta http-equiv='x-ua-compatible' content='IE=9'>");
    HTML.write("<script>var parsedData = " + СтрокаJSON + ";</script>");
    
    // Получаем разобранный объект обратно в 1С
    Возврат HTML.parentWindow.parsedData;
КонецФункции

Альтернатива №2: Класс-ориентированный подход (КОП) с использованием 1С++

Если в вашей конфигурации 1С 7.7 активно используется внешняя компонента 1С++, наиболее правильным и быстрым решением будет использование классов ООП. В сообществе разработчиков 1С 7.7 создан и успешно применяется класс КОП_JSON.ert.

Для его подключения в заголовочном файле описания классов (defcls.prm) прописывается следующее объявление:


#класс JSON = КОП_JSON.ert
#{
#  Неопределенный ЧтениеJSON(Строка Стр, Число Поз = 1);
#  Строка ЗаписьJSON(Неопределенный Значение, Число ПереносСтрок = 0, Строка Отступ = "");
#}

При использовании класса КОП_JSON соответствие типов данных настраивается автоматически:

Преимуществом такого подхода является полная автономность от системных настроек Windows, отсутствие утечек памяти и высокая скорость работы парсера на стороне встроенного языка 1С.

← На главную