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