При разработке кадрового или управленческого функционала в 1С часто возникает задача: в справочнике Сотрудники при выборе ссылки на элемент справочника ФизическиеЛица необходимо автоматически заполнить отдельные реквизиты — Фамилия, Имя и Отчество. Рассмотрим подробнее, как корректно реализовать такой механизм в управляемом приложении, какие функции платформы использовать и какие архитектурные нюансы важно учесть.
Разберем по шагам логику взаимодействия элементов формы. Пользователь выбирает физическое лицо в поле ввода на форме элемента справочника Сотрудники. Это действие вызывает событие элемента формы ПриИзменении.
В управляемом интерфейсе прямое обращение через точку к реквизитам ссылочного типа на клиенте недопустимо или приводит к неявным вызовам сервера, ухудшающим производительность. Поэтому считывание данных и их обработку необходимо выполнять с разделением контекста:
ФизическоеЛицоПриИзменении.Проанализируем ситуацию, когда конфигурация пишется с нуля или в ней нет специализированных библиотек. В платформе 1С:Предприятие 8.3 для разделения строки по разделителю предусмотрена встроенная функция СтрРазделить.
Ее синтаксис выглядит следующим образом: СтрРазделить(Строка, Разделитель, ВключатьПустые). Если указать третий параметр как Ложь, платформа автоматически отбросит пустые элементы, возникающие при случайном вводе двойных пробелов. Также перед разделением строковое значение следует очистить от крайних пробелов с помощью функции СокрЛП().
Посмотрим на пример реализации данного алгоритма в модуле формы элемента:
&НаКлиенте
Процедура ФизическоеЛицоПриИзменении(Элемент)
ЗаполнитьФИОПоФизическомуЛицуНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьФИОПоФизическомуЛицуНаСервере()
Если Не ЗначениеЗаполнено(Объект.ФизическоеЛицо) Тогда
Объект.Фамилия = "";
Объект.Имя = "";
Объект.Отчество = "";
Возврат;
КонецЕсли;
// Получаем наименование физического лица
СтрокаФИО = СокрЛП(Объект.ФизическоеЛицо.Наименование);
// Разбиваем строку по пробелам, исключая пустые вхождения
ЧастиСтроки = СтрРазделить(СтрокаФИО, " ", Ложь);
КоличествоЧастей = ЧастиСтроки.Количество();
// Обязательно проверяем границы массива перед обращением по индексу
Объект.Фамилия = ?(КоличествоЧастей > 0, ЧастиСтроки[0], "");
Объект.Имя = ?(КоличествоЧастей > 1, ЧастиСтроки[1], "");
Объект.Отчество = ?(КоличествоЧастей > 2, ЧастиСтроки[2], "");
КонецПроцедуры
Обратите внимание: обращение к элементам массива без проверки его размера через Количество() или ВГраница() приведет к критической ошибке «Индекс находится за границами массива», если у человека отсутствует отчество или введены неполные данные.
Если разработка ведется на базе типовой конфигурации (например, «1С:Бухгалтерия предприятия», «1С:Зарплата и управление персоналом» или конфигурации с внедренной «Библиотекой стандартных подсистем»), изобретать собственные алгоритмы разбора строки не требуется. В составе БСП присутствует специализированный общий модуль, учитывающий сложные случаи написания имен.
Выясним причину, почему типовой метод надежнее: простая разбивка по пробелам дает сбой на составных фамилиях (например, с приставками «фон», «де», «ван»), двойных именах или иностранных именованиях (содержащих «оглы», «кызы», «ибн»). Типовая функция ФизическиеЛицаКлиентСервер.ЧастиИмени корректно раскладывает строку в структуру со свойствами Фамилия, Имя и Отчество.
Посмотрим, как выглядит вызов типового механизма:
&НаКлиенте
Процедура ФизическоеЛицоПриИзменении(Элемент)
ЗаполнитьФИОЧерезБСП();
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьФИОЧерезБСП()
Если Не ЗначениеЗаполнено(Объект.ФизическоеЛицо) Тогда
Возврат;
КонецЕсли;
СтрокаФИО = Строка(Объект.ФизическоеЛицо);
// Вызываем типовую функцию разбора ФИО
СтруктураФИО = ФизическиеЛицаКлиентСервер.ЧастиИмени(СтрокаФИО);
Объект.Фамилия = СтруктураФИО.Фамилия;
Объект.Имя = СтруктураФИО.Имя;
Объект.Отчество = СтруктураФИО.Отчество;
КонецПроцедуры
Проанализируем структуру хранения данных, так как дублирование реквизитов Фамилия, Имя и Отчество в справочнике Сотрудники не всегда является оптимальным решением:
ФизическиеЛица уже есть реквизиты Фамилия, Имя и Отчество, разбирать строковое представление не имеет смысла. На сервере достаточно прочитать эти поля напрямую из ссылки физического лица (или с помощью функции ОбщегоНазначения.ЗначенияРеквизитовОбъекта) и присвоить их сотруднику.Сотрудники. Достаточно разместить на форме реквизиты самой формы и динамически считывать их при открытии карточки и смене физлица.ФИОФизическихЛиц). Это предотвращает искажение кадровой истории прошлых периодов при смене сотрудником фамилии (вступление в брак и т.д.). В таком случае срез последних регистра сведений на дату кадрового события дает актуальные данные без необходимости строкового разбора.