Переход с устаревшей версии 1С:Зарплата и управление персоналом 2.5 на современную 3.1 — это сложный процесс, который часто сопровождается «хвостами» в данных. Одной из самых загадочных проблем является ситуация, когда после успешного, на первый взгляд, переноса в документе Табель у одного или нескольких сотрудников начинают отображаться нереальные цифры. Например, вместо 8 часов система ставит 570, а итоговая сумма за месяц исчисляется тысячами часов. При этом индивидуальные графики работы могут быть заполнены абсолютно корректно.
В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем внутреннюю архитектуру хранения данных в ЗУП 3.1 и найдем способ окончательного решения проблемы.
Давайте проанализируем, откуда программа берет информацию для автоматического заполнения табличных частей. В версии 3.1 для оптимизации производительности разработчики 1С применили механизм денормализации данных. Вместо того чтобы при каждом открытии табеля обращаться к десятку различных регистров (кадровым данным, графикам, плановым начислениям), система считывает предварительно подготовленные сведения из вспомогательного регистра — Данные для подбора сотрудников.
Проблема заключается в том, что если в этом регистре появляются дублирующие записи по одному сотруднику на один и тот же период, программные запросы к виртуальным таблицам начинают «размножать» строки. Рассмотрим подробнее, как это происходит:
Табель система выполняет запрос к регистру ДанныеДляПодбораСотрудников.Разберем ситуацию, которая часто встречается при использовании типовых правил переноса. В структуре регистра ДанныеДляПодбораСотрудников есть измерение ИдентификаторЗаписи. Это поле имеет тип УникальныйИдентификатор (GUID).
Важный технический нюанс: наличие этого поля делает каждую запись уникальной для СУБД, даже если значения полей Сотрудник, Организация и Период полностью идентичны. При выполнении переноса данных (особенно если он производился в несколько этапов или прерывался) механизмы очистки могут не сработать. В итоге в базе остаются «фантомные» записи с разными GUID, которые визуально в списке могут выглядеть одинаково, но для системы являются разными сущностями.
Также возможна ситуация несоответствия между полями Сотрудник и Физическое лицо. В ЗУП 3.1 это разные справочники, и если при переносе по ошибке была создана запись, где связка этих объектов нарушена, регистр начнет выдавать некорректные итоги при расчете времени.
Если проблема носит единичный характер (затрагивает одного или нескольких сотрудников), мы можем воспользоваться ручной корректировкой. Для этого выполним следующие действия:
Данные для подбора сотрудников через Функции для технического специалиста (или «Все функции»).Обратите внимание: система может не дать просто перезаписать запись, если вы попытаетесь изменить ее вручную через форму, так как сработает контроль уникальности по ключевым полям (без учета GUID). Однако программное удаление или использование групповой обработки данных позволяет обойти это ограничение.
Если после переноса пострадали сотни сотрудников, ручная очистка невозможна. В этом случае нам потребуется написать небольшую обработку. Рассмотрим пример кода, который поможет выявить дубликаты. Мы будем искать записи, сгруппированные по ключевым измерениям, где количество вхождений больше одного.
// Пример логики поиска дублей в регистре
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Данные.Сотрудник КАК Сотрудник,
| Данные.Период КАК Период,
| КОЛИЧЕСТВО(*) КАК КолВоЗаписей
|ИЗ
| РегистрСведений.ДанныеДляПодбораСотрудников КАК Данные
|СГРУППИРОВАТЬ ПО
| Данные.Сотрудник,
| Данные.Период
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(*) > 1";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Здесь реализуем логику удаления лишних ИдентификаторЗаписи
// Оставляем только одну запись на комбинацию Сотрудник + Период
КонецЦикла;
При написании такой обработки важно помнить, что записи в этот регистр вносятся документами-регистраторами (например, Прием на работу, Кадровый перевод или Данные на начало эксплуатации). Однако сам регистр является независимым в части некоторых своих измерений, что позволяет проводить его чистку напрямую.
Важно понимать, что некорректные данные в этом регистре влияют не только на Табель. Если проблему проигнорировать, вы столкнетесь со следующими последствиями:
Рассмотрим ситуацию, когда стандартное Тестирование и исправление не помогает. Поскольку с точки зрения структуры базы данных записи уникальны (из-за поля ИдентификаторЗаписи), проверка логической целостности не сочтет их ошибкой. Поэтому единственный надежный способ — это осознанная работа с содержимым регистра Данные для подбора сотрудников.
В заключение отметим, что после очистки регистра рекомендуется перепровести документы, фиксирующие данные на начало эксплуатации, или кадровые приказы по пострадавшим сотрудникам. Это заставит систему заново инициировать механизмы обновления вспомогательных таблиц и гарантирует чистоту учета в будущем.