При работе в программе «1С:Зарплата и управление персоналом 3.1» (ЗУП) пользователи часто сталкиваются с неприятной ситуацией: при установке отбора по конкретному сотруднику в форме списка журнала кадровых документов (например, «Приемы, переводы, увольнения» или общий журнал кадровых документов) в список попадают документы по совершенно другим людям. В то же время документы нужного сотрудника могут загадочным образом исчезать из списка при фильтрации. Данная проблема особенно часто проявляется у документов, которые создавались методом копирования.
В этой статье мы подробно разберем, почему возникает подобный сбой, как устроен внутренний механизм оптимизации списков в ЗУП 3.1, почему стандартное тестирование и исправление базы данных здесь бессильно и какие существуют способы решения этой проблемы — от точечного перепроведения до массового исправления записей.
Для того чтобы понять природу ошибки, нам необходимо заглянуть «под капот» конфигурации. В крупных базах данных таблицы документов кадрового и расчетного учета могут содержать сотни тысяч строк. Если бы система при каждом открытии журнала документов или установке отбора напрямую обращалась к табличным частям документов для поиска физических лиц и сотрудников, это приводило бы к колоссальным нагрузкам на СУБД и долгому ожиданию со стороны пользователя.
Для оптимизации быстродействия разработчики фирмы 1С внедрили специальный механизм на базе Библиотеки стандартных подсистем (БСП). Вместо прямого сканирования документов динамические списки журналов обращаются к специальному проиндексированному вспомогательному регистру сведений — СоставДокументовЗарплатаКадры.
Давайте проанализируем, как выглядит скрытый запрос схемы компоновки данных, который платформа использует при фильтрации списка по физическому лицу:
{ГДЕ (ИСТИНА В (ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА
ИЗ РегистрСведений.СоставДокументовЗарплатаКадры КАК СоставДокументовЗарплатаКадры
ГДЕ СоставДокументовЗарплатаКадры.ФизическоеЛицо = &ФизическоеЛицо
И ЖурналДокументовКадровыеДокументы.Ссылка = СоставДокументовЗарплатаКадры.ДокументФизическогоЛица))}
Таким образом, когда мы накладываем в интерфейсе визуальный фильтр по сотруднику, программа ищет связи исключительно в регистре СоставДокументовЗарплатаКадры. Если запись в этом регистре некорректна или указывает на старое физлицо, то и в журнале документов мы увидим неверные данные.
Основной источник проблемы — копирование существующих документов в пользовательском режиме (например, по клавише F9). В старых версиях ЗУП 3.1 (вплоть до релиза 3.1.6.37) существовала зарегистрированная ошибка в логике подписок на события при создании нового документа копированием.
Сценарий сбоя выглядит следующим образом:
СоставДокументовЗарплатаКадры записывалась информация о новом документе, но в качестве физического лица там оставался Сотрудник А (из исходного документа-копии).В итоге возникает рассинхронизация: внутри самого документа реквизиты заполнены верно (указан Сотрудник Б), но в регистре-индексе документ жестко привязан к Сотруднику А. Соответственно, при отборе по Сотруднику А система покажет чужой документ, а при поиске по Сотруднику Б документ вообще не отобразится.
При возникновении любых проблем со списками администраторы баз данных часто запускают процедуру «Тестирование и исправление» (ТиИ) через Конфигуратор. Однако в данном случае ТиИ завершится успешно, но проблему не решит.
Дело в том, что утилита ТиИ проверяет базу на уровне физической и ссылочной целостности. С точки зрения СУБД все записи в регистре СоставДокументовЗарплатаКадры абсолютно корректны: документ-ссылка существует, физическое лицо в базе есть, битых ссылок нет. Платформа 1С не знает бизнес-логики прикладного решения и не сопоставляет, совпадает ли реквизит «Сотрудник» внутри документа с записью в служебном регистре сведений. Поэтому логическая ошибка игнорируется тестированием.
Перед тем как приступать к исправлению, мы можем локализовать проблему и выявить все поврежденные документы с помощью простого запроса. Рассмотрим пример запроса для консоли, который наглядно покажет расхождения между физическим лицом в кадровом документе (на примере приема на работу) и служебным регистром:
ВЫБРАТЬ
ПриемНаРаботу.Ссылка КАК ДокументСсылка,
ПриемНаРаботу.ФизическоеЛицо КАК ФизЛицоВДокументе,
СоставДокументов.ФизическоеЛицо КАК ФизЛицоВРегистре
ИЗ
Документ.ПриемНаРаботу КАК ПриемНаРаботу
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СоставДокументовЗарплатаКадры КАК СоставДокументов
ПО ПриемНаРаботу.Ссылка = СоставДокументов.ДокументФизическогоЛица
ГДЕ
ПриемНаРаботу.Проведен = ИСТИНА
И ПриемНаРаботу.ФизическоеЛицо <> СоставДокументов.ФизическоеЛицо
Выполнив этот запрос, мы сразу увидим список документов, у которых данные в шапке/табличной части не соответствуют индексу в регистре сведений.
Рассмотрим несколько способов устранения данной ошибки в зависимости от количества некорректных документов в базе данных.
Если проблема обнаружена всего в одном-двух документах, самым простым решением будет обычное перепроведение документа. При проведении документа конфигурация принудительно вызывает обработчики БСП, которые полностью очищают старые записи в регистре СоставДокументовЗарплатаКадры и создают новые, актуальные записи на основании текущих реквизитов документа.
Важно: регистр СоставДокументовЗарплатаКадры является независимым и недоступен для ручного редактирования пользователем напрямую из интерфейса, поэтому перепроведение документа-регистратора является стандартным штатным механизмом актуализации его данных.
Если документов с нарушенной индексацией в базе накопилось много, перепроводить каждый вручную нецелесообразно. Воспользуемся встроенной обработкой «Групповое изменение реквизитов»:
Прием на работу или Кадровый перевод).При обновлении ЗУП на новые релизы (где данная ошибка копирования уже исправлена на уровне кода) программа запускает фоновые процедуры обновления данных. Эти процедуры в том числе предназначены для перезаполнения и проверки служебных регистров-индексов.
Выясним, все ли процедуры завершены успешно в вашей базе:
СоставДокументовЗарплатаКадры, их необходимо перезапустить вручную.Описанная архитектура оптимизации динамических списков через регистры-индексы применяется в ЗУП 3.1 повсеместно. Если вы столкнулись с некорректным отображением сотрудников в других подсистемах, рекомендуем также проверить следующие регистры:
ФизическиеЛицаДокументов — отвечает за сопоставление кадровых документов и физических лиц. Ошибки в нем приводят к аналогичным сбоям отборов.ДанныеДляПодбораСотрудников — отвечает за корректное появление сотрудников в списках выбора при заполнении документов (например, после увольнений или кадровых переводов). Сбой в этом регистре приводит к тому, что актуальный сотрудник «исчезает» из формы подбора и его невозможно выбрать в новый документ. Исправляется также перепроведением исходных кадровых документов сотрудника.Проанализировав данную проблему, мы видим, что использование вспомогательных регистров сведений значительно ускоряет работу программы, но требует от администратора понимания внутренней структуры данных для оперативного решения подобных технических накладок.