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