Как убрать префикс (номер личной карточки) из табельного номера в печатных формах 1С:ЗУП 3.1?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Промышленность, строительство и АПК
← На главную

В конфигурации 1С:Зарплата и Управление Персоналом 3.1 табельный номер сотрудника является кодом справочника Сотрудники. На многих крупных предприятиях, особенно в промышленном секторе, принята сложная система кодирования, когда в табельный номер включается дополнительная информация, например, номер личной карточки. В результате код сотрудника принимает вид 55441-1254, где 55441 — номер личной карточки, а 1254 — собственно табельный номер.

Основная сложность заключается в том, что в кадровых приказах, расчетных листках и ведомостях требуется выводить только значимую часть номера (в нашем примере — 1254), отсекая все лишнее. Рассмотрим подробно, как работает штатный механизм очистки номеров и как его адаптировать под требования предприятия.

Анализ штатного механизма префиксации

В системе 1С за формирование «красивых» номеров для печати отвечает Библиотека стандартных подсистем (БСП). Проанализируем ситуацию: когда мы выводим документ на печать, программа не просто берет значение из поля Код, а пропускает его через специальные функции «очистки». Эти функции предназначены для удаления префиксов организации и префиксов информационной базы (РИБ).

Ключевым объектом здесь является общий модуль ПрефиксацияОбъектовКлиентСервер. Именно в нем расположена функция УдалитьПрефиксыИзНомераОбъекта(). Разберем по шагам, как она работает:

  1. Программа ищет в строке кода специальные разделители (например, дефис).
  2. Система пытается сопоставить левую часть (до дефиса) с известными префиксами, зарегистрированными в справочнике Организации или в настройках синхронизации данных.
  3. Если префикс найден и он соответствует стандарту (обычно это 2 символа организации и 3 символа базы), он удаляется.

Проблема, с которой сталкиваются пользователи (как в нашем случае), часто заключается в длине этого префикса. Если номер личной карточки состоит из 6 цифр, а штатный механизм настроен на обработку префиксов длиной до 5 символов, функция УдалитьПрефиксыИзНомераОбъекта() просто игнорирует такую строку, считая её цельным кодом, и выводит на печать в исходном виде 55441-1254.

Корректировка логики в общем модуле

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

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


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

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

Реализация через расширение конфигурации

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

Создадим новое расширение и добавим в него общий модуль ПрефиксацияОбъектовКлиентСервер. Нам понадобится применить аннотацию &Вместо для целевой функции. Проанализируем следующий код:


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

Важно помнить, что Табельный номер в печатных формах кадровых документов часто обрабатывается специализированным модулем КадровыйУчетРасширенный или КадровыйУчет. В этих модулях есть функции вроде ОтредактироватьДляПечатиТабельныйНомер(). Если изменения в префиксации не помогли для конкретного отчета (например, Расчетного листка), следует проверить именно эти кадровые функции.

Особенности работы при больших объемах данных (на примере Oracle)

Если на вашем предприятии работает большое количество сотрудников (например, 30 000 человек), и база данных развернута на СУБД Oracle, необходимо учитывать вопросы производительности. При формировании массовых отчетов, таких как расчетные листки на весь завод, преобразование строк «на лету» в запросах может существенно замедлить процесс.

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

Альтернативный подход: хранение данных в разных полях

Иногда более правильным архитектурным решением будет разделение данных. Если номер личной карточки и табельный номер — это разные сущности, их стоит хранить раздельно. Рассмотрим такой вариант:

  1. В поле Код (Табельный номер) справочника Сотрудники храним только чистый номер (например, 1254).
  2. Для номера личной карточки создаем Дополнительный реквизит.
  3. Если в каких-то специфических формах требуется выводить оба номера, мы просто дорабатываем эти формы, чтобы они подтягивали значение из доп. реквизита.

Этот способ является наиболее «чистым» с точки зрения методологии 1С, так как он не требует вмешательства в системные механизмы префиксации, которые могут затронуть не только сотрудников, но и нумерацию документов (приказов, ведомостей и т.д.), что может привести к непредсказуемым последствиям в других частях программы.

Подводя итог, можно сказать, что решение через правку общего модуля ПрефиксацияОбъектовКлиентСервер (лучше через расширение) является самым быстрым способом «починить» печать во всех документах сразу, но требует внимательного тестирования длины префиксов и корректности работы со всеми объектами системы.

← На главную