Разбор JSON во встроенном языке 1С 8.3: от открытия файла до значений полей

· 10 мин

Содержание

Чтобы прочитать JSON файл в 1С, создайте объект ЧтениеJSON, откройте файл методом ОткрытьФайл(Путь, "UTF-8") и передайте объект в глобальную функцию ПрочитатьJSON(). На выходе получится Структура или Соответствие с вложенными массивами — дальше с данными работаете как с обычными коллекциями. После чтения файл закрывают методом Закрыть().

Этого хватает для обычных обменов и API. Для больших файлов, нестандартных имён полей и дат нужны дополнительные приёмы — они разобраны ниже с готовыми примерами кода. Всё работает в платформе 8.3 начиная с версии 8.3.6, где появились объекты для работы с JSON, и не зависит от конфигурации: в БП, ЗУП, УТ или своей разработке код один и тот же.

Что нужно знать до начала: объекты и типы данных

Для чтения JSON в платформе есть три инструмента. Их легко перепутать, поэтому сначала — кто за что отвечает.

ИнструментЧто делаетКогда выбирать
ЧтениеJSONОткрывает источник и читает его по одному элементу (токену)Всегда нужен как «входная точка»; сам по себе — для потокового разбора
ПрочитатьJSON()Целиком превращает JSON в коллекции 1СФайлы до десятков мегабайт, обычные обмены и API
СериализаторXDTO.ПрочитатьJSON()Восстанавливает объекты 1С (ссылки, документы)Только для JSON, который сама 1С выгрузила через XDTO

Соответствие типов при чтении через ПрочитатьJSON():

  • 📦 объект { } → Структура (по умолчанию) или Соответствие;
  • 📋 массив [ ] → Массив;
  • 🔤 строка → Строка;
  • 🔢 число → Число (дробные тоже, точка как разделитель в JSON — не проблема);
  • ✅ true / false → Булево;
  • ⭕ null → Неопределено.

У дат в JSON нет своего типа. Строка "2026-03-15T10:30:00" так и останется строкой, пока вы явно не попросите платформу её преобразовать.

Где выполнять код. Удобнее всего — на сервере: там доступен файл по пути, нет ограничений веб-клиента, а результат сразу можно записать в базу. Если файл выбирает пользователь на своём компьютере, его сначала передают на сервер (об этом в разделе про источники).

Создаём ЧтениеJSON и открываем источник

Источник данных бывает трёх видов: файл на диске, строка и поток. Под каждый — свой метод.

Файл по пути

Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл("C:\Обмен\orders.json", "UTF-8");
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();

Кодировку указывайте всегда. Почти все внешние сервисы отдают UTF-8. Если файл пришёл из старой системы в Windows-1251, передайте "windows-1251", иначе кириллица превратится в набор символов.

Строка (ответ HTTP-сервиса, поле реквизита)

ТекстJSON = Ответ.ПолучитьТелоКакСтроку("UTF-8");

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

Здесь Ответ — это HTTPОтвет, который вернул HTTPСоединение.Получить() или ОтправитьДляОбработки(). Перед разбором проверьте Ответ.КодСостояния: при ошибке сервер часто возвращает HTML-страницу, и ПрочитатьJSON упадёт на первом же символе <.

Файл, выбранный пользователем

Путь C:\... на компьютере пользователя сервер не видит. Схема такая:

  1. На клиенте вызываете НачатьПомещениеФайлаНаСервер() (или старый ПоместитьФайл() в обычных формах) — файл уходит во временное хранилище, вы получаете его адрес.
  2. На сервере достаёте ДвоичныеДанные через ПолучитьИзВременногоХранилища(Адрес).
  3. Читаете их как поток — без записи на диск:
&НаСервере
Функция РазобратьФайлИзХранилища(Адрес)
	ДД = ПолучитьИзВременногоХранилища(Адрес);
	Поток = ДД.ОткрытьПотокДляЧтения();

	Чтение = Новый ЧтениеJSON;
	Чтение.ОткрытьПоток(Поток, "UTF-8");
	Данные = ПрочитатьJSON(Чтение, Истина);
	Чтение.Закрыть();
	Поток.Закрыть();

	Возврат Данные;
КонецФункции

Если ваша версия платформы не знает метод ОткрытьПоток, запишите двоичные данные во временный файл (ПолучитьИмяВременногоФайла("json"), затем ДД.Записать(Имя)), откройте его через ОткрытьФайл, а после чтения удалите командой УдалитьФайлы(Имя).

Как прочитать JSON в Структуру или Соответствие

Второй параметр ПрочитатьJSON решает, во что превратятся объекты JSON. Ошибка выбора — самая частая причина падения кода на «живых» данных.

Когда подходит Структура

ПрочитатьJSON(Чтение) — без второго параметра — возвращает Структура. Плюс: обращение через точку, Данные.order.number. Минус: ключ структуры обязан быть корректным идентификатором 1С.

Структура не примет имена:

  • ❌ с дефисом — "order-id";
  • ❌ начинающиеся с цифры — "1c_code";
  • ❌ со служебными символами — "@type", "$ref", "#text";
  • ❌ с пробелом — "full name".

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

Когда нужно Соответствие

ПрочитатьJSON(Чтение, Истина) возвращает Соответствие. Ключ — любая строка, ограничений нет. Обращение — через квадратные скобки: Данные["order-id"].

Для данных из внешних систем выбирайте Соответствие. Сегодня API отдаёт orderId, а после обновления на стороне поставщика добавится поле order-id — и код на структуре сломается без единой правки с вашей стороны.

ВопросСтруктураСоответствие
Любые имена полейНетДа
ОбращениеДанные.ПолеДанные["Поле"]
Проверка наличия поляСвойство("Поле", Значение)Получить("Поле") <> Неопределено
Отсутствующее поле при прямом обращенииИсключениеНеопределено
Как читать ваш JSON?

Достаём значения полей и приводим их к типам 1С

Пусть файл выглядит так:

{
  "number": "А-1024",
  "date": "2026-03-15T10:30:00",
  "paid": true,
  "total": 15480.50,
  "comment": null,
  "customer": { "inn": "7701234567", "name": "ООО Ромашка" }
}

Читаем в соответствие и раскладываем по переменным:

Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл(ПутьКФайлу, "UTF-8");
Заказ = ПрочитатьJSON(Чтение, Истина, "date");
Чтение.Закрыть();

Номер     = Заказ["number"];                 // Строка "А-1024"
ДатаЗаказа = Заказ["date"];                  // Дата 15.03.2026 10:30:00
Оплачен   = Заказ["paid"];                   // Булево Истина
Сумма     = Заказ["total"];                  // Число 15480.5
Коммент   = Заказ["comment"];                // Неопределено
ИННКлиента = Заказ["customer"]["inn"];       // Строка "7701234567"

Даты

Третий параметр ПрочитатьJSON — имена свойств, значения которых надо превратить в Дата. Можно передать строку через запятую ("date,shipDate") или массив имён. Четвёртый параметр — формат, по умолчанию ФорматДатыJSON.ISO.

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

ДатаОтгрузки = ПрочитатьДатуJSON(Заказ["shipDate"], ФорматДатыJSON.ISO);

Дата с часовым поясом ("2026-03-15T10:30:00+03:00" или с Z на конце) пересчитывается платформой. Если в базе время сместилось на несколько часов — дело в поясе, а не в коде. Сверьте пару документов вручную перед массовой загрузкой.

Безопасное чтение необязательных полей

Внешний сервис может просто не прислать поле. Прямое обращение к соответствию вернёт Неопределено, и дальше упадёт уже арифметика. Поэтому значения по умолчанию задают явно:

Скидка = Заказ.Получить("discount");
Если Скидка = Неопределено Тогда
	Скидка = 0;
КонецЕсли;

Числа, которые пришли строкой

ИНН, коды и артикулы часто приходят и числом, и строкой — в зависимости от настроения разработчика API. ИНН "0102030405" числом потеряет ведущий ноль. Правило простое: идентификаторы храните строками, а если сервис прислал число — приводите через Формат(Значение, "ЧГ=0"), а не через Строка(), иначе получите пробел между разрядами.

Обратная ситуация — сумма строкой "15480.50". Число("15480.50") сработает, но обёрните преобразование в Попытка: пустая строка или "н/д" дадут исключение.

Массивы и вложенные структуры

Массив JSON становится Массив 1С, его элементы — соответствия (или структуры). Перебор — обычным циклом:

{
  "orders": [
    { "number": "А-1024", "items": [ { "sku": "P-01", "qty": 2, "price": 500 } ] },
    { "number": "А-1025", "items": [ { "sku": "P-07", "qty": 1, "price": 1290 } ] }
  ]
}
Данные = ПрочитатьJSON(Чтение, Истина);

Заказы = Данные.Получить("orders");
Если ТипЗнч(Заказы) <> Тип("Массив") Тогда
	ВызватьИсключение "В файле нет массива orders";
КонецЕсли;

Для Каждого Заказ Из Заказы Цикл
	ИтогоПоЗаказу = 0;
	Для Каждого Строка Из Заказ["items"] Цикл
		ИтогоПоЗаказу = ИтогоПоЗаказу + Строка["qty"] * Строка["price"];
	КонецЦикла;
	// здесь создаёте документ или пишете строку в таблицу значений
КонецЦикла;

Для первого заказа итог 2 × 500 = 1000, для второго 1 × 1290 = 1290.

Если корень файла — сразу массив

JSON вида [ {...}, {...} ] тоже допустим. ПрочитатьJSON вернёт Массив, и перебирать его надо напрямую, без обращения к ключу.

Неизвестная глубина вложенности

Когда структура заранее не известна (например, нужно найти все поля inn на любом уровне), пишут рекурсивную процедуру, которая проверяет ТипЗнч каждого значения:

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

Вызов: Найденные = Новый Массив; НайтиПоле(Данные, "inn", Найденные);.

Потоковый разбор больших JSON-файлов

ПрочитатьJSON держит весь файл в памяти в виде коллекций, а они занимают в разы больше места, чем исходный текст. Файл на 300–500 МБ (выгрузка остатков маркетплейса, журнал событий) может исчерпать память рабочего процесса сервера.

Выход — читать файл по токенам. Метод Прочитать() сдвигается на следующий элемент и возвращает Ложь в конце файла. Тип элемента лежит в ТипТекущегоЗначения, значение — в ТекущееЗначение.

Основные значения ТипЗначенияJSON:

  • НачалоОбъекта / КонецОбъекта — фигурные скобки;
  • НачалоМассива / КонецМассива — квадратные скобки;
  • ИмяСвойства — ключ, его текст в ТекущееЗначение;
  • Строка, Число, Булево, Null — сами значения.

Смешанный приём: курсор + ПрочитатьJSON по элементу

Самый практичный вариант для файла [ {...}, {...}, ... ]: идём курсором по массиву и каждый объект разбираем целиком. В памяти одновременно живёт только одна запись.

Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл(ПутьКФайлу, "UTF-8");

Обработано = 0;
Пока Чтение.Прочитать() Цикл
	Если Чтение.ТипТекущегоЗначения = ТипЗначенияJSON.НачалоОбъекта Тогда
		Запись = ПрочитатьJSON(Чтение, Истина); // читает текущий объект до конца
		ОбработатьЗапись(Запись);
		Обработано = Обработано + 1;
	КонецЕсли;
КонецЦикла;

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

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

Если массив лежит не в корне, а в свойстве ({"meta": {...}, "items": [...]}), сначала дойдите до нужного ключа: ждёте ИмяСвойства со значением "items", затем НачалоМассива, и только потом запускаете цикл по объектам. Ненужный блок meta можно перескочить методом Пропустить() — он проматывает текущий объект или массив целиком.

При загрузке десятков тысяч записей пишите в базу пачками по 500–1000 объектов в одной транзакции. Одна транзакция на весь файл держит блокировки слишком долго, а транзакция на каждую запись замедляет загрузку в разы.

Закрытие файла и обработка ошибок разбора

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

Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл(ПутьКФайлу, "UTF-8");
Попытка
	Данные = ПрочитатьJSON(Чтение, Истина);
	Чтение.Закрыть();
Исключение
	Чтение.Закрыть();
	ЗаписьЖурналаРегистрации("Загрузка JSON", УровеньЖурналаРегистрации.Ошибка, , ,
		ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	ВызватьИсключение;
КонецПопытки;

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

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

  1. Файл существует и не пустой: Новый Файл(Путь).Существует() и .Размер() > 0.
  2. Первый значимый символ — { или [. Если там <, вам прислали HTML или XML.
Диагностика: выберите симптом

Если загрузка создаёт документы или элементы справочников в рабочей базе, первый прогон делайте на копии. Повторная загрузка того же файла без проверки «уже загружено» по внешнему идентификатору задвоит данные.

Частые вопросы

С какой версии платформы есть ЧтениеJSON?
Объекты для работы с JSON появились в платформе 8.3.6. В более ранних версиях JSON разбирали вручную или через внешние компоненты.
Можно ли прочитать JSON на клиенте?
Да, ЧтениеJSON и ПрочитатьJSON доступны и на клиенте. Но файлы с компьютера пользователя всё равно удобнее передать на сервер: там данные сразу записываются в базу без лишних серверных вызовов.
Как прочитать JSON из 1С 7.7 или 8.2?
Встроенных объектов там нет. Остаётся разбор строки своими процедурами или внешняя компонента. Проще выгрузить данные в 8.3 и читать уже там.
Как прочитать объект, где ключи — это коды, например {"P-01": 5, "P-07": 2}?
Читайте в Соответствие и перебирайте его циклом Для Каждого КЗ Из Данные: код товара будет в КЗ.Ключ, количество — в КЗ.Значение.
Чем ПрочитатьJSON отличается от СериализаторXDTO.ПрочитатьJSON?
Первая функция даёт простые коллекции из любого JSON. Сериализатор понимает только формат, в котором 1С сама выгружает объекты, и возвращает ссылки, документы и элементы справочников.