Как прочитать массив в формате JSON в 1С и избежать распространенных ошибок

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

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

Выясняем причину: почему встроенный парсер выдает ошибку?

Когда мы получаем тело HTTP-ответа, оно представляет собой обычную строку. Попытка прочитать массив объектов стандартными методами иногда приводит к тому, что на выходе мы получаем пустую коллекцию или ошибку разбора. Проанализируем типичные причины этой проблемы:

  1. Несоответствие ключей в коде и в JSON-строке. Это банальная, но очень частая ошибка. Разработчик считывает JSON с ключами izmer и resurs, а в цикле пытается обратиться к свойствам Kod или Imy. В результате 1С возвращает пустое значение или ошибку отсутствия свойства.
  2. Запрещенные символы в именах ключей. В JSON ключи объектов могут содержать пробелы, дефисы, начинаться с цифр или быть пустыми. Однако в 1С свойства объекта Структура обязаны соответствовать правилам идентификаторов (не могут начинаться с цифры, содержать пробелы и спецсимволы). Если парсер пытается записать ключ "1_property" в структуру, происходит сбой.
  3. Проблема BOM (Byte Order Mark). В начале полученной по HTTP строки могут находиться невидимые символы разметки кодировки. Визуально в отладчике строка выглядит нормально, но метод УстановитьСтроку() объекта ЧтениеJSON спотыкается на первом же символе, так как ожидает открывающую скобку [.

Решение 1: Стандартное чтение массива структур

Если вы уверены в качестве входящих данных и имена ключей в JSON гарантированно соответствуют правилам именования переменных в 1С, мы можем использовать стандартное чтение. Функция ПрочитатьJSON автоматически преобразует квадратные скобки JSON [...] в объект типа Массив, а фигурные скобки {...} — в Структура.

Рассмотрим пример кода для чтения такого массива:


// Предположим, что в переменной Джисон у нас хранится строка:
// [{"izmer": "ОС", "resurs": "Да"}, {"izmer": "Материал", "resurs": "Да"}]

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

// Второй параметр "Ложь" указывает, что объекты JSON нужно преобразовывать в Структуры 1С
МассивДжи = ПрочитатьJSON(ЧтениеДЖ, Ложь);
ЧтениеДЖ.Закрыть();

// Теперь мы можем обойти полученный массив в цикле
Для Каждого ТекущийЭлемент Из МассивДжи Цикл
    // Обратите внимание: имена свойств чувствительны к регистру и должны точно совпадать с ключами JSON
    ЗначениеИзмерения = ТекущийЭлемент.izmer;
    ЗначениеРесурса = ТекущийЭлемент.resurs;
    
    // Выполняем полезные действия с данными
    Сообщить("Измерение: " + ЗначениеИзмерения + ", Ресурс: " + ЗначениеРесурса);
КонецЦикла;

Решение 2: Использование «Соответствия» вместо «Структуры» (Рекомендуемый способ)

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

Разберем по шагам, как это реализовать:


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

// Указываем Истина во втором параметре для чтения в Соответствие
МассивДжи = ПрочитатьJSON(ЧтениеДЖ, Истина);
ЧтениеДЖ.Закрыть();

Для Каждого ТекущееСоответствие Из МассивДжи Цикл
    // Доступ к значениям Соответствия осуществляется через метод Получить()
    ЗначениеИзмерения = ТекущееСоответствие.Получить("izmer");
    ЗначениеРесурса = ТекущееСоответствие.Получить("resurs");
    
    Сообщить("Измерение: " + ЗначениеИзмерения + ", Ресурс: " + ЗначениеРесурса);
КонецЦикла;

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

Дополнительные важные нюансы при работе с JSON в 1С

1. Очистка строки от BOM (невидимых символов)

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


// Находим индекс начала реального JSON-массива
ИндексНачала = СтрНайти(Джисон, "[");
Если ИндексНачала > 1 Тогда
    // Обрезаем все лишние невидимые символы до открывающей скобки
    Джисон = Сред(Джисон, ИндексНачала);
КонецЕсли;

2. Потоковое чтение больших массивов данных

Если ваш JSON-массив содержит десятки тысяч элементов, стандартный метод ПрочитатьJSON загрузит их все в оперативную память одновременно, что может вызвать переполнение памяти или сильное замедление работы системы. В таких ситуациях мы применяем последовательное (потоковое) чтение токенов.

Проанализируем пример потокового обхода крупного массива:


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

// Читаем до тех пор, пока не встретим начало массива
Пока ЧтениеДЖ.Прочитать() Цикл
    Если ЧтениеДЖ.ТипУзла = ТипУзлаJSON.НачалоМассива Тогда
        Прервать;
    КонецЕсли;
КонецЦикла;

// Начинаем перебор элементов внутри массива
Пока ЧтениеДЖ.Прочитать() Цикл
    // Если встретили конец массива, прекращаем чтение
    Если ЧтениеДЖ.ТипУзла = ТипУзлаJSON.КонецМассива Тогда
        Прервать;
    КонецЕсли;
    
    // Если встретили начало объекта, считываем только его в структуру
    Если ЧтениеДЖ.ТипУзла = ТипУзлаJSON.НачалоОбъекта Тогда
        // Считываем один объект, и указатель автоматически сдвигается дальше
        ТекущийЭлемент = ПрочитатьJSON(ЧтениеДЖ, Ложь);
        
        // Сразу обрабатываем данные, не накапливая их в памяти
        ОбработатьДанныеЭлемента(ТекущийЭлемент);
    КонецЕсли;
КонецЦикла;

ЧтениеДЖ.Закрыть();

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

3. Проблема строгого соответствия стандарту (Strict Mode)

Обратите внимание, что парсер 1С очень чувствителен к валидности JSON. Например, лишняя запятая перед закрывающей скобкой вида [{"а": 1},] приведет к ошибке чтения, хотя современные веб-браузеры легко игнорируют подобные недочеты. Всегда проверяйте валидность входящего потока перед обработкой в 1С.

← На главную