Как вывести реквизит справочника в журнал документов

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Хранение данных vs Отображение: что выбрать?

Прежде чем приступать к реализации, проанализируем ситуацию и выберем стратегию. Существует два принципиально разных подхода:

  1. Физическое хранение (Денормализация): Создание реального реквизита в документе и копирование туда значения из справочника. Это полезно для сохранения «исторической правды» (например, если ИНН контрагента изменится в будущем, в старых документах останется старое значение).
  2. Динамическое отображение: Вывод данных «на лету» только для визуального удобства. Это предпочтительный метод, так как он не раздувает базу данных и гарантирует актуальность информации.

Разберем способы реализации для различных типов форм 1С.

Решение для обычных форм (Платформа 8.2 и 8.3 в режиме совместимости)

В обычных формах (которые часто встречаются в старых редакциях «Управление производственным предприятием» или «Бухгалтерия 2.0») процесс требует написания программного кода. Выясним, почему просто добавить колонку недостаточно.

Если мы просто добавим колонку в табличное поле и укажем путь к данным через точку (например, Контрагент.ИНН), система будет выполнять отдельный запрос к базе данных для каждой отрисовываемой строки. Это приведет к значительным задержкам при прокрутке списка. Чтобы избежать этого, используем событие ПриВыводеСтроки.

Шаг 1: Настройка элемента формы

Рассмотрим порядок действий в Конфигураторе:

  1. Откроем форму журнала или списка документов.
  2. Вставим новую колонку в табличное поле (список). Дадим ей имя, например, КолонкаИНН, и заголовок «ИНН».
  3. В свойствах табличного поля найдем раздел «События» и нажмем на лупу рядом с событием ПриВыводеСтроки.

Шаг 2: Написание кода

Проанализируем пример кода, который позволит нам заполнить созданную колонку данными:


Процедура СписокПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    // Проверяем, есть ли данные в строке, чтобы избежать ошибок
    Если ДанныеСтроки = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Обращаемся к реквизиту Контрагент и получаем его ИНН
    // Обратите внимание: обращение через точку в этом событии допустимо, 
    // но для больших списков лучше использовать кэширование или ПриПолученииДанных
    Попытка
        ОформлениеСтроки.Ячейки.КолонкаИНН.УстановитьТекст(ДанныеСтроки.Контрагент.ИНН);
    Исключение
        ОформлениеСтроки.Ячейки.КолонкаИНН.УстановитьТекст("");
    КонецПопытки;

КонецПроцедуры

Оптимизация для обычных форм через «ПриПолученииДанных»

Если в вашем журнале тысячи записей, событие ПриВыводеСтроки может работать медленно. Выясним причину: оно вызывается для каждой строки отдельно. Более профессиональный подход — использование события ПриПолученииДанных. Оно позволяет получить данные сразу для всей пачки видимых на экране строк одним запросом.

Посмотрим на пример реализации с использованием запроса:


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

КонецПроцедуры

Решение для управляемых форм (Платформа 8.3)

В современных конфигурациях (БП 3.0, УТ 11, ERP) работа со списками строится на объекте ДинамическийСписок. Здесь задача решается гораздо проще, часто даже без изменения программного кода.

Способ 1: Использование «Пути к данным»

Рассмотрим пошагово, как вывести ИНН, если в списке уже есть колонка «Контрагент»:

  1. В редакторе формы перейдем в дерево элементов (левая верхняя панель).
  2. Найдем таблицу списка и развернем её.
  3. Найдем поле Контрагент.
  4. Нажмем правую кнопку мыши — «Добавить поля».
  5. В открывшемся списке выберем ИНН.

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

Способ 2: Произвольный запрос в динамическом списке

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

  1. В свойствах реквизита формы Список (тип ДинамическийСписок) установим галочку «Произвольный запрос».
  2. Нажмем «Открыть» у текста запроса.
  3. Добавим левое соединение со справочником контрагентов:

ВЫБРАТЬ
    ДокументРеализация.Ссылка,
    ДокументРеализация.Дата,
    ДокументРеализация.Номер,
    ДокументРеализация.Контрагент,
    ЕСТЬNULL(СправочникКонтрагенты.ИНН, "") КАК КонтрагентИНН
ИЗ
    Документ.РеализацияТоваровУслуг КАК ДокументРеализация
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК СправочникКонтрагенты
    ПО ДокументРеализация.Контрагент = СправочникКонтрагенты.Ссылка

После этого новое поле КонтрагентИНН станет доступно для вытягивания на форму. Важный момент: использование произвольного запроса позволяет выполнять поиск и сортировку по этой колонке штатными средствами 1С.

Автоматическое заполнение реквизита в документе

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

Шаг 1: Добавление реквизита

В дереве метаданных найдем нужный документ и добавим реквизит ИННКонтрагента (тип Строка).

Шаг 2: Обработчик изменения

На форме документа для поля выбора Контрагент создадим событие ПриИзменении. Пропишем в нем код, который будет «подтягивать» данные:


&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
    
    // Вызываем серверную функцию для получения данных
    Объект.ИННКонтрагента = ПолучитьИННКонтрагентаСервер(Объект.Контрагент);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьИННКонтрагентаСервер(СсылкаНаКонтрагента)
    
    Возврат СсылкаНаКонтрагента.ИНН;
    
КонецФункции

Такой подход гарантирует, что как только пользователь выберет контрагента, поле ИНН в документе заполнится автоматически. Однако помните: если вы измените ИНН в справочнике позже, в уже записанных документах он не поменяется сам собой, пока вы не перевыберете контрагента или не запустите специальную обработку обновления данных.

Использование расширений для типовых конфигураций

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

Проанализировав все способы, можно сделать вывод: для визуального отображения в списках всегда лучше использовать возможности Динамического списка (в управляемых формах) или событие ПриПолученииДанных (в обычных формах). Это обеспечит высокую скорость работы программы и удобство пользователей.

← На главную