Почему программно созданный партнер не отображается в списке клиентов в УТ 11?

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

При программном создании элементов справочника Партнеры в конфигурации «1С:Управление торговлей 11» разработчики нередко сталкиваются с ситуацией: в коде реквизит Клиент явно устанавливается в значение Истина, запись проходит успешно, но в интерфейсе («CRM и маркетинг» — «Клиенты») новый партнер не отображается. При этом в общем списке всех партнеров элемент виден, галочка «Клиент» установлена, а если снять её и установить вручную в режиме «1С:Предприятие» — партнер мгновенно появляется в нужном списке. Разберем внутренние механизмы платформы и типовой конфигурации, выясним причину такого поведения и рассмотрим правильный способ программного создания клиентов.

Анализ проблемы и исходного кода

Рассмотрим типовой фрагмент кода, в котором возникает эта ошибка:


Функция прНайтиСоздатьПартнера(ДанныеКонтрагент, Контрагент)
    ПартнерОбъект = Справочники.Партнеры.СоздатьЭлемент();    
    ПартнерОбъект.УстановитьНовыйКод();
    ПартнерОбъект.Наименование = СокрЛП(ДанныеКонтрагент.Наименование);
    ПартнерОбъект.НаименованиеПолное = ПартнерОбъект.Наименование;
    ПартнерОбъект.ЮрФизЛицо = Перечисления.КомпанияЧастноеЛицо.ЧастноеЛицо;
    ПартнерОбъект.Клиент = Истина;
    ПартнерОбъект.ДатаРегистрации = ТекущаяДата();    
    ПартнерОбъект.Комментарий = "Создан автоматически при загрузке заказов";
    ПартнерОбъект.ОбменДанными.Загрузка = Истина;
    ПартнерОбъект.Записать();
КонецФункции

На первый взгляд реквизиты заполнены корректно. Однако обратим внимание на строчку ПартнерОбъект.ОбменДанными.Загрузка = Истина;. Именно она является корнем проблемы.

Внутренняя механика УТ 11: почему отключать обработчики опасно

Флаг ОбменДанными.Загрузка = Истина переводит объект в специальный режим обмена, при котором отключаются проверки заполнения, события ПередЗаписью, ПриЗаписи, а также все подписки на события. В типовых конфигурациях линейки «1С:Управление торговлей», «1С:Комплексная автоматизация» и «1С:ERP» справочник Партнеры тесно связан со служебными подсистемами, которые не могут инициализироваться без вызова стандартных процедур записи:

  1. Регистр сведений «Иерархия партнеров». В УТ 11 справочник партнеров поддерживает иерархию элементов. Для оптимизации запросов динамические списки форм (в том числе форма клиентов) соединяются с регистром сведений ИерархияПартнеров. Записи в этот регистр создаются именно в процедуре ПриЗаписи модуля объекта. Если запись выполняется в режиме загрузки, регистр остается пустым, и динамический список клиентов физически не может вывести элемент.
  2. Ограничение доступа на уровне записей (RLS). Подсистема БСП при штатной записи формирует служебные наборы значений доступа (регистры групп доступа). Если они не заполнены, наложенные ограничения отсекают нового партнера из динамических списков даже при наличии полных прав у пользователя.
  3. Связь с сегментами и классификаторами. Форма списка клиентов может содержать стандартные отборы по активности и сегментам. Без штатных обработчиков движения по регистрам сегментов не формируются.

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

Для корректного отображения партнера в списке клиентов достаточно убрать взведение флага ОбменДанными.Загрузка, чтобы дать конфигурации выполнить все необходимые служебные движения. Кроме того, при создании нового элемента рекомендуется инициализировать значения по умолчанию вызовом процедуры Заполнить(), которая выполняет логику обработчика ОбработкаЗаполнения.

Посмотрим на исправленный вариант программного кода:


Функция прНайтиСоздатьПартнера(ДанныеКонтрагент, Контрагент)
    ПартнерОбъект = Справочники.Партнеры.СоздатьЭлемент();
    
    // Инициализируем стандартные реквизиты значениями по умолчанию
    ПартнерОбъект.Заполнить(Неопределено);
    
    ПартнерОбъект.УстановитьНовыйКод();
    ПартнерОбъект.Наименование = СокрЛП(ДанныеКонтрагент.Наименование);
    ПартнерОбъект.НаименованиеПолное = ПартнерОбъект.Наименование;
    ПартнерОбъект.ЮрФизЛицо = Перечисления.КомпанияЧастноеЛицо.ЧастноеЛицо;
    ПартнерОбъект.Клиент = Истина;
    ПартнерОбъект.ДатаРегистрации = ТекущаяДата();    
    ПартнерОбъект.Комментарий = "Создан автоматически при загрузке заказов";
    
    // Записываем объект в стандартном режиме, без ОбменДанными.Загрузка = Истина
    ПартнерОбъект.Записать();
    
    Возврат ПартнерОбъект.Ссылка;
КонецФункции

Взаимодействие партнеров и контрагентов

Разберем еще один важный архитектурный аспект УТ 11 — разделение управленческой сущности (Партнеры) и регламентированной (Контрагенты). В зависимости от настройки базы поведение может различаться:

  1. Режим независимого ведения партнеров и контрагентов отключен: в программе действует совмещенный учет. Каждому партнеру должен строго соответствовать один контрагент. Если создать партнера без контрагента, карточка клиента в интерфейсе будет неполноценной.
  2. Режим независимого ведения партнеров и контрагентов включен: у одного партнера может быть несколько юридических лиц (контрагентов). При этом в элементе справочника Контрагенты обязательно должен быть заполнен реквизит Партнер.

Если для партнера уже подготовлен или создается контрагент, свяжем их программно:


// Создание и привязка контрагента к партнеру
КонтрагентОбъект = Справочники.Контрагенты.СоздатьЭлемент();
КонтрагентОбъект.Заполнить(Неопределено);
КонтрагентОбъект.Партнер = ПартнерСсылка; // Указываем ссылку на созданного партнера
КонтрагентОбъект.Наименование = ПартнерОбъект.Наименование;
КонтрагентОбъект.НаименованиеПолное = ПартнерОбъект.НаименованиеПолное;
КонтрагентОбъект.ЮрФизЛицо = Перечисления.КомпанияЧастноеЛицо.ЧастноеЛицо;
КонтрагентОбъект.Записать();

Что делать, если режим загрузки действительно необходим?

Иногда при массовом импорте тысяч записей разработчики вынуждены использовать ОбменДанными.Загрузка = Истина ради скорости. Если вы применяете этот режим, помните, что база данных переходит в неконсистентное состояние с точки зрения вспомогательных регистров. В таком случае необходимо выполнить один из следующих шагов:

  1. После завершения пакетного переноса выполнить повторную программную перезапись созданных объектов методом Записать() в штатном режиме без признака загрузки.
  2. Программно сформировать недостающие записи в служебном регистре сведений ИерархияПартнеров.
  3. Запустить регламентные задания по обновлению прав доступа на уровне записей и расчету сегментов.

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

← На главную