При разработке интерфейсов в «1С:Предприятие 8» часто возникает задача реализации механизма Master-Detail (ведущий-ведомый). Суть задачи заключается в том, чтобы при перемещении курсора по списку в одной табличной части (мастер-таблица), данные в другой табличной части (детальная таблица) автоматически фильтровались, отображая только те записи, которые относятся к выбранному элементу. Давайте подробно разберем, как это реализовать программно, и рассмотрим нюансы для разных типов интерфейсов.
Если вы работаете с обычными формами, основным инструментом для фильтрации строк в связанных табличных полях является свойство ОтборСтрок. Рассмотрим ситуацию на примере: у нас есть верхняя таблица ТоварныеГруппы и нижняя таблица Квоты, в которой должны отображаться записи только по выбранной товарной группе.
Для начала нам необходимо определить событие, на которое будет реагировать система. Самым подходящим является событие ПриАктивизацииСтроки основной таблицы. Это событие срабатывает каждый раз, когда пользователь кликает на строку или перемещается по списку с помощью клавиатуры.
Разберем по шагам процесс настройки:
ПриАктивизацииСтроки.
Процедура ТоварныеГруппыПриАктивизацииСтроки(Элемент)
// Получаем данные текущей выбранной строки в верхней таблице
ТекДанные = ЭлементыФормы.ТоварныеГруппы.ТекущиеДанные;
// Проверяем, выбрана ли строка, чтобы избежать ошибок при пустой таблице
Если ТекДанные = Неопределено Тогда
// Если строка не выбрана, создаем пустую ссылку для сброса фильтра
ТовГруппа = Справочники.ТоварныеГруппы.ПустаяСсылка();
Иначе
// Извлекаем значение, по которому будем фильтровать нижнюю таблицу
ТовГруппа = ТекДанные.ТоварнаяГруппа;
КонецЕсли;
// Устанавливаем отбор в подчиненной таблице
// Используем метод Установить() для свойства ОтборСтрок
ЭлементыФормы.Квоты.ОтборСтрок.ТоварнаяГруппа.Установить(ТовГруппа);
КонецПроцедуры
Важное замечание: Метод ОтборСтрок влияет только на визуальное отображение данных на форме. Если вы планируете в дальнейшем программно перебирать строки подчиненной таблицы (например, в цикле Для Каждого ТекущаяСтрока Из Квоты Цикл), помните, что итератор увидит все строки коллекции, а не только отфильтрованные. Фильтр на форме не удаляет данные из объекта ДокументОбъект или СправочникОбъект.
В современном интерфейсе (Управляемое приложение, «Такси») подход к решению этой задачи несколько иной. Здесь мы не используем ЭлементыФормы, а работаем напрямую с коллекциями через Объект или динамические списки. Рассмотрим два основных способа.
Если обе таблицы являются табличными частями одного документа, то в управляемой форме событие ПриАктивизацииСтроки также доступно. Однако свойство ОтборСтрок у элементов управляемой формы отсутствует в том виде, в котором оно было в обычных формах. В этом случае мы можем использовать свойство ФиксированныеНастройки, если данные выводятся через Динамический список, или программно перезаполнять вспомогательную коллекцию.
Но чаще всего для реализации Master-Detail в управляемых формах используются Динамические списки.
Проанализируем ситуацию, когда нижняя таблица — это список записей из регистра сведений или подчиненного справочника. Это самый эффективный метод, так как он не требует написания сложного кода в модуле формы. Выясним, как это настроить в свойствах:
Элементы.ТоварныеГруппы.ТекущиеДанные.Ссылка.Платформа 1С в автоматическом режиме будет обновлять нижний список при каждом изменении фокуса в верхней таблице. Это работает максимально быстро и оптимизировано для веб-клиента.
Рассмотрим подробнее важный технический нюанс. В управляемых формах событие ПриАктивизацииСтроки выполняется на клиенте. Если для обновления нижней таблицы вам требуется выполнить запрос к базе данных, возникнет серверный вызов.
Почему это критично? При быстрой прокрутке верхней таблицы с помощью клавиатуры (зажатая клавиша «вниз») серверные вызовы будут идти один за другим, что может привести к «подвисанию» интерфейса. Чтобы этого избежать, профессиональные разработчики применяют проверку:
&НаКлиенте
Процедура ТоварныеГруппыПриАктивизацииСтроки(Элемент)
ТекДанные = Элементы.ТоварныеГруппы.ТекущиеДанные;
// Сохраняем идентификатор строки, чтобы не делать лишних вызовов,
// если курсор бегает по колонкам одной и той же строки
Если ТекДанные = Неопределено Или ТекДанные.НомерСтроки = ТекущийИдентификатор Тогда
Возврат;
КонецЕсли;
ТекущийИдентификатор = ТекДанные.НомерСтроки;
// Вызываем сервер только при реальной смене строки
ОбновитьПодчиненныеДанныеНаСервере(ТекДанные.ТоварнаяГруппа);
КонецПроцедуры
Посмотрим на ситуацию, когда пользователь не просто перемещается между строками, а меняет значение непосредственно в колонке ТоварнаяГруппа мастер-таблицы. В этом случае событие ПриАктивизацииСтроки может не сработать, так как фокус остается на той же строке.
Чтобы интерфейс оставался отзывчивым и корректным, рекомендуется продублировать вызов процедуры фильтрации в событии ПриИзменении соответствующего поля ввода. Это гарантирует, что нижняя таблица всегда будет актуальна текущим значениям верхней.
Подводя итог, можно сказать, что для решения задачи Master-Detail в 1С важно понимать тип используемой формы:
ЭлементыФормы.ИмяТаблицы.ОтборСтрок.Поле.Установить(Значение).ТекущиеДанные на Неопределено, чтобы программа не аварийно завершалась при работе с пустыми списками.Следуя этим шагам, вы сможете создать удобный и интуитивно понятный интерфейс для пользователей, обеспечив четкую взаимосвязь данных в ваших экранных формах.