Разработка интерфейсов на управляемых формах 1С часто преподносит задачи, кажущиеся на первый взгляд тривиальными, но требующие глубокого понимания механизмов платформы. Одной из таких задач является программная активация (позиционирование курсора) на последней строке динамического списка. В этой статье мы подробно разберем, почему стандартные методы коллекций здесь не работают, и проанализируем несколько надежных способов реализации этой задачи для различных сценариев, включая работу в веб-клиенте. Для изучения других практических приемов изменения состава и структуры данных можно использовать руководство по методам доработки динамических списков.
Для начала выясним причину, почему мы не можем просто обратиться к индексу последней строки, как мы привыкли делать в таблицах значений или табличных частях. Динамический список (ДинамическийСписок) — это объект, разработанный специально для оптимальной работы с большими объемами данных. Он не считывает всю таблицу из базы данных за один раз. Вместо этого платформа запрашивает данные порциями (обычно по 20–45 строк), необходимыми для отображения на текущем экране пользователя.
Следовательно, на стороне клиента динамический список просто «не знает», сколько всего строк находится в выборке и какая строка является физически последней, пока пользователь не прокрутит список до самого конца. Традиционного индекса строк у этого объекта на клиенте не существует.
Тем не менее, решить эту задачу можно. Рассмотрим основные рабочие подходы.
Если ваша задача заключается в том, чтобы пользователь оказывался в конце списка сразу при открытии формы (например, в журнале документов или чате), то платформа предоставляет штатную настройку. Нам не потребуется писать сложный код.
Разберем, как это настроить:
ОтображениеНачальнойСтроки (в некоторых версиях платформы он называется НачальноеОтображениеСписка).Конец.Также это свойство можно установить программно при создании формы на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Элементы.Список.ОтображениеНачальнойСтроки = ОтображениеНачальнойСтрокиТаблицы.Конец;
КонецПроцедуры
Важное ограничение: этот способ работает исключительно в момент первоначального отображения таблицы на форме. Если форма уже открыта, данные обновились, и вам нужно программно «перепрыгнуть» в конец списка, данный метод не принесет результата.
Этот способ является наиболее надежным, современным и полностью работоспособным как в тонком, так и в веб-клиенте. Идея заключается в том, чтобы на сервере получить реальный запрос динамического списка со всеми пользовательскими отборами и сортировками, выполнить его и узнать ссылку на самую последнюю запись.
Для реализации этого подхода воспользуемся механизмом компоновки данных. Проанализируем следующий программный код:
&НаСервере
Функция ПолучитьСсылкуПоследнейСтрокиНаСервере()
// Получаем схему компоновки данных динамического списка и его текущие настройки
Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
// Создаем компоновщик макета для вывода результата в коллекцию
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных();
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
// Инициализируем процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// Выводим результат компоновки в таблицу значений
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТаблицаДанных = ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Если в полученной таблице есть строки, возвращаем ссылку последней строки
Если ТаблицаДанных.Количество() > 0 Тогда
// Предполагается, что основное поле списка называется "Ссылка"
Возврат ТаблицаДанных[ТаблицаДанных.Количество() - 1].Ссылка;
КонецЕсли;
Возврат Неопределено;
КонецФункции
&НаКлиенте
Процедура ПерейтиВКонецСписка()
// Обновим данные списка на клиенте, чтобы актуализировать состав строк
Элементы.Список.Обновить();
СсылкаНаПоследнююСтроку = ПолучитьСсылкуПоследнейСтрокиНаСервере();
Если ЗначениеЗаполнено(СсылкаНаПоследнююСтроку) Тогда
// Устанавливаем курсор на полученную ссылку
Элементы.Список.ТекущаяСтрока = СсылкаНаПоследнююСтроку;
КонецЕсли;
КонецПроцедуры
Преимущества метода: он абсолютно точен, так как полностью учитывает все наложенные пользователем или кодом фильтры, поисковые строки и активные сортировки. Метод бесперебойно работает во всех типах клиентов 1С. Для более глубокого освоения возможностей системы компоновки и пользовательских параметров списка пригодится материал по тонкой настройке динамических списков.
Если ваше приложение гарантированно не будет использоваться в веб-браузере (веб-клиенте), можно прибегнуть к простому и быстрому обходному пути — эмуляции нажатия клавиши End на клавиатуре с помощью системного скрипта Windows. Для реализации более сложных сценариев взаимодействия с интерфейсом без использования API можно применить платформу для создания программных роботов в 1С.
Рассмотрим пример реализации сценария:
&НаКлиенте
Процедура ПерейтиВКонецСпискаЭмуляцией()
// Активируем таблицу списка на форме
Элементы.ТекущийЭлемент = Элементы.Список;
// Принудительно обновляем отображение данных
Элементы.Список.Обновить();
// Используем Windows Script Host для отправки нажатия клавиши END
Попытка
мГенераторКлавиш = Новый COMОбъект("Wscript.shell");
мГенераторКлавиш.SendKeys("{END}");
Исключение
ЗаписьЖурналаРегистрации("ЭмуляцияКлавиатуры", УровеньЖурналаРегистрации.Предупреждение, , ,
"Не удалось запустить WScript.Shell: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Важное предупреждение: этот способ мгновенно вызовет системную ошибку в веб-клиенте, так как браузерные политики безопасности строго блокируют создание COM-объектов на стороне клиента. Используйте его с осторожностью и только в рамках закрытых корпоративных сетей без веб-доступа.
Очень часто разработчики пытаются решить техническую проблему там, где гораздо эффективнее скорректировать пользовательский интерфейс. Зададимся вопросом: почему нам так необходимо оказаться в конце списка? Чаще всего это требуется для того, чтобы увидеть самые новые, только что созданные документы или записи.
Вместо того чтобы заставлять систему программно прокручивать тысячи строк вниз, правильнее сделать так, чтобы новые записи всегда отображались **в самом верху списка**. Для этого достаточно настроить сортировку динамического списка по дате или коду/номеру **по убыванию**.
Для этого выполним следующие действия:
Дата (или Ссылка) и укажем направление сортировки: По убыванию.В этом случае при открытии формы или создании нового элемента фокус ввода по умолчанию всегда будет находиться на первой строке, которая физически является самой новой. Это кардинально снижает нагрузку на базу данных и упрощает работу пользователя.
Мы проанализировали несколько методов позиционирования. Если требуется классическое поведение с расположением новых данных внизу таблицы, наиболее технологичным и кроссплатформенным решением является Способ №2 с использованием выгрузки исполняемой схемы компоновки данных на сервере. Для простых конфигураций, работающих строго в десктопном режиме, допустимо использование быстрой эмуляции клавиш (Способ №3).