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

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

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

В чем причина такого поведения платформы?

Для понимания корня проблемы разберем разницу между реквизитом формы и элементом интерфейса:

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

Когда табличный документ перезаполняется или очищается методом Очистить(), платформа 1С по умолчанию сохраняет визуальные координаты полосы прокрутки у элемента формы. В результате окно просмотра остается смещенным далеко вниз, за границу новых данных.

Основное решение: переключение фокуса элемента формы

Посмотрим на ошибочный вариант, с которого часто начинают поиск решения:


// Ошибка: обращение к данным реквизита не скроллит визуальный контрол
ТабДок.ТекущаяОбласть = ТабДок.Область("R1C1");

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


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

Тонкости и нюансы практической реализации

Проанализируем важные технические особенности платформы, которые следует учитывать при реализации перехода к началу таблицы.

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

&НаКлиенте
Процедура ПерейтиВНачалоТаблицы()
    
    // Передаем фокус ввода на поле табличного документа
    ТекущийЭлемент = Элементы.ТабДок;
    
    // Позиционируемся на первой ячейке первой строки
    Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область(1, 1, 1, 1);
    
КонецПроцедуры

Учет фиксированных областей таблицы

Разберем ситуацию, когда в отчете включена фиксация строк шапки или левых колонок с помощью свойств ФиксацияСверху или ФиксацияСлева. Если в таком документе принудительно установить курсор на ячейку с координатами (1, 1), фокус окажется внутри зафиксированной неизменяемой шапки.

Если требуется прокрутить именно динамическую рабочую область к первой строке отчета под шапкой, координаты целевой ячейки следует рассчитывать со смещением:


&НаКлиенте
Процедура СпозиционироватьНаПервойСтрокеДанных()
    
    // Определяем первую строку под зафиксированной шапкой
    НомерСтроки = ?(ТабДок.ФиксацияСверху > 0, ТабДок.ФиксацияСверху + 1, 1);
    НомерКолонки = ?(ТабДок.ФиксацияСлева > 0, ТабДок.ФиксацияСлева + 1, 1);
    
    ТекущийЭлемент = Элементы.ТабДок;
    Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область(НомерСтроки, НомерКолонки);
    
КонецПроцедуры

Особенности работы в веб-клиенте

Посмотрим на поведение механизма в браузере. В веб-клиенте отрисовка структуры DOM-элементов таблицы может завершаться с небольшой задержкой относительно клиентского кода 1С. Из-за этого мгновенная установка ТекущаяОбласть может быть проигнорирована браузером, пока он производит финальный расчет геометрии полос прокрутки.

Для надежного позиционирования в веб-клиенте процедуру перехода вызывают асинхронно через однократный обработчик ожидания с минимальной задержкой:


&НаКлиенте
Процедура ПослеФормированияОтчета()
    
    // Подключаем однократный обработчик с интервалом 0.1 секунды
    ПодключитьОбработчикОжидания("УстановитьКурсорВНачало", 0.1, Истина);
    
КонецПроцедуры

&НаКлиенте
Процедура УстановитьКурсорВНачало()
    
    ТекущийЭлемент = Элементы.ТабДок;
    Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область(1, 1);
    
КонецПроцедуры

Такой подход обеспечивает корректное отображение отчета в тонком и веб-клиентах при любых объемах данных и исключает ложные обращения пользователей о том, что отчет сформировался пустым.

← На главную