Автоматическая фильтрация в документе.

Автор OOKapitan, 29 января 2018, 13:31

0 Пользователи и 1 гость просматривают эту тему.

OOKapitan

Цитата: Bigor от 29 января 2018, 13:20По ошибке, скорее всего твой openoffice еще не умеет так хорошо работать с vba как libre
Помогите тогда, пожалуйста, переписать код на starbasic.

OOKapitan

К стати, определять последнюю строку можно на подобие того, как это делается в макросе из этой темы: http://forumooo.ru/index.php/topic,6917.0/msg,44700.html
Только отнимать не 16, а сколько нужно здесь. количество строк после итога всегда одинаково.

JohnSUN

Можешь попробовать такой вариант (должен работать и по AOO)
Sub fltrNonZero
Dim oCurrentController As Variant
Dim oSheet As Variant, oCursor As Variant, oDataArray As Variant, oStatus As Variant
Dim i As Long, m As Long
Dim aRow As Variant, oRows As Variant
oCurrentController = ThisComponent.getCurrentController()
oSheet = oCurrentController.getActiveSheet()
oCursor = oSheet.createCursor()
oCursor.gotoEndOfUsedArea(True)
oRows = oCursor.getRows()
oRows.IsVisible = True
oDataArray = oSheet.getCellRangeByPosition(9, 0, 9, oCursor.getRangeAddress().EndRow).getDataArray()
m = UBound(oDataArray)
oStatus = oCurrentController.getFrame().createStatusIndicator()
oStatus.start("", m)
For i = m To LBound(oDataArray) Step -1
If Trim(oDataArray(i)(0)) = "" Then oRows.getByIndex(i).IsVisible = False
If i Mod 50 = 0 Then oStatus.setValue(m-i)
Next i
oStatus.end()
End Sub
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

economist

Цитата: OOKapitan от 29 января 2018, 13:01Неа, не работает. Сначала ругался на строку отключения обновления экрана. Удалил её. Теперь выдаёт ошибку - см. скрин

OpenOffice Calc поддерживает в 10 раз меньше VBA-комманд, чем LibreOffice. И это отставание растет.
Оснований использовать "отстающий по всем статьям" OpenOffice сейчас просто нет.
Единственное основание иметь OpenOffice рядом с LibreOffice - более правильное поведение при вставке в ODT графики.
 
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

OOKapitan

Цитата: JohnSUN от 29 января 2018, 13:52Можешь попробовать такой вариант (должен работать и по AOO)
Работает. Но:
1) скрывается строка итога. Всё же хотелось бы её видеть (но если сложно реализовать - то не суть)ж
2) а ускорить код как-то можно?

bigor

#20
Вот симбиоз макроса economist и JohnSUN :)
Sub test_filtr
oSheet = ThisComponent.sheets(0)
oSheet.getRows().IsVisible = True
For i = 4 To  2500 'строки как в твоем примере
If oSheet.getCellByPosition(10,i).value< 1 Then
oSheet.getCellByPosition(10,i).getRows().IsVisible = False
EndIf
Next
msgbox "Завершено"
End Sub


работает медленнее первого, как понимаю за счет того что я не знаю как в starbasic запретить перерисовку

p.s. Блокировка перерисовки на скорость практически не повлияла
Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

JohnSUN

#21
Цитата: OOKapitan от 29 января 2018, 16:00
1) скрывается строка итога. Всё же хотелось бы её видеть (но если сложно реализовать - то не суть)ж
2) а ускорить код как-то можно?
2. Можно. Например, так:
Sub qickFltr
Dim oSheet As Variant, oEmpty As Variant, oRows As Variant, i As Long
oSheet = ThisComponent.getCurrentSelection().getSpreadsheet()
oSheet.getRows().IsVisible = True
oEmpty = oSheet.getColumns.getByIndex(9).queryEmptyCells()
For i = oEmpty.getCount()-1 To 0 Step -1
oEmpty.getByIndex(i).getRows().IsVisible = False
Next i
End Sub


1. Просто заранее в строке итогов (и в других, которые не нужно скрывать) в колонке J поставь что-нибудь, хотя бы пробел

Upd. Переписал чуть лаконичнее
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

OOKapitan

Цитата: JohnSUN от 29 января 2018, 14:24Можно. Например, так:
ВАУ, СУПЕР! Отработал мгновенно! Большущее спасибо.

OOKapitan


economist

В OpenOffice на StarBasic можно запретить перерисовку и ускорить код так (еще полезно, если уместно, запретить авторасчеты):

ThisComponent.LockControllers
ThisComponent.enableAutomaticCalculation(False)
 
И в конце кода, при выходе по ошибке -

ThisComponent.UnLockControllers
ThisComponent.enableAutomaticCalculation(True)
 
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

bigor

блокировки уменьшают время выполнение примерно в 2 раза, но все равно вариант JohnSUN быстрее :)
Поддержать разработчиков LibreOffice можно можно тут, а наш форум вот тут

OOKapitan

Цитата: Bigor от 30 января 2018, 08:07но все равно вариант JohnSUN быстрее
Ну я пока на нём и остановился. Большое спасибо.

economist

#27
Если "в лоб" сравнивать одинаковый код SB в OpenOffice|LibreOffice Calc и VBA в Excel - VBA в Excel выполняется быстрее в 2 раза.
Если "в лоб" сравнивать код SB в OpenOffice|LibreOffice Calc и VBA в LibreOffice Calc  - VBA в Calc медленнее на 40% (это заметно)

Путей ускорения макроса от Bigor несколько:

1) переписать цикл с прямого (step +1) на обратный (-1). Это связано с автоподбором высоты строки и разбивкой по страницам - при движении снизу вверх их меньше.  

2) использовать диапазоны Ranges или коллекции, например ячейки с комментариями.

Второе поясню примером. Скажем, надо удалить много конкретных строк (7, 12, 14, 2056, 4565 итд)
- Если удалять в этом же порядке - долго.
- Если удалять снизу вверх - быстрее в 4 раза.
- Если удалять коллекцией (поставив комментарии циклом по диапазону) - быстрее в 8 раз. Для "скрытия" - преимущество будет чуть меньше.

   
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

OOKapitan

Цитата: economist от 31 января 2018, 10:18- Если удалять коллекцией - быстрее в 8 раз
А можно пример кода, пожалуйста.

bigor

Я так понимаю вариант JohnSUN - работа с коллекцией. Он выбирает пустые ячейки и пробегаясь по ним скрывает строки.

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