Как программно найти и вывести в печатную форму основное контактное лицо контрагента в 1С

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

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

Анализ типичных ошибок при поиске данных

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

  1. Отсутствие связи с владельцем: Справочник КонтактныеЛица является подчиненным справочнику Контрагенты. Метод НайтиПоРеквизиту ищет первый попавшийся элемент во всей таблице базы данных. Если у вас 1000 контрагентов и у каждого есть "Основной" контакт, система вернет вам ссылку на контактное лицо случайного контрагента, а не того, который указан в документе.
  2. Обращение к реквизитам формы: Использование пути типа "Список.Основной" ошибочно. Префикс Список относится к элементам интерфейса (динамическому списку на форме), в то время как программный код в модуле менеджера или объекта работает напрямую с метаданными и таблицами SQL. В базе данных реквизит называется просто Основной.
  3. Невозможность запроса к форме: Как справедливо отмечено в обсуждении, запрос выполняется к данным базы, а не к экранным формам. Все вычисляемые поля, которые пользователь видит в списке "глазками", должны быть заново рассчитаны или получены из базы в коде печати.

Метод 1: Получение данных через запрос (рекомендуемый способ)

Использование запроса — это наиболее эффективный и профессиональный способ получения данных в 1С. Проанализируем, как составить запрос, который выберет именно то контактное лицо, которое принадлежит нашему контрагенту и помечено как основное.

Для реализации этого метода нам необходимо передать в запрос ссылку на контрагента и условие по флагу Основной. Рассмотрим пример кода:


Функция ПолучитьОсновноеКонтактноеЛицо(СсылкаНаКонтрагента) Экспорт
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	КонтактныеЛица.Наименование КАК ФИО
        |ИЗ
        |	Справочник.КонтактныеЛица КАК КонтактныеЛица
        |ГДЕ
        |	КонтактныеЛица.Владелец = &Владелец
        |	И КонтактныеЛица.Основной = ИСТИНА
        |	И КонтактныеЛица.ПометкаУдаления = ЛОЖЬ";
    
    Запрос.УстановитьПараметр("Владелец", СсылкаНаКонтрагента);
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Если Не РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.ФИО;
    Иначе
        Возврат "__________________"; // Возвращаем пустую строку для макета
    КонецЕсли;
    
КонецФункции

Разберем, что мы сделали: мы ограничили выборку владельцем (Владелец = &Владелец) и добавили проверку на пометку удаления, чтобы не выводить неактуальные данные. Использование ВЫБРАТЬ ПЕРВЫЕ 1 гарантирует нам получение только одной записи, даже если в базе произошла ошибка и основных лиц оказалось несколько.

Метод 2: Использование объектной модели (метод Выбрать)

Если по каким-то причинам вы не хотите использовать запрос (хотя это не рекомендуется для производительности), можно воспользоваться методом Выбрать() самого справочника. Проанализируем этот подход:


Отбор = Новый Структура;
Отбор.Вставить("Основной", Истина);

Выборка = Справочники.КонтактныеЛица.Выбрать(СсылкаНаКонтрагента, , Отбор);

Если Выборка.Следующий() Тогда
    ОбластьПоставщик2.Параметры.тн_Контрагент = Выборка.Наименование;
Иначе
    ОбластьПоставщик2.Параметры.тн_Контрагент = "__________________";
КонецЕсли;

Здесь важно помнить: первым параметром в метод Выбрать передается Владелец. Это ключевой момент, который решает проблему поиска "не того" сотрудника. Если передать Неопределено или пустую ссылку, поиск снова пойдет по всей базе.

Разграничение понятий: Контактное лицо и Текущий пользователь

В процессе обсуждения возникла путаница между "Основным контактным лицом" (представителем клиента) и "Текущим сотрудником" (тем, кто печатает документ). Выясним причину этой путаницы и как правильно работать с обоими понятиями.

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

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

Посмотрим на пример получения ФИО текущего пользователя:


// Получаем текущего пользователя системы
ТекущийПользователь = ПараметрыСеанса.ТекущийПользователь;

// В БП 3.0 физическое лицо связано с пользователем через реквизит
ФизЛицоПользователя = ТекущийПользователь.ФизическоеЛицо;

Если ЗначениеЗаполнено(ФизЛицоПользователя) Тогда
    ОбластьПоставщик2.Параметры.тн_Контрагент = Строка(ФизЛицоПользователя);
КонецЕсли;

Интеграция в макет печатной формы

Когда мы определились с методом получения данных, нам нужно передать их в параметры макета. Рассмотрим финальный алгоритм действий в модуле менеджера при формировании табличного документа:

  1. Получаем данные объекта (например, документа Счет на оплату или Акт).
  2. Из данных объекта извлекаем ссылку на Контрагента.
  3. Вызываем функцию поиска основного контактного лица, передавая туда эту ссылку.
  4. Заполняем параметр области макета полученным значением.

Важный нюанс: Если вы работаете в конфигурации Бухгалтерия предприятия 3.0, рекомендуется использовать функции из состава БСП для форматирования ФИО (например, чтобы преобразовать "Иванов Иван Иванович" в "Иванов И.И."). Для этого можно обратиться к общему модулю ФизическиеЛица.

Таким образом, правильный подход к решению задачи заключается в строгом соблюдении иерархии данных: Контрагент (Владелец) -> Контактное лицо (Элемент) -> Свойство "Основной". Использование запроса с фильтром по владельцу — это надежный и масштабируемый способ, который обеспечит корректную работу печатной формы при любом объеме данных в базе.

← На главную