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