При разработке онлайн-мониторов, журналов обмена или систем фиксации событий часто возникает задача периодического добавления записей в таблицу. Если строки добавляются регламентно или по таймеру (например, каждые 10–15 секунд), стандартная табличная часть платформы не всегда смещает ползунок скроллинга самостоятельно. В результате пользователю приходится вручную прокручивать таблицу вверх, чтобы увидеть последние поступившие данные.
Разберем, почему возникает такое поведение и какими способами можно программно управлять позиционированием курсора и автоматической прокруткой как на обычных, так и на управляемых формах платформы 1С:Предприятие.
Проанализируем механику работы табличных элементов. Табличное поле отображает срез видимых данных и хранит положение курсора — текущую строку. При программной вставке новой записи в коллекцию (в начало или конец) сам графический элемент формы не меняет текущую выделенную позицию, если разработчик не указал это явно в коде. Чтобы таблица сместилась и отобразила добавленный элемент, необходимо активизировать строку программно.
Рассмотрим реализацию для обычного приложения. В обычных формах источником данных визуального элемента выступает объект ТаблицаЗначений, а элементом управления является ТабличноеПоле.
Для гарантированного перемещения фокуса к добавленной строке используется свойство элемента формы ТекущаяСтрока. Посмотрим на пример кода при вставке новой строки в начало таблицы:
// Вставляем новую запись на самую первую позицию таблицы
НоваяСтрока = ТаблицаДанных.Вставить(0);
НоваяСтрока.Наименование = "Новое событие";
НоваяСтрока.Время = ТекущаяДата();
// Перемещаем курсор табличного поля на созданную строку
ЭлементыФормы.ТабличноеПоле.ТекущаяСтрока = НоваяСтрока;
Если таблица теряет фокус ввода или экран обновляется во время фоновых расчетов, одного присвоения строки может быть недостаточно. Разберем шаги для гарантированного обновления интерфейса:
Активизировать(), чтобы окно перевело фокус на визуальный элемент.ТекущаяСтрока ссылку на созданную строку.ОбновитьСтроки() у табличного поля для мгновенной перерисовки содержимого на экране.
ЭлементыФормы.ТабличноеПоле.Активизировать();
ЭлементыФормы.ТабличноеПоле.ТекущаяСтрока = НоваяСтрока;
ЭлементыФормы.ТабличноеПоле.ОбновитьСтроки();
В управляемом интерфейсе логика работы с коллекциями на клиенте отличается: строки реквизитов формы представлены типом ДанныеФормыКоллекция, а обращение к элементам идет через коллекцию Элементы.
Для прокрутки таблицы на управляемой форме свойству ТекущаяСтрока можно присваивать как саму строку, так и ее числовой идентификатор. Выясним, как выглядит правильная последовательность действий на клиенте:
&НаКлиенте
Процедура ДобавитьЗаписьВНачало()
// Вставляем строку в начало коллекции данных формы
НоваяСтрока = Объект.СписокСобытий.Вставить(0);
НоваяСтрока.Описание = "Новое входящее сообщение";
// Активизируем таблицу в интерфейсе
ТекущийЭлемент = Элементы.СписокСобытий;
// Устанавливаем текущую позицию по идентификатору строки
Элементы.СписокСобытий.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецПроцедуры
Важный момент: передача управления через директиву ТекущийЭлемент = Элементы.ИмяТаблицы; критически важна, особенно при работе через веб-клиент. Без предварительной активизации таблицы браузер может не пересчитать виртуальный скроллинг контейнера.
Если в таблице используется иерархическая структура данных (ДеревоЗначений или ДанныеФормыДерево), добавление строки на верхний уровень может привести к тому, что элемент окажется скрыт внутри свернутой родительской ветки.
В этом случае перед установкой фокуса необходимо принудительно раскрыть родительский узел с помощью метода Развернуть() элемента формы:
// Разворачиваем узел дерева перед позиционированием
ИдентификаторРодителя = РодительскийУзел.ПолучитьИдентификатор();
Элементы.ДеревоДанных.Развернуть(ИдентификаторРодителя, Ложь);
// Устанавливаем фокус на дочернюю строку
Элементы.ДеревоДанных.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
Если данные регулярно записываются в базу данных (в регистр сведений или журнал документов), хранить их в ТаблицаЗначений на форме не всегда оптимально. Рассмотрим альтернативный подход — использование объекта ДинамическийСписок.
УПОРЯДОЧИТЬ ПО Дата УБЫВ.Элементы.Список.Обновить() или стандартное оповещение ОповеститьОбИзменении(...). Платформа самостоятельно отобразит актуальную верхушку списка.Постоянный принудительный скроллинг каждые 10–15 секунд создает неудобство для оператора: если пользователь пытается прокрутить список вниз, чтобы изучить архивные записи, таймер будет регулярно сбрасывать ползунок обратно наверх.
Чтобы избежать раздражения пользователей, рекомендуется реализовать тумблер автопрокрутки: