Как правильно разобрать строку JSON в 1С и получить значения свойств?

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

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

Основы десериализации JSON в 1С

Для начала проанализируем базовый механизм чтения. Платформа 1С:Предприятие 8.3 предоставляет объект ЧтениеJSON и глобальную функцию ПрочитатьJSON(). Процесс всегда состоит из трех этапов: инициализация объекта чтения, установка источника данных (строка или файл) и само преобразование в объекты 1С (Структура, Соответствие или Массив).

Рассмотрим пример кода для обработки JSON из вашего вопроса:


// 1. Создаем объект чтения
ЧтениеJson = Новый ЧтениеJSON;

// 2. Загружаем строку в объект (СтрокаJSON - это ваша переменная с текстом)
ЧтениеJson.УстановитьСтроку(СтрокаJSON);

// 3. Читаем данные. По умолчанию функция создает Структуру
Данные = ПрочитатьJSON(ЧтениеJson);

// 4. Обязательно закрываем чтение
ЧтениеJson.Закрыть();

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

Получение данных из массивов

В вашем примере свойство phoneNumbers является массивом (на это указывают квадратные скобки [] в тексте JSON). Это означает, что после десериализации 1С создаст объект типа Массив. Распространенная ошибка — пытаться перебирать в цикле сам корневой объект Данные, надеясь найти в нем свойства. На самом деле, нужно обращаться конкретно к массиву.

Разберем по шагам, как правильно вывести все номера телефонов:


// Прямое обращение к массиву внутри структуры
МассивТелефонов = Данные.phoneNumbers;

// Обход массива в цикле
Для каждого Номер Из МассивТелефонов Цикл
    Сообщить("Найден телефон: " + Номер);
КонецЦикла;

Разбор типичной ошибки: «Поле объекта не обнаружено»

Выясним причину, почему в сообщении 3 возникла ошибка «Поле объекта не обнаружено». Это происходит по двум основным причинам:

  1. Чувствительность к регистру: Хотя ключи Структуры в 1С обычно нечувствительны к регистру, при чтении JSON платформа строго следует стандарту. Если в JSON написано "phoneNumbers", а вы обратитесь к Данные.Phonenumbers, система может выдать ошибку в зависимости от настроек чтения.
  2. Неверная вложенность: Часто разработчики забывают, что данные могут быть упакованы в «конверт». Если JSON выглядит как {"response": {"phoneNumbers": [...]}}, то обращение Данные.phoneNumbers вызовет ошибку, так как нужно обращаться Данные.response.phoneNumbers.

Безопасное чтение свойств через метод Свойство()

Чтобы ваша программа не завершалась аварийно при отсутствии какого-либо ключа в ответе сервера (например, если у клиента нет телефонов и поле phoneNumbers просто отсутствует в JSON), мы рекомендуем использовать метод Свойство(). Это признак хорошего тона в разработке на 1С.

Проанализируем защищенный вариант кода:


Если Данные.Свойство("phoneNumbers") Тогда
    // Мы уверены, что ключ существует
    Телефоны = Данные.phoneNumbers;
    
    // Дополнительная проверка: является ли это массивом
    Если ТипЗнч(Телефоны) = Тип("Массив") Тогда
        Для каждого ТекущийНомер Из Телефоны Цикл
            Сообщить(ТекущийНомер);
        КонецЦикла;
    КонецЕсли;
Иначе
    Сообщить("Свойство phoneNumbers не найдено в полученных данных.");
КонецЕсли;

Когда использовать Соответствие (Map) вместо Структуры?

Иногда ключи в JSON содержат символы, которые недопустимы для ключей Структуры (например, дефисы "phone-number" или если имя начинается с цифры). В этом случае функция ПрочитатьJSON по умолчанию может сработать некорректно или вы не сможете обратиться к полю через точку.

Посмотрим, как решить эту проблему, указав тип возвращаемого значения во втором параметре функции:


// Указываем, что хотим получить Соответствие, а не Структуру
Данные = ПрочитатьJSON(ЧтениеJSON, Ложь); // Ложь во втором параметре (ИспользоватьСтруктуру)

// Теперь обращение идет через квадратные скобки, что позволяет использовать любые имена ключей
Если Данные.Получить("phone-number") <> Неопределено Тогда
    Телефоны = Данные["phone-number"];
КонецЕсли;

Работа с датами и спецформатами

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

Потоковое чтение для больших объемов данных

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

Вместо одной функции ПрочитатьJSON(), мы используем цикл по объекту ЧтениеJSON:


Пока ЧтениеJson.Прочитать() Цикл
    ТипУзла = ЧтениеJson.ТипУзла;
    
    Если ТипУзла = ТипУзлаЧтенияJSON.ИмяСвойства И ЧтениеJson.ТекущееЗначение = "phoneNumbers" Тогда
        // Нашли нужное свойство, читаем следующее значение (начало массива)
        ЧтениеJson.Прочитать(); 
        // Здесь можно реализовать логику ручного разбора элементов массива
    КонецЕсли;
КонецЦикла;

Подводя итог, можно сказать, что для решения вашей задачи достаточно правильно инициализировать ЧтениеJSON и помнить, что результат десериализации — это коллекция. Всегда проверяйте в отладчике тип переменной Данные: если это Структура, обращайтесь по имени свойства; если это Массив (в случае, если JSON начинается с [), используйте цикл Для каждого сразу по объекту Данные.

← На главную