Как в 1С передать число в формате с десятичными знаками (например, 1.00) в JSON без кавычек

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними системами на языках C++, Java или C# программисты часто сталкиваются с жесткими требованиями к формату данных. Одной из таких проблем является передача дробных чисел. В 1С тип Число является универсальным, и при стандартной сериализации в JSON платформа оптимизирует вывод: если дробная часть равна нулю, она просто отбрасывается. Например, вместо ожидаемого 1.00 внешняя система получает 1. Для строго типизированных приемников это может стать проблемой, так как они могут интерпретировать 1 как целое число (Integer), в то время как поле ожидает число с плавающей точкой (Float или Double).

В этой статье мы разберем, почему так происходит и какими способами можно заставить 1С выводить число именно в формате 1.00, не превращая его при этом в строку.

Причина проблемы: Стандарты JSON и логика 1С

Проанализируем ситуацию. Согласно стандарту JSON (ECMA-404), числа 1 и 1.00 математически эквивалентны. Платформа 1С:Предприятие при использовании метода ЗаписатьЗначение() придерживается принципа минимизации объема данных. Если у числа нет значащей дробной части, точка и нули не пишутся.

Если мы попробуем передать отформатированную строку, например, с помощью функции Формат(Число, "ЧГ=0; ЧРД=."), то в JSON мы получим значение в кавычках: "1.00". Для принимающей стороны это уже не число, а текст, что зачастую недопустимо. Рассмотрим, как обойти это ограничение.

Решение №1: Использование метода ЗаписатьБезОбработки (Raw JSON)

Это самый эффективный и гибкий способ. В объекте ЗаписьJSON существует специальный метод ЗаписатьБезОбработки() (в англоязычном варианте WriteRaw). Он позволяет вставить в поток JSON любую строку "как есть", без добавления кавычек и проверки синтаксиса.

Разберем по шагам, как реализовать этот алгоритм:

  1. Подготовим строковое представление числа с нужным количеством знаков после запятой.
  2. Убедимся, что в качестве разделителя используется точка (стандарт JSON).
  3. Запишем полученную строку напрямую в поток.

Посмотрим на пример кода:


// Исходные данные
МоеЧисло = 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}. Это именно то, что требовалось — числовой тип с фиксированной точностью без кавычек.

Решение №2: Сериализация через XDTO

Рассмотрим более сложный, но "правильный" с точки зрения архитектуры 1С способ. Тип Число в 1С соответствует типам XML Schema: decimal, double, float. Если ваша интеграция строится на использовании XDTO-пакетов, вы можете явно указать тип свойства.

Выясним причину, почему это может помочь. При использовании СериализаторXDTO для записи в JSON, платформа опирается на метаданные типа. Если в схеме указано, что поле имеет тип xsd:double, система при определенных условиях может сохранять форматирование, соответствующее этому типу данных.

Однако стоит учитывать, что этот метод менее предсказуем для простых задач, чем ЗаписатьБезОбработки, так как механизмы сериализации XDTO в JSON в 1С также стремятся к оптимизации и могут "схлопывать" нули, если настройки платформы это позволяют.

Решение №3: Обработка на стороне приемника

Проанализируем ситуацию с точки зрения архитектуры системы в целом. Требование передавать 1.00 вместо 1 в формате JSON часто свидетельствует о слабой реализации парсера на принимающей стороне. В современных веб-стандартах считается хорошим тоном, когда принимающая сторона самостоятельно выполняет приведение типов (casting).

Если у вас есть доступ к коду принимающей системы, мы рекомендуем настроить модель данных там. Например:

В этом случае парсер автоматически преобразует 1 в 1.0 при десериализации объекта, и проблема исчезнет сама собой без манипуляций с формированием JSON в 1С.

Важные нюансы при работе с числами в JSON

При использовании любого из методов помните о следующих особенностях:

  1. Региональные установки: Никогда не полагайтесь на стандартное преобразование числа в строку, так как разделитель (запятая или точка) зависит от настроек операционной системы или сеанса 1С. Всегда явно указывайте ЧРД=. в функции Формат().
  2. Экспоненциальная запись: Для очень маленьких или очень больших чисел 1С может использовать экспоненциальную запись (например, 1E-5). Если принимающая сторона ее не поддерживает, вам также придется использовать метод ЗаписатьБезОбработки для принудительного вывода в стандартном десятичном виде.
  3. Точность типов: Помните, что типы float и double в языках программирования — это числа с плавающей запятой. В отличие от 1С, они могут хранить значения неточно (например, 0.9999999997 вместо 1). Если точность критична (финансовые расчеты), настаивайте на использовании строкового формата или типа decimal на обеих сторонах.

Подведем итог: Если сторонний разработчик требует от вас "число с точкой" в JSON, самым быстрым и надежным инструментом в 1С будет комбинация функции Формат() и метода ЗаписатьБезОбработки(). Это позволит вам полностью контролировать каждый байт, уходящий в канал связи, и гарантировать совместимость систем.

← На главную