При интеграции 1С с внешними системами через API (например, amoCRM, Bitrix24 или другие REST-сервисы) программисты часто сталкиваются с необходимостью формирования сложных JSON-структур. Одной из самых частых задач является создание массива, содержащего несколько объектов. В процессе реализации этой задачи могут возникнуть вопросы о том, как расставлять запятые между элементами и почему объект ЗаписьJSON выдает ошибки. Разберем эти ситуации подробно.
Первое и самое важное правило, которое нам нужно запомнить: при использовании объекта ЗаписьJSON запятые между элементами массива или свойствами объекта ставятся платформой 1С автоматически. Нам не нужно (и нельзя) пытаться записать символ запятой вручную.
Объект ЗаписьJSON — это своего рода «потоковый принтер». Он отслеживает текущее состояние документа: открыт ли массив или объект, было ли уже записано какое-то свойство. Если вы находитесь внутри массива и вызываете метод ЗаписатьНачалоОбъекта() второй раз подряд, платформа сама поймет, что между текущим (закрытым) и новым объектом должна стоять запятая.
Рассмотрим правильную последовательность вызовов для формирования массива из двух объектов:
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписьJSON.ЗаписатьНачалоОбъекта(); // Корень всего JSON
ЗаписьJSON.ЗаписатьИмяСвойства("custom_fields_values");
ЗаписьJSON.ЗаписатьНачалоМассива(); // Начало общего массива
// ПЕРВЫЙ ОБЪЕКТ МАССИВА
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("field_id");
ЗаписьJSON.ЗаписатьЗначение(354313);
ЗаписьJSON.ЗаписатьИмяСвойства("values");
ЗаписьJSON.ЗаписатьНачалоМассива();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("value");
ЗаписьJSON.ЗаписатьЗначение("123321123");
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.ЗаписатьКонецОбъекта(); // После этого вызова платформа "знает", что объект завершен
// ВТОРОЙ ОБЪЕКТ МАССИВА
// Платформа автоматически поставит запятую перед следующим объектом
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("field_id");
ЗаписьJSON.ЗаписатьЗначение(1212121212);
// Здесь могут быть другие поля...
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.ЗаписатьКонецМассива(); // Закрываем массив "custom_fields_values"
ЗаписьJSON.ЗаписатьКонецОбъекта(); // Закрываем корневой объект
Результат = ЗаписьJSON.Закрыть();
Проанализируем ситуацию, когда 1С выдает ошибку «Приемник данных JSON не открыт». Обычно это происходит по двум причинам:
ЗаписьJSON.Закрыть(), объект уничтожает внутренний буфер и прекращает работу. Любая попытка вызвать Записать... после этого приведет к ошибке. Часто это случается в циклах, если программист случайно поместил закрытие внутрь итерации.УстановитьСтроку(), либо ОткрытьФайл(). Если этого не сделать, объекту просто «некуда» писать данные.Посмотрим на пример из практики, где ошибка возникала из-за логической ошибки в коде:
// ОШИБОЧНЫЙ ВАРИАНТ
Если НЕ ПустаяСтрока(Адрес) Тогда
ЗаписьJSON.ЗаписатьНачалоОбъекта();
// ... логика записи ...
ЗаписьJSON.ЗаписатьКонецОбъекта();
СтрокаJS = ЗаписьJSON.Закрыть(); // ОШИБКА: поток закрыт здесь!
КонецЕсли;
// Если выполнение кода пойдет дальше и встретит еще одну команду записи,
// программа упадет, так как Закрыть() уже сработал.
Еще одна частая проблема — ошибка «Обращение к процедуре объекта как к функции». Важно помнить синтаксис встроенного языка 1С. Метод УстановитьСтроку() является процедурой. Это значит, что он не возвращает значение и его нельзя использовать в правой части оператора присваивания.
Правильно:
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
Неправильно:
Результат = ЗаписьJSON.УстановитьСтроку();
Хотя ручная запись через ЗаписатьНачалоОбъекта() дает полный контроль, она очень трудоемка и чревата ошибками в иерархии (легко забыть закрыть скобку). В 1С есть гораздо более элегантный способ — использование метода ЗаписатьJSON() в сочетании со Структурой и Массивом. Для автоматического формирования кода 1С по готовому примеру и проверки структуры можно использовать инструмент для форматирования, валидации и генерации кода JSON.
Разберем, как сформировать тот же самый JSON, но гораздо проще:
// 1. Создаем структуру данных в памяти 1С
МассивОбъектов = Новый Массив;
// Формируем первый элемент
Значение1 = Новый Структура("value", "Field value");
МассивЗначений1 = Новый Массив;
МассивЗначений1.Добавить(Значение1);
Элемент1 = Новый Структура;
Элемент1.Вставить("field_id", 3);
Элемент1.Вставить("values", МассивЗначений1);
МассивОбъектов.Добавить(Элемент1);
// Формируем второй элемент
Значение2 = Новый Структура("value", "1.5");
МассивЗначений2 = Новый Массив;
МассивЗначений2.Добавить(Значение2);
Элемент2 = Новый Структура;
Элемент2.Вставить("field_id", 103);
Элемент2.Вставить("values", МассивЗначений2);
МассивОбъектов.Добавить(Элемент2);
// Корневой объект
ДанныеДляОтправки = Новый Структура("custom_fields_values", МассивОбъектов);
// 2. Сериализуем всё одним методом
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто); // Для красивого форматирования
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
ЗаписатьJSON(ЗаписьJSON, ДанныеДляОтправки); // Платформа сделает всё за нас
Результат = ЗаписьJSON.Закрыть();
Этот метод исключает ошибки с запятыми, скобками или типами данных. Массив в 1С всегда превращается в [], а Структура — в {}. Это стандарт «хорошего тона» при разработке на платформе 1С v8.3.
При формировании JSON нужно учитывать, как 1С преобразует типы:
Строка(Ссылка.УникальныйИдентификатор()), либо код/наименование.Используя эти правила и подходы, мы сможем создавать надежные механизмы обмена данными, которые легко читать и поддерживать. А для проверки и отправки сформированных запросов во внешние сервисы подойдёт инструмент для тестирования REST API в 1С.