[gelöst] Tabellenzeilen mit spez. Zellinhalt löschen

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

Moderator: Moderatoren

Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

[gelöst] Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Hallo,
komme in eine Löschfunktion mit einem String und will alle Sätze in sheet(0) löschen die diesen String in der Spalte B haben.
Habe das so realisiert:

Code: Alles auswählen

function checkadb(ls_suchnummer as string) as boolean
dim lo_zelle as object
dim lo_zeile as object
dim ls_zellinhalt as string
dim li_i as integer
dim li_del_count as integer

li_del_count = 0
li_i=0

do 
lo_zelle = go_adbsheet.getcellbyposition( 1 , li_i )
ls_zellinhalt = lo_zelle.string
   if ls_zellinhalt = ls_suchnummer then
      lo_zeile=go_adbsheet.getrows
      lo_zeile.removebyindex(li_i,1)
      li_del_count = li_del_count + 1
   else   
      li_i = li_i +1
   end if
loop until ls_zellinhalt = ""

if li_del_count > 0 then
	checkadb = true
end if

end function
Hab das jetzt nicht so leicht aus dem Handgelenk geschüttelt und möchte fragen ob sich der Aufwand für mich rentiert mich nochmal reinzuknien und die Sache eher mit...Suchen ...

Code: Alles auswählen

oZelleOderBereichOderBlatt = ThisComponent.Sheets(0).getCellRangeByName( "B1:C10000" )
oSuchBeschreibung = oZelleOderBereichOderBlatt.createSearchDescriptor()
With oSuchBeschreibung
		.SearchString = ls_suchnummer 
		.SearchBackwards = False
		.....................................................
		
und dann mit "Trefferzeilen auswerten" zu realisieren? Wie würde das ungefähr gehen?

Ich hoffe meine Frage macht Sinn ?
Danke
Zuletzt geändert von Postbyme am So, 15.04.2018 21:45, insgesamt 2-mal geändert.
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Stephan »

und dann mit "Trefferzeilen auswerten" zu realisieren? Wie würde das ungefähr gehen?
Ähnlich wie in http://www.calc-info.de/files/Calc_StarBasic.pdf Seite 28 im Makro "Sub textInZellebereichSuchen", dort musst Du statt der Zeile die die Hintergrundfärbung übernimmt Deinen Code zu Löschen der Zeile einbauen.

Also ungefähr (nicht getestet):

Code: Alles auswählen

'...
ra = oTrefferZelle.RangeAddress
li_i = ra.StartRow
lo_zeile.removebyindex(li_i,1)
'...


Gruß
Stephan
Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Hallo Stephan,
danke für den Link - ich probier es aus.
Siehst Du eine Lösung bzgl. dem anzugebenden Zellbereich weis nicht ob die Tabelle 10000 oder 15000 Zeilen hat. Nicht dass ich hier unnötige Laufzeit verbrate :shock:

Gruss
Winni
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
mikeleb
*******
Beiträge: 1315
Registriert: Fr, 09.12.2011 16:50

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von mikeleb »

Hallo,
da ich gerade so ein ähnliches Problem hatte:

Code: Alles auswählen

Sub textInZellebereichSuchen
	' Variablen deklarieren
	Dim oSuchbereich as Object
	Dim oSuchBeschreibung as Object
	Dim oTrefferBereiche as Object
	Dim oBereichszeilen as Object

	' Zellbereich holen in dem ersetzt werden soll
	spalte=1 'Spalte B
	oSuchbereich =ThisComponent.Sheets(0).columns(spalte)
	
	' SearchDescriptor erzeugen
	oSuchBeschreibung = oSuchbereich.createSearchDescriptor()
	
	' SearchDescriptor konfigurieren
	With oSuchBeschreibung
		.SearchString = "hallo"
		'.SearchBackwards = False
		'.SearchCaseSensitive = True
		'.SearchWords = True
		'.SearchRegularExpression = False
		' .SearchStyles = False
		' .SearchSimilarity = False
	End With
	oTrefferBereiche = oSuchbereich.findall(oSuchBeschreibung)
	for i=oTrefferBereiche.count-1 to 0 step -1
		oBereichszeilen=oTrefferBereiche(i).Rows
		oBereichszeilen.removeByIndex(0,oBereichszeilen.count)
	next	

End Sub
Das Makro sucht alle Zellen mit dem Suchtext "hallo" in Spalte B und löscht anschließend die dazugehörigen Zeilen.
Gruß,
mikeleb
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Stephan »

Siehst Du eine Lösung bzgl. dem anzugebenden Zellbereich weis nicht ob die Tabelle 10000 oder 15000 Zeilen hat.
Die letzte belegte Zelle/Zeile kann bestimmt werden mit:

Code: Alles auswählen

    oDoc = thisComponent
     Sheets=odoc.sheets(i)
     oCellCursor = Sheets.createCursor
     oCellCursor.GotoEndOfUsedArea(False)
     nRow = oCellCursor.getRangeAddress().endRow
     msgbox nRow
siehe:
http://www.starbasicfaq.de/Wiekannmandi ... palte.html


Falls es Dir hingegen auf Geschwindigkeit ankommt ist doch eine Kombination von .findAll() (wie von meinem Vorredner gepostet) und Löschen per Dispatcher mutmaßlich das Schnellste, also in etwa:

Code: Alles auswählen

Sub textInZellebereichSuchen
	' Variablen deklarieren
	Dim oSuchbereich as Object
	Dim oSuchBeschreibung as Object
	Dim oTrefferBereiche as Object
	Dim oBereichszeilen as Object

	' Zellbereich holen in dem ersetzt werden soll
	spalte=1 'Spalte B
	oSuchbereich =ThisComponent.Sheets(0).columns(spalte)
	
	' SearchDescriptor erzeugen
	oSuchBeschreibung = oSuchbereich.createSearchDescriptor()
	
	' SearchDescriptor konfigurieren
	With oSuchBeschreibung
		.SearchString = "hallo"
		'.SearchBackwards = False
		'.SearchCaseSensitive = True
		'.SearchWords = True
		'.SearchRegularExpression = False
		' .SearchStyles = False
		' .SearchSimilarity = False
	End With
	oTrefferBereiche = oSuchbereich.findall(oSuchBeschreibung)
	
	oView = ThisComponent.getCurrentController()
	oView.select(oTrefferBereiche)
	
	
	document   = ThisComponent.CurrentController.Frame
	dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
	dispatcher.executeDispatch(document, ".uno:DeleteRows", "", 0, Array())

End Sub
Ich weiß leider nicht wie man das ohne Dispatcher macht, vielleicht hat da jemand noch einen anderen Code zur Hand.

Gruß
Stephan
Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Bei meinem ersten Programm werden die Zeilen von Schleifendurchlauf zu Schleifendurchlauf nachvollziehbar gelöscht. Bei dem Programm von Mikeleb werden alle Sätze "Zack" auf einmal mit oBereichszeilen.removeByIndex gelöscht. Scheint schnell zu sein - Klasse!
Wahrscheinlich werden da aber auch alle Zeilen durchgeradelt und die Trefferzeilen dann in einem Objekt abgelegt, oder wie muss ich mir das vorstellen?

Mit dem Programmcode von Stephan mit Dispacher komme ich nicht zurecht - da muss ich mir erst mehr Verständnis anlesen.
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Hallo,
tatsächlich im Objekt oTrefferBereiche sind in RangeAddressses und RowDescriptons die Trefferzeilen aufgelistet.
Tut gut wenn man ein bischen ein tieferes Verständnis bekommt. 8)
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Stephan »

Wahrscheinlich werden da aber auch alle Zeilen durchgeradelt und die Trefferzeilen dann in einem Objekt abgelegt, oder wie muss ich mir das vorstellen?
Das Ergebnis von .findAll() ist Ranges-Objekt, welches aus den einzelnen gefundenen Zellranges besteht, das können einzelne Zellobjekte sein oder Range-Objekte mit mehreren zusammenhängenden Zellen.
Mit dem Programmcode von Stephan mit Dispacher komme ich nicht zurecht - da muss ich mir erst mehr Verständnis anlesen.
Der Dispatcher ist ein UnoService der einzelne Befehle (sog. Dispatchbefehle) ausführen kann. Diese Art von Code wird auch erzeugt wenn man in OO Makros aufzeichnet.
Die möglichen Dispatchbefehle findest Du z.B. hier:
https://wiki.openoffice.org/wiki/Framew ... x_Commands

die dispatch-Befehle stehen dort in Spalte 1 und müssen im Code immer um ein vorgestelltes ".uno:" erweitert werden.

Im Übrigen entsprechen auch die Funktionen von Menüeinträgen bestimmten Dispatchbefehlen, was Du siehst wenn Du Dir die KOnfigurationsdateien der Programmenüs ansiehst, weswegen z.B. ein:

Code: Alles auswählen

document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:HelpIndex", "", 0, Array())
die Hilfe von OO anzeigt.

Auch sind einige Dispatchbefehle auf der Kommandozeile zusammen mit soffice.exe nutzbar.


Gruß
Stephan
Stephan
********
Beiträge: 12369
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Stephan »

Postbyme hat geschrieben: So, 08.04.2018 21:34 Hallo,
tatsächlich im Objekt oTrefferBereiche sind in RangeAddressses und RowDescriptons die Trefferzeilen aufgelistet.
Tut gut wenn man ein bischen ein tieferes Verständnis bekommt. 8)
Das Objekt entspricht inhaltlich dem Inhalt der Variable "Selektion" im Makro "Sub mehrfachSelektion" in:
http://www.calc-info.de/files/Calc_StarBasic.pdf

und kann so behandelt werden.

Das Objekt nennt sich allgemein Ranges-Objekt, siehe auch:
http://www.openoffice.org/api/docs/comm ... anges.html


Gruß
Stephan
Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Danke für die Erklärungen Dispatcher ist mir jetzt klar.
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Hallo,
hatte andere Baustelle, jetzt hätte ich zu diesem Thema hier nochmals die Frage wie ich in der for-Schleife durch die Trefferzeilen...

Code: Alles auswählen

oTrefferBereiche = oSuchbereich.findall(oSuchBeschreibung)
	for i=oTrefferBereiche.count-1 to 0 step -1
		oBereichszeilen=oTrefferBereiche(i).Rows
		'if ......weitere Prüfung z.B. Feldwert in Spalte 3   then
		   oBereichszeilen.removeByIndex(0,oBereichszeilen.count)
		'end if   
	next
... noch andere Feldwerte prüfen kann bevor ich mich dann letztendlich für das löschen entscheide.

Danke
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
mikeleb
*******
Beiträge: 1315
Registriert: Fr, 09.12.2011 16:50

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von mikeleb »

Hallo,
in jedem Bereich kannst du per Schleife die Zeilen durchgehen:

Code: Alles auswählen

oTrefferBereiche = oSuchbereich.findall(oSuchBeschreibung)
	for i=oTrefferBereiche.count-1 to 0 step -1
		oBereichszeilen=oTrefferBereiche(i).Rows
		for i=0 to oBereichszeilen.count-1
		'if ......weitere Prüfung z.B. Feldwert in Spalte 3   then
		   oBereichszeilen.removeByIndex(0,1)
		'end if   
		next
	next
Ob es dann aber noch sinnvoll ist (zwecks Perfomance) oder gleich mit beiden Kriterien eine Schleife durch alle Zeilen laufen zu lassen, käme auf einen Test an. Man könnte natürlich auch eine Hilfsspalte generieren, die auf beide Kriterien testet und dann auf diese Hilfsspalte den Searchdescriptor ansetzen.
Gruß,
mikeleb
Postbyme
***
Beiträge: 90
Registriert: Mo, 27.11.2017 18:42

Re: Tabellenzeilen mit spez. Zellinhalt löschen

Beitrag von Postbyme »

Ok. Müsste dann mit den Trefferzeilen nochmals in der Tabelle rumspringen und dann die anderen Kriterien prüfen.
Ja, da wird es dann bald besser sein, mit einer Schleife durch alle Zeilen zu gehen. Das habe ich auch schon fertig.

Danke
-------------------------------------------------------
Windows 11 22H2 /Libre Office 7.3.6.2 (x64)
Antworten