При интеграции или сравнении данных из двух различных информационных баз 1С часто возникает проблема несовпадения форматов идентификаторов. Типичный пример — табельные номера сотрудников. В одной базе номер может иметь вид 0000-12345, в другой — просто 12345, а в третьей — 000-1234. Простое прямое сравнение строк в таком случае не сработает. В этой статье мы разберем несколько эффективных способов приведения таких номеров к единому виду для корректного сопоставления.
Проанализируем ситуацию: если в номере присутствует дефис, то значащая часть номера обычно находится справа от него. Вместо того чтобы перечислять все возможные варианты префиксов (000-, 0000- и так далее) через функцию СтрЗаменить, мы можем применить универсальный подход. Рассмотрим, как это реализовать с помощью функций СтрНайти и Сред.
Разберем по шагам логику обработки строки:
Посмотрим на пример кода:
Пока Выборка.Следующий() Цикл
ИсходныйНомер = Выборка.ТабельныйНомерСотрудника;
ПозицияТире = СтрНайти(ИсходныйНомер, "-");
Если ПозицияТире > 0 Тогда
// Берем всё, что идет после тире
ОчищенныйНомер = Сред(ИсходныйНомер, ПозицияТире + 1);
Иначе
ОчищенныйНомер = ИсходныйНомер;
КонецЕсли;
// Дальнейшая логика сравнения
СтрокаСотрудника = ДанныеИзТабСотрудников.Добавить();
СтрокаСотрудника.ТабельныйНомерСотрудника = ОчищенныйНомер;
КонецЦикла;
Если мы работаем на платформе 1С:Предприятие 8.3.10 и выше, проанализируем возможность использования функции СтрРазделить. Этот метод особенно удобен, если формат номера может содержать несколько дефисов или сложную структуру префиксов.
Рассмотрим пример, где мы разбиваем строку в массив по разделителю и забираем последний элемент:
ЧастиНомера = СтрРазделить(Выборка.ТабельныйНомерСотрудника, "-");
// Последний элемент массива — это и есть наш чистый номер
ЧистыйНомер = ЧастиНомера[ЧастиНомера.ВГраница()];
Этот способ более элегантен и устойчив к изменениям длины префикса (неважно, сколько нулей было до дефиса).
Иногда даже после удаления префикса номера могут различаться количеством ведущих нулей (например, 00123 и 123). Чтобы привести их к общему знаменателю, выясним причину различия. Если номер состоит только из цифр, самый простой способ убрать нули — преобразовать строку в число и обратно в строку.
Посмотрим на пример такой нормализации:
// Удаляем префикс как в методе 1
ПозицияТире = СтрНайти(ИсходнаяСтрока, "-");
Результат = ?(ПозицияТире > 0, Сред(ИсходнаяСтрока, ПозицияТире + 1), ИсходнаяСтрока);
// Убираем ведущие нули, если это число
Попытка
Результат = Формат(Число(Результат), "ЧГ=0");
Исключение
// Если в номере есть буквы, оставляем как есть
Результат = СокрЛП(Результат);
КонецПопытки;
Важный момент: использование функции Число может привести к потере данных, если табельный номер содержит буквенные индексы. В таких случаях лучше использовать специализированные функции из состава БСП (Библиотеки стандартных подсистем), например, ОбщегоНазначения.УдалитьЛППустыеСимволы.
В некоторых конфигурациях 1С принят стандарт хранить табельные номера фиксированной длины (например, 11 символов) с заполнением недостающих позиций нулями слева. В этом случае нам нужно не обрезать нули, а наоборот — добавить их.
Рассмотрим, как быстро дополнить строку нулями до нужной длины:
// Допустим, стандартная длина 10 символов
ДлинаСтандарта = 10;
НомерБезПрефикса = "1234"; // получили из 000-1234
НормализованныйНомер = Прав("0000000000" + НомерБезПрефикса, ДлинаСтандарта);
// Результат: "0000001234"
Этот метод позволяет сравнивать строки «один к одному», так как они гарантированно будут иметь одинаковую длину и формат.
Для наиболее сложных ситуаций, когда префиксы могут быть разнообразными (не только нули и дефисы), проанализируем использование объекта VBScript.RegExp. Это мощный инструмент для поиска шаблонов в строках.
Например, нам нужно вычленить только цифровую последовательность в конце строки. Разберем шаблон регулярного выражения:
RegEx = Новый COMОбъект("VBScript.RegExp");
RegEx.Pattern = "\d+$"; // Ищем цифры в конце строки
Matches = RegEx.Execute(Выборка.ТабельныйНомерСотрудника);
Если Matches.Count > 0 Тогда
ЧистыйНомер = Matches.Item(0).Value;
КонецЕсли;
Метод с регулярными выражениями требует наличия установленных компонентов в операционной системе, но он незаменим при работе с крайне неструктурированными данными.
Если объем данных велик (тысячи сотрудников), обработка в цикле будет занимать значительное время. Выясним, как перенести логику сопоставления на уровень SQL-запроса. В языке запросов 1С нет функции СтрНайти, но есть оператор ПОДОБНО.
Рассмотрим пример условия в запросе:
ВЫБРАТЬ
Сотрудники.Ссылка
ИЗ
Справочник.Сотрудники КАК Сотрудники
ГДЕ
Сотрудники.Код ПОДОБНО "%" + &НужныйНомер
Однако будьте осторожны: поиск по подстроке с процентом в начале (%123) не использует индексы и может работать медленно. Кроме того, номер 123 может ошибочно совпасть с номером 1123. Чтобы этого избежать, старайтесь использовать более точные условия, например, проверяя наличие дефиса перед номером.
Поскольку табельные номера часто подвергаются ручному редактированию и смене форматов, мы рекомендуем использовать дополнительные идентификаторы для повышения точности сопоставления:
Применяя комбинацию этих методов, мы сможем построить надежную систему сравнения данных, устойчивую к различиям в форматах записи идентификаторов.