При работе с конфигурацией «1С:Зарплата и управление персоналом» (ЗУП 3.1), особенно начиная с релизов ветки 3.1.24.x, пользователи часто сталкиваются с критической ошибкой при попытке оформить на работу сотрудника, который ранее уже трудился в организации. Система выдает сообщение: «Нарушено условие уникальности данных. Попытка вставки неуникального значения в уникальный индекс». В тексте ошибки фигурирует системная таблица _Reference291 (соответствующая справочнику Физические лица) и индекс с суффиксом _S_HPK.
В этой статье мы подробно разберем, почему возникает этот конфликт на уровне базы данных SQL, проанализируем программный код типовой конфигурации и рассмотрим несколько способов решения проблемы — от написания расширения до технического обслуживания базы данных.
Проанализируем ситуацию: когда мы принимаем «старого» сотрудника, в базе уже существует элемент справочника ФизическиеЛица. При создании нового элемента в справочнике Сотрудники программа должна подтянуть уже имеющееся физлицо. Однако из-за ошибки в логике типового кода (связанной с механизмом «Подбор персонала» и хранением данных кандидатов), система ошибочно инициирует создание новой записи в таблице физических лиц вместо использования существующей.
SQL-сервер блокирует эту операцию, так как уникальный индекс _Reference291_S_HPK не позволяет вставить дублирующую запись. Этот индекс часто отвечает за историю данных (Data History) или механизмы разделения данных в последних версиях платформы 8.3.20+. Ошибка HRESULT=80040E2F прямо указывает на нарушение целостности данных на уровне СУБД.
Рассмотрим наиболее эффективный метод, который позволяет устранить корень проблемы в логике конфигурации. Исследование показало, что ошибка кроется в общем модуле ПодборПерсоналаКлиент. Программа некорректно обрабатывает переменную ЛичныеДанныеКандидата, что приводит к затиранию выбранного пользователем физического лица.
Для исправления ситуации создадим расширение и воспользуемся аннотацией &Вместо для корректировки процедуры. Разберем по шагам, как должен выглядеть исправленный код:
Исходный код в типовой конфигурации выглядел так:
Процедура ПриВыбореФизическогоЛица(Форма, РезультатВыбора) Экспорт
Если ЗначениеЗаполнено(Форма.ЛичныеДанныеКандидата) Тогда
РезультатВыбора = Форма.ЛичныеДанныеКандидата;
КонецЕсли;
КонецПроцедуры
Проблема здесь в том, что условие ЗначениеЗаполнено всегда переопределяет РезультатВыбора, даже если пользователь вручную указал существующее физлицо в окне поиска. Мы модифицируем это условие, чтобы приоритет отдавался уже найденному объекту.
В расширении пропишем следующий код:
&Вместо("ПриВыбореФизическогоЛица")
Процедура ИСПР_ПриВыбореФизическогоЛица(Форма, РезультатВыбора)
// Проверяем, если результат выбора еще не определен, но данные кандидата есть
Если НЕ ЗначениеЗаполнено(РезультатВыбора) И ЗначениеЗаполнено(Форма.ЛичныеДанныеКандидата) Тогда
РезультатВыбора = Форма.ЛичныеДанныеКандидата;
КонецЕсли;
// Если РезультатВыбора уже содержит ссылку на существующее физлицо,
// мы не перезаписываем его данными кандидата, предотвращая попытку создания дубля.
КонецПроцедуры
После применения этого расширения система корректно подставит ссылку на существующее ФизическоеЛицо, и запись объекта Сотрудник пройдет без конфликтов с SQL-индексами.
Если программная правка не помогает или ошибка сохраняется из-за «зависших» значений в таблицах индексов, необходимо выполнить реиндексацию таблиц на уровне платформы. Рассмотрим два варианта проведения этой процедуры.
Вариант А: Выгрузка и загрузка файла данных (.dt)
Это классический метод «лечения» многих проблем с уникальностью ключей. Проанализируем, почему это работает: при выгрузке в .dt сохраняются только сами данные, а индексы и служебные таблицы SQL не переносятся. При загрузке файла обратно в новую базу данных платформа 1С принудительно пересоздает все уникальные индексы с нуля, выстраивая корректную последовательность ключей.
Вариант Б: Тестирование и исправление (ТиИ)
Если база данных имеет большой объем и выгрузка .dt затруднительна, воспользуемся штатным механизмом Тестирование и исправление. Выясним, какие настройки нам необходимы:
Это заставит СУБД обновить индекс _Reference291_S_HPK и устранит коллизию, если она была вызвана некорректным значением счетчика в таблице.
Поскольку проблема носит массовый характер для релизов 3.1.24.23 и соседних версий, фирма «1С» выпустила официальные исправления. Проанализируем стратегию обновления:
СотрудникиФормы или ПодборПерсонала. Если его нет, разрешите автоматическую загрузку исправлений.СотрудникиФормы.ЗаписатьФизическоеЛицоСотрудника была переработана так, чтобы исключить блокировку записи при наличии дублей по ИНН и СНИЛС.Чтобы минимизировать риск возникновения ошибки до внесения правок в код, рекомендуем придерживаться следующего алгоритма действий при приеме бывшего сотрудника:
Сотрудники. Это задействует другие программные механизмы, которые могут обойти проблемный участок кода.Таким образом, мы выяснили, что ошибка уникальности данных при записи сотрудника в ЗУП 3.1 чаще всего является следствием программной коллизии между данными кандидата и существующим физлицом. Использование предложенного расширения или обновление конфигурации позволит полностью устранить данную проблему и обеспечит корректную работу отдела кадров.