При интеграции 1С с внешними системами на языках C++, Java или C# программисты часто сталкиваются с жесткими требованиями к формату данных. Одной из таких проблем является передача дробных чисел. В 1С тип Число является универсальным, и при стандартной сериализации в JSON платформа оптимизирует вывод: если дробная часть равна нулю, она просто отбрасывается. Например, вместо ожидаемого 1.00 внешняя система получает 1. Для строго типизированных приемников это может стать проблемой, так как они могут интерпретировать 1 как целое число (Integer), в то время как поле ожидает число с плавающей точкой (Float или Double).
В этой статье мы разберем, почему так происходит и какими способами можно заставить 1С выводить число именно в формате 1.00, не превращая его при этом в строку.
Проанализируем ситуацию. Согласно стандарту JSON (ECMA-404), числа 1 и 1.00 математически эквивалентны. Платформа 1С:Предприятие при использовании метода ЗаписатьЗначение() придерживается принципа минимизации объема данных. Если у числа нет значащей дробной части, точка и нули не пишутся.
Если мы попробуем передать отформатированную строку, например, с помощью функции Формат(Число, "ЧГ=0; ЧРД=."), то в JSON мы получим значение в кавычках: "1.00". Для принимающей стороны это уже не число, а текст, что зачастую недопустимо. Рассмотрим, как обойти это ограничение.
Это самый эффективный и гибкий способ. В объекте ЗаписьJSON существует специальный метод ЗаписатьБезОбработки() (в англоязычном варианте WriteRaw). Он позволяет вставить в поток JSON любую строку "как есть", без добавления кавычек и проверки синтаксиса.
Разберем по шагам, как реализовать этот алгоритм:
Посмотрим на пример кода:
// Исходные данные
МоеЧисло = 1;
КоличествоЗнаков = 2;
// Формируем строку вида "1.00"
// Параметр ЧРД=. гарантирует точку как разделитель
// Параметр ЧЦ и ЧДЦ управляют точностью
СтрокаЧисла = Формат(МоеЧисло, "ЧГ=0; ЧРД=.; ЧДЦ=" + КоличествоЗнаков);
// Если исходное число целое, Формат может не добавить точку в некоторых случаях,
// поэтому можно выполнить дополнительную проверку
Если Найти(СтрокаЧисла, ".") = 0 Тогда
СтрокаЧисла = СтрокаЧисла + "." + Лев("0000000000", КоличествоЗнаков);
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, " ");
ЗаписьJSON.ОткрытьФайл("C:\temp\data.json", , , ПараметрыЗаписи);
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("amount");
// ВАЖНО: Вместо ЗаписатьЗначение используем ЗаписатьБезОбработки
ЗаписьJSON.ЗаписатьБезОбработки(СтрокаЧисла);
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.Закрыть();
В результате в файле JSON мы увидим структуру: {"amount": 1.00}. Это именно то, что требовалось — числовой тип с фиксированной точностью без кавычек.
Рассмотрим более сложный, но "правильный" с точки зрения архитектуры 1С способ. Тип Число в 1С соответствует типам XML Schema: decimal, double, float. Если ваша интеграция строится на использовании XDTO-пакетов, вы можете явно указать тип свойства.
Выясним причину, почему это может помочь. При использовании СериализаторXDTO для записи в JSON, платформа опирается на метаданные типа. Если в схеме указано, что поле имеет тип xsd:double, система при определенных условиях может сохранять форматирование, соответствующее этому типу данных.
Однако стоит учитывать, что этот метод менее предсказуем для простых задач, чем ЗаписатьБезОбработки, так как механизмы сериализации XDTO в JSON в 1С также стремятся к оптимизации и могут "схлопывать" нули, если настройки платформы это позволяют.
Проанализируем ситуацию с точки зрения архитектуры системы в целом. Требование передавать 1.00 вместо 1 в формате JSON часто свидетельствует о слабой реализации парсера на принимающей стороне. В современных веб-стандартах считается хорошим тоном, когда принимающая сторона самостоятельно выполняет приведение типов (casting).
Если у вас есть доступ к коду принимающей системы, мы рекомендуем настроить модель данных там. Например:
BigDecimal или Double для поля.decimal или double.В этом случае парсер автоматически преобразует 1 в 1.0 при десериализации объекта, и проблема исчезнет сама собой без манипуляций с формированием JSON в 1С.
При использовании любого из методов помните о следующих особенностях:
ЧРД=. в функции Формат().1E-5). Если принимающая сторона ее не поддерживает, вам также придется использовать метод ЗаписатьБезОбработки для принудительного вывода в стандартном десятичном виде.float и double в языках программирования — это числа с плавающей запятой. В отличие от 1С, они могут хранить значения неточно (например, 0.9999999997 вместо 1). Если точность критична (финансовые расчеты), настаивайте на использовании строкового формата или типа decimal на обеих сторонах.Подведем итог: Если сторонний разработчик требует от вас "число с точкой" в JSON, самым быстрым и надежным инструментом в 1С будет комбинация функции Формат() и метода ЗаписатьБезОбработки(). Это позволит вам полностью контролировать каждый байт, уходящий в канал связи, и гарантировать совместимость систем.