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