Запись и чтение JSON во встроенном языке 1С 8.3

· 9 мин

Содержание

Сформировать JSON в 1С проще всего так: собрать данные в Структура, Соответствие и Массив, а затем вызвать ЗаписатьJSON() с объектом ЗаписьJSON, открытым в строку или файл. Если нужен полный контроль над каждым свойством или поток в большой файл, JSON пишут вручную методами ЗаписатьНачалоОбъекта(), ЗаписатьИмяСвойства(), ЗаписатьЗначение().

Оба механизма есть в платформе начиная с 8.3.6. Для обмена между двумя базами 1С есть третий путь — СериализаторXDTO.ЗаписатьJSON(): он сохраняет типы и ссылки, но внешним системам такой формат обычно не подходит. Ниже — код для каждого случая, разбор входящих данных и ошибки, на которых спотыкаются чаще всего.

Три способа сформировать JSON в 1С: какой когда выбрать

Выбор зависит от того, кто будет читать результат и насколько большой объём данных.

СпособКогда выбиратьОграничения
ЗаписьJSON + ручные методыПоток в файл на сотни мегабайт, нестандартный порядок свойств, частичная записьМного кода, легко забыть закрыть объект или массив
ЗаписатьJSON() из коллекцийREST API, веб-сервисы, обмен с сайтом, маркетплейсамиПишет только примитивы и коллекции; ссылки и перечисления надо преобразовать
СериализаторXDTO.ЗаписатьJSON()Обмен 1С ↔ 1С с одинаковыми метаданнымиФормат со служебными полями #type и #value, внешней системе он непонятен

💡 На практике 9 задач из 10 закрывает второй способ. Ручная запись нужна, когда данные не помещаются в память целиком.

Типы, которые JSON понимает без преобразований:

  • 🔤 Строка → строка в кавычках;
  • 🔢 Число → число без разделителей разрядов;
  • ✅ Булево → true / false;
  • 📅 Дата → строка в формате ISO, например "2026-10-07T14:30:00";
  • ⭕ Неопределено и Null → null;
  • 📦 Структура, Соответствие (ключи — строки) → объект {};
  • 📚 Массив и фиксированные коллекции → массив [].

Всё остальное — ссылки, перечисления, ТаблицаЗначений, УникальныйИдентификатор, ДвоичныеДанные — ЗаписатьJSON() без подготовки не запишет.

Как записать JSON вручную через объект ЗаписьJSON

Объект ЗаписьJSON работает как курсор: вы по очереди открываете объект, пишете имя свойства, значение, закрываете объект. Результат уходит в строку или в файл.

Запись в строку

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

ЗаписьJSON.ЗаписатьНачалоОбъекта();

ЗаписьJSON.ЗаписатьИмяСвойства("number");
ЗаписьJSON.ЗаписатьЗначение("00-000125");

ЗаписьJSON.ЗаписатьИмяСвойства("sum");
ЗаписьJSON.ЗаписатьЗначение(15400.50);

ЗаписьJSON.ЗаписатьИмяСвойства("paid");
ЗаписьJSON.ЗаписатьЗначение(Ложь);

ЗаписьJSON.ЗаписатьКонецОбъекта();

ТекстJSON = ЗаписьJSON.Закрыть();

Метод Закрыть() при записи в строку возвращает готовый текст:

{
"number": "00-000125",
"sum": 15400.5,
"paid": false
}

Запись в файл

Вместо УстановитьСтроку() вызывают ОткрытьФайл() с именем файла и кодировкой:

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл("C:\Exchange\orders.json", "UTF-8");
// ... те же вызовы ЗаписатьНачалоОбъекта / ЗаписатьИмяСвойства ...
ЗаписьJSON.Закрыть();

У ОткрытьФайл() есть параметр, отвечающий за метку BOM в начале файла. Часть внешних парсеров на BOM падает, поэтому, если получатель жалуется на «невалидный JSON» при внешне правильном тексте, первым делом проверьте его.

Параметры записи: отступы и экранирование

Внешний вид текста задают через ПараметрыЗаписиJSON. Компактная строка без переносов — частое требование API, где важен размер запроса:

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

Для отладки, наоборот, удобен ПереносСтрокJSON.Авто и отступ табуляцией или пробелами — второй параметр конструктора. Остальные параметры управляют экранированием: угловых скобок, амперсанда, слеша, символов вне ASCII. Если в данных HTML или текст будет вставлен в веб-страницу, экранирование угловых скобок включите.

Вложенные объекты и массивы в JSON

Реальный запрос к API — это почти всегда объект с массивом внутри: заказ и его строки, контрагент и его счета.

Вручную, через пары «начало — конец»

ЗаписьJSON.ЗаписатьНачалоОбъекта();

ЗаписьJSON.ЗаписатьИмяСвойства("order");
ЗаписьJSON.ЗаписатьЗначение("00-000125");

ЗаписьJSON.ЗаписатьИмяСвойства("items");
ЗаписьJSON.ЗаписатьНачалоМассива();

Для Каждого Строка Из Товары Цикл
    ЗаписьJSON.ЗаписатьНачалоОбъекта();
    ЗаписьJSON.ЗаписатьИмяСвойства("sku");
    ЗаписьJSON.ЗаписатьЗначение(Строка.Артикул);
    ЗаписьJSON.ЗаписатьИмяСвойства("qty");
    ЗаписьJSON.ЗаписатьЗначение(Строка.Количество);
    ЗаписьJSON.ЗаписатьКонецОбъекта();
КонецЦикла;

ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.ЗаписатьКонецОбъекта();

Каждому ЗаписатьНачалоОбъекта() нужен свой ЗаписатьКонецОбъекта(), каждому ЗаписатьНачалоМассива() — ЗаписатьКонецМассива(). Платформа следит за порядком и выдаёт исключение, если, например, записать значение без имени свойства внутри объекта.

Через коллекции: тот же результат короче

Заказ = Новый Структура;
Заказ.Вставить("order", "00-000125");
Заказ.Вставить("date", ТекущаяДатаСеанса());

Строки = Новый Массив;
Для Каждого Строка Из Товары Цикл
    Позиция = Новый Структура("sku, qty, price");
    Позиция.sku   = Строка.Артикул;
    Позиция.qty   = Строка.Количество;
    Позиция.price = Строка.Цена;
    Строки.Добавить(Позиция);
КонецЦикла;
Заказ.Вставить("items", Строки);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Заказ);
ТекстJSON = ЗаписьJSON.Закрыть();

Когда ключ свойства — не идентификатор 1С (user-id, 1c_code, @type), Структура не подойдёт: ключ с дефисом или цифрой в начале в неё не вставить. Используйте Соответствие:

Данные = Новый Соответствие;
Данные.Вставить("user-id", 4512);
Данные.Вставить("1c_code", "000000017");

Пустой массив запишется как [], пустая структура — как {}. Если API требует, чтобы пустое поле вообще отсутствовало, не вставляйте ключ в коллекцию.

ЗаписатьJSON: как конвертировать ссылки, даты и таблицы

Главная боль при выгрузке объектов 1С — ссылки на справочники и документы. Есть три рабочих приёма.

Приём 1. Подготовить данные заранее

Перед записью превратите ссылку в то, что нужно получателю:

  • 🆔 GUID — XMLСтрока(Ссылка) или Строка(Ссылка.УникальныйИдентификатор());
  • 🏷️ код или наименование — Ссылка.Код, Ссылка.Наименование (в запросе лучше выбрать поле сразу, а не обращаться через точку в цикле);
  • 📋 значение перечисления — XMLСтрока(ЗначениеПеречисления) вернёт имя значения из метаданных, а не синоним.

ТаблицаЗначений в JSON не пишется. Её обходят циклом и складывают строки в массив структур, как в примере выше.

Приём 2. Функция преобразования

Если структура данных глубокая и готовить каждое поле неудобно, передайте в ЗаписатьJSON() имя экспортной функции, которая вызывается для значений неподдерживаемых типов:

ЗаписатьJSON(ЗаписьJSON, Данные, , "ПреобразоватьДляJSON", ЭтотОбъект);

Функция ПреобразоватьДляJSON(Свойство, Значение, ДополнительныеПараметры, Отказ) Экспорт
    Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Значение)) Тогда
        Возврат XMLСтрока(Значение);
    КонецЕсли;
    Отказ = Истина; // прочее не пишем
КонецФункции

Четвёртый параметр — имя функции, пятый — модуль, где она лежит (модуль формы или объекта через ЭтотОбъект, либо общий модуль). Проверка ОбщегоНазначения.ЭтоСсылка() есть в типовых конфигурациях на БСП; в своей конфигурации проверьте тип иначе, например через Справочники.ТипВсеСсылки().СодержитТип().

Приём 3. СериализаторXDTO для обмена 1С ↔ 1С

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
СериализаторXDTO.ЗаписатьJSON(ЗаписьJSON, ДокументОбъект, НазначениеТипаXML.Явное);
ТекстJSON = ЗаписьJSON.Закрыть();

На выходе — объект с полями #type и #value, по которым другая база с теми же метаданными восстановит объект через СериализаторXDTO.ПрочитатьJSON(). Для сайта или чужого API этот формат избыточен.

Выгрузка результата запроса в JSON

Типовая задача — отдать список документов или остатков. Схема: запрос выбирает уже готовые для JSON поля, цикл по выборке складывает их в массив структур.

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Номенклатура.Код КАК code,
|    Номенклатура.Наименование КАК name,
|    Номенклатура.Артикул КАК sku
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|    НЕ Номенклатура.ЭтоГруппа";

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

Приём в том, что псевдонимы полей в запросе (КАК code) совпадают с ключами структуры. Тогда ЗаполнитьЗначенияСвойств() переносит все значения одной строкой, и не нужно присваивать каждое поле вручную. Если в выборке есть ссылка, выберите в запросе её код или наименование, а GUID получите через XMLСтрока() уже в цикле.

Даты: формат и часовой пояс

По умолчанию дата пишется в ISO без смещения. Чтобы передать дату в UTC или со смещением, задайте НастройкиСериализацииJSON:

Настройки = Новый НастройкиСериализацииJSON;
Настройки.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
Настройки.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДатаСоСмещением;
ЗаписатьJSON(ЗаписьJSON, Данные, Настройки);

Кроме ISO, доступны форматы JavaScript и Microsoft — их требуют старые .NET-сервисы.

Чтение и разбор JSON в 1С

Входящий JSON читают тоже двумя способами: целиком в коллекции или потоком.

Целиком: ПрочитатьJSON

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

Для Каждого Позиция Из Данные["items"] Цикл
    Артикул = Позиция["sku"];
КонецЦикла;

Второй параметр Истина — читать объекты в Соответствие. Без него объекты превращаются в Структура, и первый же ключ вида order-id вызовет исключение. Для данных из внешних систем всегда читайте в Соответствие: формат ключей там вам не гарантирован.

Даты в JSON — просто строки, и 1С не знает, что "2026-10-07T14:30:00" надо превратить в Дата. Перечислите такие свойства в третьем параметре ПрочитатьJSON() (массив имён) и укажите формат дат в четвёртом — тогда они придут типом Дата. Альтернатива — конвертировать вручную через ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO).

Значение null после чтения становится Неопределено. Проверяйте его до обращения к вложенным полям.

Потоком: ЧтениеJSON.Прочитать()

Для файлов на десятки мегабайт читать всё в память неэкономно. Курсорное чтение обходит текст по элементам:

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл("C:\Exchange\prices.json");

Пока ЧтениеJSON.Прочитать() Цикл
    Если ЧтениеJSON.ТипТекущегоЗначения = ТипЗначенияJSON.ИмяСвойства
        И ЧтениеJSON.ТекущееЗначение = "price" Тогда
        ЧтениеJSON.Прочитать();
        Цена = ЧтениеJSON.ТекущееЗначение;
        // обработать цену
    КонецЕсли;
КонецЦикла;

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

ТипТекущегоЗначения принимает значения НачалоОбъекта, КонецОбъекта, НачалоМассива, КонецМассива, ИмяСвойства, Строка, Число, Булево, Null, Комментарий, Ничего. Комбинированный приём для больших массивов: доходите курсором до начала нужного массива, а каждый его элемент читаете ПрочитатьJSON(ЧтениеJSON) — функция заберёт ровно один объект и оставит курсор за ним.

Ошибки при формировании JSON в 1С и как их исправить

Диагностика: выберите симптом

Отдельная ловушка — значение реквизита составного типа. Сегодня в нём строка, завтра пользователь выбрал ссылку, и выгрузка падает. Для таких полей функция преобразования надёжнее подготовки «на глаз».

Практики: скорость, размер и обмен по HTTP

Отправка JSON во внешнее API

Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 30,
    Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/v1/orders");
Запрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(ТекстJSON, "UTF-8",
    ИспользованиеByteOrderMark.НеИспользовать);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
    ТекстОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
КонецЕсли;

Заголовок Content-Type многие сервисы проверяют строго: без него тело может не разобраться.

Что ускоряет выгрузку

  • ⚡ Получайте данные одним запросом сразу с нужными полями (артикул, код, наименование). Обращение через точку к реквизиту ссылки в цикле каждый раз читает объект из базы.
  • 🧱 Не собирайте JSON конкатенацией строк. Кавычки, переносы и обратные слеши в данных сломают текст, а экранирование ЗаписьJSON делает сама.
  • 📁 Больше 50–100 тысяч строк — пишите потоком в файл ручными методами, а не строите огромную коллекцию в памяти.
  • 🗜️ Для API выключайте переносы (ПереносСтрокJSON.Нет): на больших выгрузках это заметно уменьшает размер.

Где выполнять код

ЗаписьJSON, ЧтениеJSON и функции ЗаписатьJSON() / ПрочитатьJSON() доступны и на клиенте, и на сервере. Обращение к базе и HTTP-запросы к внешним сервисам держите на сервере: так не гоняются лишние данные между клиентом и сервером, а в веб-клиенте не мешают ограничения браузера.

Проверка перед отправкой JSON
Выполнено: 0 / 6

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

С какой версии платформы есть ЗаписьJSON и ЧтениеJSON?
С платформы 8.3.6. На более ранних версиях JSON собирали строками или через внешние компоненты.
Можно ли получить из 1С JSON с ключами в порядке вставки?
Да. Структура и ручная запись сохраняют порядок, в котором свойства добавлялись. Порядок обхода Соответствия лучше не считать гарантированным.
Как вывести JSON красиво, с отступами, для отладки?
Передайте в УстановитьСтроку() объект ПараметрыЗаписиJSON с ПереносСтрокJSON.Авто и символом отступа, например Символы.Таб.
Чем JSON лучше XML для обмена из 1С?
Текст короче, его понимают почти все веб-сервисы, а код записи проще. XML остаётся стандартом там, где формат задан схемой: например, в регламентированных обменах.
Как передать в JSON двоичные данные, например картинку?
Преобразуйте ДвоичныеДанные в строку Base64 функцией Base64Строка() и запишите как обычную строку. На стороне 1С обратно — Base64Значение().