При формировании или обновлении отчетов в 1С разработчики нередко сталкиваются с неприятным визуальным поведением: если пользователь прокрутил отчет вниз, а затем изменил отбор и переформировал его с меньшим количеством строк, отчет визуально кажется абсолютно пустым. Полоса прокрутки остается на прежней позиции внизу, отображая пустое белое пространство за пределами таблицы данных. Рассмотрим, почему так происходит и как корректно вернуть курсор и прокрутку в самое начало таблицы.
Для понимания корня проблемы разберем разницу между реквизитом формы и элементом интерфейса:
ТабличныйДокумент) представляет собой модель данных. Он хранит структуру ячеек, стили, текст и формулы. Обращение к его свойствам (например, попытка установить ТабДок.ТекущаяОбласть) меняет состояние самих данных, но никак не влияет на графический интерфейс пользователя.ПолеТабличногоДокумента, доступный через коллекцию Элементы) отвечает за отображение данных на экране. Именно этот визуальный контрол хранит координаты прокрутки, положение скроллбаров и текущий видимый фокус.Когда табличный документ перезаполняется или очищается методом Очистить(), платформа 1С по умолчанию сохраняет визуальные координаты полосы прокрутки у элемента формы. В результате окно просмотра остается смещенным далеко вниз, за границу новых данных.
Посмотрим на ошибочный вариант, с которого часто начинают поиск решения:
// Ошибка: обращение к данным реквизита не скроллит визуальный контрол
ТабДок.ТекущаяОбласть = ТабДок.Область("R1C1");
Для того чтобы интерфейс действительно сдвинул полосу прокрутки к первой ячейке, необходимо обратиться к свойству ТекущаяОбласть визуального элемента через коллекцию Элементы. Разберем рабочий пример:
&НаКлиенте
Процедура ОбновитьОтчетПослеВыполнения()
// Выполняем формирование на сервере
СформироватьОтчетНаСервере();
// Сбрасываем позицию отображения в начало таблицы
Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область("R1C1");
КонецПроцедуры
Проанализируем важные технические особенности платформы, которые следует учитывать при реализации перехода к началу таблицы.
Элементы и управление визуальными свойствами контролов существуют строго на клиенте (директива &НаКлиенте). Вызов этого кода внутри серверной процедуры (&НаСервере или &НаСервереБезКонтекста) приведет к ошибке времени выполнения. Позиционирование должно выполняться после возврата управления на клиент."R1C1" рекомендуется использовать числовые координаты строк и колонок — ТабДок.Область(1, 1, 1, 1) или ТабДок.Область(1, 1). Это повышает скорость выполнения, избавляет систему от парсинга строк и предотвращает сбои при различных языковых настройках платформы.
&НаКлиенте
Процедура ПерейтиВНачалоТаблицы()
// Передаем фокус ввода на поле табличного документа
ТекущийЭлемент = Элементы.ТабДок;
// Позиционируемся на первой ячейке первой строки
Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область(1, 1, 1, 1);
КонецПроцедуры
Разберем ситуацию, когда в отчете включена фиксация строк шапки или левых колонок с помощью свойств ФиксацияСверху или ФиксацияСлева. Если в таком документе принудительно установить курсор на ячейку с координатами (1, 1), фокус окажется внутри зафиксированной неизменяемой шапки.
Если требуется прокрутить именно динамическую рабочую область к первой строке отчета под шапкой, координаты целевой ячейки следует рассчитывать со смещением:
&НаКлиенте
Процедура СпозиционироватьНаПервойСтрокеДанных()
// Определяем первую строку под зафиксированной шапкой
НомерСтроки = ?(ТабДок.ФиксацияСверху > 0, ТабДок.ФиксацияСверху + 1, 1);
НомерКолонки = ?(ТабДок.ФиксацияСлева > 0, ТабДок.ФиксацияСлева + 1, 1);
ТекущийЭлемент = Элементы.ТабДок;
Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область(НомерСтроки, НомерКолонки);
КонецПроцедуры
Посмотрим на поведение механизма в браузере. В веб-клиенте отрисовка структуры DOM-элементов таблицы может завершаться с небольшой задержкой относительно клиентского кода 1С. Из-за этого мгновенная установка ТекущаяОбласть может быть проигнорирована браузером, пока он производит финальный расчет геометрии полос прокрутки.
Для надежного позиционирования в веб-клиенте процедуру перехода вызывают асинхронно через однократный обработчик ожидания с минимальной задержкой:
&НаКлиенте
Процедура ПослеФормированияОтчета()
// Подключаем однократный обработчик с интервалом 0.1 секунды
ПодключитьОбработчикОжидания("УстановитьКурсорВНачало", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура УстановитьКурсорВНачало()
ТекущийЭлемент = Элементы.ТабДок;
Элементы.ТабДок.ТекущаяОбласть = ТабДок.Область(1, 1);
КонецПроцедуры
Такой подход обеспечивает корректное отображение отчета в тонком и веб-клиентах при любых объемах данных и исключает ложные обращения пользователей о том, что отчет сформировался пустым.