Как программно заполнить прием на работу по штатному расписанию в 1С:ЗУП 3.1

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

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

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

Почему возникает сложность при программном заполнении

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

Если попытаться использовать эти функции напрямую в коде (например, при импорте данных из внешней CRM или ERP-системы), система выдаст ошибку отсутствия контекста формы. Чтобы решить эту проблему красиво и надежно, нам нужно обойти «клиентскую» обертку и обратиться напрямую к бизнес-логике конфигурации.

---

Способ 1. Использование официального API для получения параметров позиции штатного расписания

Вместо написания собственных тяжелых запросов к регистрам сведений штатного расписания, мы можем использовать стабильный программный интерфейс, который разработчики 1С заложили в систему. Для получения всех параметров позиции штатного расписания на определенную дату (включая начисления и графики работы) предназначен общий модуль УправлениеШтатнымРасписанием.

Основная функция, которая нам понадобится: УправлениеШтатнымРасписанием.ДанныеПозицииШтатногоРасписания().

Рассмотрим ее параметры подробнее:

  1. Позиция — ссылка на элемент справочника ШтатноеРасписание.
  2. Дата — дата, на которую необходимо получить актуальные данные (дата приема сотрудника на работу).
  3. ВключатьНачисления — булево значение. Если передать Истина, функция вернет таблицу плановых начислений и показателей, привязанных к этой позиции.

Давайте проанализируем пример кода, который получает эти данные:


// Определяем параметры
ПозицияШР = Справочники.ШтатноеРасписание.НайтиПоРеквизиту("Код", "00000001");
ДатаПриема = ТекущаяДата();

// Получаем структуру данных позиции
ДанныеПозиции = УправлениеШтатнымРасписанием.ДанныеПозицииШтатногоРасписания(ПозицияШР, ДатаПриема, Истина);

Если ДанныеПозиции = Неопределено Тогда
    ВызватьИсключение "Не удалось получить данные по выбранной позиции штатного расписания!"; КонецЕсли;

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

---

Способ 2. Заполнение табличных частей «Начисления» и «Показатели» (Критически важный нюанс)

Просто перенести строки из структуры штатного расписания в документ Прием на работу недостаточно. Наиболее частая ошибка начинающих разработчиков в ЗУП 3.1 — это некорректное заполнение плановых начислений сотрудника. При ручном добавлении строк на форме они выглядят пустыми, хотя расчет ФОТ (фонда оплаты труда) при этом может отрабатывать.

Выясним причину этого поведения. В документе Прием на работу табличная часть Начисления и табличная часть Показатели жестко связаны между собой через служебный реквизит ИдентификаторСтрокиВидаРасчета.

При программном заполнении нам необходимо строго соблюдать следующий алгоритм:

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

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


Функция СоздатьПриемНаРаботуПоШтатномуРасписанию(Сотрудник, ПозицияШР, ДатаПриема, Организация) Экспорт

    // 1. Создаем новый документ
    ДокОбъект = Документы.ПриемНаРаботу.СоздатьДокумент();
    ДокОбъект.Дата = ТекущаяДата();
    ДокОбъект.Организация = Организация;
    ДокОбъект.Сотрудник = Сотрудник;
    ДокОбъект.ФизическоеЛицо = Сотрудник.ФизическоеЛицо;
    ДокОбъект.ДатаПриема = ДатаПриема;
    
    // 2. Получаем данные позиции штатного расписания через API
    ДанныеПозиции = УправлениеШтатнымРасписанием.ДанныеПозицииШтатногоРасписания(ПозицияШР, ДатаПриема, Истина);
    
    Если ДанныеПозиции <> Неопределено Тогда
        // Заполняем основные кадровые реквизиты
        ДокОбъект.Подразделение = ДанныеПозиции.Подразделение;
        ДокОбъект.Должность = ДанныеПозиции.Должность;
        ДокОбъект.ДолжностьПоШтатномуРасписанию = ПозицияШР;
        ДокОбъект.ГрафикРаботы = ДанныеПозиции.ГрафикРаботы;
        ДокОбъект.КоличествоСтавок = 1; // Указываем количество ставок по умолчанию
    КонецЕсли;
    
    // Очищаем ТЧ перед заполнением
    ДокОбъект.Начисления.Очистить();
    ДокОбъект.Показатели.Очистить();
    
    // Инициализируем счетчик связи табличных частей
    ИндексСвязи = 1;
    
    // 3. Заполняем плановые начисления и показатели
    Если ДанныеПозиции.Свойство("Начисления") И ТипЗнч(ДанныеПозиции.Начисления) = Тип("ТаблицаЗначений") Тогда
        
        Для Каждого СтрокаНачисленияИзШР Из ДанныеПозиции.Начисления Цикл
            
            // Добавляем строку в ТЧ Начисления
            НоваяСтрокаНачисления = ДокОбъект.Начисления.Добавить();
            ЗаполнитьЗначенияСвойств(НоваяСтрокаНачисления, СтрокаНачисленияИзШР);
            НоваяСтрокаНачисления.ИдентификаторСтрокиВидаРасчета = ИндексСвязи;
            
            // Ищем показатели, связанные с этим начислением в ШР
            Если ДанныеПозиции.Свойство("Показатели") И ТипЗнч(ДанныеПозиции.Показатели) = Тип("ТаблицаЗначений") Тогда
                
                // Фильтруем показатели по текущему начислению
                Отбор = Новый Структура("ИдентификаторСтрокиВидаРасчета", СтрокаНачисленияИзШР.ИдентификаторСтрокиВидаРасчета);
                НайденныеПоказатели = ДанныеПозиции.Показатели.НайтиСтроки(Отбор);
                
                Для Каждого СтрокаПоказателяИзШР Из НайденныеПоказатели Цикл
                    // Добавляем строку в ТЧ Показатели документа
                    НоваяСтрокаПоказателя = ДокОбъект.Показатели.Добавить();
                    ЗаполнитьЗначенияСвойств(НоваяСтрокаПоказателя, СтрокаПоказателяИзШР);
                    // Связываем строку показателя со строкой начисления
                    НоваяСтрокаПоказателя.ИдентификаторСтрокиВидаРасчета = ИндексСвязи;
                КонецЦикла;
                
            КонецЕсли;
            
            // Увеличиваем индекс для следующего начисления
            ИндексСвязи = ИндексСвязи + 1;
            
        КонецЦикла;
        
    КонецЕсли;
    
    // Перед записью обязательно рассчитываем ФОТ по заполненным показателям
    // Используем стандартный метод для пересчета ФОТ документа
    КадровыйУчет.РассчитатьФОТДокумента(ДокОбъект);
    
    // Записываем документ
    Попытка
        ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
        Возврат ДокОбъект.Ссылка;
    Исключение
        ЗаписьЖурналаРегистрации("ПрограммныйПриемНаРаботу", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        Возврат Неопределено;
    КонецПопытки;

КонецФункции

Использование метода КадровыйУчет.РассчитатьФОТДокумента() гарантирует, что фонд оплаты труда по документу будет рассчитан строго по правилам конфигурации, и у расчетчиков зарплаты не возникнет расхождений при последующем начислении.

---

Способ 3. Проверка свободных ставок (Контроль вакансий)

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

Для программной проверки свободных ставок мы можем использовать функцию:

УправлениеШтатнымРасписанием.ЗанятостьПозицийШтатногоРасписания(ПозицияШР, ДатаПриема)

Проанализируем пример функции проверки вакантных мест перед созданием приема:


Функция ЕстьСвободнаяСтавка(ПозицияШР, ДатаПриема) Экспорт

    ТаблицаЗанятости = УправлениеШтатнымРасписанием.ЗанятостьПозицийШтатногоРасписания(ПозицияШР, ДатаПриема);
    
    Если ТаблицаЗанятости.Количество() > 0 Тогда
        ТекущаяСтрока = ТаблицаЗанятости[0];
        // Вычисляем количество свободных ставок
        СвободноСтавок = ТекущаяСтрока.КоличествоСтавок - ТекущаяСтрока.КоличествоЗанятыхСтавок;
        Возврат (СвободноСтавок >= 1);
    КонецЕсли;
    
    Возврат Ложь;

КонецФункции

Такой превентивный контроль убережет базу данных от рассогласованности кадрового учета и штатного расписания.

---

Способ 4. Оптимизация для внешних обработок (Тип команды «ЗаполнениеФормы»)

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

При регистрации внешней обработки заполнения табличных частей укажите тип команды ЗаполнениеФормы вместо стандартного ВызовКлиентскогоМетода или ВызовСерверногоМетода.

Преимущества этого подхода:

Пример секции регистрации внешней обработки:


Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработкеКопированием();
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
    ПараметрыРегистрации.Назначение.Добавить("Документ.ПриемНаРаботу");
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Заполнить по штатному расписанию (Умное заполнение)";
    НоваяКоманда.Идентификатор = "ЗаполнитьПоШР";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыЗаполнениеФормы();
    
    Возврат ПараметрыРегистрации;

КонецФункции

---

Резюме и рекомендации для стабильной разработки

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

  1. Никогда не пишите прямые запросы к регистрам сведений штатного расписания, если нужно получить состав начислений позиции — используйте готовый метод УправлениеШтатнымРасписанием.ДанныеПозицииШтатногоРасписания().
  2. При заполнении начислений программно всегда связывайте ТЧ Начисления и ТЧ Показатели через генерацию сквозного уникального значения ИдентификаторСтрокиВидаРасчета.
  3. Не забывайте принудительно вызывать пересчет ФОТ документа методом КадровыйУчет.РассчитатьФОТДокумента() перед его записью.

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

← На главную