При разработке и поддержке отчетов или печатных форм в среде 1С:Предприятие 7.7 программисты часто сталкиваются с ограничениями встроенного языка. Одной из классических задач является разбор полной строки ФИО (например, "Иванов Иван Иванович") на три составляющие: Фамилию, Имя и Отчество. В более современных версиях платформы (1С 8.x) для этого существуют развитые строковые функции и объекты вроде Символы.ПС, но в "семерке" разработчикам приходится использовать иные подходы.
В этой статье мы подробно разберем несколько эффективных способов решения данной задачи: от простых ручных алгоритмов до использования встроенных механизмов типовых конфигураций.
Многие начинающие разработчики пытаются перенести логику из 1С 8 в 1С 7.7 и ищут предопределенный символ перевода строки Символы.ПС. В семерке его нет, но существует его полный аналог — системная константа РазделительСтрок. С ее помощью можно превратить обычную строку с пробелами в многострочный текст, а затем легко считать нужные фрагменты.
Давайте разберем этот алгоритм по шагам:
РазделительСтрок с помощью встроенной функции СтрЗаменить().СтрПолучитьСтроку(), мы извлекаем первую строку как Фамилию, вторую как Имя и третью как Отчество.Рассмотрим пример готового кода, реализующего эту логику:
// Исходная строка с ФИО (может содержать случайные двойные пробелы)
СтрокаФИО = " Петров Пётр Петрович ";
// Очищаем пробелы в начале и в конце строки
СтрокаФИО = СокрЛП(СтрокаФИО);
// Избавляемся от двойных пробелов внутри строки
Пока Найти(СтрокаФИО, " ") > 0 Цикл
СтрокаФИО = СтрЗаменить(СтрокаФИО, " ", " ");
КонецЦикла;
// Заменяем обычные пробелы на перенос строки
МногострочноеФИО = СтрЗаменить(СтрокаФИО, " ", РазделительСтрок);
// Извлекаем составляющие ФИО по номерам строк
Фамилия = СтрПолучитьСтроку(МногострочноеФИО, 1);
Имя = СтрПолучитьСтроку(МногострочноеФИО, 2);
Отчество = СтрПолучитьСтроку(МногострочноеФИО, 3);
// Выводим результат в окно сообщений для проверки
Сообщить("Фамилия: " + Фамилия);
Сообщить("Имя: " + Имя);
Сообщить("Отчество: " + Отчество);
Этот способ крайне лаконичен и быстр, так как операции замены строк на уровне платформы работают очень эффективно. Если у физического лица нет отчества, функция СтрПолучитьСтроку() для третьей строки вернет пустую строку, что исключает возникновение ошибок.
Если вы работаете в типовой конфигурации 1С 7.7 (например, "Торговля и Склад", "Бухгалтерский учет" или "Зарплата и Кадры"), вам не нужно писать собственный код для разбора строк. Разработчики фирмы 1С уже добавили в глобальный модуль удобную функцию глФамилияИмяОтчество.
Проанализируем преимущества использования этой типовой функции:
Вызов типовой функции в вашем коде будет выглядеть следующим образом:
// Объявляем переменные для хранения результатов
ПриемникФамилия = "";
ПриемникИмя = "";
ПриемникОтчество = "";
// Передаем исходную строку и переменные-приемники в глобальную функцию
глФамилияИмяОтчество(СтрокаФИО, ПриемникФамилия, ПриемникИмя, ПриемникОтчество);
// Теперь переменные заполнены значениями
Сообщить("Ф: " + ПриемникФамилия);
Сообщить("И: " + ПриемникИмя);
Сообщить("О: " + ПриемникОтчество);
Внутри этой функции платформа использует объект СписокЗначений и заполняет его через функцию глРазложить(), которая разбивает исходный текст по пробелам. При этом первое значение списка всегда назначается Фамилией, второе — Именем, а все последующие элементы списка склеиваются обратно через пробел и записываются в Отчество. Это защищает алгоритм от обрезания сложных имен.
Иногда требуется решить задачу без привязки к глобальному модулю конфигурации и без использования многострочных преобразований — чисто математическим перебором строки. Для этого мы можем запустить цикл, который будет искать первый пробел с помощью функции Найти(), отрезать подстроку через Сред() и переходить к следующей итерации.
Разберем пример такого алгоритма:
СтрокаФИО = СокрЛП(СтрокаФИО);
// Избавляемся от лишних пробелов
Пока Найти(СтрокаФИО, " ") > 0 Цикл
СтрокаФИО = СтрЗаменить(СтрокаФИО, " ", " ");
КонецЦикла;
ВременнаяСтрока = СтрокаФИО;
Фамилия = "";
Имя = "";
Отчество = "";
// Извлекаем Фамилию (все до первого пробела)
ПозПробела = Найти(ВременнаяСтрока, " ");
Если ПозПробела > 0 Тогда
Фамилия = Сред(ВременнаяСтрока, 1, ПозПробела - 1);
ВременнаяСтрока = СокрЛП(Сред(ВременнаяСтрока, ПозПробела + 1));
Иначе
Фамилия = ВременнаяСтрока;
ВременнаяСтрока = "";
КонецЕсли;
// Извлекаем Имя (все до следующего пробела)
ПозПробела = Найти(ВременнаяСтрока, " ");
Если ПозПробела > 0 Тогда
Имя = Сред(ВременнаяСтрока, 1, ПозПробела - 1);
// Все оставшееся пишем в Отчество
Отчество = СокрЛП(Сред(ВременнаяСтрока, ПозПробела + 1));
Иначе
Имя = ВременнаяСтрока;
КонецЕсли;
Этот способ более громоздкий, но он наглядно показывает логику работы со строковыми функциями и работает абсолютно автономно в любой внешней обработке.
При разборе реальной базы данных вы обязательно столкнетесь с нестандартными именами. Например, тюркские отчества часто содержат приставки "кызы" (дочь) или "оглы" / "улы" (сын), которые пишутся через пробел (например, Мамедов Али Мустафа оглы).
Если использовать простейший алгоритм разделения по трем пробелам, то "Мустафа" станет именем, а "оглы" — отчеством, что юридически неверно. Типовая функция 1С глФамилияИмяОтчество решает эту проблему изящно: она относит все элементы после второго слова к Отчеству. Таким образом, отчеством запишется корректная фраза "Мустафа оглы".
Для работы со сложными европейскими фамилиями (например, де Соуза, ван Бетховен) разработчики часто используют маленькую хитрость: при вводе таких фамилий в базу обычный пробел заменяют на неразрывный пробел (символ с ASCII-кодом 160). В этом случае стандартные алгоритмы поиска пробела не увидят разрыва, и фамилия "де Соуза" будет обработана как единое слово.