Часто при работе с документами или при подготовке печатных форм мы сталкиваемся с необходимостью привести строковый номер к более читаемому виду. Платформа генерирует номера с нулями для обеспечения правильной сортировки, например: 00ББ-001204 или 0000-001204. Наша задача — преобразовать такие строки в ББ-1204 и 1204 соответственно. Рассмотрим несколько способов решения этой задачи и проанализируем их плюсы и минусы.
Прежде чем писать собственные алгоритмы, давайте посмотрим на готовые решения, которые уже встроены в современные конфигурации 1С. Если ваша конфигурация (например, УТ 11, БП 3.0, ERP) построена на базе БСП, мы настоятельно рекомендуем использовать именно этот метод.
Для получения номера, предназначенного для вывода на печать, отлично подходит следующая функция:
НомерНаПечать = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(НомерДокумента, Истина, Истина);
Если же мы работаем со старыми конфигурациями на обычных формах (УТ 10.3, БП 2.0), эта процедура выглядит так:
Номер = ОбщегоНазначения.ПолучитьНомерНаПечать(СсылкаНаОбъект);
Кроме того, в БСП есть специализированная функция, которая удаляет только незначащие нули, не трогая префиксы и дефисы:
ОчищенныйНомер = ПрефиксацияОбъектовКлиентСервер.УдалитьЛидирующиеНулиИзНомераОбъекта(Номер);
Если готовых функций в конфигурации нет, разберем алгоритмический подход. Суть метода заключается в том, чтобы разбить исходную строку на массив подстрок (до и после дефиса), очистить каждую часть от нулей слева и соединить обратно.
Многие разработчики пытаются использовать функцию СтрЗаменить, заменяя "0" на пробел, отсекая пробелы функцией СокрЛ, а затем возвращая нули обратно. Проанализируем ситуацию: этот "трюк" очень опасен! Если в исходной строке уже были пробелы, они превратятся в нули, и номер будет искажен. Поэтому мы применим безопасный цикл Пока.
МассивСтроки = СтрРазделить(ВхСтрока, "-", Ложь);
НаклБезНулей = Новый Массив;
Для каждого ЭлементМассива Из МассивСтроки Цикл
ТекСтрока = ЭлементМассива;
// Безопасно отсекаем нули только слева
Пока Лев(ТекСтрока, 1) = "0" Цикл
ТекСтрока = Сред(ТекСтрока, 2);
КонецЦикла;
НаклБезНулей.Добавить(ТекСтрока);
КонецЦикла;
СтрокаИзМассива = СтрСоединить(НаклБезНулей, "-");
Сообщить(СтрокаИзМассива);
Если мы точно знаем структуру номера (например, первые 4 символа — это префикс, а последние 6 — чисто числовой порядковый номер), мы можем воспользоваться математическим отбрасыванием нулей. При приведении строки к типу Число платформа автоматически игнорирует лидирующие нули.
Рассмотрим, как это выглядит в коде:
// Берем правые 6 символов, переводим в число и обратно в строку
// ЧГ=0 отключает группировку разрядов, чтобы не появились неразрывные пробелы
ЧисловаяЧасть = Строка(Формат(Число(Прав(ВхСтрока, 6)), "ЧГ=0"));
// Очищаем префикс (если там только нули и буквы)
Префикс = СтрЗаменить(Лев(ВхСтрока, 4), "0", "");
НовНомер = Префикс + "-" + ЧисловаяЧасть;
Этот подход работает очень быстро, но он жестко привязан к формату строки. Если бизнес-логика изменится и дефис исчезнет, код придется переписывать.
Если ваша база 1С работает под управлением ОС Windows, мы можем решить эту задачу максимально элегантно, без циклов и массивов, используя COM-объект VBScript.RegExp. Регулярное выражение найдет все нули, которые стоят в самом начале строки или сразу после дефиса, и заменит их.
Посмотрим на пример реализации:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
// Ищем нули, которые идут после начала строки (^) или после дефиса (-)
RegExp.Pattern = "(^|-)0+";
// Заменяем найденное на то, что было в первой скобке (пустоту или дефис)
НовНомер = RegExp.Replace(ВхСтрока, "$1");
Лев, Прав и приведение к типу Число (Способ 3).