Запись JSON в файл средствами 1С 8.3: код, кодировка, ошибки

· 9 мин

Содержание

Чтобы записать JSON в файл в 1С 8.3, создайте объект ЗаписьJSON, откройте файл методом ОткрытьФайл() с кодировкой "UTF-8", передайте данные в глобальную функцию ЗаписатьJSON() и закройте запись методом Закрыть(). Данные удобно собирать заранее в Структуру, Соответствие или Массив.

Типичная ситуация: интегратор просит выгрузить остатки или список контрагентов «в джейсоне» на сетевую папку, а файл не читается — то лишний BOM в начале, то кракозябры, то ошибка на поле с датой. Ниже — рабочий код и разбор всех мест, где запись JSON в файл обычно ломается.

Минимальный пример, который можно сразу вставить в серверную процедуру:

Данные = Новый Структура;
Данные.Вставить("ИНН", "7701234567");
Данные.Вставить("Наименование", "ООО Ромашка");
Данные.Вставить("Активен", Истина);

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

1. Открываем файл и выбираем кодировку

Всё начинается с объекта ЗаписьJSON. У него два режима вывода:

  • 📄 ОткрытьФайл(ИмяФайла, Кодировка, ЗаписатьBOM, ПараметрыЗаписи) — результат сразу пишется на диск;
  • 🧵 УстановитьСтроку(ПараметрыЗаписи) — результат собирается в памяти, а Закрыть() возвращает готовую строку.

Для файла почти всегда нужна кодировка "UTF-8". Это стандарт для JSON: так ждут файл веб-сервисы, маркетплейсы, сайты на PHP и Python.

Нужен ли BOM

BOM — три служебных байта EF BB BF в начале файла. Блокнот Windows с ними дружит, а многие парсеры — нет: строгий разбор падает на первом же символе.

Третий параметр ОткрытьФайл() управляет записью BOM. Если принимающая сторона не просила обратного, задайте его явно:

Запись.ОткрытьФайл(ИмяФайла, "UTF-8", Ложь);

Явно указанный Ложь избавляет от сюрпризов при смене версии платформы и делает намерение понятным коллеге, который будет читать код.

Когда нужна другая кодировка

Иногда старый получатель просит windows-1251. Технически это работает: передайте строку "windows-1251" вторым параметром. Но символы вне этой кодовой страницы (например, € или эмодзи в комментарии) потеряются. Если выбор есть — оставайтесь на UTF-8.

2. Готовим данные перед записью JSON

ЗаписатьJSON() умеет сериализовать не всё подряд. Без дополнительных настроек в JSON уходят только простые и универсальные типы.

Тип 1СВо что превращается в JSONНюансы
Строкастрокаэкранирование кавычек и \ делается само
Числочислобез пробелов-разделителей и без кавычек
Булевоtrue / false—
Неопределеноnullудобно для пустых полей
Датастрокаформат задают настройки сериализации
Структура, ФиксированнаяСтруктураобъектключи — имена из структуры
Соответствие, ФиксированноеСоответствиеобъектключи — только строки
Массив, ФиксированныйМассивмассивэлементы любых типов из таблицы

Ссылки на справочники и документы, ТаблицаЗначений, ДвоичныеДанные напрямую не пишутся. Их сначала превращают в строки, массивы и структуры — или подключают функцию преобразования (раздел 4).

Структура или Соответствие

Ключ Структуры должен быть допустимым идентификатором 1С. Ключ вида order-id, 1c_code или Вид операции с пробелом в структуру не вставить.

  • ✅ Свои имена полей на латинице без дефисов — берите Структуру, код короче.
  • ✅ Внешний формат с дефисами, цифрой в начале или пробелами — только Соответствие.

Таблица значений в массив объектов

Самый частый случай выгрузки — список строк. Перегоните таблицу в массив структур:

Функция ТаблицаВМассив(Таблица)
    Результат = Новый Массив;
    Колонки = Таблица.Колонки;
    Для Каждого Строка Из Таблица Цикл
        Элемент = Новый Структура;
        Для Каждого Колонка Из Колонки Цикл
            Элемент.Вставить(Колонка.Имя, Строка[Колонка.Имя]);
        КонецЦикла;
        Результат.Добавить(Элемент);
    КонецЦикла;
    Возврат Результат;
КонецФункции

Если в колонках лежат ссылки, в запросе сразу выбирайте Номенклатура.Код и ПРЕДСТАВЛЕНИЕ(Номенклатура) — тогда в таблице окажутся строки, и функция преобразования не понадобится.

3. Пишем JSON в файл: целиком или по частям

Есть два способа вывода. Они работают с одним и тем же объектом ЗаписьJSON.

Способ 1. Одним вызовом ЗаписатьJSON

Подходит, когда данные уже собраны в коллекцию и помещаются в память. Это 90 % задач: справочник на несколько тысяч элементов, остатки, пакет документов за день.

ЗаписатьJSON(Запись, Данные);

Способ 2. Потоковая запись по элементам

Нужна для больших выгрузок — сотни тысяч строк, когда массив структур съест гигабайт памяти. Пишете структуру JSON вручную, строка за строкой из выборки запроса:

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

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Запись.ЗаписатьНачалоОбъекта();
    Запись.ЗаписатьИмяСвойства("code");
    Запись.ЗаписатьЗначение(Выборка.Код);
    Запись.ЗаписатьИмяСвойства("qty");
    Запись.ЗаписатьЗначение(Выборка.Количество);
    Запись.ЗаписатьКонецОбъекта();
КонецЦикла;

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

Способы можно смешивать: открыть массив вручную, а каждый элемент выводить вызовом ЗаписатьJSON(Запись, Элемент).

Каждому ЗаписатьНачало… нужен парный ЗаписатьКонец…. Лишний или пропущенный вызов вызовет исключение ещё при записи — это лучше, чем битый файл у получателя.

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

Внешний вид файла задаёт объект ПараметрыЗаписиJSON. Его передают в ОткрытьФайл() или УстановитьСтроку().

Параметры = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, "  ");
Запись.ОткрытьФайл(ИмяФайла, "UTF-8", Ложь, Параметры);

Что можно настроить:

  • 📐 Перенос строк — ПереносСтрокJSON.Нет даёт компактный файл в одну строку, Авто, Windows или Unix — читаемый с переносами.
  • ↔️ Символы отступа — второй параметр, обычно два пробела или символ табуляции.
  • 🔤 Экранирование — перечисление ЭкранированиеСимволовJSON: можно записать кириллицу как есть или превратить её в последовательности \u0410. Нужно, если получатель понимает только ASCII.
  • 🔒 Отдельные флаги экранирования угловых скобок, амперсанда, слеша и одинарных кавычек — для JSON, который потом вставят в HTML-страницу.
РежимРазмер файлаКогда брать
Без переносовминимальныйобмен между системами, большие выгрузки
С переносами и отступомзаметно большеотладка, файлы, которые читает человек
Кириллица в \uXXXXпримерно втрое больше для русских строкстарый получатель без поддержки UTF-8

4. Даты, ссылки и объекты: что делать с «неудобными» типами

Формат даты

Даты сериализуются по правилам из объекта НастройкиСериализацииJSON. Чаще всего нужен ISO 8601 — вида 2026-10-07T14:30:00:

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

Вариант УниверсальнаяДата пишет время в UTC, а ЛокальнаяДатаСоСмещением добавляет смещение вроде +03:00. Если получатель сравнивает время с другими системами, договоритесь о варианте заранее. Разница в три часа — классическая причина «документ ушёл вчерашним числом».

Функция преобразования для ссылок

Когда в данных встречаются ссылки, а переписывать запрос неудобно, подключите функцию преобразования. Платформа вызывает её для каждого значения, которое не умеет записать сама:

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

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

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

Не обращайтесь в функции преобразования к реквизитам через точку для каждой ссылки — на 10 000 строк это 10 000 отдельных запросов к базе. Выбирайте нужные поля в основном запросе.

Объект целиком через СериализаторXDTO

Если надо выгрузить документ или элемент справочника со всеми реквизитами и табличными частями, используйте СериализаторXDTO.ЗаписатьJSON(Запись, Объект). Формат получится «внутренний» для 1С: с типами и идентификаторами. Его удобно читать обратно другой базой 1С, но внешнему сайту он почти всегда неудобен.

5. Ошибки при записи JSON в файл и их перехват

Запись в файл всегда оборачивайте в Попытка…Исключение. Иначе при ошибке файл останется открытым до завершения сеанса, и повторная выгрузка упадёт на занятом файле.

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

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

Каталог для выгрузки платформа сама не создаёт. Проверьте его заранее:

Каталог = Новый Файл("C:\Обмен");
Если Не Каталог.Существует() Тогда
    СоздатьКаталог(Каталог.ПолноеИмя);
КонецЕсли;
Диагностика: выберите симптом

6. Какой способ записи JSON выбрать

В поисковой выдаче часто встречается название «КонвертерJSON». Такого объекта в платформе 1С:Предприятие 8.3 нет. Так называют самописные общие модули-обёртки, которые внутри всё равно вызывают ЗаписьJSON. Сравнивать имеет смысл реальные варианты:

СпособКогда подходитМинусы
ЗаписьJSON + ЗаписатьJSON()данные собраны в коллекцию, до десятков тысяч элементоввся структура в памяти
Потоковые методы ЗаписатьНачалоОбъекта() и др.большие выгрузки из выборки запросабольше кода, легко забыть парный вызов
СериализаторXDTO.ЗаписатьJSON()обмен между базами 1С, выгрузка объекта целикомгромоздкий формат, неудобен внешним системам
Общий модуль-обёрткаединые правила дат, ссылок и кодировки во всей конфигурацииего нужно написать и поддерживать
Склейка строк через +никогданет экранирования кавычек и спецсимволов, битый JSON

Не собирайте JSON конкатенацией строк. Первый же контрагент с названием ООО "Ромашка" сломает файл: кавычки останутся неэкранированными.

7. Запись JSON в файл на сервере, в тонком и веб-клиенте

Объект ЗаписьJSON доступен и на сервере, и на клиенте. Но «файл» в каждом случае оказывается на разных компьютерах.

Файловая база и тонкий клиент

В файловом варианте серверный код выполняется на компьютере пользователя. Путь C:\Обмен\file.json — это диск того, кто нажал кнопку.

В тонком клиенте можно вызвать ОткрытьФайл() прямо в клиентской процедуре. Это удобно для выгрузки «себе на рабочий стол», но данные из базы всё равно придётся получить серверным вызовом.

Клиент-серверная база

Здесь серверный код работает на сервере 1С. Путь C:\Обмен — это диск сервера, и пишет туда служба сервера 1С от своей учётной записи. Отсюда самая частая жалоба: «код отработал без ошибок, а файла у меня нет».

Варианты решения:

  • 🖥️ Пишите в сетевую папку по UNC-пути \\fileserver\obmen\file.json и дайте службе сервера 1С права на неё.
  • 📥 Формируйте JSON на сервере в строку, передавайте её на клиент и сохраняйте там.

Веб-клиент

Браузер не даёт коду писать на диск напрямую. Порядок такой:

  1. На сервере соберите JSON в строку через УстановитьСтроку() и Закрыть().
  2. Превратите строку в двоичные данные: ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь).
  3. Поместите их во временное хранилище: ПоместитьВоВременноеХранилище(ДД, УникальныйИдентификатор).
  4. На клиенте передайте адрес в метод получения файла. В конфигурациях на БСП это ФайловаяСистемаКлиент.СохранитьФайл(), без БСП — асинхронные методы платформы для получения файла с сервера.

Браузер покажет пользователю стандартное окно сохранения или положит файл в папку загрузок. Тот же способ работает в тонком клиенте, поэтому для универсальной кнопки «Выгрузить в JSON» берите его.

Последний параметр ПолучитьДвоичныеДанныеИзСтроки() отвечает за BOM. Поставьте Ложь, иначе получите те же проблемы с парсерами, что и в разделе 1.

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

Как записать JSON не в файл, а в строку?
Вызовите Запись.УстановитьСтроку() вместо ОткрытьФайл(), запишите данные и получите результат: Текст = Запись.Закрыть();. Строку потом можно отправить HTTP-запросом или сохранить в реквизит.
Как дописать данные в уже существующий JSON-файл?
Режима дозаписи у ЗаписьJSON нет, да и добавить элемент в конец JSON-массива простым дописыванием нельзя. Прочитайте файл через ЧтениеJSON и ПрочитатьJSON(), добавьте элементы в коллекцию и перезапишите файл целиком.
Почему числа в файле записаны с точкой, а не с запятой?
Так требует стандарт JSON: дробная часть отделяется точкой, разделителей разрядов нет. Платформа делает это сама, форматировать числа через Формат() не нужно — получится строка вместо числа.
Можно ли записать в JSON пустую дату?
Можно, но получатель увидит 0001-01-01T00:00:00. Обычно лучше заменить пустую дату на Неопределено — в файле будет null.
Как сделать читаемый файл с отступами для отладки?
Передайте в ОткрытьФайл() параметры Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, " "). Для боевого обмена верните запись без переносов — файл станет меньше.