Как настроить автоматическую прокрутку таблицы к новой строке в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке онлайн-мониторов, журналов обмена или систем фиксации событий часто возникает задача периодического добавления записей в таблицу. Если строки добавляются регламентно или по таймеру (например, каждые 10–15 секунд), стандартная табличная часть платформы не всегда смещает ползунок скроллинга самостоятельно. В результате пользователю приходится вручную прокручивать таблицу вверх, чтобы увидеть последние поступившие данные.

Разберем, почему возникает такое поведение и какими способами можно программно управлять позиционированием курсора и автоматической прокруткой как на обычных, так и на управляемых формах платформы 1С:Предприятие.

Причина поведения интерфейса

Проанализируем механику работы табличных элементов. Табличное поле отображает срез видимых данных и хранит положение курсора — текущую строку. При программной вставке новой записи в коллекцию (в начало или конец) сам графический элемент формы не меняет текущую выделенную позицию, если разработчик не указал это явно в коде. Чтобы таблица сместилась и отобразила добавленный элемент, необходимо активизировать строку программно.

Решение для обычных форм

Рассмотрим реализацию для обычного приложения. В обычных формах источником данных визуального элемента выступает объект ТаблицаЗначений, а элементом управления является ТабличноеПоле.

Для гарантированного перемещения фокуса к добавленной строке используется свойство элемента формы ТекущаяСтрока. Посмотрим на пример кода при вставке новой строки в начало таблицы:


// Вставляем новую запись на самую первую позицию таблицы
НоваяСтрока = ТаблицаДанных.Вставить(0);
НоваяСтрока.Наименование = "Новое событие";
НоваяСтрока.Время = ТекущаяДата();

// Перемещаем курсор табличного поля на созданную строку
ЭлементыФормы.ТабличноеПоле.ТекущаяСтрока = НоваяСтрока;

Если таблица теряет фокус ввода или экран обновляется во время фоновых расчетов, одного присвоения строки может быть недостаточно. Разберем шаги для гарантированного обновления интерфейса:

  1. Активизируем табличное поле с помощью метода Активизировать(), чтобы окно перевело фокус на визуальный элемент.
  2. Присваиваем свойству ТекущаяСтрока ссылку на созданную строку.
  3. При необходимости вызываем метод ОбновитьСтроки() у табличного поля для мгновенной перерисовки содержимого на экране.

ЭлементыФормы.ТабличноеПоле.Активизировать();
ЭлементыФормы.ТабличноеПоле.ТекущаяСтрока = НоваяСтрока;
ЭлементыФормы.ТабличноеПоле.ОбновитьСтроки();

Решение для управляемых форм

В управляемом интерфейсе логика работы с коллекциями на клиенте отличается: строки реквизитов формы представлены типом ДанныеФормыКоллекция, а обращение к элементам идет через коллекцию Элементы.

Для прокрутки таблицы на управляемой форме свойству ТекущаяСтрока можно присваивать как саму строку, так и ее числовой идентификатор. Выясним, как выглядит правильная последовательность действий на клиенте:


&НаКлиенте
Процедура ДобавитьЗаписьВНачало()
    // Вставляем строку в начало коллекции данных формы
    НоваяСтрока = Объект.СписокСобытий.Вставить(0);
    НоваяСтрока.Описание = "Новое входящее сообщение";
    
    // Активизируем таблицу в интерфейсе
    ТекущийЭлемент = Элементы.СписокСобытий;
    
    // Устанавливаем текущую позицию по идентификатору строки
    Элементы.СписокСобытий.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецПроцедуры

Важный момент: передача управления через директиву ТекущийЭлемент = Элементы.ИмяТаблицы; критически важна, особенно при работе через веб-клиент. Без предварительной активизации таблицы браузер может не пересчитать виртуальный скроллинг контейнера.

Особенности работы с иерархией (Дерево значений)

Если в таблице используется иерархическая структура данных (ДеревоЗначений или ДанныеФормыДерево), добавление строки на верхний уровень может привести к тому, что элемент окажется скрыт внутри свернутой родительской ветки.

В этом случае перед установкой фокуса необходимо принудительно раскрыть родительский узел с помощью метода Развернуть() элемента формы:


// Разворачиваем узел дерева перед позиционированием
ИдентификаторРодителя = РодительскийУзел.ПолучитьИдентификатор();
Элементы.ДеревоДанных.Развернуть(ИдентификаторРодителя, Ложь);

// Устанавливаем фокус на дочернюю строку
Элементы.ДеревоДанных.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();

Альтернативный вариант: использование Динамического списка

Если данные регулярно записываются в базу данных (в регистр сведений или журнал документов), хранить их в ТаблицаЗначений на форме не всегда оптимально. Рассмотрим альтернативный подход — использование объекта ДинамическийСписок.

  1. Настраиваем запрос динамического списка с сортировкой по убыванию: УПОРЯДОЧИТЬ ПО Дата УБЫВ.
  2. При таком подходе любая новая запись автоматически оказывается на первой позиции списка без ручного сдвига элементов массива.
  3. При поступлении новых данных на клиенте достаточно вызвать метод Элементы.Список.Обновить() или стандартное оповещение ОповеститьОбИзменении(...). Платформа самостоятельно отобразит актуальную верхушку списка.

Рекомендации по удобству интерфейса (UX)

Постоянный принудительный скроллинг каждые 10–15 секунд создает неудобство для оператора: если пользователь пытается прокрутить список вниз, чтобы изучить архивные записи, таймер будет регулярно сбрасывать ползунок обратно наверх.

Чтобы избежать раздражения пользователей, рекомендуется реализовать тумблер автопрокрутки:

  1. Создаем на форме булевый реквизит Автопрокрутка и выносим его на панель в виде флажка или кнопки.
  2. Перед выполнением кода позиционирования проверяем состояние реквизита. Если флаг снят — новая строка добавляется в фоновом режиме, а ползунок пользователя остается на месте.
  3. Дополнительно можно проверять, находился ли пользователь на первой строке перед добавлением: если он уже смотрел верхнюю запись, прокручиваем экран, если читал историю внизу — не сбиваем позицию просмотра.
← На главную