После проведения очередного обновления конфигурации «1С:Зарплата и управление персоналом» (ЗУП) до версии 3.1.13.151 (или других актуальных релизов веток 3.1.10 / 3.1.13 и выше) пользователи часто сталкиваются с неприятной проблемой. При формировании регламентированных печатных форм, таких как Расчетная ведомость (Т-51) или Платежная ведомость (Т-53), у всех сотрудников неожиданно пропадают инициалы. Вместо привычного формата «Иванов И. И.» программа выводит исключительно фамилию — «Иванов».
В этой статье мы подробно разберем, какие архитектурные изменения в платформе привели к возникновению этой ситуации, почему штатные механизмы обновления могут давать сбой и как быстро вернуть инициалы сотрудников в печатные формы с помощью административных и программных методов.
Для того чтобы понять причину сбоя, проанализируем внутреннее устройство хранения персональных данных в конфигурациях на платформе «1С:Предприятие 8.3». Ранее при формировании отчетов и печатных документов система получала фамилию, имя и отчество сотрудника из регистра сведений ФИОФизическихЛиц. Однако для вывода краткого формата (Фамилия + Инициалы) программе приходилось динамически преобразовывать строку полного имени.
Для этого в цикле или внутри запросов вызывались функции общих модулей, например, метод ФизическиеЛицаЗарплатаКадрыКлиентСервер.ФамилияИнициалы. Этот подход работал безотказно на небольших базах, но при формировании массовых расчетных ведомостей Т-51 на несколько тысяч сотрудников постоянный строковый разбор ФИО «на лету» приводил к колоссальным потерям производительности и перегрузке процессора на сервере приложений.
С целью оптимизации быстродействия разработчики 1С изменили структуру базы данных. В структуру периодического регистра сведений ФИОФизическихЛиц был добавлен новый ресурс — Инициалы (в ранних версиях он мог называться ИнициалыИмени). Теперь при любой записи физического лица или изменении его паспортных данных система автоматически рассчитывает инициалы один раз и сохраняет их в этот ресурс в виде готовой строки (например, «И.О.»). При формировании отчетов система делает простой и быстрый запрос напрямую к этому полю, минуя сложные вызовы строковых функций общего модуля.
Рассмотрим пример упрощенного запроса, который теперь используется в системе для вывода кадровых данных:
ВЫБРАТЬ
Сотрудники.Ссылка КАК Сотрудник,
ФИОФизическихЛиц.Фамилия КАК Фамилия,
ФИОФизическихЛиц.Инициалы КАК Инициалы
ИЗ
Справочник.Сотрудники КАК Сотрудники
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ФИОФизическихЛиц.СрезПоследних(&Период, ) КАК ФИОФизическихЛиц
ПО Сотрудники.ФизическоеЛицо = ФИОФизическихЛиц.ФизическоеЛицо
Если поле Инициалы в регистре оказывается пустым, то при соединении строк «Фамилия» и «Инициалы» программа выводит только фамилию, что мы и наблюдаем в ведомостях Т-51 и Т-53.
Поскольку поле Инициалы является новым, у всех физических лиц, которые уже были внесены в информационную базу до момента обновления, этот ресурс по умолчанию пуст. Чтобы заполнить его историческими данными, в составе обновления предусмотрен специальный инструмент — отложенный обработчик обновления информационной базы, работающий в рамках Библиотеки стандартных подсистем (БСП).
Этот обработчик должен запускаться автоматически в фоновом режиме сразу после первого запуска обновленной базы данных. Он порциями считывает записи регистра ФИОФизическихЛиц, рассчитывает инициалы и записывает их обратно. Если этот процесс не завершился или вообще не начался, инициалы в печатных формах не появятся.
Выясним основные причины, почему отложенное обновление не отрабатывает:
Проанализируем три практических способа решения этой проблемы в зависимости от масштаба вашей информационной базы.
Если вы столкнулись с пустой колонкой инициалов, первым делом необходимо проверить статус регламентных заданий и запустить отложенную обработку данных силами самой БСП.
Разберем этот процесс по шагам:
После того как фоновое задание завершит работу (время выполнения зависит от количества физических лиц в базе и может занимать от нескольких секунд до пары десятков минут), откройте ведомости Т-51 или Т-53 и проверьте результат. Инициалы должны успешно появиться.
Если в вашей организации числится небольшое количество сотрудников (до 50-100 человек), и вы не хотите разбираться в консоли администрирования или процедурах БСП, можно прибегнуть к простому интерактивному способу пересчета данных.
Выполните следующие действия:
При записи элемента справочника система активирует внутренний обработчик объекта (событие ПередЗаписью или ПриЗаписи), который принудительно пересчитает инициалы по актуальному алгоритму и мгновенно запишет корректное значение в периодический регистр сведений ФИОФизическихЛиц. Данные в печатных формах по этому сотруднику сразу же восстановятся.
В крупных компаниях с численностью сотрудников в несколько тысяч человек ручной обход карточек невозможен, а штатные обработчики БСП могут зависать или выдавать неочевидные ошибки блокировок БД. В этом случае программист 1С может быстро решить проблему с помощью внешней обработки, написав скрипт для принудительного заполнения ресурса регистра.
Рассмотрим пример кода, который считывает пустые записи из регистра сведений ФИОФизическихЛиц, программно формирует инициалы на основе полей «Имя» и «Отчество» и записывает результат напрямую в базу данных:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ФИОФизическихЛиц.ФизическоеЛицо КАК ФизическоеЛицо,
| ФИОФизическихЛиц.Период КАК Период,
| ФИОФизическихЛиц.Фамилия КАК Фамилия,
| ФИОФизическихЛиц.Имя КАК Имя,
| ФИОФизическихЛиц.Отчество КАК Отчество
|ИЗ
| РегистрСведений.ФИОФизическихЛиц КАК ФИОФизическихЛиц
|ГДЕ
| ФИОФизическихЛиц.Инициалы = """"";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
ПроведеноЗаписей = 0;
Пока Выборка.Следующий() Цикл
// Формируем строку инициалов
СтрокаИнициалов = "";
Если ЗначениеЗаполнено(Выборка.Имя) Тогда
СтрокаИнициалов = СтрокаИнициалов + Лев(СокрЛП(Выборка.Имя), 1) + ".";
КонецЕсли;
Если ЗначениеЗаполнено(Выборка.Отчество) Тогда
СтрокаИнициалов = СтрокаИнициалов + Лев(СокрЛП(Выборка.Отчество), 1) + ".";
КонецЕсли;
// Если инициалы удалось собрать, записываем их в базу
Если ЗначениеЗаполнено(СтрокаИнициалов) Тогда
МенеджерЗаписи = РегистрыСведений.ФИОФизическихЛиц.СоздатьМенеджерЗаписи();
МенеджерЗаписи.ФизическоеЛицо = Выборка.ФизическоеЛицо;
МенеджерЗаписи.Период = Выборка.Период;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
МенеджерЗаписи.Инициалы = СтрокаИнициалов;
Попытка
МенеджерЗаписи.Записать(Истина);
ПроведеноЗаписей = ПроведеноЗаписей + 1;
Исключение
ЗаписьЖурналаРегистрации("ОбновлениеФИО", УровеньЖурналаРегистрации.Предупреждение, , ,
"Не удалось записать ФИО для: " + Выборка.ФизическоеЛицо + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
КонецЦикла;
ПоказатьПредупреждение(, "Успешно обработано и заполнено записей: " + ПроведеноЗаписей);
Данный скрипт работает максимально безопасно, так как он обрабатывает исключительно те записи регистра ФИОФизическихЛиц, в которых поле Инициалы не заполнено (равно пустой строке ""). Использование метода Записать(Истина) гарантирует замещение старых некорректных записей без дублирования информации в базе данных.
Чтобы избежать подобных инцидентов при последующих обновлениях любых конфигураций (будь то ЗУП, ERP или Бухгалтерия предприятия), выработайте строгое правило контроля регламентных заданий. По завершении любого обновления ИБ обязательно проверяйте статус фонового планировщика задач в консоли администрирования. Своевременный запуск отложенных обработчиков обновлений гарантирует корректность отображения всех печатных форм и стабильную работу аналитических отчетов программы.