Работа со строками и числами — одна из самых частых задач при программировании в 1С:Предприятие 8. Некорректное преобразование текстового значения в числовой формат может приводить к ошибкам выполнения, искажению данных или непредсказуемому поведению программы. Особенно актуальна эта проблема при обмене данными между системами, импорте из внешних файлов или обработке пользовательского ввода, где числа часто приходят в виде строк.

В этой статье мы разберём все возможные способы конвертации строк в числа в 1С 8.3, включая стандартные функции платформы, методы обработки ошибок и нюансы работы с разными форматами (десятичные разделители, валюты, даты в числовом виде). Вы узнаете, когда лучше использовать Число(), а когда — Val(), как обрабатывать исключения и почему иногда проще написать свою функцию преобразования.

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

1. Стандартная функция Число(): простое преобразование

Функция Число() — самый очевидный и часто используемый способ преобразования строки в число. Она поддерживает автоматические замены десятичных разделителей (точка/запятая) в соответствии с региональными настройками системы, что делает её удобной для работы с международными форматами.

Базовый синтаксис:

Число = Число(Строка[, РазделительЦелойИДробнойЧасти]);

Примеры использования:

  • 📌 Число("1234,56") → вернёт 1234.56 (если в настройках системы разделитель — запятая)
  • 📌 Число("1,234.56", ".") → явно указываем, что точка — разделитель дробной части
  • 📌 Число(" 500 ") → автоматически обрежет пробелы и вернёт 500

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

💡

Для быстрой проверки формата строки перед преобразованием можно использовать регулярные выражения с функцией СтрСравнить() или Найти() для поиска недопустимых символов.

2. Функция Val(): альтернатива с другими правилами

Функция Val() работает иначе, чем Число(). Она игнорирует все символы, кроме цифр, знаков "+", "-", "." и "E/e" (для научной нотации). Это делает её более устойчивой к "грязным" данным, но одновременно и менее строгой.

Синтаксис проще:

Число = Val(Строка);

Примеры и особенности:

  • 🔢 Val("123abc45") → вернёт 123 (остановится на первом нечисловом символе)
  • 💰 Val("$1,234.56") → вернёт 1 (символ "$" не распознаётся как часть числа)
  • ⚠️ Val("12.34.56") → вернёт 12.34 (вторая точка воспринимается как ошибка)

Главное отличие от Число(): Val() никогда не вызывает исключений. Вместо этого она возвращает 0 для полностью некорректных строк. Это удобно для обработки пользовательского ввода, но требует дополнительной проверки результата.

📊 Какой функцией вы чаще пользуетесь для преобразования строк в числа?
Число()
Val()
Собственная функция
Другое

3. Обработка ошибок при преобразовании

Даже с надёжными функциями вроде Число() всегда есть риск получить ошибку из-за неожиданного формата данных. В для этого предусмотрен механизм Попытка...Исключение.

Пример безопасного преобразования:

Процедура БезопасноеПреобразование(Строка)

Попытка

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

Сообщить("Успешно преобразовано в: " + Результат);

Исключение

Сообщить("Ошибка преобразования: " + ОписаниеОшибки());

Результат = Неопределено; // или 0, в зависимости от логики

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

КонецПроцедуры

Для Val() проверка результата может выглядеть так:

Число = Val(Строка);

Если Число = 0 И НЕ СтрНачинаетсяС(Строка, "0") Тогда

Сообщить("Некорректный формат числа: " + Строка);

КонецЕсли;

Дополнительные меры безопасности:

  • 🛡️ Всегда проверяйте длину строки перед преобразованием
  • 📊 Для валютных значений сначала удаляйте символы валют (СтрЗаменить(Строка, "$", ""))
  • 🔄 При работе с большими объёмами данных используйте Массив для хранения результатов и ошибок
Что делать если строка содержит несколько чисел?

В этом случае можно использовать комбинацию СтрРазделить() и цикла по полученным подстрокам. Например:

Строка = "100;200;300";

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

Для Каждого Элемент Из Числа Цикл

Попытка

МассивЧисел.Добавить(Число(Элемент));

Исключение

МассивЧисел.Добавить(0); // или другой обработчик ошибки

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

КонецЦикла;

4. Работа с разными форматами чисел

Один из самых сложных случаев — когда строки содержат числа в нестандартных форматах: с разделителями тысяч, валютами, научной нотацией или специфическими символами. Здесь стандартные функции могут не справиться.

Распространённые форматы и решения:

Формат примераПроблемаРешение
"1 234,56"Пробел как разделитель тысячСтрЗаменить(Строка, " ", "")
"$1,234.56"Символ валюты в началеСтрЗаменить(Строка, "$", "")
"1.234,56"Европейский формат (точка — тысячи, запятая — дробь)Число(СтрЗаменить(Строка, ".", ""), ",")
"1.23E+05"Научная нотацияИспользовать Val() или парсинг вручную
"12:34:56"Время в виде строкиПреобразовать в секунды через Число(Лев(Строка, 2)) * 3600 + ...

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

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

// Удаляем все нечисловые символы кроме . , + - E e

Значение = СтрЗаменить(Значение, " ", "");

Значение = СтрЗаменить(Значение, "$", "");

// Дальнейшая обработка в зависимости от формата...

Возврат Число(Значение);

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

Удалить символы валют ($, €, ₽)|Заменить разделители тысяч (пробел, запятая)|Проверить наличие знака "-"/"+"|Учесть региональные настройки разделителей|Обработать возможную научную нотацию-->

5. Преобразование строк с датами в числовой формат

Особый случай — когда строка содержит дату, которую нужно преобразовать в числовой формат (например, для расчётов или сравнений). В для этого есть несколько подходов.

Способ 1: Через функцию Дата() с последующим преобразованием:

ДатаИзСтроки = Дата(Строка);

ЧисловойФормат = ДатаИзСтроки.УниверсальныйФормат(); // Например, 20231231 для 31.12.2023

Способ 2: Непосредственное преобразование в число (например, для расчёта разницы в днях):

Дата1 = Дата(2023, 12, 31);

Дата2 = Дата(2023, 1, 1);

РазницаВДнях = Дата1 - Дата2; // Вернёт 364

Важные нюансы:

  • 📅 Формат строки с датой должен соответствовать региональным настройкам (DD.MM.YYYY или MM/DD/YYYY)
  • ⏳ Для временных меток используйте ДобавитьСекунды() или аналогичные функции
  • 🔢 Числовой формат даты (например, 20231231) удобен для сортировки, но не для расчётов
💡

При работе с датами в числовом формате всегда учитывайте, что внутренне хранит даты как количество дней с 01.01.0001. Это позволяет корректно вычислять разницы, но требует аккуратности при ручных преобразованиях.

6. Оптимизация производительности при массовой обработке

Когда нужно преобразовать тысячи или миллионы строк в числа (например, при загрузке больших файлов), стандартные функции могут работать медленно. В таких случаях стоит рассматривать альтернативные подходы.

Способы ускорения:

  1. Пакетная обработка: Используйте Массив и обрабатывайте данные порциями по 1000-5000 элементов.
  2. Регулярные выражения: Для сложных форматов один проход с РегВыражение может быть быстрее, чем несколько СтрЗаменить().
  3. Кэширование: Если одни и те же строки повторяются, храните результаты преобразования в Соответствие.
  4. Низкоуровневые функции: В крайних случаях можно использовать ПобитовоеИ() для работы с ASCII-кодами символов.

Пример оптимизированной функции для массовой обработки:

Процедура МассовоеПреобразование(МассивСтрок)

СоотвРезультатов = Новый Соответствие;

Рег = Новый РегВыражение("^[+-]?\d+[\.,]?\d*");

Для Каждого Строка Из МассивСтрок Цикл

Если НЕ СоотвРезультатов.Содержит(Строка) Тогда

Если Рег.Поиск(Строка) Тогда

СоотвРезультатов.Вставить(Строка, Число(Рег.НайденноеЗначение));

Иначе

СоотвРезультатов.Вставить(Строка, Неопределено);

КонецЕсли;

КонецЕсли;

КонецЦикла;

КонецПроцедуры

Критическая особенность: при обработке более 100 000 строк стандартными методами время выполнения может увеличиваться в геометрической прогрессии. В таких случаях рассмотрите возможность вынесения операции на сервер или использования временных таблиц.

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

Даже опытные разработчики иногда сталкиваются с неочевидными проблемами при преобразовании строк в числа. Вот самые распространённые ошибки:

  • 🚫 Игнорирование региональных настроек: Код работает на одной машине, но падает на другой из-за разных разделителей дробной части.
  • 🚫 Неучтённые пробелы: Строка выглядит как "100", но содержит невидимые символы (СтрДлина(Строка) > 3).
  • 🚫 Переполнение типов: Преобразование слишком большого числа в Число(15,2) без проверки.
  • 🚫 Неявные преобразования: Использование строк в арифметических операциях без явного приведения типов.

Пример опасной конструкции:

// Некорректно! Неявное преобразование

Результат = "100" + 50; // В некоторых контекстах это сработает как сложение строк ("10050")

Правильный вариант:

Результат = Число("100") + 50; // Явное преобразование
💡

Для отладки проблем с преобразованием используйте функцию ТипЗнч(), чтобы убедиться, что вы действительно работаете со строкой, а не с другим типом, который неявно преобразовался.

⚠️ Внимание: При работе с данными из внешних источников (Excel, XML, JSON) всегда проверяйте реальный формат чисел в исходном файле. Например, Excel может экспортировать числа в научной нотации (1.23E+05), что требует специальной обработки.

8. Создание универсальной функции-преобразователя

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

Функция УниверсальноеПреобразованиеВЧисло(Строка, РазделительДробной = ",", УдалятьСимволыВалюты = Истина, ВозвращатьНольПриОшибке = Истина)

Попытка

// Предобработка

Если УдалятьСимволыВалюты Тогда

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

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

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

КонецЕсли;

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

Строка = СтрЗаменить(Строка, "_", ""); // Иногда используется как разделитель

// Преобразование

Если РазделительДробной = "," Тогда

Строка = СтрЗаменить(Строка, ".", ""); // Удаляем точки-разделители тысяч

Возврат Число(Строка, ",");

Иначе

Строка = СтрЗаменить(Строка, ",", ""); // Удаляем запятые-разделители тысяч

Возврат Число(Строка, ".");

КонецЕсли;

Исключение

Если ВозвращатьНольПриОшибке Тогда

Возврат 0;

Иначе

ВызватьИсключение ОписаниеОшибки();

КонецЕсли;

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

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

Преимущества такого подхода:

  • 🔧 Гибкость: можно настроить под конкретные требования проекта
  • 🛠️ Централизованная обработка ошибок
  • 📈 Легко модифицировать для новых форматов
  • 🔍 Упрощает отладку (все преобразования в одном месте)
⚠️ Внимание: При использовании таких функций в распределённых системах (например, в облачных решениях 1С) убедитесь, что региональные настройки на сервере и клиенте совпадают. В противном случае результат может отличаться.

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

Можно ли преобразовать строку с буквами в число, игнорируя символы?

Да, для этого подходит функция Val(). Она остановится на первом нечисловом символе. Например, Val("123abc") вернёт 123. Если нужно извлечь все цифры из строки, потребуется дополнительная обработка с регулярными выражениями.

Как преобразовать строку в число с двумя десятичными разделителями (например, "12.34,56")?

Это типичная проблема при работе с европейскими форматами, где точка используется как разделитель тысяч, а запятая — дробной части. Решение:

Строка = "12.345,67";

Строка = СтрЗаменить(Строка, ".", ""); // Удаляем точки

Результат = Число(Строка, ","); // Указываем запятую как разделитель

Для более сложных случаев (неопределённое количество разделителей тысяч) может понадобиться регулярное выражение.

Почему функция Число() выдаёт ошибку на корректной строке?

Наиболее частые причины:

  1. В строке есть невидимые символы (пробелы, табуляции, символы переноса). Проверьте с помощью СтрДлина() и КодСимвола().
  2. Региональные настройки системы ожидают другой разделитель дробной части (запятая вместо точки или наоборот).
  3. Строка содержит символы валюты или другие недопустимые знаки, которые нужно предварительно удалить.
  4. Передаётся не строка, а другой тип данных (например, Null или Неопределено).

Для диагностики используйте Сообщить(Строка + "|") — это поможет увидеть скрытые символы.

Как преобразовать строку в число с научной нотацией (например, "1.23E+05")?

Функция Число() не поддерживает научную нотацию напрямую. Варианты решения:

  1. Использовать Val(): Val("1.23E+05") вернёт 123000.
  2. Написать собственную функцию парсинга, которая разбирает строку на мантиссу и порядок.
  3. Для массовой обработки рассмотреть внешние компоненты или OLE-объекты (например, через VBScript).

Пример парсинга вручную:

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

Части = СтрРазделить(Строка, "E");

Если Части.Количество() = 2 Тогда

Мантисса = Число(Части[0]);

Порядок = Число(Части[1]);

Возврат Мантисса * Pow(10, Порядок);

Иначе

Возврат Число(Строка);

КонецЕсли;

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

Какая функция быстрее работает: Число() или Val()?

Производительность зависит от конкретной задачи:

  • Число() быстрее, когда строка имеет корректный формат и не требует предобработки.
  • Val() может быть медленнее из-за внутреннего анализа строки, но зато не требует обработки исключений.

Для критических по производительности участков кода (обработка миллионов строк) стоит замерять время выполнения обоих вариантов на реальных данных с помощью ПолучитьИмяВременногоФайла() и таймеров. Часто выигрыш даёт предварительная очистка строк от лишних символов.