К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как получить контрагента по партнеру в 1С

Как получить контрагента по партнеру в 1С:УТ 11, КА 2 и ERP: запрос к регистру связей, готовые функции на встроенном языке, типовые механизмы и типичные ошибки.

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

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

Все примеры ориентированы на УТ 11.4/11.5, КА 2 и ERP 2 — в этих конфигурациях модель партнеров и контрагентов одинакова. Для самописных конфигураций и УТ 10.3 механика отличается, об этом отдельный раздел.

Как устроена связь партнера и контрагента

В справочнике «Контрагенты» есть реквизит Партнер — ссылка на элемент справочника «Партнеры». Именно этот реквизит и является точкой связи. Обратной ссылки в карточке партнера нет: список контрагентов партнера в интерфейсе строится динамическим запросом по реквизиту «Партнер» справочника контрагентов.

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

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

Способ 1. Запрос к справочнику «Контрагенты»

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

Функция ПолучитьКонтрагентаПоПартнеру(Партнер) Экспорт

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Контрагенты.Ссылка КАК Контрагент

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| Контрагенты.Партнер = &Партнер

| И НЕ Контрагенты.ПометкаУдаления

|

|УПОРЯДОЧИТЬ ПО

| Контрагенты.Ссылка";

Запрос.УстановитьПараметр("Партнер", Партнер);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Контрагент;

КонецЕсли;

Возврат Справочники.Контрагенты.ПустаяСсылка();

КонецФункции

Обратите внимание на три детали. Отбор по НЕ ПометкаУдаления отсекает «мертвых» контрагентов, которые могли остаться после чистки базы. Конструкция ПЕРВЫЕ 1 с упорядочиванием дает детерминированный результат — при повторных вызовах вернется один и тот же контрагент. Возврат пустой ссылки вместо Неопределено упрощает дальнейшие проверки в вызывающем коде.

Если нужны все контрагенты партнера (например, для выбора в форме), уберите ПЕРВЫЕ 1 и выгрузите результат в таблицу значений или массив.

bsl
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 Контрагенты.Ссылка ИЗ Справочник.Контрагенты КАК Контрагенты ГДЕ Контрагенты.Партнер = &Партнер И НЕ Контрагенты.ПометкаУдаления";

Способ 2. Типовые механизмы конфигурации

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

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

Также полезен поиск по ИНН и КПП: типовой метод Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ИНН) позволяет сначала найти контрагента, а уже из него получить партнера через реквизит Партнер. Это обратная задача, но в интеграциях (загрузка заказов с сайта, обмен с ЭДО) она встречается чаще.

Когда у партнера несколько контрагентов

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

Практические варианты критерия: контрагент из действующего соглашения с клиентом, контрагент из последнего проведенного документа по этому партнеру, контрагент, указанный в договоре по умолчанию. Ниже пример выборки контрагента из последнего документа реализации.

Функция КонтрагентИзПоследнейРеализации(Партнер)

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| РеализацияТоваровУслуг.Контрагент КАК Контрагент

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Партнер = &Партнер

| И РеализацияТоваровУслуг.Проведен

|

|УПОРЯДОЧИТЬ ПО

| РеализацияТоваровУслуг.Дата УБЫВ";

Запрос.УстановитьПараметр("Партнер", Партнер);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Выборка.Контрагент;

КонецЕсли;

Возврат Справочники.Контрагенты.ПустаяСсылка();

КонецФункции

Маршрут решения

Как выбрать действие

У партнера всегда один контрагентИспользуйте простой запрос с ПЕРВЫЕ 1 и отбором по реквизиту Партнер
Контрагентов несколько и есть соглашениеБерите контрагента из соглашения или договора, действующего на дату документа
Контрагентов несколько, соглашений нетБерите контрагента из последнего проведенного документа партнера
Нужен выбор пользователемПолучите массив контрагентов партнера и покажите форму выбора с отбором

Проверка результата и обработка пустых значений

Полученного контрагента нельзя сразу подставлять в документ или выгрузку — сначала проверьте результат. Минимальный набор проверок: ссылка не пустая, элемент не помечен на удаление, у контрагента заполнены ИНН (для юрлиц) и другие обязательные для вашего сценария реквизиты.

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

Контрольные точки

Как проверить результат

Ссылка на контрагента
Норма

Ссылка заполнена и элемент доступен

Тревожный признак

Пустая ссылка или битая ссылка (объект не найден)

Реквизит Партнер у контрагента
Норма

Совпадает с исходным партнером

Тревожный признак

Другой партнер или пустое значение

Пометка удаления
Норма

Элемент не помечен

Тревожный признак

Помечен на удаление

ИНН и наименование
Норма

Заполнены для юрлица

Тревожный признак

Пустые при выгрузке в отчетность или ЭДО

Типичные ошибки и ограничения

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

Третья группа ошибок — производительность. Запрос контрагента внутри цикла по тысячам строк табличной части выполняется тысячи раз. Решение: собрать всех партнеров в массив, выполнить один запрос с условием Партнер В (&МассивПартнеров), выгрузить в соответствие и брать значения из него.

Типичные ошибки
01
Обращение к несуществующему реквизиту Партнер.Контрагент — ошибка выполнения или пустой результат
02
Игнорирование нескольких контрагентов у партнера — в документ подставляется неверное юрлицо
03
Запрос в цикле по строкам документа — резкое падение производительности на больших объемах
04
Отсутствие отбора по пометке удаления — в выгрузку попадают удаленные контрагенты
05
Возврат Неопределено вместо пустой ссылки — лишние проверки и ошибки сравнения типов в вызывающем коде

Отдельное ограничение — права. Если код выполняется под пользователем без доступа к справочнику «Контрагенты» (например, в регламентном задании с ограниченным профилем), запрос вернет пустой результат без ошибки. Проверяйте права или используйте привилегированный режим осознанно.

Особенности для УТ 10.3, БП 3.0 и самописных конфигураций

В «Управлении торговлей» 10.3 и «Бухгалтерии предприятия» раздельной модели партнеров нет: там существует только справочник «Контрагенты» (в УТ 10.3 у контрагента есть договоры и контактные лица, но партнера как сущности нет). Поэтому задача «получить контрагента по партнеру» для этих конфигураций неактуальна — чаще требуется обратное или поиск контрагента по ИНН.

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

Итог

Что важно запомнить

Связь хранится в реквизите «Партнер» справочника «Контрагенты», обратной ссылки нет. Получайте контрагента запросом с отбором по партнеру, отсекайте помеченные на удаление, обрабатывайте случай нескольких контрагентов и пустого результата. Для массовых операций используйте один запрос с условием В(&Массив) вместо запросов в цикле.

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

Можно ли получить контрагента без запроса, через точку?

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

Как получить всех контрагентов партнера списком?

Используйте тот же запрос к справочнику «Контрагенты» с отбором по реквизиту «Партнер», но без конструкции ПЕРВЫЕ 1. Результат выгрузите методом Выгрузить() в таблицу значений или обойдите выборку и соберите массив ссылок — его удобно передавать в параметры динамических списков и формы выбора.

Что вернуть из функции, если контрагент не найден?

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

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

Если вы уже выбираете документы, отдельный запрос не нужен: в документах УТ 11, КА 2 и ERP 2 есть оба поля — Партнер и Контрагент. Достаточно добавить в выборку поле Контрагент с отбором по Партнер. Это быстрее и точнее, чем искать контрагента по справочнику, потому что отражает фактический выбор в документе.

Почему запрос возвращает не того контрагента, хотя у партнера он один?

Чаще всего причина в отсутствии отбора по пометке удаления: в базе есть старый помеченный контрагент, и без упорядочивания запрос может вернуть именно его. Добавьте условие НЕ ПометкаУдаления и детерминированное упорядочивание. Также проверьте, нет ли дублей партнера — контрагент может быть привязан к другому элементу справочника «Партнеры» с похожим наименованием.

Как избежать запросов в цикле при обработке множества партнеров?

Соберите партнеров в массив или таблицу значений, выполните один запрос с условием Контрагенты.Партнер В (&СписокПартнеров), выгрузите результат и постройте соответствие «партнер → контрагент». В цикле обращайтесь к соответствию — это снижает число обращений к базе с тысяч до одного.