В практике разработки на платформе 1С:Предприятие 8 задача преобразования строкового значения в числовое встречается повсеместно: от обработки данных, введенных пользователем, до загрузки сложных прайс-листов из внешних файлов. На первый взгляд кажется, что достаточно одной встроенной функции, но реальность диктует свои условия: лишние пробелы, разные разделители дробной части и специфические символы часто вызывают ошибки. В этой статье мы подробно рассмотрим, как правильно выполнять преобразование, обрабатывать ошибки и работать с данными в «грязных» выборках.
Самый простой и очевидный способ, предусмотренный платформой — использование встроенной функции Число(). Она принимает строку и пытается интерпретировать её как числовое значение. Рассмотрим базовый пример:
// Простое преобразование целого числа
МоеЧисло = Число("100"); // Результат: 100
// Преобразование дробного числа
Цена = Число("25.5"); // Результат: 25.5
Однако стоит помнить, что функция Число() очень чувствительна к содержимому строки. Если в строке встретятся буквы, знаки (кроме плюса, минуса и разделителя) или некорректные символы, система вызовет исключение и выполнение кода прервется. Поэтому использование этой функции напрямую безопасно только тогда, когда вы абсолютно уверены в качестве данных.
Чтобы программа не завершалась аварийно при встрече с некорректными данными (например, если в поле количества попала строка "> 100"), проанализируем ситуацию и применим конструкцию Попытка ... Исключение. Это позволит нам задать значение по умолчанию в случае неудачи.
Функция ПреобразоватьВЧислоБезопасно(ЗначениеСтрока)
Попытка
Возврат Число(ЗначениеСтрока);
Исключение
// Если преобразование не удалось, возвращаем 0 или другое дефолтное значение
Возврат 0;
КонецПопытки;
КонецФункции
В типовых конфигурациях на базе БСП (Библиотеки стандартных подсистем) уже существует готовый метод, который рекомендуется использовать программистам. Рассмотрим его:
ВведеннаяОчередность = СтроковыеФункцииКлиентСервер.СтрокаВЧисло(СтрокаТаблицы.ПредставлениеОчередности);
Этот метод удобен тем, что он не вызывает исключения, а возвращает Неопределено, если строка не является числом, что позволяет элегантно обрабатывать результат в условиях.
Чаще всего проблемы возникают при загрузке данных из Excel. Пользователи могут ставить пробелы для визуального разделения разрядов, использовать запятые вместо точек или добавлять невидимые символы. Разберем по шагам, как подготовить строку к преобразованию. Например, при переносе сведений о продажах маркетплейсов в 1С:Бухгалтерию 3.0 все эти сложности берет на себя обработка для загрузки отчетов о продажах из Excel, которая автоматически разбирает и очищает исходные файлы.
1. Удаление пробелов. Важно знать, что в 1С при выводе чисел часто используется «неразрывный пробел» (символ с кодом 160). Обычная функция СтрЗаменить(Строка, " ", "") его не увидит. Проанализируем правильный подход:
// Удаляем обычные пробелы и неразрывные пробелы
ЧистаяСтрока = СтрЗаменить(ИсходнаяСтрока, " ", "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.НПП, "");
2. Замена разделителя. В зависимости от региональных настроек, разделителем может быть точка или запятая. Чтобы функция Число() отработала корректно, приведем все к единому стандарту:
// Пример комплексной очистки данных из ячейки Excel
ТекстИзФайла = Sheet.Cells(НомерСтроки, НомерКолонки).Text;
ПодготовленнаяСтрока = СтрЗаменить(ТекстИзФайла, ",", "."); // Заменяем запятую на точку
ПодготовленнаяСтрока = СтрЗаменить(ПодготовленнаяСтрока, " ", ""); // Убираем пробелы
Результат = Число(ПодготовленнаяСтрока);
Иногда задача стоит сложнее: нужно получить число из строки вида "Артикул 123-Б". В этом случае стандартные функции не помогут. Рассмотрим алгоритм, который перебирает строку посимвольно и оставляет только цифры:
Функция ИзвлечьТолькоЦифры(Знач ВходнаяСтрока)
РезультатСтрокой = "";
ШаблонЦифр = "0123456789.,"; // Добавляем возможные разделители
Для Позиция = 1 По СтрДлина(ВходнаяСтрока) Цикл
Символ = Сред(ВходнаяСтрока, Позиция, 1);
Если Найти(ШаблонЦифр, Символ) > 0 Тогда
РезультатСтрокой = РезультатСтрокой + Символ;
КонецЕсли;
КонецЦикла;
// После сборки строки пробуем преобразовать её в число
Попытка
Возврат Число(СтрЗаменить(РезультатСтрокой, ",", "."));
Исключение
Возврат 0;
КонецПопытки;
КонецФункции
Для более высокой производительности на больших объемах данных (например, тысячи строк прайса) рекомендуется использовать объект VBScript.RegExp. Регулярные выражения позволяют одной командой очистить текст от всего лишнего, что работает значительно быстрее циклов. При необходимости можно воспользоваться библиотекой функций VBScript, позволяющей эффективно обрабатывать и очищать строковые значения.
Это одна из самых сложных задач, так как в языке запросов 1С отсутствует прямая функция Число(). Если вам необходимо отсортировать справочник по артикулу, который записан строкой, но содержит числа, придется использовать конструкцию ВЫБОР КОГДА.
Выясним, как преобразовать хотя бы первые несколько символов строки в числовое значение прямо в запросе. Разберем пример для четырехзначного числа:
ВЫБРАТЬ
Номенклатура.Ссылка,
ВЫБОР
КОГДА ПОДСТРОКА(Номенклатура.Артикул, 1, 1) = "1" ТОГДА 1
КОГДА ПОДСТРОКА(Номенклатура.Артикул, 1, 1) = "2" ТОГДА 2
// ... и так далее для каждой цифры
ИНАЧЕ 0
КОНЕЦ * 1000 +
ВЫБОР
КОГДА ПОДСТРОКА(Номенклатура.Артикул, 2, 1) = "1" ТОГДА 1
// ... логика для второго разряда
ИНАЧЕ 0
КОНЕЦ * 100 КАК ЧисловойАртикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
Нужно понимать, что такой подход сильно нагружает базу данных и является «костылем». Если вам постоянно требуется числовое представление строкового поля в запросах, правильнее будет создать дополнительный реквизит числового типа и заполнять его при записи объекта.
Существуют специфические способы преобразования, которые могут пригодиться в узких задачах:
XMLЗначение(Тип("Число"), "123.45") работает очень быстро и строго. Он идеален для обработки данных, полученных через веб-сервисы или XML-файлы, где гарантирован международный формат числа с точкой.Число() не справится. В этом случае мы используем Результат = Вычислить(СтрокаСВыражением). Внимание: никогда не используйте этот метод для строк, полученных от пользователей, так как это огромная дыра в безопасности (пользователь может ввести команду удаления данных).Зачастую, получив число, программист хочет вернуть его в строку (например, для формирования кода или артикула), но сталкивается с тем, что 1С автоматически добавляет пробелы между разрядами (например, "1 000" вместо "1000"). Чтобы избежать этого, проанализируем функцию Формат().
Используйте параметр ЧГ=0 (Группировка разрядов = 0), чтобы получить «чистую» строку:
ЧислоДляКода = 1500;
СтрокаБезПробелов = Формат(ЧислоДляКода, "ЧГ=0"); // Результат: "1500"
Подведем итог: для стабильной работы системы всегда очищайте входящие строки от пробелов (включая неразрывные), заменяйте запятые на точки и используйте блоки обработки исключений. Это гарантирует, что ваша обработка не «упадет» на середине долгого процесса загрузки данных.