Запись JSON в файл средствами 1С 8.3: код, кодировка, ошибки
Содержание
Чтобы записать 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 на сервере в строку, передавайте её на клиент и сохраняйте там.
Веб-клиент
Браузер не даёт коду писать на диск напрямую. Порядок такой:
- На сервере соберите JSON в строку через
УстановитьСтроку()иЗакрыть(). - Превратите строку в двоичные данные:
ПолучитьДвоичныеДанныеИзСтроки(Текст, КодировкаТекста.UTF8, Ложь). - Поместите их во временное хранилище:
ПоместитьВоВременноеХранилище(ДД, УникальныйИдентификатор). - На клиенте передайте адрес в метод получения файла. В конфигурациях на БСП это
ФайловаяСистемаКлиент.СохранитьФайл(), без БСП — асинхронные методы платформы для получения файла с сервера.
Браузер покажет пользователю стандартное окно сохранения или положит файл в папку загрузок. Тот же способ работает в тонком клиенте, поэтому для универсальной кнопки «Выгрузить в JSON» берите его.
Последний параметр ПолучитьДвоичныеДанныеИзСтроки() отвечает за BOM. Поставьте Ложь, иначе получите те же проблемы с парсерами, что и в разделе 1.
8. Частые вопросы
Как записать JSON не в файл, а в строку?
Запись.УстановитьСтроку() вместо ОткрытьФайл(), запишите данные и получите результат: Текст = Запись.Закрыть();. Строку потом можно отправить HTTP-запросом или сохранить в реквизит.Как дописать данные в уже существующий JSON-файл?
ЗаписьJSON нет, да и добавить элемент в конец JSON-массива простым дописыванием нельзя. Прочитайте файл через ЧтениеJSON и ПрочитатьJSON(), добавьте элементы в коллекцию и перезапишите файл целиком.Почему числа в файле записаны с точкой, а не с запятой?
Формат() не нужно — получится строка вместо числа.Можно ли записать в JSON пустую дату?
0001-01-01T00:00:00. Обычно лучше заменить пустую дату на Неопределено — в файле будет null.Как сделать читаемый файл с отступами для отладки?
ОткрытьФайл() параметры Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, " "). Для боевого обмена верните запись без переносов — файл станет меньше.