Как исправить ошибку «Запись с такими ключевыми полями существует!» при синхронизации УТ 11 и БП 2.0

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Бухгалтерский учет IT и автоматизация бизнеса
← На главную

Приветствуем вас, уважаемые коллеги! Сегодня мы детально разберем одну из весьма распространенных и неприятных проблем, возникающих при организации одностороннего обмена данными между конфигурациями «1С:Управление торговлей» (начиная с версии 11.4.5.x и выше) и устаревшей, но все еще активно используемой базой «1С:Бухгалтерия предприятия» редакции 2.0.

Ситуация выглядит следующим образом. Вы успешно обновили свою базу УТ 11 до актуального релиза (например, 11.4.5.143). При этом ваша база БП 2.0 также обновлена до последнего поддерживаемого релиза, а платформа 1С:Предприятие работает на стабильной и современной версии. Однако при попытке выполнить очередной сеанс синхронизации данных выгрузка из торговли проходит без видимых проблем, но на этапе загрузки данных в бухгалтерию процесс аварийно прерывается.

В журнале регистрации или в окне сообщений обмена появляется пугающая техническая ошибка следующего вида:


Ошибка при загрузке данных: {Обработка.КонвертацияОбъектовИнформационныхБаз.МодульОбъекта(1607)}: Ошибка записи объекта
ТипОбъекта = Регистр сведений набор записей: Контактная информация
Объект = РегистрСведенийНаборЗаписей.КонтактнаяИнформация
ОписаниеОшибки = Ошибка при вызове метода контекста (Записать)
Объект.Записать; по причине:
Запись с такими ключевыми полями существует! : КонтактнаяИнформация: ХАЙ ЛЕВЕЛ ООО, Адрес, Юридический адрес (Регистр сведений: Контактная информация; Номер строки: 3)

В дополнение к этой ошибке пользователи замечают крайне неприятный симптом: все новые документы, которые должны были перенестись в рамках текущего сеанса, переносятся, но загружаются непроведенными. При этом до обновления конфигурации УТ 11 (например, на релизе 11.4.3.167) этот же самый обмен работал без единого сбоя. Давайте проанализируем ситуацию, выясним глубинную причину этой ошибки и разберем по шагам все возможные пути ее решения.

Выясняем причину: конфликт поколений конфигураций и новые механизмы БСП

Для того чтобы осознанно подойти к решению проблемы, давайте разберемся, что именно происходит «под капотом» системы 1С в момент обмена. Ошибка «Запись с такими ключевыми полями существует!» на уровне СУБД всегда означает одну простую вещь: система пытается записать в базу данных строку, уникальный ключ которой полностью совпадает с уже существующей строкой в этой же таблице или в рамках одного пакета записи (набора записей).

В нашем случае конфликт возникает в регистре сведений КонтактнаяИнформация (или соответствующей табличной части) конфигурации БП 2.0. Почему же раньше этого не происходило, а после обновления УТ 11 ошибка стала массовой?

Дело в том, что начиная с версии 11.4.5 в УТ 11 была внедрена обновленная версия Библиотеки стандартных подсистем (БСП). В рамках этого обновления разработчики фирмы «1С» радикально переработали механизм хранения адресов и телефонов, добавив функционал под названием «История изменений контактной информации».

  1. Как это работает в УТ 11: В табличной части КонтактнаяИнформация справочника Контрагенты появилось новое служебное поле (измерение/ресурс) — ДействуетС. Благодаря этому полю система теперь может хранить неограниченное количество исторических записей одного и того же типа адреса для одного контрагента. Например, если контрагент «ХАЙ ЛЕВЕЛ ООО» сменил юридический адрес в текущем месяце, система не заменяет старую строку новой. Вместо этого она сохраняет старый адрес с пометкой его действия, а новый записывает как актуальный. Это необходимо для того, чтобы при печати старых документов за прошлые периоды выводился именно тот адрес, который был актуален на дату совершения операции.
  2. Как это устроено в БП 2.0: Конфигурация Бухгалтерия предприятия 2.0 спроектирована по старым стандартам. В ее архитектуре регистра сведений КонтактнаяИнформация нет и никогда не было поля «ДействуетС» или аналогичного механизма хранения истории. Для конфигурации БП 2.0 уникальный ключ записи однозначно определяется жесткой связкой полей: Объект (ссылка на контрагента) + Тип (Адрес, Телефон и т.д.) + Вид (Юридический адрес, Фактический адрес и т.д.).

Когда типовые правила обмена пытаются выполнить выгрузку, они берут все имеющиеся строки контактной информации из УТ 11 и «как есть» транслируют их в XML-файл обмена. Если у контрагента накопилось несколько записей юридического адреса (текущий и один или несколько старых из истории), в XML-пакет попадают все эти строки. При чтении этого пакета в БП 2.0 обработка загрузки пытается последовательно записать их в регистр. Поскольку поля ДействуетС в БП 2.0 нет, для нее эти строки выглядят абсолютно идентичными. Происходит попытка записать в набор две записи с ключом «ХАЙ ЛЕВЕЛ ООО - Адрес - Юридический адрес». База данных закономерно отвергает такую операцию и транслирует ошибку уникальности ключа.

Роль сервиса «1С-Контрагент» в возникновении дублей

Многие пользователи и администраторы замечают, что ошибка появляется хаотично — не у всех контрагентов подряд, а только у некоторых, преимущественно недавно созданных или измененных. Проанализируем, почему так происходит.

Главным виновником лавинообразного появления таких дублей в базе является встроенный сервис «1С-Контрагент». Рассмотрим типичный сценарий работы пользователя:

  1. Менеджер создает в УТ 11 нового контрагента и вводит его ИНН.
  2. Сервис «1С-Контрагент» автоматически запрашивает сведения из государственного реестра ЕГРЮЛ и заполняет карточку. В этот момент создается первая запись адреса.
  3. Через некоторое время (или даже в процессе текущего редактирования) пользователь повторно нажимает кнопку заполнения по ИНН или перевыбирает адрес.
  4. Если в государственном реестре формат записи адреса хоть немного изменился (например, сокращение «ул.» заменилось на «улица», поменялся индекс или порядок слов), система УТ 11 считает этот адрес новым.
  5. Вместо перезаписи старой строки система, повинуясь логике ведения истории изменений, аккуратно переносит старый адрес в разряд исторических, а новый записывает как актуальный.

Визуально в пользовательском интерфейсе УТ 11 менеджер видит только один красивый актуальный адрес. Однако в базе данных в табличной части контрагента теперь физически содержатся две (или даже три-четыре) строки с разными датами начала действия. При первой же попытке выгрузить этого контрагента в БП 2.0 обмен «споткнется» именно на нем.

Рассмотрим подробнее варианты решения проблемы

Поскольку фирма «1С» официально прекратила активное развитие редакции БП 2.0, ожидать выпуска официального исправления, адаптирующего старую бухгалтерию к новым механизмам УТ 11.4, не приходится. Нам необходимо решить эту проблему самостоятельно. Ниже подробно описаны четыре практических метода — от самых простых организационных до профессиональных программистских.

Вариант А. Отключение истории изменений контактной информации в УТ 11

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

Выполним следующие шаги:

  1. Авторизуйтесь в базе 1С:Управление торговлей под учетной записью с правами администратора.
  2. Перейдите в раздел меню НСИ и администрирование, затем выберите пункт Общие настройки.
  3. Раскройте группу параметров Контактная информация.
  4. Найдите гиперссылку Виды контактной информации и перейдите по ней.
  5. В открывшемся списке найдите группу справочника Контрагенты.
  6. Поочередно откройте свойства критически важных видов адресов, которые участвуют в обмене (как правило, это Юридический адрес и Фактический адрес).
  7. В карточке настройки вида контактной информации найдите и снимите флаг «Хранить историю изменений».
  8. Сохраните изменения, нажав кнопку Записать и закрыть.

Важное примечание: Отключение этой настройки предотвратит появление новых дублирующих строк в будущем. Однако те дубли, которые уже успели записаться в базу за время работы в новом релизе, никуда не исчезнут автоматически. Чтобы обмен пошел нормально, вам потребуется очистить накопленные дубли у проблемных контрагентов. Сделать это можно вручную (как описано в сообщении 10 форума, очистив адрес и заполнив его заново один раз) либо воспользовавшись стандартной обработкой «Групповое изменение реквизитов» или написав небольшой очищающий скрипт.

Вариант Б. Корректировка правил конвертации данных (КД 2.0)

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

Разберем по шагам, как это реализовать с помощью конфигурации «1С:Конвертация данных 2.0»:

  1. Выгрузите текущие правила обмена из вашей базы УТ 11 во внешний XML-файл.
  2. Запустите базу Конвертация данных 2.0 и импортируйте в нее этот файл правил.
  3. Перейдите в раздел настроек правил и найдите Правило конвертации свойств (ПКС) для табличной части КонтактнаяИнформация справочника Контрагенты.
  4. Нам необходимо модифицировать логику выгрузки этой табличной части. Перейдем в обработчик события «Перед выгрузкой» для этой табличной части.
  5. Напишем специализированный алгоритм фильтрации строк на языке 1С. Нам нужно сгруппировать строки по видам контактной информации и оставить только те, у которых дата в поле ДействуетС является максимальной (последней) или пустой. Остальные строки мы должны исключить из процесса выгрузки.

Проанализируем пример программного кода, который можно использовать в обработчике:


// Создаем соответствие для отслеживания самых свежих записей по видам адресов
АктуальныеАдреса = Новый Соответствие;

Для Каждого СтрокаКИ Из Источник.КонтактнаяИнформация Цикл
    ТекущийВид = СтрокаКИ.Вид;
    СуществующаяЗапись = АктуальныеАдреса.Получить(ТекущийВид);
    
    Если СуществующаяЗапись = Неопределено Тогда
        // Если для данного вида еще нет записи, добавляем текущую
        АктуальныеАдреса.Вставить(ТекущийВид, СтрокаКИ);
    Иначе
        // Сравниваем даты начала действия, чтобы оставить самую свежую
        Если СтрокаКИ.ДействуетС > СуществующаяЗапись.ДействуетС Тогда
            АктуальныеАдреса.Вставить(ТекущийВид, СтрокаКИ);
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

// Формируем результирующую коллекцию только из актуальных строк
// и подменяем ею стандартную коллекцию выгрузки
КоллекцияОбъектов = Новый ТаблицаЗначений;
КоллекцияОбъектов.Колонки.Добавить("Вид");
КоллекцияОбъектов.Колонки.Добавить("Тип");
КоллекцияОбъектов.Колонки.Добавить("Представление");
КоллекцияОбъектов.Колонки.Добавить("ЗначенияПолей");

Для Каждого КлючИЗначение Из АктуальныеАдреса Цикл
    НоваяСтрока = КоллекцияОбъектов.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, КлючИЗначение.Значение);
КонецЦикла;

После сохранения измененных правил в Конвертации данных, выгрузите их обратно в XML-файл и загрузите в настройки синхронизации вашей базы УТ 11. Теперь при выгрузке данных в БП 2.0 всегда будет уходить ровно одна, актуальная на текущий момент строка адреса, и СУБД в бухгалтерии больше не выдаст ошибку о дублировании ключевых полей.

Вариант В. Использование расширения конфигурации в УТ 11

Если вы не хотите редактировать правила конвертации в специализированной программе КД 2.0, отличной альтернативой станет разработка небольшого расширения конфигурации непосредственно в базе УТ 11.

Этот способ позволяет перехватить процедуру регистрации изменений или сам момент формирования XML-пакета выгрузки (например, через механизм подписки на события или перехват метода выгрузки данных в модуле менеджера обмена). В коде расширения перед отправкой данных в узел обмена с БП 2.0 программно очищается коллекция контактной информации от архивных записей. Плюс этого метода в том, что при последующих обновлениях конфигурации УТ 11 ваши доработки не затрутся, а правила обмена останутся типовыми, что существенно облегчит дальнейшую поддержку системы.

Вариант Г. Переход на актуальную конфигурацию БП 3.0

Посмотрим на ситуацию шире. Фирма «1С» давно прекратила активное развитие редакции БП 2.0. Она поддерживается исключительно в рамках сдачи регламентированной отчетности, при этом новые технологические фичи платформы и библиотек в нее не переносятся. Использование связки современной УТ 11.4 и архивной БП 2.0 с каждым годом будет порождать все больше подобных технических конфликтов.

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

Подведем итоги

Резюмируя все вышесказанное, отметим, что корень проблемы кроется в несовместимости форматов хранения данных старого и нового поколений конфигураций. Если вам нужно быстрое решение «здесь и сейчас» без привлечения программистов — используйте Вариант А (отключение истории изменений). Если программист в штате есть и история адресов важна для управленческого учета — реализуйте фильтрацию в правилах через Вариант Б. Ну а для долгосрочной стабильной работы всей ИТ-инфраструктуры планируйте переход на БП 3.0.

Надеемся, данный разбор помог вам разобраться в ситуации и успешно восстановить работоспособность вашей системы синхронизации данных!

← На главную