При загрузке данных из внешних источников (текстовых файлов, выгрузок из Excel, CSV или сторонних баз данных) мы нередко сталкиваемся с числами в экспоненциальном виде (научной нотации), например 2,60096E+13 или 0.260096E+14. Задача заключается в том, чтобы корректно преобразовать такую строку в стандартное числовое значение платформы 1С (например, 26009600000000) и вывести его в реквизит формы или записать в базу данных.
Выясним причину, почему стандартные подходы вызывают затруднения. Встроенная функция Число(), а также метод XMLЗначение(Тип("Число"), СтрокаЗначения) в платформе 1С не поддерживают экспоненциальную нотацию напрямую: при попытке преобразования такой строки генерируется исключение «Преобразование значения к типу Число не может быть выполнено». Функция Формат() также не решает задачу парсинга, так как предназначена исключительно для форматирования уже имеющегося числового типа в строку.
Разберем основные проверенные способы решения этой задачи.
Спецификация формата JSON изначально поддерживает числа в экспоненциальной форме записи. Платформа 1С содержит встроенные высокопроизводительные объекты для работы с JSON, которые корректно парсят такие значения в стандартный тип Число.
Проанализируем нюанс: синтаксис JSON требует, чтобы разделителем дробной части была точка, а не запятая. Поэтому перед разбором строки заменим все запятые на точки с помощью функции СтрЗаменить().
Посмотрим на пример универсальной функции преобразования:
Функция ПреобразоватьЭкспонентуВЧислоJSON(Знач ИсходнаяСтрока) Экспорт
// Заменяем разделитель дробной части на точку
СтрокаJSON = СтрЗаменить(СокрЛП(ИсходнаяСтрока), ",", ".");
// Инициализируем объект чтения JSON
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
Попытка
Результат = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Возврат Результат;
Исключение
ЧтениеJSON.Закрыть();
ВызватьИсключение "Ошибка разбора экспоненциального числа: " + ОписаниеОшибки();
КонецПопытки;
КонецФункции
Этот метод является кроссплатформенным, работает на сервере и клиенте под любыми операционными системами (Windows, Linux, macOS).
Число в экспоненциальной записи математически представляет собой произведение мантиссы на 10 в указанной степени: Мантисса * 10^(Порядок). Например, запись 2,60096E+13 означает 2,60096 * 10^13.
Разберем по шагам реализацию собственного алгоритма парсинга строки:
ВРег(), чтобы обработать как русскую «Е», так и латинскую «E».СтрНайти().Число().Мантисса * Pow(10, Степень).Посмотрим на пример программной реализации:
Функция ПреобразоватьЭкспонентуВЧисло(Знач ИсходнаяСтрока) Экспорт
СтрокаОбработки = ВРег(СокрЛП(ИсходнаяСтрока));
// Поддерживаем как латинскую 'E', так и русскую 'Е'
ПозицияЕ = СтрНайти(СтрокаОбработки, "E");
Если ПозицияЕ = 0 Тогда
ПозицияЕ = СтрНайти(СтрокаОбработки, "Е");
КонецЕсли;
// Если экспоненты нет, выполняем стандартное преобразование
Если ПозицияЕ = 0 Тогда
Возврат Число(СтрокаОбработки);
КонецЕсли;
// Получаем мантиссу и показатель степени
СтрокаМантиссы = Лев(СтрокаОбработки, ПозицияЕ - 1);
СтрокаСтепени = Сред(СтрокаОбработки, ПозицияЕ + 1);
// Убираем знак плюс, если он присутствует в степени
СтрокаСтепени = СтрЗаменить(СтрокаСтепени, "+", "");
Мантисса = Число(СтрокаМантиссы);
Степень = Число(СтрокаСтепени);
Возврат Мантисса * Pow(10, Степень);
КонецФункции
Рассмотрим альтернативный вариант для толстого клиента под управлением Windows с использованием COM-объекта MSScriptControl.ScriptControl. Движок VBScript или JScript автоматически распознает экспоненциальную нотацию чисел при выполнении функции Eval().
Функция ПреобразоватьЭкспонентуЧерезCOM(Знач ИсходнаяСтрока) Экспорт
// Заменяем запятую на точку для соответствия синтаксису скрипта
СтрокаДляВычисления = СтрЗаменить(СокрЛП(ИсходнаяСтрока), ",", ".");
Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "JScript";
Результат = Скрипт.Eval(СтрокаДляВычисления);
Возврат Число(Результат);
КонецФункции
Обратите внимание: данный способ считается устаревшим и не рекомендуется для современных конфигураций из-за привязки к платформе Windows и разрядности процесса.
После того как число успешно получено и записано в реквизит, интерфейс платформы 1С по умолчанию может форматировать его с группировкой триад (например, 26 009 600 000 000). Если требуется видеть сплошную строку цифр вида 26009600000000, настроим форматирование элемента формы:
ЧГ=0 (отключение группировки разрядов).ЧДЦ=0. Итоговая строка формата: ЧДЦ=0; ЧГ=0.Также форматную строку можно применить программно при выводе данных строкой:
СтрокаОтображения = Формат(ИтоговоеЧисло, "ЧДЦ=0; ЧГ=0");
Учитывайте ограничения платформы 1С: максимальная разрядность типа Число составляет 38 знаков (включая целую и дробную части). Если степень числа превышает допустимую разрядность, при вычислениях возникнет переполнение.