Как программно заполнить реквизит КраткийСоставДокумента в документе ОтпускаСотрудников

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

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

Анализ механизма формирования состава сотрудников

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

В ЗУП 3.1 существует специальный Определяемый тип ОбъектСУчетомСоставаСотрудников. Все документы, включенные в этот тип, автоматически участвуют в работе подписок на события:

  1. ЗаполнитьСоставСотрудниковДокументаПередЗаписью
  2. ЗаполнитьСоставСотрудниковДокументаПриЗаписи

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

Приоритет табличных частей и проблема скрытых данных

Рассмотрим подробнее работу функции ОписаниеСоставаОбъектаПоМетаданным в модуле ЗарплатаКадрыСоставДокументов. Оказывается, система ищет сотрудников в документе в строго определенном порядке приоритетности табличных частей:

  1. ФизическиеЛица (наивысший приоритет);
  2. Сотрудники;
  3. Состав.

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

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

Пошаговое решение проблемы

Разберем по шагам, что нужно сделать, чтобы КраткийСоставДокумента заполнился корректно при программном создании документа.

Шаг 1. Синхронизация табличных частей

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


НовыйДокумент = Документы.ОтпускаСотрудников.СоздатьДокумент();
// Заполнение основных реквизитов (Организация, Дата и т.д.)
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = Справочники.Организации.НайтиПоНаименованию("Наша Организация");

// Заполнение табличной части Сотрудники (или Отпуска)
НоваяСтрока = НовыйДокумент.Сотрудники.Добавить();
НоваяСтрока.Сотрудник = ВыбранныйСотрудник;
// ... заполнение остальных полей строки ...

// КРИТИЧЕСКИ ВАЖНЫЙ МОМЕНТ:
// Синхронизируем ТЧ ФизическиеЛица на основании ТЧ Сотрудники
ЗарплатаКадрыСоставДокументов.ОбновитьФизическиеЛицаОбъекта(НовыйДокумент);

Метод ЗарплатаКадрыСоставДокументов.ОбновитьФизическиеЛицаОбъекта проанализирует заполненную вами таблицу сотрудников и наполнит служебную таблицу ФизическиеЛица. Без этого шага подписка на событие перед записью «не увидит» людей в документе.

Шаг 2. Вызов формирования краткого состава

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


// Явный вызов формирования строки состава
ЗарплатаКадрыСоставДокументов.ЗаполнитьСоставСотрудниковДокументаПередЗаписью(НовыйДокумент);

// Теперь можно записывать
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);

Почему поведение различается: Интерактивно vs Программно

Выясним причину, почему при интерактивной записи всё работает, а программно — нет. В форме документа ОтпускаСотрудников обычно реализован обработчик события ПередЗаписьюНаСервере. В нем вызываются механизмы «оживляющие» объект: обновляются дополнительные свойства, рассчитываются итоги и, что самое важное, подготавливаются структуры данных, которые подписка на события ожидает увидеть.

При использовании ДокументОбъект.Записать() контекст формы отсутствует. Если вы не заполнили ТЧ ФизическиеЛица, функция ОписаниеСоставаОбъектаПоМетаданным может вернуть неверное имя таблицы (например, решив, что данные должны быть в ФизическиеЛица, хотя вы заполнили Сотрудники). В результате запрос внутри подписки возвращает пустой результат, и реквизит очищается.

Особенности для сложных случаев

Если вы работаете с документами-исправлениями (когда заполнен реквизит ДокументИсправление), логика может быть еще сложнее. В этом случае система может пытаться анализировать состав первичного документа. Убедитесь, что все связи между документами установлены до вызова методов обновления состава.

Также стоит помнить про кэширование метаданных. В некоторых версиях ЗУП 3.1 модуль ЗарплатаКадрыСоставДокументов кэширует структуру табличных частей для каждого типа документа. Если вы вносили изменения в состав табличных частей в расширении, может потребоваться очистка серверного кэша или перезапуск сеанса, чтобы система увидела изменения и начала правильно определять приоритетную ТЧ.

Резюме для реализации

Подведем итог. Чтобы успешно программно заполнить КраткийСоставДокумента, следуйте этой схеме:

  1. Заполните все ключевые реквизиты шапки (Организация, ПериодРегистрации).
  2. Заполните основную табличную часть (Сотрудники или Отпуска).
  3. Обязательно вызовите ЗарплатаКадрыСоставДокументов.ОбновитьФизическиеЛицаОбъекта(ЭтотОбъект).
  4. Для надежности вызовите ЗарплатаКадрыСоставДокументов.ЗаполнитьСоставСотрудниковДокументаПередЗаписью(ЭтотОбъект).
  5. Выполните Записать().

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

← На главную