Работа с интеграциями часто требует от разработчика 1С выгрузки данных во внешние системы через формат JSON. Несмотря на кажущуюся простоту метода ЗаписатьJSON, программисты часто сталкиваются с трудночитаемыми ошибками на этапе выполнения этой функции. В рамках данной статьи мы подробно разберем, почему возникают ошибки при записи структуры, проанализируем типичный код и выясним, как правильно подготовить данные для сериализации.
Основная причина возникновения ошибок при вызове метода ЗаписатьJSON(Запись, СтруктураДанных) заключается в том, что платформа 1С строго ограничивает типы данных, которые могут быть автоматически преобразованы в формат JSON. Если внутри вашей структуры или массива окажется объект типа, который JSON «не понимает», система выдаст исключение.
Рассмотрим список разрешенных типов данных:
Неопределено (преобразуется в null);Булево;Число;Строка;Дата (автоматически приводится к строковому формату ISO);Структура, ФиксированнаяСтруктура;Массив, ФиксированныйМассив;Соответствие, ФиксированноеСоответствие.Если в вашей выборке из запроса присутствуют любые другие типы, например, ссылки на справочники, документы или специальное значение NULL, запись завершится сбоем.
Проанализируем ситуацию, когда данные берутся из результата запроса. В 1С существует критическое различие между Неопределено и NULL. Значение NULL появляется в результатах запроса (например, при левом соединении), и оно категорически не поддерживается сериализатором JSON.
Рассмотрим пример кода, который может привести к ошибке:
СтруктураТовара = Новый Структура("quantity, price");
ЗаполнитьЗначенияСвойств(СтруктураТовара, Выборка); // Если в Выборка.quantity содержится NULL — будет ошибка
ЗаписатьJSON(Запись, СтруктураТовара);
Как решить: Лучший способ — обрабатывать пустые значения еще на уровне запроса, используя функцию ЕСТЬNULL. Если же данные уже в коде, необходимо программно заменить NULL на Неопределено или пустое значение.
Выясним причину, по которой код автора часто ломается после добавления новых полей. Если в поле Выборка.stock или Выборка.packet_id передается ссылка на объект (например, СправочникСсылка.Склады), 1С не сможет ее записать. JSON — это текстовый формат, он не знает, что такое «ссылка на таблицу базы данных».
Проанализируем фрагмент кода:
СтруктураСклад = Новый Структура;
СтруктураСклад.Вставить("stock", Выборка.stock); // Ошибка, если тут Ссылка
СтруктураТовара.Вставить("stockData", СтруктураСклад);
Правильный подход: Вместо ссылки нужно передавать строковое представление или уникальный идентификатор.
// Вариант 1: Передача наименования
СтруктураСклад.Вставить("stock", Строка(Выборка.stock));
// Вариант 2: Передача UUID
СтруктураСклад.Вставить("stock_uuid", Строка(Выборка.stock.УникальныйИдентификатор()));
Посмотрим на поле guid в коде автора. Даже если это поле типа УникальныйИдентификатор, оно может вызвать ошибку. Несмотря на то, что в отладчике GUID выглядит как строка, для платформы 1С это отдельный объектный тип. Перед вставкой в структуру его всегда нужно принудительно преобразовывать в строку с помощью функции Строка().
Проанализируем еще несколько моментов из сообщения автора, которые могут косвенно влиять на стабильность кода:
КоличествоЗаписейВТаблице = Выборка.count;. Важно помнить, что у объекта ВыборкаИзРезультатаЗапроса нет свойства count. Правильно использовать метод Выборка.Количество(). Ошибочное обращение может вернуть значение, которое позже «отравит» вашу структуру некорректным типом.Если НЕ Выборка.image.Пустая Тогда не выполняется), переменная ДанныеBase64 может содержать данные от предыдущего товара. Рекомендуется явно инициализировать переменную: ДанныеBase64 = ""; в начале каждой итерации цикла.Рассмотрим, как должен выглядеть надежный код для формирования JSON, исключающий подобные ошибки:
Выборка = Запрос.Выполнить().Выбрать();
Товары = Новый Массив();
Пока Выборка.Следующий() Цикл
СтруктураТовара = Новый Структура();
// 1. Примитивные типы заполняем аккуратно
// Рекомендуется проверять на NULL каждое поле, если нет уверенности в запросе
СтруктураТовара.Вставить("id", Строка(Выборка.id));
СтруктураТовара.Вставить("name", Выборка.name);
// 2. Обработка чисел (заменяем NULL на 0)
СтруктураТовара.Вставить("quantity", ?(Выборка.quantity = NULL, 0, Выборка.quantity));
// 3. Обработка вложенных структур (только примитивы!)
СтруктураСклад = Новый Структура();
// Вместо ссылки пишем представление склада
СтруктураСклад.Вставить("stock_name", Строка(Выборка.stock));
СтруктураТовара.Вставить("stockData", СтруктураСклад);
// 4. Обработка UUID
СтруктураТовара.Вставить("guid", Строка(Выборка.guid));
// 5. Обработка Binary/Base64
ДанныеBase64 = "";
Если ЗначениеЗаполнено(Выборка.image) Тогда
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(Выборка.image);
ДанныеBase64 = Base64Строка(ДвоичныеДанные);
// Очистка от спецсимволов переноса строк
ДанныеBase64 = СтрЗаменить(СтрЗаменить(ДанныеBase64, Символы.ВК, ""), Символы.ПС, "");
КонецЕсли;
СтруктураТовара.Вставить("image_data", ДанныеBase64);
Товары.Добавить(СтруктураТовара);
КонецЦикла;
СтруктураДанных = Новый Структура("Items", Товары);
// Запись в строку JSON
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, СтруктураДанных);
РезультатJSON = Запись.Закрыть();
Если ошибка «Недопустимое значение параметра (параметр номер 2)» все равно появляется, выполните следующие действия:
ЗаписатьJSON.СправочникСсылка..., ДокументСсылка... или NULL — это и есть причина сбоя.Соблюдение этих простых правил типизации позволит вам создавать надежные механизмы обмена данными.