Strona główna
» Porady PC
»
Przyspiesz działanie makr Calc, odczytując i zapisując dane w partiach
Przyspiesz działanie makr Calc, odczytując i zapisując dane w partiach
Najbardziej niezawodnym sposobem na przyspieszenie powolnego makra Calc jest zastąpienie powtarzanych odczytów i zapisów komórka po komórce jednym odczytem zakresu, pętlą w pamięci i jednym zapisem zakresu. To eliminuje wywołania między Basiciem a Calc; nie gwarantuje to stałego wzrostu szybkości, ponieważ formuły, formatowanie, rozmiar pliku i logika makr również mogą wpływać na czas wykonania. Poniższy przykład zmienia kolumnę statusu i pokazuje, jak mierzyć zarówno szybkość, jak i poprawność. Szczegóły API zostały sprawdzone pod kątem dokumentacji LibreOffice 26.8 9 października 2026 roku.
Co należy poprawić i jak to zmierzysz?
Uruchom bieżące makro na kopii skoroszytu i zapisz czas jego działania. Użyj nowej kopii z tymi samymi danymi początkowymi dla starych i poprawionych makr lub przywróć dane wejściowe między uruchomieniami; w przeciwnym razie drugie uruchomienie może być mniej pracochłonne. Zachowaj tę samą liczbę wierszy, ustawienia obliczeń i warunki wyjściowe. Powtarzaj każde uruchomienie i porównuj typowy czas, zamiast polegać na jednym nietypowo szybkim uruchomieniu. Sprawdź, czy wynik jest zgodny z oczekiwaną regułą. Makro, które kończy się szybciej, ale zmienia niewłaściwe wiersze, nie jest ulepszeniem.
Funkcja LibreOffice Basic Timerraportuje sekundy od północy; przypisz ją do Longzmiennych, aby uzyskać sekundy w wartościach liczbowych. W przypadku krótkich przebiegów, zapisz wartość początkową i końcową, a następnie je odejmij. Jeśli wartość końcowa jest niższa, przebieg przekroczył północ, więc dodaj 86 400 sekund do różnicy. Timer raportuje pełne sekundy; użyj ScriptForgeusługi Timer, aby uzyskać precyzję milisekundową. Zapoznaj się z dokumentacją Timera LibreOffice Basic i dokumentacją usługi Timer ScriptForge . Otwarcie, zapisanie i ręczna inspekcja skoroszytu powinny odbywać się poza zmierzonym interwałem, chyba że są one częścią rzeczywistego zadania.
Rozpocznij od tego samego ciągłego zakresu danych i warunków skoroszytu dla każdego przebiegu pomiaru czasu.
Dlaczego duże makra Calc działają wolniej?
Pętla, która getCellByPosition()wielokrotnie wywołuje lub odczytuje i zapisuje właściwości poszczególnych komórek, żąda od Calca przejścia przez interfejs Basic-to-Calc dla każdej operacji. W przypadku wielu wierszy i kolumn, te wywołania mogą się sumować, nawet jeśli sama transformacja jest prosta. Pętla po tablicy w pamięci nadal odwiedza każdy wiersz, ale unika oddzielnego wywołania API komórki dla każdej wartości.
Najpierw usuń operacje, które nie wpływają na wynik: unikaj zaznaczania lub aktywowania komórek wewnątrz pętli, nie przeliczaj ani nie formatuj komórki wielokrotnie, gdy wystarczy jedna operacja na zakresie końcowym, i nie przetwarzaj całych kolumn, jeśli potrzebny jest tylko ograniczony blok danych. Te zmiany pomagają wyizolować faktyczne wąskie gardło przed dodaniem kolejnych kontrolek.
Jak przetworzyć zakres jako tablicę?
Użyj prostokątnego zakresu zawierającego tylko wartości, które makro ma zamiar zmienić. Przykład zakłada arkusz o nazwie Data, wiersz nagłówka w wierszu 1 oraz wartości statusu w kolumnie C. Zmień nazwę arkusza i zakres, aby dopasować je do skoroszytu. Interfejs API getDataArray()zwraca zakres jako wiersze zawierające wartości; setDataArray()zapisuje tablicę o tym samym rozmiarze do tego zakresu.
Przed pętlą w pamięci należy odczytać potrzebny zakres prostokątny.
Sub UpdateStatuses
Dim oSheet As Object
Dim oRange As Object
Dim aData As Variant
Dim i As Long
oSheet = ThisComponent.Sheets.getByName("Data")
oRange = oSheet.getCellRangeByName("A2:C10001")
aData = oRange.getDataArray()
For i = LBound(aData) To UBound(aData)
If aData(i)(2) = "pending" Then
aData(i)(2) = "review"
End If
Next i
oRange.setDataArray(aData)
End Sub
Tablica wierszy jest liczona od zera: aData(i)(2)adresuje trzecią kolumnę w każdym wierszu. W tym przypadku jest to kolumna C, ponieważ wybrany zakres zaczyna się od A. Zewnętrzna sekwencja tablicy reprezentuje wiersze, a każda wewnętrzna sekwencja reprezentuje kolumny. Przekazywany zakres setDataArray()musi mieć takie same wymiary jak tablica; niezgodność powoduje błąd. Zobacz dokumentację API LibreOffice XCellRangeData oraz dokumentację tablic LibreOffice ScriptForge .
Zastosuj regułę w pamięci, a następnie zapisz uzupełnioną tablicę w programie Calc w jednym wywołaniu.
Nie dopuszczaj do aktualizacji wyłącznie wartości komórek formuł
getDataArray()Zwraca wartości komórek jako liczby lub ciągi znaków, a nie oryginalny tekst formuły. Jeśli odczytasz zakres zawierający formuły i zapiszesz tę tablicę za pomocą setDataArray(), formuły te mogą zostać zastąpione ich bieżącymi wynikami. Ogranicz metodę wartości-tablicy do komórek wejściowych/wyjściowych, które powinny zawierać wartości. Gdy makro musi zachować lub zmodyfikować formuły, użyj metod formuł-tablicy getFormulaArray()i setFormulaArray(), lub pracuj tylko na zakresie innym niż formuła. Dokumentacja API XCellRangeFormula oddziela interfejs.
Kiedy należy zmienić ustawienia obliczeń lub wyświetlania?
Przetestuj te opcje dopiero po zmierzeniu wersji tablicy. Jeśli przeliczanie formuły stanowi znaczną część przebiegu, możesz wykonać zapytanie isAutomaticCalculationEnabled(), tymczasowo wyłączyć automatyczne obliczanie za pomocą enableAutomaticCalculation(False), a następnie przywrócić pierwotne ustawienie i w razie potrzeby przeliczyć zanieczyszczone komórki. Umieść przywracanie w ścieżce czyszczenia, aby błąd nie pozostawił skoroszytu w trybie obliczeń ręcznych. Nie wyłączaj obliczeń, jeśli makro wymaga nowych wyników formuły między krokami. LibreOffice dokumentuje to calculate()jako przeliczanie zanieczyszczonych komórek; calculateAll()wymusza to pełne przeliczanie i samo w sobie może być kosztowne. Zobacz dokumentację API XCalculatable .
lockControllers()Może zawiesić niektóre powiadomienia używane do aktualizacji wyświetlania, gdy makro zmienia wiele komórek. Połącz każdą blokadę z unlockControllers(), również gdy makro kończy działanie poprzez procedurę obsługi błędów. Zmniejsza to nakład pracy związany z aktualizacją wyświetlania; nie wyłącza obliczeń formuł ani nie przekształca logiki dla poszczególnych komórek w operację zbiorczą. Używaj tego w celu ograniczenia wąskiego gardła związanego z odświeżaniem ekranu, a nie jako zamiennika tablic zakresów. Zobacz dokumentację interfejsu API XModel .
Jak weryfikujesz zmianę i wiesz, kiedy zmienić metodę?
Uruchom zmienione makro na kopii skoroszytu i zapisz jego czas w tych samych warunkach, co w wersji bazowej. Porównaj wiersze, których dotyczy problem, wiersze, których problem nie dotyczy, formuły i sumy kluczowe. Zapisz, zamknij i ponownie otwórz kopię, jeśli przepływ pracy obejmuje zapisywanie; może to ujawnić problemy, które nie zostaną wykryte podczas szybkiej kontroli wizualnej. Stabilna poprawa powinna być widoczna po kolejnych uruchomieniach, podczas gdy kontrole wyników będą nadal pomyślne.
Potwierdź przekształcone wartości i zapisz zmierzone czasy, nie zakładając z góry przyspieszenia.
Jeśli makro nadal poświęca większość czasu na złożone formuły, formatowanie, operacje wejścia/wyjścia plików lub sortowanie, należy oddzielnie profilować te etapy; tablice zakresów jedynie redukują powtarzający się dostęp do komórek. W przypadku bardzo dużych arkuszy pełna tablica w pamięci może również zużywać znaczną ilość pamięci. Przetwarzaj kilka kolumn naraz lub podziel wiersze na bloki pomiarowe, jeśli obciążenie pamięci wzrośnie, jednocześnie sprawdzając, czy każdy blok zaczyna się i kończy na odpowiednich wierszach. Jeśli dane znajdują się już w bazie danych, a zadaniem jest filtrowanie, grupowanie lub aktualizowanie rekordów, przeniesienie tej pracy do zapytania do bazy danych może być lepszym rozwiązaniem niż ładowanie każdego rekordu do Calc.