При автоматизации учета рабочего времени в программе 1С:Зарплата и управление персоналом 3.1 разработчики часто сталкиваются со странным поведением системы при интеграции с внешними источниками. Типичный сценарий: в течение месяца кадровики создают документы Отсутствие (болезнь, прогул, неявка), регистрируя невыходы (код «НН»). В конце месяца из сторонней системы (например, СКУД или внешней базы) загружаются данные и программно создаются документы Табель. Однако сразу после загрузки в отчете «Т-13» вместо ожидаемых «НН» в дни отсутствий выводятся выходные дни («В»).
Самое удивительное происходит дальше: если этот табель вручную распровести, а затем снова провести, то «НН» возвращается на свое место в отчете Т-13! Выясним причину этого феномена и найдем системные способы его решения без использования «костылей» в виде интерактивного перепроведения.
Для начала проанализируем, как конфигурация 1С:ЗУП 3.1 собирает данные для унифицированной формы Т-13. В отличие от старых версий (например, ЗУП 2.5), где документ Табель обладал абсолютным приоритетом и перезаписывал любые другие кадровые данные, в редакции 3.1 логика кардинально изменилась.
Отчет Т-13 строится на основании данных из нескольких регистров накопления:
Табель.Больничный лист, Отпуск, Отсутствие (болезнь, прогул, неявка) и т.д.).При формировании Т-13 программа сопоставляет эти данные. Согласно методологии конфигурации, документы-отклонения имеют приоритет вытеснения над плановым временем и явками, указанными в табеле. Если за один и тот же день зарегистрированы и невыход, и явка (или выходной), приоритет отдается невыходу.
Однако при программном создании документа Табель этот механизм дает сбой. Рассмотрим по шагам, почему при первой записи документа код «НН» заменяется на «В»:
Записать(РежимЗаписиДокумента.Проведение).ОбработкаПроведения модуля документа. На этом этапе система выполняет сложные поисковые запросы к СУБД для сопоставления данных новой табличной части документа Табель с существующими в базе документами отклонений.Когда мы делаем отмену проведения и повторное проведение, документ уже записан в базе данных. Его строки физически сохранены на диске. При повторном проведении запросы ЗУП отрабатывают штатно, находят пересечение с документом Отсутствие и заменяют «В» на «НН» в движениях регистров.
---
Рассмотрим несколько вариантов решения этой проблемы в коде вашей обработки загрузки.
Чтобы избежать сбоев в работе запросов внутри обработчика проведения, нам необходимо гарантировать, что данные табличной части физически попадут в базу данных до того, как начнется транзакция проведения и расчет движений. Для этого достаточно разделить запись объекта и его проведение.
Посмотрим на пример правильной последовательности вызовов в коде:
// Заполняем реквизиты и табличные части документа "Табель"...
ДокТабель.Дата = КонецМесяца(ПериодРегистрации);
ДокТабель.Организация = ВыбраннаяОрганизация;
// ... (заполнение ТЧ ДанныеОРабочемВремени)
// Шаг 1. Записываем документ в базу данных без проведения
ДокТабель.Записать(РежимЗаписиДокумента.Запись);
// Шаг 2. Проводим уже физически существующий в базе документ
ДокТабель.Записать(РежимЗаписиДокумента.Проведение);
При такой схеме во время выполнения транзакции проведения СУБД успешно прочитает строки табличной части документа из базы данных, сопоставит их с зарегистрированными ранее отклонениями и запишет в регистры верные данные с кодом «НН».
Просто переносить «Я» и «В» из внешнего файла в пустой документ — не всегда лучшее решение, так как кадровики не увидят реальную картину отклонений в интерфейсе самого документа Табель (там останутся «В» вместо «НН», хотя в отчете Т-13 все будет красиво).
Правильнее сначала заполнить документ по данным системы, а уже затем поверх накладывать изменения из внешнего файла. Разберем этот алгоритм по шагам:
Табель.УчетРабочегоВремени или модуля менеджера документа. Например:
// Заполняем документ стандартным механизмом ЗУП
Документы.Табель.ЗаполнитьДокумент(ДокТабель);
После этого в табличной части документа уже будут стоять корректные «НН», «ОТ» (отпуска) и «Б» (больничные). Теперь мы можем обойти табличную часть циклом, сравнить ее с данными из нашего внешнего файла загрузки, обновить только часы явки («Я») там, где это необходимо, и провести документ стандартным образом.
При программном создании документов в ЗУП 3.1 разработчики часто забывают, что под капотом сложных документов скрывается множество служебных табличных частей. У документа Табель, помимо основной ТЧ ДанныеОРабочемВремени, присутствуют табличные части Сотрудники и ФизическиеЛица.
Если при программном формировании документа вы заполняете только ДанныеОРабочемВремени, оставляя служебные ТЧ пустыми, то при проведении алгоритмы расчета времени ЗУП отработают непредсказуемо, так как они ориентируются на состав сотрудников в ТЧ Сотрудники.
Обязательно проверяйте полноту заполнения всех связанных табличных частей. Для упрощения этой задачи рекомендуется использовать процедуру инициализации документа:
// Заполнение служебных таблиц на основании основных данных
ДокТабель.ЗаполнитьФизическихЛиц();
Применение этих простых правил позволит вам избежать расхождения данных между документами и отчетами, а также избавит пользователей от необходимости вручную перепроводить документы после автоматической загрузки.