Как исправить ошибку «Обнаружено дублирование ключевых значений в колонках "Ссылка"» при подборе сотрудников в 1С:ЗУП?

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

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

В этой статье мы подробно разберем, почему возникает эта ошибка, как проанализировать механизмы работы формы подбора и какими способами можно восстановить работоспособность системы — от ручного исправления до программного перезаполнения регистров.

Выясняем причину возникновения ошибки

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

Ошибка дублирования возникает в тот момент, когда запрос динамического списка возвращает две или более строки с одинаковым значением в колонке Ссылка (в данном случае — одинаковую ссылку на физическое лицо). Система 1С не может отобразить такой список, так как уникальность ключа (ссылки) нарушена.

Проанализируем ситуацию: чаще всего это происходит из-за некорректных или перекрывающихся записей в так называемых «витринных» или интервальных регистрах. Рассмотрим основные регистры, которые участвуют в формировании списка подбора:

  1. ОсновныеСотрудникиФизическихЛиц — здесь хранится информация о том, какой сотрудник является основным для данного физлица в конкретной организации.
  2. ТекущиеКадровыеДанныеСотрудников — содержит актуальные данные о позиции, подразделении и датах приема/увольнения.
  3. ДанныеДляПодбораСотрудников — специальный регистр-оптимизатор для быстрого поиска.
  4. ВидыЗанятостиСотрудниковИнтервальный — хранит историю изменений видов занятости (основное место, совместительство).

Анализируем текст запроса динамического списка

Важно понимать, что текст запроса в форме подбора Справочник.ФизическиеЛица.Форма.ФормаВыбораСотрудников переопределяется программно. Если мы просто откроем форму в конфигураторе, мы увидим упрощенную версию. На самом деле при создании формы на сервере система конструирует сложный запрос с использованием соединений (ВНУТРЕННЕЕ СОЕДИНЕНИЕ и ЛЕВОЕ СОЕДИНЕНИЕ).

Рассмотрим фрагмент реального запроса, который отрабатывает в момент ошибки. Обратите внимание на соединения по регистру ОсновныеСотрудникиФизическихЛиц и ДанныеДляПодбораСотрудников. Если в одном из этих регистров для одного и того же сотрудника/физлица созданы две записи на одну дату или с пересекающимися периодами, запрос «размножит» строки, и мы получим дубль ссылки.

Чаще всего виновником становится регистр ОсновныеСотрудникиФизическихЛиц. Если в нем по какой-то причине (сбой при проведении документа, некорректный перенос данных) зафиксированы две записи как «основные», форма подбора перестанет открываться.

Способ 1: Ручное исправление через поиск дублей

Если ошибка возникла недавно и сотрудников в базе немного, мы можем попробовать локализовать проблему. Проанализируем последние кадровые изменения. Часто ошибка проявляется после приема внутреннего совместителя или перевода сотрудника между филиалами.

Для диагностики выполним следующие шаги:

  1. Откроем регистр сведений ОсновныеСотрудникиФизическихЛиц (через функции технического специалиста).
  2. Установим отбор по организации.
  3. Визуально или с помощью выгрузки в Excel проверим наличие двух активных записей для одного физического лица на текущую дату.
  4. Удалим лишнюю (ошибочную) запись.

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

Способ 2: Программное перезаполнение регистров

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

Рассмотрим пример кода, который поможет «сбросить» и заново заполнить проблемные регистры. Внимание: любые подобные манипуляции следует проводить только на копии базы данных и после создания бэкапа!


&НаСервереБезКонтекста
Процедура ПерезаполнитьРегистрыНаСервере()
    // Очищаем наборы записей для обновления
    НаборЗаписей = РегистрыСведений.ОсновныеСотрудникиФизическихЛиц.СоздатьНаборЗаписей;
    НаборЗаписей.ОбменДанными.Загрузка = Истина;
    НаборЗаписей.Записать();

    НаборЗаписей = РегистрыСведений.ТекущиеКадровыеДанныеСотрудников.СоздатьНаборЗаписей;
    НаборЗаписей.ОбменДанными.Загрузка = Истина;
    НаборЗаписей.Записать();

    НаборЗаписей = РегистрыСведений.ДанныеДляПодбораСотрудников.СоздатьНаборЗаписей;
    НаборЗаписей.ОбменДанными.Загрузка = Истина;
    НаборЗаписей.Записать();

    // Получаем массив всех сотрудников для обновления
    Запрос = Новый Запрос("ВЫБРАТЬ Ссылка ИЗ Справочник.Сотрудники");
    МассивСотрудников = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");

    // Вызываем штатные процедуры обновления из типовой конфигурации
    // Обновляем основных сотрудников
    КадровыйУчет.ОбновитьОсновныхСотрудниковФизическихЛицПоСотрудникам(МассивСотрудников);
    КадровыйУчет.ОбновитьОсновныхСотрудниковФизическихЛицСотрудниковПоДоговорамГПХ(МассивСотрудников);
    КадровыйУчет.ОбновитьОсновныхСотрудниковФизическихЛицПоТрудовымДоговорам(МассивСотрудников);

    // Обновляем текущие кадровые данные
    КадровыйУчет.ОбновитьТекущиеКадровыеДанныеСпискаСотрудников(МассивСотрудников, Новый Массив);

    // Полное обновление данных для подбора
    КадровыйУчетРасширенный.ЗаполнитьДанныеДляПодбораСотрудников();

    // Обновление интервальных регистров (важно для корректного отображения видов занятости)
    ЗарплатаКадрыПериодическиеРегистрыРасширенный.ЗаполнитьЗависимыеДанныеПослеСозданияНовогоУзла(Неопределено);
КонецПроцедуры

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

Почему данные переопределяются динамически?

Многих специалистов смущает тот факт, что в конфигураторе запрос выглядит иначе, чем тот, что вызывает ошибку. Выясним причину этого поведения. В ЗУП 3.1 форма подбора реализована универсально. В зависимости от того, из какого документа она открыта (Ведомость, Больничный лист, Отпуск), система добавляет в запрос различные фильтры и соединения.

Например, если документ создается по конкретному филиалу, запрос будет дополнен условиями по ГоловнаяОрганизация или Филиал. Все это происходит в процедуре ПриСозданииНаСервере формы подбора. Именно поэтому для диагностики проблемы так важно анализировать фактический текст запроса динамического списка, который можно получить в отладчике.

Резюме и рекомендации

Мы проанализировали одну из самых коварных ошибок в интерфейсе ЗУП 3.1. Для успешного решения проблемы рекомендуем придерживаться следующего алгоритма:

  1. Выявите, для какого именно сотрудника происходит дублирование. Это можно сделать через Консоль запросов, запустив запрос, приведенный в начале статьи, и добавив группировку по ссылке.
  2. Проверьте кадровые документы этого сотрудника. Возможно, был введен лишний документ-исправление или на одну дату пришлись два разных кадровых события.
  3. Если проблема массовая — воспользуйтесь приведенным программным кодом для полной регенерации вспомогательных данных.
  4. Помните, что запись в Справочник.Сотрудники также инициирует обновление части этих данных. Иногда простое перепроведение последнего кадрового документа сотрудника может решить проблему без программирования.

Использование этих методов позволит вам быстро вернуть бухгалтерию к работе и глубже понять внутреннюю архитектуру учета кадров в системе 1С.

← На главную