Leere Zeilen löschen - Endlosschleife

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

Bergkaffee
*
Beiträge: 14
Registriert: Di, 15.03.2011 13:11

Leere Zeilen löschen - Endlosschleife

Beitrag von Bergkaffee »

Hallo zusammen,

dank googel und vorallem diesem Forum ist es mir als Anfänger nun gelungen mein erstes Makro mit Schleifen zu programmieren was mich rechts stolz macht.
Allerdings bin ich zwischendurch auf ein Problem gestossen, aus dem ich nicht so ganz schlau werden, weil es für mich der Lösungsansatz im Prinzip logisch richtig aussieht. Dennoch entsteht dabei aber eine Endlosschleife. Der Code dazu:

Code: Alles auswählen

Sub LeereZeilen

dim PTab as object
dim ETab as object
dim i as Integer

PTab = thisComponent.Sheets().getByName( "Punkte Startsystem" )		'Punkttabelle auslesen
ETab = thisComponent.Sheets().getByName( "Export" )		'Exporttabelle auslesen
EZImp = PTab.getCellRangeByName("H8").value				'Punktanzahl (=Zeilen und damit lezte Zeile) abfragen
EZeile = EZImp - 1									'Punktanzahl für byPosition aufbereiten
SZeile = 1											'Startzeile definieren

	For i = SZeile to EZeile							'Schleife um leere Zeilen zu löschen
		If ETab.getcellbyPosition(1,i).string = "" Then
		   ETab.removeRange( ETab.getcellbyPosition(1,i).getrangeaddress,_
                    com.sun.star.sheet.CellDeleteMode.ROWS)
		 		If i = EZeile Then
		 			Exit Sub
		 		End If
		   i = i - 1
		End if
	Next

End Sub
Da mir die Anzahl der Leerzeilen bekannt ist (Diese könnte natürlich auch über eine zweite Schleife bestimmt werden) konnte ich das Problem mit folgendem Code umgehen.

Code: Alles auswählen

Sub LeereZeilen

dim PTab as object
dim ETab as object
dim i as Integer

PTab = thisComponent.Sheets().getByName( "Punkte Startsystem" )		'Punkttabelle auslesen
ETab = thisComponent.Sheets().getByName( "Export" )		'Exporttabelle auslesen
EZImp = PTab.getCellRangeByName("H8").value				'Punktanzahl (=Zeilen und damit lezte Zeile) abfragen
EZeile = EZImp - 1									'Punktanzahl für byPosition aufbereiten
LZeile = 0											'Anzahl gelöschte Zeilen zählen
SZeile = 1											'Startzeile definieren

	For i = SZeile to EZeile							'Schleife um Leere Zeilen zu löschen
		If ETab.getcellbyPosition(1,i).string = "" Then
		   ETab.removeRange( ETab.getcellbyPosition(1,i).getrangeaddress,_
                    com.sun.star.sheet.CellDeleteMode.ROWS)
		   LZeile = LZeile + 1
		 		If LZeile = 40 Then
		 			Exit Sub
		 		End If
		   i = i - 1
		End if
	Next

End Sub
Mir ist aber nicht klar warum in der ersten Variante eine Endlosschleife entsteht. Kann mir jemand sagen warum das passiert?
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: Leere Zeilen löschen - Endlosschleife

Beitrag von Karolus »

Hallo
Iteriere rückwärts ( ...step -1 ) über die Zeilen, dann musst du dich in der Schleife nicht auch noch zusätzlich um den Schleifenindex kümmern, und wenn du eh die ganze Zeile löscht benutze gleich 'osheet.getrows.removebyindex( index , anzahl )'

Code: Alles auswählen

Sub LeereZeilen

dim PTab as object
dim ETab as object
dim i as Integer
with ThisComponent.sheets

PTab = .getByName( "Punkte Startsystem" )      'Punkttabelle auslesen
ETab = .getByName( "Export" )      'Exporttabelle auslesen

eRows = Etab.getRows()

EZImp = PTab.getCellRangeByName("H8").value       'Punktanzahl (=Zeilen und damit lezte Zeile) abfragen
EZeile = EZImp - 1       'Punktanzahl für byPosition aufbereiten
SZeile = 1              'Startzeile definieren

For i = EZeile to SZeile  step -1                   'Schleife um leere Zeilen zu löschen
    If ETab.getcellbyPosition(1,i).string = "" Then
        eRows.removebyindex( i. 1)
    End if
Next i

end with

End Sub
!! Ungetestet !!

Gruß Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
DPunch
*******
Beiträge: 1112
Registriert: Mo, 02.11.2009 16:16
Wohnort: Marburg

Re: Leere Zeilen löschen - Endlosschleife

Beitrag von DPunch »

Aloha
Bergkaffee hat geschrieben:Mir ist aber nicht klar warum in der ersten Variante eine Endlosschleife entsteht. Kann mir jemand sagen warum das passiert?
Durch das Löschen der Zellen rutschen alle darunterliegenden Zellen jeweils eins hoch - ab einem gewissen Zeitpunkt rutschen dann vermutlich nur noch leere Zellen nach oben.
Nun hast Du z.B. ermittelt, dass bis zur Zeile 10 Daten vorhanden sind, davon 3 leere Zellen.
Die Zellen werden gelöscht, die Zellen darunter rutschen hoch, am Ende sind die Daten zusammengerückt auf die Zeilen 1-7. Dein Schleifenende liegt immer noch bei 10, Deine Schleife wird ab i=8 aber nur noch leere Zellen vorfinden, dadurch bei jedem Durchlauf wieder um 1 verringert, also auf 7, und dann wieder am Ende der Schleife auf 8 erhöht - usw.
Du müsstest bei Deinem Lösungsweg also auch immer die Abbruchbedingung (EZeile) um 1 verringern.
Aber die Lösung von Karolus ist die deutlich elegantere ;)

Nachtrag:
Folgender Weg sollte schneller sein als das iterieren über alle Zellen:

Code: Alles auswählen

Sub LeereZeilen
dim PTab as object
dim ETab as object
dim i as Integer, EZeile as Integer, SZeile as Integer

thisComponent.lockControllers
PTab = thisComponent.Sheets().getByName( "Tabelle2" )      'Punkttabelle auslesen
ETab = thisComponent.Sheets().getByName( "Tabelle1" )      'Exporttabelle auslesen
EZImp = PTab.getCellRangeByName("H8").value            'Punktanzahl (=Zeilen und damit lezte Zeile) abfragen
EZeile = EZImp - 1                           'Punktanzahl für byPosition aufbereiten
SZeile = 1                                 'Startzeile definieren
If EZeile < 1 Then
	thisComponent.unlockControllers
	Exit Sub
End If

oRange = ETab.getCellRangeByPosition(1,SZeile,1,EZeile)
oEmptyCells = oRange.queryEmptyCells.RangeAddresses

For i = UBound(oEmptyCells) To 0 Step -1
	ETab.removeRange(oEmptyCells(i),com.sun.star.sheet.CellDeleteMode.ROWS)
Next i
thisComponent.unlockControllers
End Sub
Bergkaffee
*
Beiträge: 14
Registriert: Di, 15.03.2011 13:11

Re: Leere Zeilen löschen - Endlosschleife

Beitrag von Bergkaffee »

Vielen Dank! Jetzt funktioniert das ganze wie es soll und ist wesentlich eleganter als mein Versuch.
Antworten