При запуске системы или в процессе обновления информационной базы на платформе 1С:Предприятие 8 вы можете столкнуться с критической ошибкой, которая полностью блокирует работу пользователей. Текст ошибки выглядит следующим образом: «Ошибка в базе данных. Пользователю ИБ c идентификатором... соответствует более одного элемента в справочнике Пользователи». При этом имя пользователя базы данных может отображаться как <не найден>.
Данный сбой является классической проблемой механизмов Библиотеки стандартных подсистем (БСП), на базе которой построены практически все современные конфигурации 1С, включая 1С:ERP, 1С:Управление торговлей, 1С:Бухгалтерия и 1С:Зарплата и Управление Персоналом. В этой статье мы подробно разберем причины возникновения этой ситуации и пошагово рассмотрим все доступные методы её решения — от простых административных действий до продвинутого программного исправления и прямой правки базы данных на уровне СУБД.
Для того чтобы эффективно устранить ошибку, нам необходимо понять внутреннее устройство хранения учетных записей в 1С. Архитектура платформы предполагает хранение списка пользователей в двух независимых местах:
Справочник.Пользователи (или Справочник.ВнешниеПользователи). Это необходимо для того, чтобы ссылаться на пользователей в документах, отчетах и задачах.Для связывания этих двух сущностей БСП использует специальный реквизит справочника под названием ИдентификаторПользователяИБ, который имеет тип данных УникальныйИдентификатор (GUID). При каждом входе в систему или обновлении конфигурации срабатывает процедура БСП НайтиНеоднозначныхПользователейИБ(). Она проверяет целостность данных: каждому пользователю из базы данных должен соответствовать ровно один элемент в Справочник.Пользователи с аналогичным GUID.
Если система находит два или более элемента справочника с абсолютно одинаковым значением реквизита ИдентификаторПользователяИБ, БСП аварийно завершает работу, выдавая ошибку. Пометка <не найден> в тексте ошибки указывает на то, что соответствующий пользователь на уровне платформы (в Конфигураторе) уже удален, но в самом справочнике остались "зависшие" карточки, ссылающиеся на один и тот же старый GUID.
К основным причинам появления таких дублей относятся:
Ниже мы подробно проанализируем четыре практических способа устранения этой проблемы.
Если ошибка возникает непосредственно при входе в программу, мы можем временно отключить механизмы проверки БСП, чтобы зайти в базу под администратором и исправить данные интерактивно.
Разберем по шагам, как запустить систему в обход стартовых процедур:
/C ОтключитьЛогикуНачалаРаботыСистемы (обратите внимание, что буква "C" должна быть латинской).Этот ключ позволяет запустить сеанс без выполнения процедур инициализации БСП. После успешного входа мы сможем открыть нужные справочники или запустить обработку исправления данных.
Этот способ является наиболее аккуратным и профессиональным. Нам потребуется очистить дублирующийся GUID у "лишнего" (неактивного) пользователя справочника, установив для него пустой уникальный идентификатор. Для выполнения кода можно использовать любую консоль разработчика, групповую обработку реквизитов или внешнюю обработку.
Рассмотрим пример кода, который решает эту задачу:
// Создаем запрос для поиска дублирующихся элементов справочника
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Пользователи.Ссылка КАК Ссылка
|ИЗ
| Справочник.Пользователи КАК Пользователи
|ГДЕ
| Пользователи.ИдентификаторПользователяИБ = &Идентификатор";
// Указываем проблемный GUID из текста ошибки
ПроблемныйGUID = Новый УникальныйИдентификатор("c7878dfd-90b8-4ece-85b2-1784182953d1");
Запрос.УстановитьПараметр("Идентификатор", ПроблемныйGUID);
РезультатЗапроса = Запрос.Выполнить();
Если Не РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
// Первую найденную запись мы оставляем без изменений (она будет основной)
Выборка.Следующий();
ОсновнойПользователь = Выборка.Ссылка;
// У всех последующих дублирующих записей очищаем идентификатор
Пока Выборка.Следующий() Цикл
ОбъектПользователя = Выборка.Ссылка.ПолучитьОбъект();
// Присваиваем пустой уникальный идентификатор
ОбъектПользователя.ИдентификаторПользователяИБ = Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000");
// Отключаем бизнес-логику БСП при записи, чтобы избежать блокировок проверки
ОбъектПользователя.ОбменДанными.Загрузка = Истина;
Попытка
ОбъектПользователя.Записать();
Сообщить("Успешно очищен идентификатор у пользователя: " + ОбъектПользователя.Наименование);
Исключение
Сообщить("Не удалось записать пользователя: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
КонецЦикла;
КонецЕсли;
Использование свойства ОбменДанными.Загрузка = Истина является ключевым моментом, так как оно позволяет обойти жесткие платформенные проверки БСП, которые в обычном режиме не дали бы нам записать элемент с некорректными данными. Для интерактивной корректировки значений без написания кода подойдёт обработка для изменения недоступных реквизитов объектов.
Если мы смогли зайти в базу под администратором (например, используя первый способ или под другой учетной записью), мы можем воспользоваться стандартным функционалом БСП. Это самый безопасный метод для сохранения целостности базы данных, так как программа автоматически перенесет все ссылки (документы, задачи, регистры) со "старого" дубликата на "активного" пользователя.
Проанализируем этот процесс по шагам:
Справочник.Пользователи.Наименование (совпадает).Программа автоматически перенаправит все существующие ссылки со второго элемента на первый, после чего пометит дублирующийся элемент на удаление. Ошибка перестанет возникать. Для комплексного аудита базы и безопасной перепривязки ссылок можно использовать инструмент для поиска и удаления дублей с алгоритмами нечеткого поиска.
Бывают ситуации, когда база заблокирована настолько, что запуск в режиме «Предприятие» невозможен ни под каким предлогом, а восстановить базу из резервной копии нельзя по причине возможной потери актуальных данных. В этом случае мы можем прибегнуть к прямому редактированию таблиц на уровне СУБД (MS SQL Server, PostgreSQL и др.).
Важно: Перед проведением любых работ в СУБД обязательно сделайте резервную копию (бэкап) базы данных! Некорректные запросы могут полностью разрушить структуру данных.
Разберем логику исправления на примере MS SQL Server:
ПолучитьСтруктуруХраненияБазыДанных() или специализированными обработками. Предположим, что таблица справочника называется _Reference150, а колонка идентификатора — _Fld2550. Колонкой со ссылкой на элемент будет _IDRRef.
-- Обнуляем идентификатор у дублирующего пользователя, зная его внутренний IDRRef
UPDATE _Reference150
SET _Fld2550 = 0x00000000000000000000000000000000
WHERE _IDRRef = 0x87b87427ead59c1811e51fa37c2fde2c
После успешного выполнения данного запроса на уровне базы данных СУБД конфликт уникальных идентификаторов будет исчерпан, и вы сможете беспрепятственно обновить или запустить систему в штатном режиме.
Для предотвращения повторного появления подобных ошибок в вашей практике рекомендуем соблюдать простые правила администрирования 1С: