Ошибка «Значение поля Код не уникально»: находим дубль и чиним нумерацию

· 10 мин

Содержание

Ошибка Значение поля "Код" не уникально! значит одно: в справочнике уже есть элемент с таким же кодом, а у справочника включён контроль уникальности. Решение — найти второй элемент с этим кодом и дать одному из них новый код. Если дублей много, их перенумеровывают обработкой, а причину (чаще всего обмен или загрузку) устраняют отдельно.

Типичная картина: бухгалтер открывает карточку контрагента, меняет телефон, нажимает «Записать и закрыть» — и получает ошибку уникальности кода, хотя сам код не трогал. Это верный признак, что дубль попал в базу раньше, в обход проверки, а сейчас платформа просто сверила код при записи и обнаружила второй такой же.

Почему 1С считает код справочника неуникальным

Проверку выполняет сама платформа 1С:Предприятие 8.3 при записи элемента. Она срабатывает, если в свойствах справочника включён «Контроль уникальности». Сравнение идёт в пределах «серии кодов» — во всём справочнике, внутри одной группы или внутри одного владельца.

Откуда берутся дубли:

  • ✍️ Код ввели вручную. Пользователь набрал код, который уже занят. Самый безобидный случай — ошибка появляется сразу, и дубль в базу не попадает.
  • 🗑️ Код занят помеченным на удаление элементом. Пометка удаления не освобождает код. Пока элемент не удалён окончательно, его код участвует в проверке.
  • 🔄 Обмен данными между базами. Две базы независимо выдали код 00-00000125 разным элементам. При загрузке по обмену проверки платформы частично отключаются, и в базе-приёмнике оказываются два элемента с одним кодом.
  • 📥 Загрузка из файла или переноса данных. Перенос через выгрузку XML, загрузка из таблицы, обработки миграции — всё, что пишет объекты в режиме загрузки, может принести дубль.
  • 🧩 Сменили настройки нумерации. Серию кодов расширили с «В пределах подчинения» до «Во всём справочнике» — и коды, которые раньше жили в разных группах, столкнулись.
  • 🛠️ Повреждение базы или прямые правки в СУБД. Редкий, но тяжёлый вариант: разрушен индекс, база восстановлена частями, кто-то правил таблицы SQL напрямую.

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

У документов есть та же проблема с другим текстом: Значение поля "Номер" не уникально!. Логика поиска и исправления у неё та же, только вместо кода — номер, а вместо серии кодов — периодичность номера (в пределах года, квартала и т.д.).

Диагностика: выберите симптом

Как найти дубли кодов в справочнике 1С

Сначала определите справочник. Он виден по заголовку формы, где выскочила ошибка: «Контрагенты», «Номенклатура», «Физические лица» и т.п.

Быстрый способ — через список

  1. Откройте список справочника.
  2. Нажмите Ctrl+F и найдите элементы по колонке «Код» с проблемным значением.
  3. Если колонки кода нет, добавьте её через Ещё → Изменить форму.
  4. Убедитесь, что в списке видны помеченные на удаление элементы — они тоже держат код.

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

Надёжный способ — запросом

Запрос выполняют в консоли запросов (внешняя обработка для 8.3, есть у любого специалиста по 1С). Пример для справочника «Номенклатура» с серией кодов «Во всём справочнике»:

ВЫБРАТЬ
    Т.Код КАК Код,
    КОЛИЧЕСТВО(Т.Ссылка) КАК Количество
ИЗ
    Справочник.Номенклатура КАК Т
СГРУППИРОВАТЬ ПО
    Т.Код
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(Т.Ссылка) > 1

Если серия кодов «В пределах подчинения», добавьте в группировку Т.Родитель. Если «В пределах подчинения владельцу» — Т.Владелец. Иначе запрос покажет «дубли», которые для платформы дублями не являются.

Чтобы увидеть сами элементы, а не только коды, выведите Т.Ссылка, Т.Наименование и Т.ПометкаУдаления и отфильтруйте по найденному коду.

Запускайте поиск под администратором. Под обычным пользователем часть элементов может быть скрыта ограничением доступа, и дубль «не найдётся».

Как вручную исправить неуникальный код

Когда дублей один-два, проще всего поправить руками.

  1. Решите, какой элемент оставить со старым кодом. Обычно это тот, по которому больше документов, или тот, чей код знают контрагенты и внешние системы.
  2. Откройте второй элемент.
  3. Очистите поле «Код» полностью.
  4. Нажмите «Записать». При включённой автонумерации платформа сама присвоит следующий свободный код.
  5. Если поле кода недоступно для редактирования или скрыто в форме, переходите к способу с обработкой.

Если второй элемент помечен на удаление и не нужен, удалите его окончательно через Администрирование → Обслуживание → Удаление помеченных объектов (путь для БП 3.0 и других конфигураций на БСП). Код освободится, ошибка уйдёт.

Удаление помеченных проверяет ссылки: если на элемент ссылаются документы, он не удалится. В этом случае перенумеруйте его, а не удаляйте.

Код вручную лучше не придумывать. Набранный «на глаз» код может совпасть с тем, который счётчик выдаст следующим, и ошибка вернётся на другом элементе.

Массовое исправление кодов обработкой

После неудачного обмена дублей бывают сотни. Перенумеровать их помогает короткий код во внешней обработке или в консоли с режимом выполнения кода. Метод УстановитьНовыйКод() объекта справочника берёт следующий код по правилам нумерации, включая префиксы типовой конфигурации.

Перед запуском:

  • сделайте резервную копию базы — запись идёт в рабочие данные, откатить её кнопкой нельзя;
  • выполняйте вне рабочего времени или на копии, чтобы проверить результат;
  • выясните, не используются ли коды во внешних системах (сайт, сканеры, обмен с контрагентами).

Код серверной процедуры для «Номенклатуры», серия кодов во всём справочнике:

&НаСервере
Процедура ПеренумероватьДублиНаСервере()

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Т.Код КАК Код
    |ПОМЕСТИТЬ Дубли
    |ИЗ
    |    Справочник.Номенклатура КАК Т
    |СГРУППИРОВАТЬ ПО
    |    Т.Код
    |ИМЕЮЩИЕ
    |    КОЛИЧЕСТВО(Т.Ссылка) > 1
    |;
    |ВЫБРАТЬ
    |    Т.Ссылка КАК Ссылка,
    |    Т.Код КАК Код
    |ИЗ
    |    Справочник.Номенклатура КАК Т
    |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Дубли КАК Д
    |        ПО Т.Код = Д.Код
    |УПОРЯДОЧИТЬ ПО
    |    Т.Код,
    |    Т.ПометкаУдаления";

    ПредыдущийКод = Неопределено;
    Выборка = Запрос.Выполнить().Выбрать();

    Пока Выборка.Следующий() Цикл
        Если Выборка.Код = ПредыдущийКод Тогда
            Объект = Выборка.Ссылка.ПолучитьОбъект();
            Объект.УстановитьНовыйКод();
            Объект.Записать();
            Сообщить(СтрШаблон("%1: новый код %2", Выборка.Код, Объект.Код));
        КонецЕсли;
        ПредыдущийКод = Выборка.Код;
    КонецЦикла;

КонецПроцедуры

Как это работает: запрос выбирает все элементы с повторяющимися кодами, отсортированные по коду. Первый элемент в каждой группе сохраняет код, остальные получают новый. Сортировка по пометке удаления ставит действующие элементы первыми — новый код достаётся помеченным.

Возможные затруднения:

  • Запись падает с другой ошибкой. У элемента не заполнен обязательный реквизит или сработала проверка конфигурации. Исправьте этот элемент вручную и запустите обработку снова — она подхватит оставшиеся дубли.
  • Серия кодов по группам или владельцу. Добавьте Родитель или Владелец в группировку и в соединение, иначе обработка перенумерует лишнее.
  • Ошибка доступа. Запускайте под пользователем с полными правами.

Настройка нумерации справочника

Свойства нумерации задаются в Конфигураторе: откройте объект справочника и перейдите на вкладку «Нумерация». Там:

СвойствоЧто даётЧто учесть
Тип кодаСтрока или ЧислоСтроковый код поддерживает префиксы
Длина кодаМаксимум символовКороткий код быстрее «кончается»
Серии кодовВо всём справочнике / в пределах подчинения / в пределах подчинения владельцуРасширение серии сводит вместе разные коды
Контроль уникальностиВключает проверку при записиОтключение не убирает дубли, а прячет их
АвтонумерацияНовый код выдаётся автоматическиБез неё код вводят вручную

Не отключайте контроль уникальности, чтобы «убрать ошибку». Ошибка пропадёт, дубли останутся, а поиск по коду, загрузка прайсов и обмены начнут выбирать случайный элемент из двух.

Для типовой конфигурации на поддержке изменять эти свойства не стоит вообще. Изменение требует снятия с поддержки или расширения, а потом мешает обновлениям. Нумерацию в типовых решениях настраивают префиксами, а не свойствами метаданных.

В собственной (нетиповой) конфигурации изменение длины или серии кодов — это изменение структуры. Применение такого изменения требует монопольного доступа к базе: пользователей придётся отключить на время обновления конфигурации базы данных.

Как не допустить дублей кодов при обмене данными

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

Префикс информационной базы

В конфигурациях на БСП (БП 3.0, УТ 11, ЗУП 3.1 и других) у каждой базы есть префикс. Он добавляется в коды справочников и номера документов, поэтому коды из разных баз не пересекаются. Префикс задаётся в разделе Администрирование → Синхронизация данных, в поле префикса этой информационной базы.

Правила:

  1. У каждой базы в обмене — свой уникальный префикс.
  2. Префикс задают до первой синхронизации. Смена префикса не перенумеровывает уже созданные элементы.
  3. Копию базы, развёрнутую как новый узел обмена, сразу переименовывают префиксом — иначе она продолжит выдавать коды оригинала.

Сопоставление вместо создания

Второй источник дублей — когда при обмене элемент не сопоставился и пришёл как новый. В правилах синхронизации проверьте, по каким полям сопоставляются объекты (для контрагентов — обычно ИНН и КПП). Если приёмник получил «нового» контрагента с кодом, который уже занят, ошибка появится при первом же редактировании.

Перед запуском нового обмена
Выполнено: 0 / 5

Загрузка из файлов

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

Технические причины: проблемы на уровне базы и СУБД

Если запрос дублей не находит, серия кодов учтена, а ошибка повторяется, проверьте саму базу. Возможны повреждённые индексы, недописанная транзакция после аварийного выключения сервера, ручные правки таблиц в SQL.

Тестирование и исправление

  1. Сделайте резервную копию (выгрузку .dt или бэкап средствами СУБД).
  2. Предупредите пользователей: для проверки нужен монопольный доступ, все сеансы будут завершены. Делайте это вечером или в выходной.
  3. Откройте Конфигуратор: Администрирование → Тестирование и исправление.
  4. Отметьте «Реиндексация таблиц информационной базы» и «Проверка логической целостности информационной базы».
  5. Сначала запустите в режиме «Тестирование», посмотрите отчёт, затем — с исправлением.

Для файловой базы есть ещё утилита chdbfl.exe в каталоге bin платформы. Она проверяет физическую целостность файла 1Cv8.1CD. Запускать её можно только при полностью закрытой базе.

Не путайте с ошибкой СУБД

У СУБД своя, более «низкая» ошибка: Попытка вставки неуникального значения в уникальный индекс. Она про служебные индексы таблиц и к коду справочника обычно отношения не имеет. Её лечат реиндексацией, обновлением статистики и пересчётом итогов, а не перенумерацией элементов.

Текст ошибкиУровеньЧто делать
Значение поля "Код" не уникально!Платформа, справочникНайти дубль и перенумеровать
Значение поля "Номер" не уникально!Платформа, документНайти документ с тем же номером за период
Попытка вставки неуникального значения в уникальный индексСУБДТестирование и исправление, реиндексация

Клиент-серверная база

На сервере 1С с MS SQL Server или PostgreSQL дубли без видимой причины чаще появляются после восстановления базы из разных бэкапов или после ручного вмешательства в таблицы. Если в базу заходили скриптами напрямую, выясните, что именно меняли, — перенумерация вылечит симптом, но не повторное вмешательство.

Частые вопросы

Можно ли просто поменять код у элемента, если на него ссылаются документы?
Да. Документы ссылаются на элемент по внутреннему идентификатору, а не по коду. Смена кода ничего не ломает в учёте внутри базы. Риск только для внешних систем, которые ищут элемент по коду.
Освободится ли код, если пометить элемент на удаление?
Нет. Помеченный элемент хранится в базе и держит свой код. Код освобождается только после окончательного удаления помеченных объектов.
Почему новые элементы получают коды, которые уже были?
Счётчик выдаёт код по максимальному занятому значению в серии. Если коды в базе с разными префиксами или часть кодов набрана вручную в другом формате, новый код может совпасть с существующим. Проверьте префикс базы и формат кодов.
Ошибка возникает только у одного пользователя. Почему?
Скорее всего, у него свои права: он не видит второй элемент из-за ограничений доступа и не может его найти. Поиск дубля выполняйте под администратором.
Поможет ли обновление конфигурации?
Само по себе нет. Обновление не удаляет и не перенумеровывает дубли. Сначала исправьте коды, потом обновляйтесь.