Работа с JSON в 1С: чтение, запись, даты и типичные ошибки
JSON — основной формат обмена с веб-сервисами, маркетплейсами и мобильными приложениями, и в 1С 8.3 для него есть полноценные встроенные средства. В статье — готовые примеры: как прочитать JSON в структуру или соответствие, как превратить структуру и массив в строку JSON, как правильно передавать даты, когда пригодится СериализаторXDTO и что делать с ошибкой «Непредвиденный символ при чтении JSON».
Инструменты для JSON в 1С
Для работы с 1С JSON платформа предлагает два уровня. Низкоуровневые объекты ЧтениеJSON и ЗаписьJSON позволяют пройти по документу токен за токеном. Над ними работают глобальные функции ПрочитатьJSON и ЗаписатьJSON, которые за один вызов превращают текст в коллекции 1С и обратно: объект JSON становится Структурой или Соответствием, массив — Массивом, null — значением Неопределено. В девяти случаях из десяти хватает именно этих функций.
Как прочитать JSON в структуру
Типичная задача — 1С JSON в структуру: получили строку от сервиса и хотим обращаться к полям через точку. Строку передаём в ЧтениеJSON методом УстановитьСтроку, затем вызываем ПрочитатьJSON.
Текст = "{""id"": 15, ""name"": ""Склад №1"", ""active"": true, ""tags"": [""main"", ""retail""]}";
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Текст);
Данные = ПрочитатьJSON(Чтение); // Структура
Чтение.Закрыть();
Сообщить(Данные.name); // Склад №1
Для Каждого Тег Из Данные.tags Цикл
Сообщить(Тег);
КонецЦикла;
Числа из JSON становятся типом Число, логические значения — Булево, вложенные объекты — вложенными структурами. Проверять наличие необязательного поля удобно методом Данные.Свойство("name", Значение), чтобы не получить исключение «Поле объекта не обнаружено».
Когда нужно Соответствие
Структура требует, чтобы ключи были допустимыми идентификаторами встроенного языка. Если в JSON встречаются ключи вроде "order-id", "2fa", "@type" или "first name", чтение в структуру завершится ошибкой. Решение — второй параметр ПрочитатьJSON со значением Истина: все объекты будут прочитаны в Соответствие.
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку("{""order-id"": ""A-77"", ""2fa"": false}");
Данные = ПрочитатьJSON(Чтение, Истина); // Соответствие
Чтение.Закрыть();
НомерЗаказа = Данные.Получить("order-id");
Если Данные.Получить("comment") = Неопределено Тогда
// поля нет или в нём null
КонецЕсли;
Для данных от внешних сервисов, где состав полей заранее не гарантирован, чтение в соответствие — более безопасный выбор по умолчанию: метод Получить не падает на отсутствующем ключе.
Чтение JSON из файла
Если JSON лежит в файле, используйте ОткрытьФайл вместо УстановитьСтроку. Кодировку лучше указать явно.
Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл("C:\Exchange\orders.json", КодировкаТекста.UTF8);
Заказы = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Для очень больших файлов, где весь документ не помещается в память комфортно, можно читать потоково: в цикле Пока Чтение.Прочитать() Цикл анализировать Чтение.ТипТекущегоЗначения и Чтение.ТекущееЗначение. Это сложнее, но позволяет обработать файл в сотни мегабайт по частям.
Как записать структуру или массив в строку JSON
Обратная задача — 1С строка в JSON, точнее коллекция в строку. Создаём ЗаписьJSON, вызываем УстановитьСтроку, затем ЗаписатьJSON, а результат забираем методом Закрыть. Массив в JSON 1С записывает как массив, структуры внутри — как объекты.
Товары = Новый Массив;
Товары.Добавить(Новый Структура("sku, qty, price", "A-1", 2, 150.5));
Товары.Добавить(Новый Структура("sku, qty, price", "B-7", 1, 990));
Пакет = Новый Структура;
Пакет.Вставить("orderNumber", "000123");
Пакет.Вставить("items", Товары);
Пакет.Вставить("comment", Неопределено); // будет null
Настройки = Новый НастройкиЗаписиJSON(ПереносСтрокJSON.Нет, , , ЭкранированиеСимволовJSON.Нет);
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку(Настройки);
ЗаписатьJSON(Запись, Пакет);
СтрокаJSON = Запись.Закрыть();
// {"orderNumber":"000123","items":[{"sku":"A-1","qty":2,"price":150.5},...],"comment":null}
НастройкиЗаписиJSON управляют оформлением. ПереносСтрокJSON.Нет даёт компактную строку для передачи по сети, ПереносСтрокJSON.Авто — читаемый вывод с отступами для логов. Параметр экранирования ЭкранированиеСимволовJSON.Нет оставляет кириллицу как есть; при СимволыВнеASCII она будет записана последовательностями вида \u0410. Оба варианта корректны с точки зрения стандарта, но читаемый текст удобнее отлаживать. Дополнительные параметры конструктора позволяют включить экранирование угловых скобок, амперсанда и слеша — это полезно, если JSON вставляется в HTML.
Записать в JSON можно не всё. Поддерживаются Строка, Число, Булево, Дата, Неопределено, Массив, ФиксированныйМассив, Структура, ФиксированнаяСтруктура и Соответствие со строковыми ключами. Ссылки, таблицы значений и объекты сначала нужно преобразовать в эти типы.
Дата в JSON 1С
У JSON нет отдельного типа для даты, поэтому договорённость о формате — частый источник ошибок. При записи формат задаётся объектом НастройкиСериализацииJSON; на практике почти всегда нужен ISO 8601.
НастройкиСериализации = Новый НастройкиСериализацииJSON;
НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением;
Данные = Новый Структура("number, date", "000123", ТекущаяДатаСеанса());
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Данные, НастройкиСериализации);
Текст = Запись.Закрыть(); // "date":"2026-10-31T14:05:00+03:00"
При чтении платформа сама не знает, какая строка является датой. Перечислите такие свойства в третьем параметре ПрочитатьJSON и укажите формат четвёртым:
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Текст);
Данные = ПрочитатьJSON(Чтение, Истина, "date,createdAt", ФорматДатыJSON.ISO);
Чтение.Закрыть();
// или точечно для одной строки
ДатаДокумента = ПрочитатьДатуJSON("2026-10-31T14:05:00", ФорматДатыJSON.ISO);
Помните, что в типе Дата нет часового пояса. Если сервис присылает время в UTC с суффиксом Z, а вам нужна местная дата, учитывайте смещение явно — например, через МестноеВремя.
Обход JSON с заранее неизвестной структурой
Бывает, что формат ответа меняется или нужно вывести в лог все поля без знания схемы. После чтения в соответствие документ представляет собой дерево из соответствий, массивов и простых значений, и его легко обойти рекурсивно. Функция ниже превращает такое дерево в плоский список «путь — значение», который удобно показать пользователю или сохранить в таблицу для анализа.
Процедура РазвернутьJSON(Значение, Путь, Результат) Экспорт
ТипЗначения = ТипЗнч(Значение);
Если ТипЗначения = Тип("Соответствие") Или ТипЗначения = Тип("Структура") Тогда
Для Каждого КлючИЗначение Из Значение Цикл
РазвернутьJSON(КлючИЗначение.Значение,
?(Путь = "", "", Путь + ".") + КлючИЗначение.Ключ, Результат);
КонецЦикла;
ИначеЕсли ТипЗначения = Тип("Массив") Тогда
Для Индекс = 0 По Значение.ВГраница() Цикл
РазвернутьJSON(Значение[Индекс], Путь + "[" + Формат(Индекс, "ЧН=0; ЧГ=") + "]", Результат);
КонецЦикла;
Иначе
Результат.Вставить(Путь, Значение);
КонецЕсли;
КонецПроцедуры
// Использование
Плоско = Новый Соответствие;
РазвернутьJSON(Данные, "", Плоско);
// "items[0].sku" -> "A-1", "items[0].qty" -> 2, ...
Тот же приём пригодится для сравнения двух ответов сервиса: развернув оба документа, достаточно сравнить соответствия по ключам. А при загрузке данных в справочники рекурсивный обход позволяет не писать отдельный код под каждую вложенность.
Если структура ответа известна, но меняется от версии API, пишите код чтения защитно: проверяйте наличие ключа и тип значения перед использованием. Например, поле, которое обычно содержит массив, при единственном элементе некоторые сервисы отдают как объект; проверка ТипЗнч(Значение) = Тип("Массив") избавит от неожиданных исключений в рабочей базе.
Сериализация объектов через СериализаторXDTO
Иногда нужно передать между двумя базами 1С целый объект — документ с табличными частями или ссылку. Для этого есть СериализаторXDTO: он записывает значения в JSON в собственном формате платформы, с указанием типов, и умеет прочитать их обратно.
Объект = Документы.ЗаказКлиента.НайтиПоНомеру("000123").ПолучитьОбъект();
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(Запись, Объект, НазначениеТипаXML.Явное);
ТекстОбъекта = Запись.Закрыть();
// В другой базе с той же конфигурацией
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОбъекта);
ОбъектИзJSON = СериализаторXDTO.ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Такой JSON удобен только для обмена между базами 1С с одинаковыми метаданными. Внешнему сервису он не подойдёт: структура содержит служебные поля типов и имена реквизитов на русском. Для внешних интеграций формируйте структуры вручную.
Ошибка «Непредвиденный символ при чтении JSON»
Это самая частая ошибка разбора. Непредвиденный символ при чтении JSON 1С выдаёт, когда текст вообще не является корректным JSON. Основные причины:
- BOM в начале строки. Файл сохранён в UTF-8 с меткой порядка байтов, и первый символ строки — невидимый
Символ(65279). - Пустая строка. Сервис вернул пустое тело (например, с кодом 204 или при ошибке), а код всё равно пытается его разобрать.
- HTML вместо JSON. Сервис ответил страницей ошибки 404, 502 или страницей авторизации — первый символ
<. - Нестандартный JSON. Одинарные кавычки, комментарии, висящая запятая после последнего элемента, значения
NaN. - Неверная кодировка. Файл в Windows-1251 прочитан как UTF-8.
Перед разбором полезно сделать защитную проверку:
Функция РазобратьJSON(Знач Текст) Экспорт
Если Лев(Текст, 1) = Символ(65279) Тогда
Текст = Сред(Текст, 2); // убираем BOM
КонецЕсли;
Текст = СокрЛП(Текст);
Если ПустаяСтрока(Текст) Тогда
Возврат Неопределено;
КонецЕсли;
ПервыйСимвол = Лев(Текст, 1);
Если ПервыйСимвол <> "{" И ПервыйСимвол <> "[" Тогда
ВызватьИсключение "Ответ не является JSON: " + Лев(Текст, 200);
КонецЕсли;
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Текст);
Результат = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Возврат Результат;
КонецФункции
При ответе от HTTP-сервиса сначала проверяйте КодСостояния, и только при успешном коде разбирайте тело. Текст ошибки с первыми двумя сотнями символов ответа сразу покажет, что пришло на самом деле. Если JSON приходит из файла, откройте его в редакторе с отображением кодировки: метка BOM и кодировка Windows-1251 сразу видны в строке состояния. Для файлов из других систем надёжнее указывать кодировку в ОткрытьФайл явно, а не полагаться на автоопределение.
Типичные ошибки
- Чтение в структуру данных с ключами, которые не являются идентификаторами, — используйте соответствие.
- Попытка записать ссылку,
ТаблицуЗначенийили объект напрямую черезЗаписатьJSON. Соответствиес ключами не строкового типа при записи — ключи обязательно строки.- Дата без явного формата: принимающая сторона ожидает ISO, а получает другой вид.
- Забытый вызов
ЗакрытьуЗаписьJSON: без него строка не будет получена.
| Задача | Что использовать |
|---|---|
| Строка JSON в коллекцию | ЧтениеJSON.УстановитьСтроку + ПрочитатьJSON |
| Ключи с дефисами и цифрами | ПрочитатьJSON(Чтение, Истина) |
| Коллекция в строку | ЗаписьJSON.УстановитьСтроку + ЗаписатьJSON + Закрыть |
| Даты | НастройкиСериализацииJSON, ИменаСвойствСоЗначениямиДата |
| Объект 1С целиком | СериализаторXDTO.ЗаписатьJSON / ПрочитатьJSON |
Актуальность для новых версий
Объекты ЧтениеJSON, ЗаписьJSON и функции ПрочитатьJSON/ЗаписатьJSON появились в платформе 8.3.6 и с тех пор работают без несовместимых изменений; в актуальных релизах 8.3.2x примеры выполняются как есть. Методы СериализаторXDTO.ЗаписатьJSON и ПрочитатьJSON также доступны с 8.3.6. Если конфигурация работает в режиме совместимости ниже 8.3.6, глобальные функции JSON будут недоступны.
Частые вопросы
Когда читать JSON в Соответствие, а не в Структуру?
Когда имена ключей не являются допустимыми идентификаторами 1С: содержат дефис, пробел, точку, начинаются с цифры. Структура в этом случае вызовет ошибку, а Соответствие примет любой строковый ключ.
Как записать ссылку на справочник в JSON?
Ссылку напрямую ЗаписатьJSON не принимает. Передайте вместо неё строку уникального идентификатора — Строка(Ссылка.УникальныйИдентификатор()) — или код и наименование.
Почему в строке JSON кириллица превращается в \u0430?
Включено экранирование символов вне ASCII. Создайте НастройкиЗаписиJSON с параметром ЭкранированиеСимволовJSON.Нет, и кириллица будет записана как есть.
Как прочитать дату из JSON, если она пришла строкой?
Укажите имя свойства в параметре ИменаСвойствСоЗначениямиДата функции ПрочитатьJSON и формат даты, либо преобразуйте строку отдельно функцией ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO).