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