Danke für die Antwort, dann bin ich ja "beruhigt", dass es nur umständlich geht. Nun weiß ich auch, warum
mit einer Exception endet; ich dachte immer, dass ich ein falsches TextRange-Objekt übergeben wollte.
Dann ist meine
Notlösung, die ich in der Zwischenzeit gebastelt habe, im Vergleich auch nicht komplizierter.
Die erste Suche habe ich geändert; ich benutze jetzt das Verfahren von
(Dannenhoefer) 8.3.3 Wie kann man auf Absätze zugreifen? So, wie ich das zweite Textdokument
destDoc erstellt hatte, kann ich sicher sein, dass bei der Enumeration die Bestandteile so aufeinanderfolgen:
- Index 0: Paragraph (unwichtig), Index 1: Paragraph (enthält ggf. den Suchbegriff), Index 2: TextTable 0
- Index 3: Paragraph (unwichtig), Index 4: Paragraph (enthält ggf. den Suchbegriff), Index 5: TextTable 1 usw.
Also durchlaufe ich in einer Schleife alle Elemente des Textes, benutze zusätzlich einen laufenden Index und kann aus dem Index beim Treffer den Index der TextTable berechnen.
Code: Alles auswählen
Function Schueler_suchen_in_Klasse(ByVal Doc As Object, ByVal student As String) As Integer
Enum = Doc.Text.createEnumeration
Dim index As Integer
index = -1
' Schleife über alle Absätze
do While Enum.hasMoreElements
index = index + 1
element = Enum.nextElement
check = hasunointerfaces(element,"com.sun.star.text.XTextTable")
if not check then ' nur Bestandteile prüfen, die nicht TextTable sind
if element.string = student then
'Treffer: der gesuchte Schüler befindet sich im Bestandteil index
index = (index - 1) / 3
'daraus kann der Tables-Index der folgenden TextTable abgeleitet werden
exit do
end if
end if
loop
Schueler_suchen_in_Klasse = index
End Function
Achtung für spätere Nutzer dieser Lösung: Das geht nur, weil die Bestandteile in dieser Reihenfolge erzeugt und gespeichert wurden!
Damit habe ich die gesuchte TextTable (1 Spalte, n Zeilen) und kann nach einem ähnlichen Verfahren das gesuchte Fach suchen; das ist immer der Inhalt des ersten Absatzes in einer Zelle.
Code: Alles auswählen
Function Fach_suchen_in_Klasse(ByVal studentTable As TextTable, ByVal current As String) As Integer
Dim result As Integer
result = -1
objLength = Len(current)
Dim maxRow As Integer
maxRow = studentTable.getRows().getcount()
rem Schleife über alle Zeilen und jeweils die erste (einzige) Spalte
for x1 = 0 to maxRow-1
currentCell = studentTable.getCellByPosition(0, x1)
if( not isNull(currentCell) ) then
' hole den Inhalt als Text und vergleiche den Anfang mit dem Suchbegriff
if( current = Mid(currentCell.getString(), 1, objLength) ) then
result = x1 ' Treffer: es handelt sich um den Inhalt von Zelle(0,x1)
exit for
end if
end if
next x1
Fach_suchen_in_Klasse = result
End Function
Also weiß ich jetzt, welche Zelle ich bearbeiten muss (also die Stelle, an die ich eigentlich mit dem TextCursor gehen wollte). Das geht zunächst durch den Aufruf dieser beiden Funktionen (jeweils mit Fehlerprüfung: index < 0 sagt "nicht gefunden"):
Code: Alles auswählen
rem suche den Schüler in der Zieldatei
index = Schueler_suchen_in_Klasse(destDoc, schueler)
rem suche das Fach
thisTable = destTables.getByIndex(index)
index = Fach_suchen_in_Klasse(thisTable, fach)
rem wenn gefunden, dann bearbeite diese Zelle
found = thisTable.getCellByPosition(0, index)
Auch wenn jede Zelle genau zwei Absätze enthält (den ersten, der das gesuchte Fach enthält, und den zweiten, in den ich Text einfügen will), kann ich nicht direkt darauf zugreifen, sondern muss wieder nach dem o.g. Verfahren per Enumeration vorgehen. Aber das geht analog:
Code: Alles auswählen
rem Umweg über alle Absätze, die in der Zelle enthalten sind
Enum = found.Text.createEnumeration()
do While Enum.hasMoreElements
par = Enum.nextElement()
If par.supportsService("com.sun.star.text.Paragraph") Then
para = par.createEnumeration()
do While para.hasMoreElements()
element = para.nextElement()
elemType = element.TextPortionType
elemInhalt = element.GetString
If elemType = "Text" AND elemInhalt = "" Then
element.setString(content)
end if
loop
end if
loop
Wie gesagt: schön ist etwas anderes. Aber da es keine Paragraph-Collection gibt sowie Absätze und TextTables gesondert behandelt werden müssen, sehe ich keine Vereinfachung (abgesehen davon, dass ich künftig die TextTables per "Schüler"-Name suchen will). Vorläufig funktioniert es; und ich kann meine Arbeit erledigen. Aber wenn jemand noch Verbesserungsvorschläge hat, nehme ich sie dankbar zur Kenntnis!
Gruß Jürgen
@DPunch
Heute zwischen 13 und 18 Uhr war ich mit meiner Notlösung beschäftigt. Deshalb konnte ich deinen Vorschlag nicht mehr berücksichtigen. Aber es sieht so aus, als wenn mich das auch nicht schneller zum Ziel geführt hätte. Jedenfalls hat er mein Verständnis für OOo-Feinheiten verbessert.
Situation: LibO 3.6 auf Win 7 Home Premium (64-bit) mit MySQL (localhost) über JDBC