В процессе разработки часто возникает задача приведения контактных данных к единому стандарту. Особенно это актуально при выгрузке сотрудников в сторонние системы или при подготовке отчетов, где номера телефонов должны выглядеть единообразно (например, в формате @-@@@-@@@-@@-@@). Рассмотрим подробно, как решить эту задачу программно, разберем различные подходы и выясним, почему хранение данных в маске — не самая лучшая идея.
Проанализируем самый универсальный алгоритм, который будет работать на любой версии платформы 1С. Суть его заключается в трех последовательных шагах. Во-первых, нам необходимо очистить исходную строку от всех символов, которые не являются цифрами. Во-вторых, нужно разбить полученную последовательность цифр на логические блоки. В-третьих — собрать итоговую строку, вставив между блоками нужные разделители (тире, скобки, пробелы).
Разберем пример реализации функции очистки номера:
Функция ОчиститьНомерОтЛишнихСимволов(Знач ИсходныйНомер)
Результат = "";
Для Индекс = 1 По СтрДлина(ИсходныйНомер) Цикл
Символ = Сред(ИсходныйНомер, Индекс, 1);
Если Найти("0123456789", Символ) > 0 Тогда
Результат = Результат + Символ;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
После того как мы получили «чистый» номер, состоящий только из цифр, мы можем применить к нему нашу маску. Рассмотрим, как программно собрать номер 89991234567 в маску 8-999-123-45-67:
Функция ФорматироватьПоМаске(ЧистыйНомер)
// Предполагаем, что номер состоит из 11 цифр
Если СтрДлина(ЧистыйНомер) <> 11 Тогда
Возврат ЧистыйНомер; // Возвращаем как есть, если длина не совпадает
КонецЕсли;
Часть1 = Сред(ЧистыйНомер, 1, 1);
Часть2 = Сред(ЧистыйНомер, 2, 3);
Часть3 = Сред(ЧистыйНомер, 5, 3);
Часть4 = Сред(ЧистыйНомер, 8, 2);
Часть5 = Сред(ЧистыйНомер, 10, 2);
Возврат Часть1 + "-" + Часть2 + "-" + Часть3 + "-" + Часть4 + "-" + Часть5;
КонецФункции
Если вы работаете на современной версии платформы, мы рекомендуем использовать функцию СтрШаблон. Она делает код гораздо более читаемым и избавляет от нагромождения плюсов при конкатенации строк. Проанализируем ситуацию: нам нужно подставить части номера в готовую структуру маски.
// Пример использования функции СтрШаблон для форматирования
ЧистыйНомер = "79001112233";
Результат = СтрШаблон("%1-%2-%3-%4-%5",
Сред(ЧистыйНомер, 1, 1),
Сред(ЧистыйНомер, 2, 3),
Сред(ЧистыйНомер, 5, 3),
Сред(ЧистыйНомер, 8, 2),
Сред(ЧистыйНомер, 10, 2));
// На выходе получим: 7-900-111-22-33
Этот способ удобен тем, что маску легко поменять. Если завтра вам понадобится формат со скобками, достаточно будет изменить строку шаблона на %1 (%2) %3-%4-%5, не меняя логику выделения подстрок.
Выясним причину, по которой ручной перебор строки (как в первом методе) может быть неэффективен. Если номеров десятки тысяч, цикл по каждому символу будет работать медленнее, чем использование специализированных средств. В среде Windows мы можем задействовать объект VBScript.RegExp для мгновенной очистки строки от всего лишнего.
Функция ОчиститьСтрокуRegExp(ИсходнаяСтрока)
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.IgnoreCase = Истина;
RegExp.Pattern = "\D"; // Искать все, что НЕ является цифрой
Возврат RegExp.Replace(ИсходнаяСтрока, "");
КонецФункции
Использование регулярного выражения \D позволяет одной строкой удалить все скобки, тире, пробелы и даже случайно затесавшиеся буквы, подготавливая идеальный «субстрат» для наложения маски.
Если ваша конфигурация использует Библиотеку стандартных подсистем (БСП), то изобретать велосипед не нужно. Рассмотрим модули, которые уже содержат все необходимое. В частности, модуль УправлениеКонтактнойИнформацией или УправлениеКонтактнойИнформациейКлиентСервер.
В БСП часто встречается функция ПроверитьИОчиститьНомерТелефона, а также механизмы, которые позволяют работать с телефонным номером как со структурой. Это наиболее правильный путь для конфигураций типа 1С:ERP, УТ 11 или ЗУП 3.
Важный архитектурный момент, который стоит обсудить: не храните номера в базе с маской. Это классическая ошибка начинающих разработчиков. Посмотрим на последствия такого решения:
8-999-111, а другой как 8(999)111, поиск по номеру перестанет работать.Правильный подход: в базе данных храним только цифры. Маску накладываем только в момент вывода данных на форму или в печатную форму. Для этого на управляемых формах можно использовать событие ПриВыводеДанных или настроить формат в свойствах элемента, а в обычных формах — программно форматировать строку перед отображением.
Если же ваша задача — изменить данные для выгрузки во внешнюю систему, как описывал автор темы, используйте предложенные выше функции преобразования непосредственно в момент формирования файла выгрузки.