Как в 1С разбить строку ФИО на фамилию, имя и отчество?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При обмене данными через Конвертацию данных 2.1 или при импорте информации из внешних систем часто возникает ситуация, когда ФИО передается одной строкой (реквизит Наименование), а в базе-приемнике требуется разложить его по отдельным полям: Фамилия, Имя и Отчество. На первый взгляд задача кажется простой, но она требует учета нюансов платформы и возможных исключений в написании имен. В этой статье мы разберем несколько способов решения — от классических строковых функций до использования возможностей Библиотеки Стандартных Подсистем (БСП).

Способ 1. Использование классических строковых функций (универсальный метод)

Если вы работаете в КД 2.1 и код должен выполняться на стороне источника со старой платформой (ниже 8.3.6), или если вы просто хотите максимально контролировать процесс, воспользуемся базовыми функциями Найти, Лев и Сред. Рассмотрим алгоритм, который ищет пробелы и последовательно отсекает части строки.

Рассмотрим подробнее логику реализации:

  1. Очищаем строку от лишних пробелов по краям с помощью СокрЛП.
  2. Находим первый пробел — все, что до него, считаем фамилией.
  3. Отрезаем фамилию и в оставшейся части строки ищем следующий пробел — это будет граница между именем и отчеством.
  4. Все, что осталось после второго пробела, записываем в отчество.

Пример кода для реализации этой логики:


// Предположим, ФИО лежит в переменной ИсточникНаименование
ФИО = СокрЛП(ИсточникНаименование);

// Ищем первый пробел (отделяем фамилию)
ПозицияПервогоПробела = Найти(ФИО, " ");
Если ПозицияПервогоПробела > 0 Тогда
    Фамилия = Лев(ФИО, ПозицияПервогоПробела - 1);
    ОстатокСтроки = СокрЛП(Сред(ФИО, ПозицияПервогоПробела + 1));
    
    // Ищем второй пробел в остатке (отделяем имя от отчества)
    ПозицияВторогоПробела = Найти(ОстатокСтроки, " ");
    Если ПозицияВторогоПробела > 0 Тогда
        Имя = Лев(ОстатокСтроки, ПозицияВторогоПробела - 1);
        Отчество = СокрЛП(Сред(ОстатокСтроки, ПозицияВторогоПробела + 1));
    Иначе
        // Если второго пробела нет, значит есть только фамилия и имя
        Имя = ОстатокСтроки;
        Отчество = "";
    КонецЕсли;
Иначе
    // Если пробелов вообще нет, считаем всю строку фамилией
    Фамилия = ФИО;
    Имя = "";
    Отчество = "";
КонецЕсли;

Способ 2. Современный подход с использованием СтрРазделить

Начиная с версии платформы 8.3.6, в 1С появилась замечательная функция СтрРазделить. Она работает значительно быстрее классических методов и позволяет получить массив подстрок одной командой. Это особенно эффективно, если вам нужно обработать большой массив данных.

Разберем, как применить этот метод для нашей задачи:


МассивЧастей = СтрРазделить(СокрЛП(ИсточникНаименование), " ", Ложь);

КоличествоЧастей = МассивЧастей.Количество();

Фамилия = ?(КоличествоЧастей > 0, МассивЧастей[0], "");
Имя     = ?(КоличествоЧастей > 1, МассивЧастей[1], "");

// Для отчества соберем все оставшиеся части массива, если имя состоит из нескольких слов
Отчество = "";
Для Индекс = 2 По КоличествоЧастей - 1 Цикл
    Отчество = Отчество + ?(Отчество = "", "", " ") + МассивЧастей[Индекс];
КонецЦикла;

Преимущество этого метода в том, что если у человека двойное отчество или присутствуют национальные приставки (например, "оглы"), цикл корректно соберет их в одну переменную Отчество.

Способ 3. Преобразование в многострочную строку

Существует еще один "хитрый" способ, который часто использовали до появления функции СтрРазделить. Суть метода заключается в замене пробелов на символы перевода строки, после чего к каждой части можно обратиться по индексу строки.

Проанализируем этот вариант:


ТекстФИО = СтрЗаменить(СокрЛП(ИсточникНаименование), " ", Символы.ПС);
КоличествоСтрок = СтрЧислоСтрок(ТекстФИО);

Фамилия = СтрПолучитьСтроку(ТекстФИО, 1);
Имя     = ?(КоличествоСтрок > 1, СтрПолучитьСтроку(ТекстФИО, 2), "");

// Собираем отчество из оставшихся строк
Отчество = "";
Для к = 3 По КоличествоСтрок Цикл
    Отчество = Отчество + ?(Отчество = "", "", " ") + СтрПолучитьСтроку(ТекстФИО, к);
КонецЦикла;

Важно: Этот метод работает медленнее, чем СтрРазделить на больших объемах данных, так как функция СтрПолучитьСтроку каждый раз пересчитывает символы с начала текста.

Способ 4. Использование типовых функций (БСП)

Если ваша конфигурация построена на базе БСП (Библиотеки Стандартных Подсистем), то изобретать велосипед не нужно. В программном интерфейсе уже существуют проверенные функции, которые учитывают множество нюансов. В типовых решениях (ЗУП, БП 3.0, ERP) за это отвечает модуль ФизическиеЛицаКлиентСервер.

Выясним, как вызвать это решение:


// Функция возвращает структуру с полями Фамилия, Имя, Отчество
СтруктураФИО = ФизическиеЛицаКлиентСервер.РазложитьФИО(ИсточникНаименование);

Фамилия  = СтруктураФИО.Фамилия;
Имя      = СтруктураФИО.Имя;
Отчество = СтруктураФИО.Отчество;

Этот метод является наиболее предпочтительным для разработки внутри типовых конфигураций, так как он автоматически обрабатывает лишние пробелы и корректно распределяет слова, если их больше трех.

Нюансы и сложные случаи

Проанализируем ситуацию, когда данные "грязные" или содержат специфические национальные компоненты:

Резюме: Для быстрых разовых задач в КД 2.1 отлично подойдет Способ 1 или Способ 2. Если же вы пишете код внутри современной системы, используйте Способ 4, чтобы обеспечить максимальную надежность обработки данных.

← На главную