При разработке интерфейсов на управляемых формах 1С часто возникает задача: отобразить основной список элементов (например, справочник) и одновременно с ним показать содержимое табличной части текущего выбранного элемента. Казалось бы, платформа позволяет сделать это простым перетаскиванием реквизитов, но на практике разработчики сталкиваются с тем, что «собственные» поля табличной части отображаются корректно, а поля, полученные «через точку» от ссылочных реквизитов, остаются пустыми. Разберем, почему так происходит и как правильно реализовать этот механизм.
Рассмотрим стандартную ситуацию. У нас есть Справочник1 с табличной частью, в которой одно из полей — это ссылка на Справочник2. Мы хотим видеть на форме не просто ссылку, а конкретный реквизит этого Справочника2 (например, его артикул или описание). Если мы привязываем таблицу формы к пути Элементы.СписокСпр1.ТекущиеДанные.ТабличнаяЧасть, платформа пытается отобразить данные из кэша динамического списка.
Проанализируем причину сбоя: Динамический список оптимизирован для передачи минимально необходимого объема данных. Реквизиты, находящиеся непосредственно в табличной части, считываются легко. Однако реквизиты, идущие через ссылку (разыменование ссылки), требуют выполнения дополнительного соединения (Left Join) в SQL-запросе на уровне СУБД. При обращении через ТекущиеДанные к вложенной коллекции платформа не всегда автоматически пробрасывает эти связи для «удаленных» реквизитов, так как считает их избыточными для оптимизации скорости отрисовки интерфейса.
Первый и самый простой способ заставить платформу считывать данные — это изменение настроек отображения. Выясним, как это сделать:
Однако стоит учитывать, что для реквизитов именно табличной части, отображаемой через CurrentData, этот метод срабатывает не во всех версиях платформы и может приводить к избыточной нагрузке на сервер, так как данные будут тянуться для каждой строки списка, а не только для выделенной.
Наиболее надежным и производительным решением в 1С считается использование отдельного динамического списка для отображения табличной части. Это позволяет полностью контролировать SQL-запрос и гарантирует получение любых данных через точку.
Разберем по шагам реализацию этого метода:
1. Создадим на форме новый реквизит с типом ДинамическийСписок. Назовем его, например, СписокТабличнойЧасти.
2. В свойствах этого списка установим основную таблицу: Справочник.Спр1.ТабличнаяЧасть.
3. Настроим запрос этого списка. Теперь мы можем явно прописать выборку нужных полей:
ВЫБРАТЬ
ТЧ.Текст2 КАК Текст2,
ТЧ.Спр2.Р1 КАК ПолеИзСсылки,
ТЧ.Ссылка КАК СсылкаНаВладельца
ИЗ
Справочник.Спр1.ТабличнаяЧасть КАК ТЧ
ГДЕ
ТЧ.Ссылка = &СсылкаНаВладельца
4. Перетащим этот реквизит на форму. Теперь нам нужно обеспечить связь между основным списком справочника и этим новым списком табличной части.
5. Создадим обработчик события ПриАктивизацииСтроки для основного динамического списка (Элемент1). В этом обработчике мы будем передавать ссылку текущего элемента в параметр второго списка.
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
ТекущаяСтрока = Элементы.Список.ТекущиеДанные;
Если ТекущаяСтрока = Неопределено Тогда
Попытка
СписокТабличнойЧасти.Параметры.УстановитьЗначениеПараметра("СсылкаНаВладельца", ПредопределенноеЗначение("Справочник.Спр1.ПустаяСсылка"));
Исключение
КонецПопытки;
Иначе
СписокТабличнойЧасти.Параметры.УстановитьЗначениеПараметра("СсылкаНаВладельца", ТекущаяСтрока.Ссылка);
КонецЕсли;
КонецПроцедуры
Выясним преимущества этого метода: такой подход работает быстрее, так как данные табличной части подгружаются только для одного конкретного элемента, выбранного пользователем. Кроме того, в динамическом списке нам доступны все возможности оформления (условное оформление, группировки), которые недоступны при прямой привязке к CurrentData.
Если ваша задача подразумевает, что пользователь должен не просто смотреть на данные, но и редактировать табличную часть прямо в этом окне, динамический список не подойдет, так как он предназначен только для чтения.
В этом случае проанализируем альтернативный сценарий:
ОбъектСправочника с типом СправочникОбъект.Спр1.ПриАктивизацииСтроки будем программно считывать объект из базы в этот реквизит.Пример кода для загрузки объекта:
&НаСервере
Процедура ЗагрузитьОбъектНаСервере(СсылкаНаОбъект)
ЗначениеВРеквизитФормы(СсылкаНаОбъект.ПолучитьОбъект(), "ОбъектСправочника");
КонецПроцедуры
В этом случае путь к данным для таблицы на форме будет ОбъектСправочника.ТабличнаяЧасть. При таком подходе механизм 1С автоматически подтянет представления ссылок, и поля «через точку» будут отображаться корректно, так как они работают в контексте данных формы объекта, а не оптимизированного кэша списка.
Подводя итог, отметим: если вы видите пустые поля при разыменовании ссылок в связанных таблицах, это сигнал о том, что платформа оптимизирует запросы и «не видит» необходимости в глубоком считывании данных. Для простого просмотра лучше всего использовать второй динамический список с параметром, а для редактирования — загрузку объекта в реквизит формы. Использование ТекущиеДанные.ТабличнаяЧасть допустимо только для отображения примитивных типов данных, хранящихся непосредственно в самой ТЧ.