Строка в число на встроенном языке 1С: от Число() до массовой загрузки

· 9 мин

Содержание

Строку переводят в число функцией Число(Строка): Число("1250.75") вернёт 1250,75. Если в строке есть что-то кроме цифр, знака минус и точки, платформа выбросит исключение Преобразование значения к типу Число не может быть выполнено. Поэтому в рабочем коде вызов оборачивают в Попытка или заменяют на ОписаниеТипов("Число").ПривестиЗначение(), которое не падает, а возвращает 0.

Типичная ситуация: бухгалтер присылает выгрузку из банка или Excel, суммы в ней записаны как «1 250,75», и обработка загрузки валится на первой же строке. Перевести строку в число в 1С несложно, но сначала строку нужно привести к виду, который понимает платформа. Ниже — способы, подготовка данных, скорость на больших объёмах и что делать в запросе. Всё относится к платформе 8.3 и не зависит от конфигурации.

Чем перевести строку в число в 1С: четыре способа

В платформе нет функции ЧислоИзСтроки — это название встречается в форумах и чужих общих модулях. Штатных путей четыре.

Функция Число()

Самый прямой вариант. Ждёт строку с точкой в качестве десятичного разделителя.

Сумма = Число("1250.75");   // 1250.75
Сдача = Число("-15");        // -15
Код   = Число("007");        // 7, ведущие нули отбрасываются

На некорректной строке — исключение. Это не баг, а способ сказать, что данные плохие.

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

Приводит значение к указанному типу. Если привести нельзя, возвращает значение по умолчанию для типа, то есть 0.

ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
Сумма = ТипЧисло.ПривестиЗначение("1250.756");  // 1250.76 — округлено до 2 знаков
Брак  = ТипЧисло.ПривестиЗначение("abc");       // 0, без исключения

Минус способа: «0» в исходной строке и мусор дают один результат. Если важно отличить ошибку от нуля — этот вариант не подходит.

XMLЗначение()

Читает число из XML-представления, где разделитель всегда точка.

Сумма = XMLЗначение(Тип("Число"), "1250.75");

Удобно в паре с XMLСтрока(): что записали XMLСтрока(Сумма), то гарантированно прочитаете обратно. На мусоре тоже выбрасывает исключение.

СтрокаВЧисло() из БСП

Во всех типовых конфигурациях на Библиотеке стандартных подсистем есть СтроковыеФункцииКлиентСервер.СтрокаВЧисло(Значение). Если строку не удалось преобразовать, функция возвращает Неопределено. В самописной конфигурации без БСП её нет.

СпособОшибка на мусореПлюсМинус
Число()исключениебыстрый, понятныйнужен Попытка
ОписаниеТипов.ПривестиЗначение()возвращает 0не падает, округляет по квалификатору0 и ошибка неразличимы
XMLЗначение()исключениенадёжен для обменатолько «XML-формат» строки
СтрокаВЧисло() (БСП)Неопределеноошибка видна явнотолько в конфигурациях с БСП

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

Попытка — Исключение

Базовый шаблон для единичного значения:

Попытка
    Количество = Число(СтрокаКоличества);
Исключение
    Количество = 0;
    Сообщить(СтрШаблон("Строка %1: не число «%2»", НомерСтроки, СтрокаКоличества));
КонецПопытки;

Не глотайте исключение молча. Пустой блок Исключение превращает кривые данные в нули, и бухгалтер узнает о проблеме только при сверке остатков.

Склеивая сообщение, не подставляйте число напрямую: "Строка " + 1250 даст «1 250» с неразрывным пробелом. Для номеров строк используйте Формат(НомерСтроки, "ЧГ=0") или СтрШаблон().

Проверка перед преобразованием

Если нужно точно знать, что строка — число, проверьте её посимвольно. Функция ниже допускает цифры, одну точку и минус только в начале:

Функция ЭтоЗаписьЧисла(Текст)
    Цифры = "0123456789";
    БылаТочка = Ложь;
    БылаЦифра = Ложь;
    Для Позиция = 1 По СтрДлина(Текст) Цикл
        Символ = Сред(Текст, Позиция, 1);
        Если СтрНайти(Цифры, Символ) > 0 Тогда
            БылаЦифра = Истина;
        ИначеЕсли Символ = "." И Не БылаТочка Тогда
            БылаТочка = Истина;
        ИначеЕсли Символ = "-" И Позиция = 1 Тогда
            Продолжить;
        Иначе
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;
    Возврат БылаЦифра;
КонецФункции

Строки «-», «.» и пустая строка вернут Ложь: флаг БылаЦифра не даст их пропустить.

Универсальная функция для общего модуля

Объединим очистку, проверку и преобразование. Функцию удобно положить в общий модуль с флагами «Клиент» и «Сервер»:

Функция СтрокаВЧислоБезопасно(Знач Значение, ПоУмолчанию = 0) Экспорт
    Если ТипЗнч(Значение) = Тип("Число") Тогда
        Возврат Значение;
    КонецЕсли;
    Текст = СокрЛП(Строка(Значение));
    Текст = СтрЗаменить(Текст, Символы.НПП, "");
    Текст = СтрЗаменить(Текст, " ", "");
    Текст = СтрЗаменить(Текст, ",", ".");
    Если Не ЭтоЗаписьЧисла(Текст) Тогда
        Возврат ПоУмолчанию;
    КонецЕсли;
    Возврат Число(Текст);
КонецФункции

После ЭтоЗаписьЧисла строка содержит только допустимые символы, поэтому Попытка здесь уже не нужна. Через параметр ПоУмолчанию можно передать Неопределено, чтобы отличать ошибку от нуля.

Отдельно о значениях, которые приходят из запроса или реквизита составного типа. Там вместо строки бывает Null или Неопределено. Строка(Null) даёт пустую строку, поэтому функция вернёт ПоУмолчанию, а не упадёт. Но если такие значения в данных встречаться не должны, лучше поймать их раньше: проверьте Значение = Null до вызова и запишите номер строки в журнал загрузки. Тогда пустые суммы не растворятся среди честных нулей.

Запятая, пробелы и валюта: как подготовить строку к переводу в число

Чаще всего строка не переводится не из-за букв, а из-за формата. Вот что приходит из внешних источников и что с этим делать:

Исходная строкаОткуда берётсяЧто сделать
1250,75Excel, ручной вводзаменить запятую на точку
1 250,75 (неразрывный пробел)Строка() от числа, печатные формыубрать Символы.НПП и запятую заменить
1 250.75 (обычный пробел)CSV, банковские выпискиубрать пробелы
1250.75 руб.текстовые отчётыотрезать хвост, оставить цифры
(1250.75)бухгалтерские отчёты, отрицательные суммыскобки → минус
1,250.75англоязычные системысначала убрать запятую, точку не трогать

Последняя строка — ловушка. Если универсально менять запятую на точку, «1,250.75» превратится в «1.250.75», проверка вернёт Ложь, и сумма станет нулём. Когда источник известен, пишите отдельную очистку под него.

💡 При загрузке из табличного документа читайте не Область.Текст, а значение ячейки, если оно хранится как число. Текст ячейки — это то, что видно на экране, с разделителями групп и форматом. Значение (свойство Значение при СодержитЗначение = Истина) уже является числом, и переводить ничего не нужно.

  • 🔍 Перед загрузкой файла проверьте 5–10 строк глазами: где разделитель, есть ли пробелы.
  • 🧹 Чистите строку в одной функции, а не разбросанными СтрЗаменить по всей обработке.
  • 🧾 Логируйте исходное значение строки, которая не прошла: так проще найти виновника в файле.

Обратный путь: как записать число в строку, чтобы потом её прочитать

Классическая ошибка — сохранить число через Строка() и потом пытаться прочитать его через Число():

Текст = Строка(1250.75);   // "1 250,75" — с разделителем групп и запятой
Сумма = Число(Текст);      // исключение

Строка() форматирует число по региональным настройкам: разделитель групп разрядов и запятая. Чтобы записать число в «машинный» вид, есть два варианта:

Текст1 = Формат(1250.75, "ЧРД=.; ЧГ=0");   // "1250.75"
Текст2 = XMLСтрока(1250.75);                // "1250.75"

ЧРД задаёт символ десятичного разделителя, ЧГ=0 отключает группировку разрядов. Для хранения в реквизитах, регистрах сведений и файлах обмена берите XMLСтрока() — пару к ней составляет XMLЗначение().

Нулевое значение Формат() по умолчанию возвращает пустую строку. Если затем передать её в Число(), будет исключение. Добавьте параметр ЧН=0, чтобы ноль выводился как «0»: Формат(0, "ЧРД=.; ЧГ=0; ЧН=0").

Перевод строк в числа при массовой загрузке: скорость

На десятке строк разницы между способами нет. На выписке в 50 000 операций или прайсе на 200 000 позиций она становится заметной.

Что тормозит

  • 🐢 Исключения. Выброс и перехват исключения стоит намного дороже обычной проверки. Если в файле много пустых или текстовых ячеек, цикл с Попытка на каждой строке замедляется сильнее всего.
  • 🐢 Создание объектов в цикле. Новый ОписаниеТипов(...) внутри цикла создаёт объект на каждой итерации.
  • 🐢 Клиент-серверные вызовы. Преобразование каждой строки отдельным серверным вызовом из формы — самый медленный вариант из возможных.

Как ускорить

  1. Создайте ОписаниеТипов один раз до цикла и используйте его повторно.
  2. Отсекайте пустые значения проверкой ПустаяСтрока() до любого преобразования.
  3. Передавайте на сервер весь файл или таблицу значений целиком и преобразуйте там одним проходом.
  4. Если источник надёжный (собственная выгрузка через XMLСтрока()), не делайте посимвольную проверку — хватит Число() в Попытка.
ТипСумма = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
Для Каждого СтрокаТЗ Из ТаблицаЗагрузки Цикл
    Если ПустаяСтрока(СтрокаТЗ.СуммаТекст) Тогда
        СтрокаТЗ.Сумма = 0;
        Продолжить;
    КонецЕсли;
    Текст = СтрЗаменить(СтрЗаменить(СтрокаТЗ.СуммаТекст, " ", ""), ",", ".");
    СтрокаТЗ.Сумма = ТипСумма.ПривестиЗначение(Текст);
КонецЦикла;

Ещё быстрее — сразу задать колонке таблицы значений тип «Число» через ОписаниеТипов: при присвоении строки в такую колонку значение будет приведено к типу колонки. Правило то же, что у ПривестиЗначение: непреобразуемое станет нулём.

Строка в число в запросе 1С

В языке запросов ВЫРАЗИТЬ не умеет превращать строку в число. Конструкция ВЫРАЗИТЬ(Таблица.Код КАК ЧИСЛО(10, 0)) для строкового поля даст ошибку несовместимости типов. Функции Число() в запросе нет.

Что делают на практике:

  1. Преобразуют после запроса. Выгружают результат в таблицу значений и проходят по ней кодом. Самый простой и надёжный вариант.
  2. Добавляют числовой реквизит. Если поле постоянно нужно как число (сортировка, сравнение), заведите реквизит типа «Число» и заполняйте его при записи объекта. В том числе в расширении, если конфигурация типовая.
  3. Разбирают по символам через ВЫБОР. Для коротких строк фиксированной длины цифру можно получить так:
ВЫБОР ПОДСТРОКА(Т.Код, 1, 1)
    КОГДА "1" ТОГДА 1 КОГДА "2" ТОГДА 2 КОГДА "3" ТОГДА 3
    КОГДА "4" ТОГДА 4 КОГДА "5" ТОГДА 5 КОГДА "6" ТОГДА 6
    КОГДА "7" ТОГДА 7 КОГДА "8" ТОГДА 8 КОГДА "9" ТОГДА 9
    ИНАЧЕ 0
КОНЕЦ * 100

Для трёхзначного кода повторяют блок для второго и третьего символа с множителями 10 и 1 и складывают. Работает, но читается тяжело и ломается на любом нецифровом символе. Используйте этот приём только когда без вычисления в самом запросе не обойтись — например, в условии отбора по диапазону кодов.

💡 Часто числовое преобразование кода нужно только для правильной сортировки («2» после «10»). Если коды одной длины с ведущими нулями («0002», «0010»), строковая сортировка уже совпадает с числовой.

Ошибки при переводе строки в число и как их разобрать

Диагностика: выберите симптом

Частые вопросы

Как проверить, что значение уже является числом?
Сравните тип: ТипЗнч(Значение) = Тип("Число"). Если условие истинно, преобразование не нужно.
Можно ли перевести в число строку с шестнадцатеричной записью?
Да, в платформе 8.3 есть отдельные функции ЧислоИзШестнадцатеричнойСтроки() и ЧислоИзДвоичнойСтроки(). Требования к формату строки уточните в синтаксис-помощнике конфигуратора.
Почему Число() принимает «007» и возвращает 7?
Ведущие нули не несут значения для числа и отбрасываются. Если нули важны (артикулы, коды), храните такое значение строкой.
Как перевести строку в число с округлением до копеек?
Используйте ОписаниеТипов с квалификатором Новый КвалификаторыЧисла(15, 2) или примените Окр(Число(Текст), 2) после преобразования.
Что вернёт СтрокаВЧисло из БСП на пустой строке?
Неопределено, как и на любой непреобразуемой строке. Проверяйте результат на Неопределено до использования в расчётах.