Как правильно обрабатывать вложенный JSON-объект в 1С и избежать ошибки "Поле объекта не обнаружено"?

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

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

Рассмотрим типовую ситуацию, когда HTTP-сервис 1С получает вложенный JSON-объект, содержащий информацию о товарах, например, в следующем формате:


{
  "Имя": "Иван",
  "Телефон": "+79001234567",
  "Товары": {
    "item1": {
      "Артикул": "5051",
      "Количество": "2",
      "Цена": "599"
    },
    "item2": {
      "Артикул": "6052",
      "Количество": "1",
      "Цена": "369"
    }
  }
}

Наша задача – извлечь данные об артикуле, количестве и цене для каждого товара, который находится внутри объекта "Товары".

Разбираем структуру JSON и ее представление в 1С

Прежде чем приступить к обработке, важно понять, как 1С интерпретирует JSON-структуры. Функция ПрочитатьJSON() преобразует JSON-строку в объекты 1С:Предприятия. Ключевые моменты здесь:

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

В нашем примере JSON:

Анализируем начальную попытку и причину ошибки "Поле объекта не обнаружено"

Рассмотрим предложенную в теме функцию, которая пытается обработать полученный JSON:


Функция ТестДжейсонТоварыМетод1(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку;
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ТелоЗапроса);
    Данные = ПрочитатьJSON(ЧтениеJSON);
    
    // Получаем Имя и Телефон
    Имя = Данные.Имя;
    Телефон = Данные.Телефон;
    
    // Получаем объект "Товары"
    Товары = Данные.Товары;
    ЧтениеJSON.Закрыть; // Закрываем чтение JSON
    
    Результат = "";
    // Начальная попытка итерации
    Для Каждого Товар из Товары Цикл
        // Здесь возникает ошибка "Поле объекта не обнаружено (Артикул)"
        Артикул = Товар["Артикул"]; 
        Количество = Товар["Количество"];
        Цена = Товар["Цена"];
        Результат = Результат + "Артикул: " + Артикул + " Количество: " + Количество + " Цена: " + Цена + Символы.ПС;
    КонецЦикла;
    
    Ответ.УстановитьТелоИзСтроки(Результат);
    Возврат Ответ;
КонецФункции

Ошибка "Поле объекта не обнаружено (Артикул)" возникает на строке Артикул = Товар["Артикул"];. Давайте выясним причину. Когда мы пишем Товары = Данные.Товары;, переменная Товары становится структурой, которая содержит элементы с ключами "item1", "item2". При итерации по этой структуре с помощью Для Каждого Товар из Товары Цикл, каждый элемент Товар в цикле будет не самой вложенной структурой (например, `{ "Артикул": "5051", ... }`), а объектом, который содержит в себе два свойства: Ключ (например, "item1") и Значение (именно здесь и находится вложенная структура с Артикулом, Количеством, Ценой).

Таким образом, на первой итерации Товар.Ключ будет равен "item1", а Товар.Значение будет равно структуре { "Артикул": "5051", "Количество": "2", "Цена": "599" }. Соответственно, попытка обратиться к Товар["Артикул"] напрямую проваливается, потому что у самого объекта Товар (который является элементом итерации) нет поля с именем "Артикул", оно находится внутри его свойства Значение.

Правильное решение: доступ к вложенным элементам через свойство "Значение"

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

Вот как будет выглядеть исправленный участок кода:


Функция ТестДжейсонТоварыМетод1(Запрос)
    Ответ = Новый HTTPСервисОтвет(200);
    ТелоЗапроса = Запрос.ПолучитьТелоКакСтроку;
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ТелоЗапроса);
    Данные = ПрочитатьJSON(ЧтениеJSON);
    
    Имя = Данные.Имя;
    Телефон = Данные.Телефон;
    Товары = Данные.Товары; // Товары - это структура (Соответствие), содержащая item1, item2 и т.д.
    ЧтениеJSON.Закрыть();
    
    Результат = "Полученные данные:" + Символы.ПС;
    Результат = Результат + "Имя: " + Имя + Символы.ПС;
    Результат = Результат + "Телефон: " + Телефон + Символы.ПС;
    Результат = Результат + "--- Товары ---" + Символы.ПС;
    
    // Корректная итерация по структуре "Товары"
    Для Каждого ЭлементТовараИзСтруктуры Из Товары Цикл
        // ЭлементТовараИзСтруктуры имеет свойства Ключ (например, "item1") и Значение (вложенная структура)
        
        // Вложенная структура с данными товара
        ВложеннаяСтруктураТовара = ЭлементТовараИзСтруктуры.Значение;
        
        // Доступ к полям внутри вложенной структуры
        Артикул   = ВложеннаяСтруктураТовара["Артикул"];
        Количество = ВложеннаяСтруктураТовара["Количество"];
        Цена      = ВложеннаяСтруктураТовара["Цена"];
        
        Результат = Результат + "  Ключ товара: " + ЭлементТовараИзСтруктуры.Ключ + Символы.ПС;
        Результат = Результат + "  Артикул: " + Артикул + Символы.ПС;
        Результат = Результат + "  Количество: " + Количество + Символы.ПС;
        Результат = Результат + "  Цена: " + Цена + Символы.ПС + Символы.ПС;
    КонецЦикла;
    
    Ответ.УстановитьТелоИзСтроки(Результат);
    Возврат Ответ;
КонецФункции

Как мы видим, основное изменение заключается в доступе к полям: ВложеннаяСтруктураТовара["Артикул"], где ВложеннаяСтруктураТовара — это ЭлементТовараИзСтруктуры.Значение. Этот подход позволяет правильно извлечь данные из каждой вложенной структуры.

Дополнительные рекомендации по работе с JSON в 1С

Для более надежной и эффективной работы с JSON в 1С рекомендуем следующие подходы:

  1. Использование ЧтениеJSON и ПрочитатьJSON()

    Эти встроенные механизмы являются стандартным способом десериализации JSON в 1С. ЧтениеJSON позволяет пошагово читать JSON, а ПрочитатьJSON() — преобразовать всю JSON-строку целиком в объекты 1С (Структура, Соответствие, Массив).

    
    // Пример использования ЧтениеJSON для установки строки
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ТелоЗапроса);
    Данные = ПрочитатьJSON(ЧтениеJSON);
    ЧтениеJSON.Закрыть(); // Всегда закрывайте объект ЧтениеJSON после использования
    
  2. Проверка наличия ключа с помощью метода .Свойство()

    Перед тем как пытаться обратиться к полю по ключу, всегда полезно проверить его существование. Это позволит избежать ошибок "Поле объекта не обнаружено", особенно при работе с внешними системами, которые могут отправлять неполные данные или данные с изменяющейся структурой.

    
    Если ВложеннаяСтруктураТовара.Свойство("Артикул") Тогда
        Артикул = ВложеннаяСтруктураТовара["Артикул"];
    Иначе
        Артикул = Неопределено; // Или обработка отсутствующего поля
    КонецЕсли;
    
  3. Обработка дат

    При десериализации дат из JSON следует быть внимательными. JSON воспринимает дату как обычную строку. Для корректного преобразования строкового представления даты в формат даты 1С, вы можете использовать параметры функции ПрочитатьJSON(): ИменаСвойствСоЗначениямиДата и ОжидаемыйФорматДаты. Если эти параметры не указаны, вам придется преобразовывать строки в даты вручную, используя, например, Дата(СтрокаДаты).

    
    // Пример с указанием формата даты (если в JSON даты в определенном формате)
    // Представьте, что у нас есть JSON вида: { "ДатаДокумента": "2023-10-26T10:30:00" }
    // ИменаСвойствСоЗначениямиДата - массив строк с именами свойств, которые содержат даты
    // ОжидаемыйФорматДаты - строка, описывающая формат даты (например, "ISO")
    ДанныеСДатой = ПрочитатьJSON(ЧтениеJSON, , Новый Массив("ДатаДокумента"), "ISO");
    // Теперь ДанныеСДатой.ДатаДокумента будет иметь тип Дата 1С
    
  4. Сериализация/десериализация XDTO-объектов

    Начиная с версии 8.3.7.1759, платформа 1С:Предприятие поддерживает сериализацию и десериализацию JSON для любых объектов 1С:Предприятия с использованием СериализаторXDTO. Это более мощный инструмент для работы со сложными и типизированными структурами данных, особенно когда необходимо преобразовывать объекты 1С в JSON и обратно, сохраняя при этом метаданные.

    
    // Пример сериализации объекта 1С в JSON с использованием XDTO
    // Запрос = Новый Запрос("ВЫБРАТЬ ...");
    // РезультатЗапроса = Запрос.Выполнить().Выгрузить();
    // Сериализатор = Новый СериализаторXDTO;
    // СтрокаJSON = Сериализатор.ЗаписатьJSON(РезультатЗапроса);
    
  5. Производительность для больших JSON-документов

    При работе с очень большими JSON-документами, которые могут потреблять много памяти, или при медленных операциях, может быть эффективнее использовать потоковый метод чтения/записи JSON. Для этого можно использовать ЧтениеJSON и ЗаписьJSON в сочетании с файловыми потоками, что позволяет обрабатывать данные по частям, не загружая весь документ в память.

  6. Использование вспомогательных функций

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

Таким образом, понимание того, как 1С преобразует JSON-структуры, и правильное использование свойств Ключ и Значение при итерации по структурам, является ключом к успешной обработке вложенных JSON-объектов и предотвращению ошибки "Поле объекта не обнаружено". Используя эти рекомендации, вы сможете создавать более надежные и эффективные HTTP-сервисы и интеграционные решения в 1С.

← На главную