Как программно заменить подразделение в регистре «Место позиции штатного расписания в структуре предприятия»

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

В процессе реорганизации компании, изменения управленческой структуры или исправления ошибок ведения учета в конфигурациях 1С:Зарплата и управление персоналом 3.1 (ЗУП), 1С:ERP Управление предприятием или 1С:Комплексная автоматизация (КА) часто возникает необходимость массово скорректировать данные. Одной из типичных задач является программное изменение привязки позиций штатного расписания к определенным узлам управленческой структуры.

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

Разбор терминологии и архитектурных различий справочников

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

  1. Справочник «Подразделения организаций» — отвечает за регламентированную (юридическую) структуру предприятия. Этот справочник имеет выраженную подчиненность конкретному юридическому лицу. У него заполняется стандартный реквизит Владелец (ссылка на справочник Организации).
  2. Справочник «Структура предприятия» — используется для ведения управленческого учета. Именно он задействован в регистре сведений МестоПозицииШтатногоРасписанияВСтруктуреПредприятия. Этот справочник не имеет владельца в терминах платформы 1С. Он построен по принципу обычной иерархии элементов, где связь между узлами определяется реквизитом Родитель.

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

Алгоритм поиска «двойника» подразделения в новой ветке структуры

Для того чтобы корректно выполнить замену, нам нужно сопоставить старое подразделение с новым. Предположим, у нас есть старая ветка структуры «Филиал А -> Бухгалтерия» и новая ветка «Филиал Б -> Бухгалтерия». Нам нужно заменить старое подразделение «Бухгалтерия» (принадлежащее Филиалу А) на новое подразделение «Бухгалтерия» (принадлежащее Филиалу Б).

Рассмотрим по шагам логику поиска аналогичного подразделения:

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

Для реализации этого поиска оптимально использовать запрос к базе данных. Посмотрим на пример функции, которая находит ссылку на аналогичное подразделение:


Функция НайтиАналогичноеПодразделение(НаименованиеИсточника, НовыйРодитель) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |   СтруктураПредприятия.Ссылка КАК Ссылка
        |ИЗ
        |   Справочник.СтруктураПредприятия КАК СтруктураПредприятия
        |ГДЕ
        |   СтруктураПредприятия.Наименование = &Наименование
        |   И СтруктураПредприятия.Ссылка В ИЕРАРХИИ (&НовыйРодитель)
        |   И СтруктураПредприятия.Ссылка <> &НовыйРодитель";
        
    Запрос.УстановитьПараметр("Наименование", НаименованиеИсточника);
    Запрос.УстановитьПараметр("НовыйРодитель", НовыйРодитель);
    
    РезультатЗапроса = Запрос.Выполнить();
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.Ссылка;
    КонецЕсли;
    
    Возврат Справочники.СтруктураПредприятия.ПустаяСсылка();
    
КонецФункции

Программное изменение регистра сведений

Теперь рассмотрим, как перезаписать данные в регистре сведений МестоПозицииШтатногоРасписанияВСтруктуреПредприятия. Мы применим метод работы с набором записей, так как он является наиболее безопасным и производительным при массовых изменениях.

Проанализируем пример кода, выполняющего чтение регистра, поиск аналогов и перезапись значений:


Процедура ВыполнитьЗаменуПодразделений(НовыйРодитель) Экспорт
    
    // Получаем набор записей регистра
    НаборЗаписей = РегистрыСведений.МестоПозицииШтатногоРасписанияВСтруктуреПредприятия.СоздатьНаборЗаписей();
    НаборЗаписей.Прочитать();
    
    Модифицирован = Ложь;
    
    Для Каждого Запись Из НаборЗаписей Цикл
        
        ТекущееПодразделение = Запись.Подразделение;
        
        // Проверяем, что подразделение заполнено и не входит в целевую ветку
        Если ЗначениеЗаполнено(ТекущееПодразделение) Тогда
            
            // Проверим, не принадлежит ли оно уже новой ветке
            Если Не ТекущееПодразделение.ПринадлежитИерархии(НовыйРодитель) Тогда
                
                НаименованиеТекущего = ТекущееПодразделение.Наименование;
                НовоеПодразделение = НайтиАналогичноеПодразделение(НаименованиеТекущего, НовыйРодитель);
                
                Если ЗначениеЗаполнено(НовоеПодразделение) Тогда
                    Запись.Подразделение = НовоеПодразделение;
                    Модифицирован = Истина;
                Иначе
                    ЗаписьЖурналаРегистрации("ЗаменаСтруктурыПредприятия",
                        УровеньЖурналаРегистрации.Предупреждение,
                        ,
                        ,
                        "Не найдено аналогичное подразделение для: " + НаименованиеТекущего);
                КонецЕсли;
                
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
    Если Модифицирован Тогда
        НачатьТранзакцию();
        Попытка
            // Записываем измененный набор с замещением старых записей
            НаборЗаписей.Записать(Истина);
            ЗафиксироватьТранзакцию();
            Сообщить("Замена подразделений успешно выполнена!");
        Исключение
            ОтменитьТранзакцию();
            ВызватьИсключение "Ошибка при записи набора в регистр: " + ОписаниеОшибки();
        КонецПопытки;
    Иначе
        Сообщить("Изменений не обнаружено. Все записи соответствуют выбранной структуре.");
    КонецЕсли;
    
КонецПроцедуры

Критические подводные камни решения (Архитектура 1С)

Программная перезапись записей регистра напрямую в базу данных — это быстрое решение, но в реальных рабочих базах 1С оно скрывает в себе серьезные опасности. Выясним основные технические риски и методы борьбы с ними.

1. Появление периодичности регистра в новых релизах

Обратите внимание, что в последних версиях прикладных решений на базе 1С:ЗУП 3.1 разработчики фирмы «1С» изменили структуру регистра сведений МестоПозицииШтатногоРасписанияВСтруктуреПредприятия. Регистр стал периодическим. Это значит, что у него появилось ключевое измерение Период.

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

2. Рассинхронизация с регистром «Данные для подбора сотрудников»

В 1С данные о структуре предприятия активно кэшируются для ускорения работы интерфейсов кадровых документов и отчетов. Основным местом хранения кэша является регистр сведений ДанныеДляПодбораСотрудников.

Когда вы меняете подразделение непосредственно в регистре позиций штатного расписания, у уже работающих сотрудников (привязанных к этим позициям) в регистре ДанныеДляПодбораСотрудников остается старое значение управленческого подразделения. Это приведет к следующим проблемам:

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

3. Риск автоматического затирания изменений документами

Если в настройках программы включена опция «Ведется история изменений штатного расписания», то основным источником данных для регистра мест позиций являются документы:

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

4. Интеграция с ERP / Комплексной автоматизацией

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

Резюме

Программная замена подразделения в регистре управленческой структуры — эффективный инструмент оптимизации рутинной работы системного администратора и программиста 1С. Для безопасного выполнения этой операции всегда используйте транзакции, учитывайте иерархическую структуру справочника СтруктураПредприятия и не забывайте обновлять кэшированные данные сотрудников для сохранения целостности всей учетной системы.

← На главную