К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как преобразовать значение в число в 1С

Как преобразовать строку или другое значение в число в 1С: функция Число(), ОписаниеТипов, обработка ошибок, разделители, примеры кода и типичные ошибки разработчиков.

Преобразование значения в число — одна из самых частых операций при разработке на встроенном языке 1С. Данные приходят из файлов Excel и CSV, из веб-сервисов, из полей ввода на форме, и почти всегда они представлены строкой. Пока значение остаётся строкой, с ним нельзя выполнять арифметику, сравнения по величине и корректную сортировку.

Платформа 1С:Предприятие предлагает несколько способов такого преобразования: функцию Число(), приведение через ОписаниеТипов, методы работы со строками из типовых библиотек. У каждого способа есть ограничения: одни вызывают исключение при неверных данных, другие молча возвращают ноль. Выбор зависит от того, насколько вы доверяете источнику данных и что должно произойти при ошибке.

Ниже разобраны основные приёмы преобразования, обработка нестандартных форматов (пробелы, запятые, неразрывные пробелы), проверка результата и типичные ошибки, которые приводят к потере данных или падению кода.

Функция Число() — базовый способ преобразования

Встроенная функция Число() принимает значение и возвращает его числовое представление. Она работает со строками, булевыми значениями и датами. Синтаксис предельно прост:

Результат = Число("123,45");   // 123,45

Результат = Число(Истина); // 1

Результат = Число(Ложь); // 0

При преобразовании строки функция строга к формату. Строка должна содержать только цифры, необязательный знак минус в начале и один разделитель дробной части. Допустимы как точка, так и запятая — платформа распознаёт оба варианта. Любые другие символы (буквы, пробелы внутри числа, символы валют) приводят к ошибке «Преобразование значения к типу Число не может быть выполнено».

Важная особенность: пустая строка и строка из пробелов также вызывают исключение. Поэтому вызывать Число() напрямую на данных из внешних источников без предварительной проверки небезопасно.

Обработка ошибок через Попытка/Исключение

Самый надёжный способ защититься от падения кода — обернуть преобразование в конструкцию Попытка...Исключение. В блоке исключения можно задать значение по умолчанию и записать проблемную строку в журнал регистрации для последующего разбора.

Функция СтрокаВЧисло(Строка)

Результат = 0;

Попытка

Результат = Число(Строка);

Исключение

ЗаписьЖурналаРегистрации("Загрузка данных",

УровеньЖурналаРегистрации.Предупреждение,,,

"Не удалось преобразовать в число: " + Строка);

КонецПопытки;

Возврат Результат;

КонецФункции

Такой подход удобен при пакетной загрузке: одна «битая» строка не остановит обработку тысячи корректных записей. Недостаток — исключения в платформе относительно дорогая операция, поэтому в циклах с большим процентом ошибок лучше сначала проверять строку, а не ловить исключения.

bsl
Попытка
    Значение = Число(СтрокаИзФайла);
Исключение
    Значение = 0;
КонецПопытки;

Очистка строки перед преобразованием

Реальные данные редко приходят в чистом виде. Числа из Excel часто содержат пробелы-разделители разрядов («1 234 567»), неразрывные пробелы (символ с кодом 160), символы валют и разные разделители дробной части. Перед вызовом Число() строку нужно нормализовать.

Типовая последовательность очистки выглядит так:

Строка = "1 234 567,89 руб.";

Строка = СтрЗаменить(Строка, Символ(160), ""); // неразрывный пробел

Строка = СтрЗаменить(Строка, " ", ""); // обычные пробелы

Строка = СтрЗаменить(Строка, "руб.", "");

Строка = СокрЛП(Строка);

Значение = Число(Строка); // 1234567,89

Неразрывный пробел — самая коварная проблема: визуально он неотличим от обычного пробела, но СокрЛП() и замена обычного пробела его не убирают. Если преобразование «непонятно почему» падает на внешне корректной строке, проверьте наличие символа с кодом 160 в первую очередь.

Порядок действий
  1. 1
    Уберите неразрывные пробелы: СтрЗаменить(Строка, Символ(160), "")
  2. 2
    Удалите обычные пробелы и посторонние символы (валюта, единицы измерения)
  3. 3
    При необходимости приведите разделитель дробной части к точке или запятой
  4. 4
    Выполните СокрЛП() и вызовите Число() внутри Попытка/Исключение
  5. 5
    Проверьте результат на контрольном примере с дробным числом

Преобразование через ОписаниеТипов

Альтернативный способ — приведение значения через объект ОписаниеТипов. Метод ПривестиЗначение() не вызывает исключения: если преобразование невозможно, он возвращает значение по умолчанию для типа, то есть ноль.

ОписаниеЧисла = Новый ОписаниеТипов("Число",

Новый КвалификаторыЧисла(15, 2));

Значение = ОписаниеЧисла.ПривестиЗначение("abc"); // 0, без ошибки

Такой вариант удобен, когда ошибочное значение равнозначно нулю и прерывать выполнение не нужно. Кроме того, ОписаниеТипов позволяет сразу ограничить разрядность: лишние знаки после запятой будут отброшены по правилам округления платформы.

Однако у молчаливого преобразования есть обратная сторона: «тихий» ноль может замаскировать проблему в данных. Если ноль и ошибка для вашей логики — разные вещи, комбинируйте приведение с проверкой исходной строки или используйте вариант с исключением.

Сравнение вариантов

Число()

Быстро и просто, но падает с ошибкой на некорректной строке. Подходит для гарантированно чистых данных.

Попытка/Исключение + Число()

Надёжно для ненадёжных источников, позволяет логировать ошибки. Чуть медленнее при массовых ошибках.

ОписаниеТипов.ПривестиЗначение()

Не вызывает исключений, возвращает 0 при ошибке. Риск: ошибка в данных маскируется нулём.

Преобразование других типов в число

Булево и дата

Булевы значения преобразуются однозначно: Истина становится единицей, Ложь — нулём. Это используется, например, при выгрузке флагов в форматы, где допустимы только числа.

Дата функцией Число() преобразуется в количество секунд, прошедших с начала эпохи (1 января 0001 года). На практике такое преобразование применяется редко; чаще нужен обратный приём — получить из даты год, месяц или день через функции Год(), Месяц(), День(), которые уже возвращают числа.

Значения из полей формы

Если реквизит формы имеет строковый тип, а пользователь вводит туда числа, преобразование выполняется теми же средствами. Но правильнее сразу задать реквизиту тип «Число» — тогда платформа сама контролирует ввод, не допускает буквы и хранит значение в нужном виде, избавляя от ручного преобразования.

Типичные ошибки и как их избежать

Первая распространённая ошибка — преобразование строки с разделителем групп разрядов. Число «1 000 000» после удаления пробелов превращается в корректное значение, но если разделитель — точка («1.000.000» в некоторых локалях), результат будет совершенно иным. Всегда уточняйте формат источника данных перед написанием кода очистки.

Вторая ошибка — потеря точности при работе с большими числами. Числа в 1С имеют ограниченную разрядность (по умолчанию при хранении в реквизитах — до 38 знаков, но конкретный предел задаётся квалификаторами). Если вы приводите значение через ОписаниеТипов с квалификатором 15,2, а исходное число длиннее, «лишняя» часть будет отброшена без предупреждения.

Третья ошибка — использование строковых функций поиска для проверки «числовости». Проверка вида «если в строке только цифры» через перебор символов надёжнее реализуется регулярными выражениями или попыткой преобразования, а ручные проверки часто забывают про знак минус и разделитель дробной части.

Типичные ошибки
01
Вызов Число() на сырой строке из файла — исключение останавливает всю загрузку данных
02
Игнорирование неразрывного пробела (Символ(160)) — преобразование падает на визуально корректной строке
03
Молчаливое приведение через ОписаниеТипов без логирования — ошибки в данных превращаются в незаметные нули
04
Отбрасывание разрядности через узкие квалификаторы числа — теряется дробная часть или старшие разряды

Проверка результата преобразования

После преобразования полезно убедиться, что результат соответствует ожиданиям. Минимальный набор проверок: тип значения (ТипЗнч(Значение) = Тип("Число")), попадание в допустимый диапазон и совпадение с исходной строкой после обратного форматирования.

Для контрольных примеров берите граничные случаи: отрицательное число, число с дробной частью, строку с пробелами-разделителями, пустую строку. Если обработка корректно отрабатывает все четыре случая, она с высокой вероятностью выдержит реальные данные.

Контрольные точки

Как проверить результат

Тип результата
Норма

ТипЗнч() возвращает Число

Тревожный признак

Осталась строка или Неопределено

Дробная часть
Норма

1234,56 преобразуется в 1234,56

Тревожный признак

Дробная часть обрезана или число умножено на 100

Ошибочные данные
Норма

Некорректная строка даёт 0 и запись в журнале

Тревожный признак

Выполнение прерывается исключением

Часто задаваемые вопросы

Что вернёт Число() для пустой строки?

Функция вызовет исключение «Преобразование значения к типу Число не может быть выполнено». Если пустые значения допустимы, проверяйте строку через ПустаяСтрока() до вызова или используйте ОписаниеТипов.ПривестиЗначение(), который вернёт 0.

Как преобразовать строку с запятой, если данные приходят с точкой?

Функция Число() понимает оба разделителя — и точку, и запятую, поэтому замена обычно не нужна. Замена требуется только когда в одной строке встречаются оба символа (например, «1,234.56»): тогда сначала удалите разделитель разрядов, затем приведите дробный разделитель к одному виду.

Можно ли преобразовать в число значение типа Неопределено или NULL?

Напрямую — нет, будет ошибка. Сначала замените такие значения, например: Строка = ?(Значение = Неопределено, "0", Значение). При работе с результатами запросов NULL удобно обрабатывать функцией ЕСТЬNULL(Поле, 0) прямо в тексте запроса.

Чем отличается Число() от приведения в запросе через ВЫРАЗИТЬ?

ВЫРАЗИТЬ(Поле КАК ЧИСЛО(15,2)) работает на уровне СУБД в запросе и при невозможности преобразования возвращает NULL, а не ошибку. Число() работает в коде встроенного языка и при ошибке вызывает исключение. Выбор зависит от того, где обрабатываются данные.

Как проверить, что строка содержит число, не вызывая исключение?

Используйте ОписаниеТипов.ПривестиЗначение() и сравните результат с исходной строкой через обратное форматирование, либо примените регулярное проверку на допустимые символы. В типовых конфигурациях также встречаются готовые функции вида СтроковыеФункцииКлиентСервер.СтрокаВЧисло() — проверьте их наличие в вашей конфигурации.

Почему после преобразования пропадают копейки?

Чаще всего причина в квалификаторах числа: если значение приводится через ОписаниеТипов с нулевой точностью или записывается в реквизит с разрядностью дробной части 0, дробная часть отбрасывается. Проверьте квалификаторы числа у реквизита или в описании типов и увеличьте точность до нужного количества знаков.

Итог

Что важно запомнить

Для чистых данных используйте Число(), для ненадёжных — очистку строки плюс Попытка/Исключение, а когда ошибка равнозначна нулю — ОписаниеТипов.ПривестиЗначение(). Всегда помните про неразрывные пробелы и контролируйте разрядность результата.