В процессе разработки прикладных решений на платформе 1С:Предприятие одной из регулярных задач является обработка персональных данных физических лиц. Очень часто возникает необходимость преобразовать полное имя сотрудника или контрагента (например, "Иванов Иван Иванович") в сокращенный формат с инициалами ("Иванов И. И."), а также выделить отдельно его составляющие (фамилию, имя и отчество). В этой статье мы подробно рассмотрим, какими методами можно решить эту задачу, разберем по шагам готовые алгоритмы и проанализируем современные возможности платформы.
Если вы работаете в любой современной типовой конфигурации 1С (такой как ERP, ЗУП, Комплексная автоматизация, Управление торговлей или Бухгалтерия предприятия), вам не нужно изобретать велосипед и писать собственный код разбора строк. В составе этих конфигураций есть встроенная Библиотека стандартных подсистем (БСП), которая уже содержит готовые оптимизированные функции для работы с персональными данными.
Для решения нашей задачи отлично подойдет общий модуль ФизическиеЛицаКлиентСервер или специализированный модуль ФизическиеЛицаЗарплатаКадрыКлиентСервер. Давайте посмотрим на пример использования такой функции:
// Пример получения фамилии и инициалов в типовой конфигурации
ПолноеИмя = "Иванов Иван Иванович";
СокращенноеИмя = ФизическиеЛицаКлиентСервер.ФамилияИнициалы(ПолноеИмя);
// Результат: "Иванов И. И."
Разберем подробнее преимущества использования этого метода. Функция ФамилияИнициалы из БСП умеет корректно обрабатывать сложные национальные имена и фамилии. Она учитывает специфические приставки (например, "оглы", "кызы", "улы"), не обрезая их случайным образом до первой буквы, как это часто происходит в простых самописных алгоритмах.
Если вам требуется получить не просто строку с инициалами, а структуру, содержащую отдельно фамилию, имя и отчество, мы можем применить функцию ЧастиИмени:
СтруктураФИО = ФизическиеЛицаКлиентСервер.ЧастиИмени(ПолноеИмя);
Фамилия = СтруктураФИО.Фамилия; // "Иванов"
Имя = СтруктураФИО.Имя; // "Иван"
Отчество = СтруктураФИО.Отчество; // "Иванович"
Для поиска подобных функций в вашей текущей конфигурации мы рекомендуем использовать глобальный поиск по конфигурации (сочетание клавиш Ctrl+Shift+F), указав поисковый запрос "ФамилияИнициалы".
Что делать, если вы ведете разработку в нетиповой (самописной) конфигурации, где БСП отсутствует? Писать сложные циклы со строковыми функциями больше нет необходимости. Начиная с версии платформы 8.3.6, в 1С появились замечательные встроенные функции СтрРазделить() и СтрСоединить(), работающие на уровне ядра системы.
Давайте проанализируем, как с помощью функции СтрРазделить() элегантно решить задачу разделения ФИО и сбора строки с инициалами:
Функция ПолучитьФамилиюИнициалы(Знач ИсходноеФИО) Экспорт
// Очищаем строку от лишних пробелов по краям
СтрокаПодготовки = СокрЛП(ИсходноеФИО);
// Разделяем строку в массив по символу пробела.
// Третий параметр Ложь указывает игнорировать пустые строки при наличии двойных пробелов.
МассивЧастей = СтрРазделить(СтрокаПодготовки, " ", Ложь);
КоличествоЭлементов = МассивЧастей.Количество();
Если КоличествоЭлементов = 0 Тогда
Возврат "";
КонецЕсли;
// Фамилия всегда идет первым элементом
Результат = МассивЧастей[0];
// Добавляем инициал имени, если оно присутствует в строке
Если КоличествоЭлементов > 1 Тогда
Имя = МассивЧастей[1];
Результат = Результат + " " + Лев(Имя, 1) + ".";
КонецЕсли;
// Добавляем инициал отчества, если оно присутствует
Если КоличествоЭлементов > 2 Тогда
Отчество = МассивЧастей[2];
Результат = Результат + " " + Лев(Отчество, 1) + ".";
КонецЕсли;
Возврат Результат;
КонецФункции
Этот способ является наиболее производительным и надежным среди всех ручных алгоритмов, так как функция СтрРазделить() работает значительно быстрее, чем обход строки в цикле Пока.
Рассмотрим очень интересный и лаконичный прием, предложенный опытными разработчиками на форуме. Его суть заключается в том, чтобы временно преобразовать исходную строку в многострочный текст, заменив обычные пробелы на символы перевода строки Символы.ПС. После этого мы можем обращаться к каждому слову по его индексу строки.
Посмотрим на пример реализации этого алгоритма:
// Входная строка ФИО
ИсходнаяСтрока = СокрЛП(ФИО);
// Шаг 1. Заменяем все пробелы на символы перевода строк
МногострочноеФИО = СтрЗаменить(ИсходнаяСтрока, " ", Символы.ПС);
// Шаг 2. Извлекаем строки по номерам позиций и формируем инициалы
ФамилияИО = СтрПолучитьСтроку(МногострочноеФИО, 1)
+ " "
+ Лев(СтрПолучитьСтроку(МногострочноеФИО, 2), 1) + ". "
+ Лев(СтрПолучитьСтроку(МногострочноеФИО, 3), 1) + ".";
Важное предупреждение: Данный метод подкупает своей простотой и краткостью (всего пара строк кода), однако он имеет серьезный недостаток. Если во входной строке между фамилией и именем случайно окажется два пробела подряд, функция СтрПолучитьСтроку() на второй позиции вернет пустую строку, что приведет к неверному результату (пропадут инициалы). Поэтому перед использованием этого метода обязательно нужно производить очистку строки от двойных пробелов.
В реальных базах данных пользователи часто копируют ФИО из других документов, допуская ошибки форматирования: вставляют неразрывные пробелы, знаки табуляции или несколько пробелов подряд. Чтобы наши алгоритмы работали безошибочно, рассмотрим, как выполнить предварительную очистку текста с помощью объекта VBScript.RegExp:
Функция ОчиститьСтрокуФИО(Знач ВходноеФИО)
Попытка
РегВыражение = Новый COMОбъект("VBScript.RegExp");
РегВыражение.Pattern = "\s+"; // Ищет любые пробельные символы (пробелы, табы, переносы)
РегВыражение.Global = Истина;
// Заменяем любые последовательности пробелов на один стандартный пробел
Возврат СокрЛП(РегВыражение.Replace(ВходноеФИО, " "));
Исключение
// Если COM-объект недоступен (например, на сервере Linux), используем стандартную замену
Возврат СокрЛП(СтрЗаменить(ВходноеФИО, " ", " "));
КонецПопытки;
КонецФункции
Применив данную очистку перед разделением строки, мы гарантируем стабильную работу любого из выбранных алгоритмов форматирования ФИО.
Часто задача вывода ФИО с инициалами тесно связана со склонением имен (например, для печатной формы приказа: "Выдать сотруднику Иванову И. И."). Начиная с версии платформы 8.3.13, разработчикам доступна мощная встроенная функция склонения без использования внешних библиотек:
// Пример склонения ФИО в дательный падеж
РезультатСклонения = ПолучитьСклоненияСтроки("Иванов Иван Иванович", , "Падеж=Дательный");
Если РезультатСклонения.Количество() > 0 Тогда
ДательныйПадежФИО = РезультатСклонения[0]; // Получаем "Иванову Ивану Ивановичу"
// Далее можем применить к полученной строке любую из наших функций для сокращения до инициалов
ФИОДательныйИнициалы = ПолучитьФамилиюИнициалы(ДательныйПадежФИО);
// Результат: "Иванову И. И."
КонецЕсли;
Мы детально разобрали различные подходы к форматированию ФИО в системе 1С. Подводя итог, можно дать следующие рекомендации:
ФизическиеЛицаКлиентСервер и его функции ФамилияИнициалы(). Это избавит вас от необходимости поддерживать собственный код.СтрРазделить() и проверки количества элементов массива.