zamiana kodu VBA na Basic- SOLVED

Dyskusje dotyczące tworzenia makropoleceń, pisania skryptów oraz programowania przy użyciu UNO
stets
Posty: 4
Rejestracja: pt lip 23, 2021 6:41 pm

zamiana kodu VBA na Basic- SOLVED

Post autor: stets »

Witam serdecznie, nie dawno moja firma przeszła na LibreOffice, przenosząc pliki z Excela w jednym napotkałem problem, mianowicie w Excelu miałem zrobione makro które czyści filtry przy zamykaniu formularza.
Wyglądało tak:

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim ws As Worksheet
For Each ws In Worksheets
If ws.AutoFilterMode Then
ws.AutoFilter.ShowAllData
End If
Next ws
End Sub

nie potrafię tego zrobić w Libreoffice Calc. Czy mogę liczyć na Waszą pomoc?

Pozdrawiam
Ostatnio zmieniony czw lip 29, 2021 11:32 pm przez stets, łącznie zmieniany 1 raz.
libreoffice-7.1.4.2
Windows 10 (x64)
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: zamiana kodu VBA na Basic

Post autor: Jermor »

W podręczniku A. Pitonyaka jest następująca informacja:
When a filter is applied to a sheet, it replaces any existing filter for the sheet. Setting an empty filter in a sheet will therefore remove all filters for that sheet.
Czyli: Gdy filtr zostanie zastosowany do arkusza, zastępuje on każdy istniejący filtr w arkuszu. Ustawienie pustego filtra w arkuszu spowoduje zatem usunięcie wszystkich filtrów z tego arkusza.
Pitonyak podaje taki oto sposób:

Kod: Zaznacz cały

Sub RemoveSheetFilter()
Dim oSheet ' Sheet to filter.
Dim oFilterDesc ' Filter descriptor.
oSheet = ThisComponent.getSheets().getByIndex(0)
oFilterDesc = oSheet.createFilterDescriptor(True)
oSheet.filter(oFilterDesc)
End Sub
AOO 4.1.15, LO 24.8.2 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
stets
Posty: 4
Rejestracja: pt lip 23, 2021 6:41 pm

Re: zamiana kodu VBA na Basic

Post autor: stets »

Witam,
nie chodzi o usunięcie filtrów tylko o odfiltrowanie wszystkich użytych filtrów. Przykładowo jeżeli w tabeli w kolumnie A mam listę nazwisk i ktoś użyje filtra ze swoim nazwiskiem to przy zamykaniu skoroszytu powinno odfiltrować zawartość. Jeszcze lepiej byłoby gdyby zawartość została odfiltrowana przy zapisywaniu.
Pozdrawiam
libreoffice-7.1.4.2
Windows 10 (x64)
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: zamiana kodu VBA na Basic

Post autor: Jermor »

Kod podany przez Pitonyaka w odniesieniu do autofiltra w rzeczywistości nie usuwa go. Spowoduje tylko, że zostaną wyświetlone wszystkie rekordy bazy. W ustawieniach filtru pozostaną jednak ostatnio zastosowane opcje, a przyciski przy nazwach pól będą miały oznakowanie, że kryteria są ustawione.
AOO 4.1.15, LO 24.8.2 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
stets
Posty: 4
Rejestracja: pt lip 23, 2021 6:41 pm

Re: zamiana kodu VBA na Basic

Post autor: stets »

Kod działa tylko jest to połowiczne załatwienie sprawy, ponieważ w innych kolumnach co prawda wszystkie rekordy bazy zostają wyświetlone jednak nie widzę możliwości wyboru innych opcji filtra. Czy jest możliwość wyczyszczenie z ustawień filtra ostatnio wybranych opcji?
Pozdrawiam serdecznie
libreoffice-7.1.4.2
Windows 10 (x64)
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: zamiana kodu VBA na Basic

Post autor: Jermor »

Zacznę od tego, że w Calc filtrowanie można zrealizować ad hoc, czyli zażądać filtrowania bez wskazywania obszaru filtrowanych danych albo po zaznaczeniu zakresu (wówczas Calc samoistnie stara się rozpoznać taki zakres). Calc w takich sytuacjach pyta, czy pierwszy wiersz zakresu zawiera nazwy pól.
Inny przypadek to taki, gdy obszarowi zakresu danych zostanie nadana nazwa zakresu bazy danych (polecenie "Dane -> Określ zakres...") i filtrowanie wykonywane jest w takim właśnie obszarze. Podczas definiowana takiego obszaru określa się czy pierwszy wiersz zawiera nagłówki kolumn.
Poszukując rozwiązania problemu resetowania kryteriów wyboru, nie udało mi się znaleźć odpowiedzi na pytanie, jak rozpoznać, że został wykorzystany pierwszy sposób filtrowania. Przeglądając właściwości i metody związane z arkuszem Calc, nie znalazłem także informacji, gdzie znajduje się zapis o obszarze danych takiego sortowania (prawdopodobnie mam za małą wiedzę na ten temat). Dlatego nie potrafię napisać makra o ogólnym działaniu. Jeśli znane są konkretne wymogi w danym projekcie, można łatwiej znaleźć rozwiązanie.
W swoim rozwiązaniu przyjąłem, że każdy obszar danych, który może podlegać filtrowaniu, ma nadaną nazwę zakresu bazy danych i na takim obszarze wykonany jest AutoFiltr.
Napisane makro resetuje kryteria tylko dla takich baz danych.
Problem, jaki napotkałem, to faktyczne usunięcie kryteriów. Metoda przedstawiona przez A. Pitonyaka powoduje wyświetlenie wszystkich wierszy, ale pozostawia włączone ostatnio wykorzystane kryteria.
Poszedłem w kierunku resetowania filtra, czyli wykonania odpowiednika polecenia „Dane → Więcej filtrów → Resetuj filtr”. Ta operacja jest dostępna tylko wówczas, gdy komórka aktywna arkusza znajduje się w obszarze filtrowanych danych.
Dlatego w moim makrze można to wykonać tylko w nazwanych obszarach baz danych. Nie znalazłem jednak sposobu wykonania tego resetu bez wykorzystania obiektu UNO. Dlatego nagrałem tę czynność i włączyłem do makra.
Makro działa następująco:
  • Odnajduje wszystkie obszary nazwanych baz danych, jeżeli takich obszarów nie ma, makro zostaje zakończone.
  • Dla każdego obszaru odnajduje nr arkusza, w którym ten obszar się znajduje oraz położenie pierwszej komórki tego obszaru.
  • Zaznacza pierwszą komórkę obszaru.
  • Wykonuje operację UNO usunięcia filtrów.
Makro można wywołać z parametrem o wartości logicznej TRUE albo FALSE. Wartość FALSE oznacza, że obszar bazy danych pozostanie w takim stanie, w jakim był przy wywołaniu makra. To znaczy, że jeśli obszar bazy danych nie miał przypisanego autofiltra, to po zresetowaniu kryteriów nadal nie będzie miał przypisanego autofiltra. Wartość TRUE, lub pominiecie tego parametru, oznacza, że do każdego obszaru bazy danych, po usunięciu kryteriów zostanie przypisany autofiltr.
Oto napisane makro:

Kod: Zaznacz cały

Sub ClearFiltersCriterias(Optional bAutofilter As Boolean)
REM Procedura czyści wszystkie kryteria filtrowania w znalezionych obszarach nazwanych baz danych.
REM Gdy bAutofilter = False, obszary baz danych zachowają swój bieżący status.
REM Gdy bAutofilter = True, do obszarów baz danych zostanie przypisany AutoFiltr.
REM Autor: Jermor; Polskie Forum LibreOffice (2021) 
If IsMissing(bAutofiler) then Autofilter=True
oDoc = ThisComponent
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
k= oDoc.DatabaseRanges.count
If k=0 Then stop
For i=0 to k-1
	oRange = oDoc.DatabaseRanges.getByIndex(i)
	with oRange.DataArea
		ark= .sheet
		kol= .StartColumn
		wrs= .StartRow
	End With
	oCell=oDoc.Sheets(ark).getCellByPosition(kol,wrs)
	document = ThisComponent.getCurrentController()
	document.select(oCell)
	dispatcher.executeDispatch(document, ".uno:DataFilterRemoveFilter", "", 0, Array())
	If bAutofilter Then oRange.Autofilter=True
Next
End Sub
AOO 4.1.15, LO 24.8.2 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
stets
Posty: 4
Rejestracja: pt lip 23, 2021 6:41 pm

Re: zamiana kodu VBA na Basic

Post autor: stets »

Chciałem kod przypisać do przycisku jednak pojawia się komunikat o błędzie. W jaki sposób mogę uruchomić makro?
Chciałbym Panu wysłać plik z problem który próbuję rozwiązać. Czy mogę prosić o prywatnego emaila?
Załączniki
2021-07-28.png
libreoffice-7.1.4.2
Windows 10 (x64)
Awatar użytkownika
Jermor
Posty: 2361
Rejestracja: sob paź 12, 2013 11:09 am
Kontakt:

Re: zamiana kodu VBA na Basic

Post autor: Jermor »

Błąd występuje, gdy przypisujesz to makro do przycisku, ponieważ makro ma zdefiniowany parametr.
Musisz utworzyć dodatkowy kod, coś w rodzaju:

Kod: Zaznacz cały

Sub Makro
ClearFiltersCriterias(True) 'lub tylko ClearFiltersCriterias(), jeśli tym parametrem ma być True
End Sub
i do przycisku przypisać to nowe makro.
AOO 4.1.15, LO 24.8.2 (x64) na Windows 10 64bit
Ważne!
Jeśli twój problem został rozwiązany, wróć do swojego pierwszego postu, przejdź do edycji i dopisz [SOLVED] w temacie.
Inni, którzy mają podobny problem, będą wiedzieli, że istnieje jego rozwiązanie.
ODPOWIEDZ