Dle postřehů lp. S tím setříděním to bylo při testování o hodně rychlejší, byť tedy nevím jak rychlé to bude o barevnýho. Je ale otázkou, zda-li když bude v mazacím sloupci víc hodnot než jen 0/1 (já zkoušel různě 0,1,2), tak zda to setřídění ve výsledku nebude vadit.
Sub LP_mazani 'setřídí a pak smaže úvodní blok který obsahuje nuly
on local error goto chyba
dim oDoc as object, oSheet as object, oRange as object, data(), i&, iSloupec&, i1&, i2&, aSkryt as variant, sList$, oSheets as object, bAutomatic as boolean, iSheet%, iEndColumn&
'dim cas as date : cas=Now
oDoc=ThisComponent
bAutomatic=oDoc.isAutomaticCalculationEnabled 'jak je to aktuálně s automatickým přepočtem
if bAutomatic then oDoc.enableAutomaticCalculation(false) 'kdyžtak deaktivovat automatický přepočet
oDoc.lockControllers() 'zakáže aktualizaci obrazovky
oDoc.addActionLock() 'zakáže přepočet
rem test existence požadovaného listu
sList="FAKTURA" 'jméno listu
oSheets=oDoc.Sheets 'listy sešitu
if oSheets.hasByName(sList) then 'sešit list obsahuje
oSheet=oSheets.getByName(sList) 'požadovaný list
oSheets.moveByName(sList, 0) 'přesune list na první pozici
iSheet=oSheet.RangeAddress.Sheet 'číslo požadovaného listu
else
msgbox(sList, 48, "List neexistuje")
exit sub
end if
iSloupec=3 'sloupec dle kterého budu mazat (A=0, B=1 atd.)
i1=1 : i2=3000 'testované řádky (první řádek=0, druhý=1 atd.)
aSkryt=0 'hodnota pro kterou skrývám řádek (v případě řetězců třeba "0")
dim oCur as object
oCur=oSheet.createCursor
oCur.goToEndOfUSedArea(false)
iEndColumn=oCur.RangeAddress.EndColumn 'poslední použitý sloupec v listu
oRange=oSheet.getCellRangeByPosition(0, i1, iEndColumn, i2) 'data pro třídění od prvního sloupce do posledního použitého v daných řádcích
rem setřídit obsah dle mazacího sloupce - dostanu tedy všechny řádky s nulou na začátek
dim tridpodle(0) as New com.sun.star.util.SortField
dim serad(0) as New com.sun.star.beans.PropertyValue
tridpodle(0).Field=iSloupec
tridpodle(0).SortAscending=True
'tridpodle(0).FieldType = com.sun.star.util.SortFieldType.NUMERIC 'jde jen o čísla ve sloupci
serad(0).Name="SortFields"
serad(0).Value=tridpodle()
oRange.sort(serad())
oRange=oSheet.getCellRangeByPosition(iSloupec, i1, iSloupec, i2)
data=oRange.getDataArray() 'data z "mazacího" sloupce
rem zjistit počet nul v mazacím sloupci
dim bKonec as boolean
if data(0)(0)=aSkryt then 'je alespoň jeden řádek který budu mazat
dim aRange as new com.sun.star.table.CellRangeAddress 'rozsah pro smazání
with aRange
.Sheet=iSheet
.StartColumn=0
.StartRow=i1
.EndColumn=iEndColumn
end with
if i2-i1>1 then 'mám v rozsahu alespoň dva řádky abych mohl porovnat jejich hodnoty
i=0
do 'spočítat kolik řádků se má smazat
i=i+1 'počet řádků které se budou mazat
bKonec=data(i)(0)=data(i-1)(0) 'když je řádek jiný než předchozí tak skončit
loop while bKonec=true
aRange.EndRow=i1+i-1 'poslední řádek v rozsahu pro smazání
else 'jen jeden řádek pro smazání
aRange.EndRow=i1
end if
oSheet.removeRange(aRange, com.sun.star.sheet.CellDeleteMode.UP) 'smazat řádky
end if
oDoc.removeActionLock() 'povolí přepočet
oDoc.unlockControllers() 'povolí aktualizaci zobrazení
oDoc.enableAutomaticCalculation(bAutomatic) 'původní nastavení automatického přepočtu
konec:
'cas=Now-cas : msgbox Minute(cas) & ":" & Second(cas)
exit sub
chyba:
if NOT isNull(oDlg) then oDlg.dispose()
msgbox("Řádek: " & Erl & chr(13) & "Chyba č. " & Err & chr(13) & Error, 16, "LP_mazani")
End Sub
Ještě jde zjednodušit ta rovnice pro výpočet centrování ukazatele průběhu v předchozí ukázce .positionX=fix(...) ve Function progressBarInit.
with oDlgModel
.positionX=fix( (koef*oSize.Width-iDlgWidth)/2 ) 'pozice X od levého horního rohu okna; šířku dialogu je třeba brát zvětšenou koef, pozici X pak zmenšenou koef
.positionY=fix( (koef*oSize.Height-iDlgHeight)/2 ) 'pozice Y od levého horního rohu okna
end with
Ukázka od lp. s menším počtem proměnných pro zjišťování oblasti v příspěvku #20 funguje. Já věděl že ten algoritmus jsem měl složitěji a že to půjde jednodušeji, avšak nějak mi to tehdy nespínalo a tak jsem nad tím dále neuvažoval a nechal to prostě o něco složitější, hlavně že to fungovalo :-).
Tu konstrukci pro konverzi hodnoty výrazu do boolean proměnné test=data(i)(0)=aSkryt, či v současné ukázce bKonec=data(i)(0)=data(i-1)(0) jsem neznal, to je též dobrý zlepšovák. Objevil jsem to tedy i v Pitonyakově knize - ale jak je to celé v en, tak jsem tu knihu ani zdaleka nepročetl celou.
To oDoc.lockControllers() 'zakáže aktualizaci obrazovky a oDoc.addActionLock() 'zakáže přepočet jsem viděl v nějakém starém tipu ale bez vysvětlení, jen že je to pro zrychlení makra - avšak když jsem to zkoušel na pár mých ukázkách tak mi to nic nezrychlilo a tak jsem myslel, že to je nějaká zastaralá věc a nikdy to nepoužil :-).