'номер первой видимой строки
Это не работает, поскольку на листе есть закреплённая строка: "Строка заголовков столбцов данных закреплена".
Во всяком случае я не знаю, как этим воспользоваться.
Строки 1-5 отведены для диапазона условий расширенного фильтра с заголовками в строке 1;
строка 7 - итоги по базе данных (SUBTOTAL);
строка 9 - заголовки полей базы данных, эта строка закреплена;
со строки 10 (индекс строки 9) идут сами данные диапазона базы данных.
Строки 6 и 8 оставлены пустыми.
Сработала, как писал выше, такая строка:
ThisComponent.CurrentController.freezeAtPosition(0, 9)
То есть повторное закрепление строки заголовков вызывает прокрутку отфильтрованных данных к началу диапазона.
Но будет ли такой способ оптимальным,
rami?
Диапазон отфильтрованных на скриншоте данных начинается со строки 57. Но так как диапазон данных в ходе предыдущей работы с ним был прокручен к концу, то после наложения нового фильтра (полей вправо много, и условий фильтра не видно) отображена первая строка 1910, а надо, разумеется, прокрутить к началу - строке 57. Если использовать метод 'select', то теряется активная ячейка в диапазоне условий, и это неудобно.
А пользователь, работая с диапазоном условий, может нажать как TAB (переход вправо), так и ENTER (переход вниз). В общем, активизация ячеек в диапазоне базы данных (DatabaseRange) мешает работе пользователя, ибо активной ячейкой в момент срабатывания события является исходная, а к какой вернуться (перейти) - зависит от ранее нажатой клавиши... При этом не хочется усложнять код.
UPD: Некоторые замечания по сравнению с работой расширенного фильтра Excel и о самом LO Calc AdvancedFilterУсловия в диапазоне условий в Excel должны вводится только подряд, и там я использовал .CurrentRegion для уточнения размера диапазона условий перед его передачей методу диапазона .AdvancedFilter. В LO Calc это не имеет значения. Можно вводить условия в любую строку, хоть в 5-ю, то есть не подряд. Странно однако... Зато удобно!
Кроме того, обнаружена ошибка (возможно, баг).
В LO Calc диапазон базы данных (DatabaseRange), в отличие от обычного именованного диапазона, уже имеет свой дескриптор фильтра (FilterDescriptor) и, соответственно, не имеет метода
filter, зато у него имеется метод
refresh. Однако к диапазону базы данных можно обратиться и как к обычному диапазону по имени. Далее создать независимый дескриптор фильтра, связать его с диапазоном условий и передать диапазону данных. В этом случае у диапазона данных будет метод filter. Этот способ рассматривается здесь на форме (
пример от rami для AdvancedFilter).
Другой вариант сложнее: использовать встроенный дескриптор фильтра объекта базы данных (DatabaseRange.FilterDescriptor), примеров нет ни здесь, ни у Питоньяка. Дело усложняется и тем, что некоторые объекты предоставляют
копии своих свойств, и значения этим свойствам нельзя устанавливать напрямую. В результате процесс инициализации свойств усложняется и непонятен.
Вот так работает (зд. имена переменных говорят сами за себя):
oDescriptor = oDBRange.FilterDescriptor
oFields = oCriteriaRange.createFilterDescriptorByObject(oDBRange.ReferredCells).FilterFields
oDescriptor.FilterFields = oFields
А вот так у меня не работает:
oFields = oCriteriaRange.createFilterDescriptorByObject(oDBRange.ReferredCells).FilterFields
oDBRange.FilterDescriptor.FilterFields = oFields
Вот не смог я установить .FilterDescriptor.FilterFields напрямую!? Могу ошибаться. Увы, я не программист и не понимаю смысл этой "концепции".
Однако использование встроенного дескриптора фильтра выглядит логичнее, не правда ли?
В первом случае мы вызываем метод filter, во втором - метод refresh, поскольку у объекта DatabaseRange нет метода filter.
А теперь о баге. В первом случае в диапазоне данных могут отображаться кнопки автофильтра, и он не мешает работе расширенного фильтра. Во втором случае мешает, расширенный фильтр
не работает через вызов метода refresh, но работает-таки через меню расширенного фильтра LO Calc (Данные/Ещё фильтры/Расширенный фильтр...).
Лечится просто:
If oDBRange.AutoFilter Then oDBRange.AutoFilter = False
Вот только локализовать ошибку удалось с большим трудом и не сразу! Ибо Calc "молчит, как партизан".
Два способа обратиться к диапазону базы данных, где "Database" есть имя диапазона:
oDataRange = ThisComponent.CurrentController.ActiveSheet.getCellRangeByName("Database") '<<< oDataRange.filter()
oDBRange = ThisComponent.DatabaseRanges.getByName("Database") '<<< oDBRange.refresh()
При этом заметьте, что в окне "Управление именами" нет имени "Database". А если вы его создадите (продублируете и тут), то у вас не будут работать структурные ссылки (см. ниже).
UPD2: А зачем вообще работать с диапазонами базы данных?Лично мне периодически приходится обрабатывать "сырые" данные, и использование
структурных ссылок (с использованием квадратных скобок, кто знает) при обращении к полям диапазона базы данных позволяет не создавать временных именованных диапазонов. Это очень наглядно и легко. Однако после повторного открытия файла структурные ссылки будет заменены на абсолютные. Но в моём случае это неважно.