[Rätsel gelöst] Calc: URL-Textfeld in Zelle ändern

Antwort erstellen


BBCode ist eingeschaltet
[img] ist ausgeschaltet
[url] ist eingeschaltet
Smileys sind ausgeschaltet

Die letzten Beiträge des Themas
   

Ansicht erweitern Die letzten Beiträge des Themas: [Rätsel gelöst] Calc: URL-Textfeld in Zelle ändern

Re: [Rätsel gelöst] Calc: URL-Textfeld in Zelle ändern

von preklov » Fr, 13.05.2016 11:58

Ich habe den Abschnitt 15.11 in OOME deutsch (https://www.uni-due.de/~abi070/ooo.html) um eine Beschreibung des schreibenden Zugriffs auf Hyperlinks in Calc-Tabellenzellen ergänzt.

Re: [Rätsel gelöst] Calc: URL-Textfeld in Zelle ändern

von preklov » So, 08.05.2016 11:27

Das Rätsel ist wohl gelöst, s. https://bz.apache.org/ooo/show_bug.cgi?id=126950.

Textportions sind readonly (hatte ich leider übersehen) und geben ein SvxUnoTextField-Objekt zurück. Das wiederum ist der View des Modelobjekts ScCellFieldbj. SvxUnoTextField unterstützt "com.sun.star.text.TextField.URL", ScCellFieldObj hingegen nicht.

ScCellFieldObj speichert die benötigten Werte in den Eigenschaften "Representation", "TargetFrame" und "URL". Für die visuelle Darstellung ist dann SvxUnoTextField mit der zusätzlichen Eigenschaft "Format" zuständig.

Somit habe ich eine saubere Lösung für das Ändern eines URL-Felds:

Code: Alles auswählen

Sub WriteCellFieldURL()
  Dim oCell
  Dim oFields, oField
  oCell = ThisComponent.Sheets(0).getCellByPosition(0, 0)
  oFields = oCell.TextFields.createEnumeration()
  Do While oFields.hasMoreElements()
    oField = oFields.nextElement()
    If oField.PropertySetInfo.hasPropertyByName("Representation") Then
      Print oField.Representation & ": " & oField.URL
      oField.Representation = "New file"
      oField.URL = "file:///home/volker/newfile.pdf"
      Print oField.Representation & ": " & oField.URL
      Exit Do
    Else
      Print "Kein URL"
    End If
  Loop
  Print oCell.String
End Sub
Natürlich geht das auch mit

Code: Alles auswählen

 	...
 	oFields = oCell.TextFields
 	For i = 0 To oFields.Count - 1
		oField = oFields.getByIndex(i)
		...

Re: Calc: URL-Textfeld in Zelle ändern

von preklov » Di, 03.05.2016 15:24

Ich vermute, dass das Zell-Objekt an der Stelle als By Value übergeben erkannt wird (und niht -wie Standard- By Reference) ... Deine PRINTs und MRI zeigen an der Stelle, dass die Änderung "angekommen" ist, sie wird aber nicht in die Zelle übernommen (=gespeichert)
Das klingt schlüssig.
Versuche als Ausweichlösung doch mal das Löschen und Neuerstellen des Textfeldes...
Wäre eine Option, aber meine Lösung (s. GetCellFieldURL3) ist m.E. schlicht und direkt. Ist aber eben nur ein Bug-Workaround.

Re: Calc: URL-Textfeld in Zelle ändern

von komma4 » Di, 03.05.2016 12:51

preklov hat geschrieben:Aber wie ist es zu erklären, dass Änderungen nur in dann der Zelle ankommen
Ich vermute, dass das Zell-Objekt an der Stelle als By Value übergeben erkannt wird (und niht -wie Standard- By Reference) ... Deine PRINTs und MRI zeigen an der Stelle, dass die Änderung "angekommen" ist, sie wird aber nicht in die Zelle übernommen (=gespeichert)

Versuche als Ausweichlösung doch mal das Löschen und Neuerstellen des Textfeldes...

Re: Calc: URL-Textfeld in Zelle ändern

von preklov » Di, 03.05.2016 12:23

Ich tippe auf einen Programmfehler (getestet mit LO4.1.6.2)
Danke für die Bestätigung meiner Vermutung. Meine Tests beziehen sich auf Linux (openSUSE 13.2) mit LO 5.0.4.2 (openSUSE-Brand) und AOO 4.1.2 (original Brand). Eigenartig, dass mit der Methode 1, bzw. 3 (Enumeration der Textfelder) der Service URL nicht erkannt wird, aber mit der Methode 2 (Enumeration der Absatzelemente). OK, Bug im Programm.

Aber wie ist es zu erklären, dass Änderungen nur in dann der Zelle ankommen, wenn das Textfeld entweder direkt oder über die Methode 1(3) referenziert wird, aber nicht über die Methode 2? Ein anderer Bug?

Ich werde einen Fehlerreport schreiben und den Abschnitt 15.11 in OOME deutsch (https://www.uni-due.de/~abi070/ooo.html) ergänzen.

Re: Calc: URL-Textfeld in Zelle ändern

von komma4 » Mo, 02.05.2016 13:16

preklov hat geschrieben:Mache ich etwas falsch?
Wahrscheinlich nichts.

Wenn Du die Änderung direkt ausführst [.getTextFields().getByIndex(0)], dann wird sie auch übernommen.

MRI zeigt mir in den FUNCTIONs auch keine Unterstützung des Service .URL an....

Ich tippe auf einen Programmfehler (getestet mit LO4.1.6.2)

[Rätsel gelöst] Calc: URL-Textfeld in Zelle ändern

von preklov » So, 01.05.2016 12:55

Gegeben sei: in einer Calc-Tabellenzelle steckt ein URL-Textfeld mit z.B. dem Text "Alte Datei" und dem Pfad "file:///home/volker/altedatei.pdf". Dieses Feld soll per Makro manipuliert werden, z.B. zu: "Neue Datei" und "file:///home/volker/neuedatei.pdf".
Ich finde 3 Möglichkeiten, aber nur eine davon funktioniert.

Die Prozedur WriteCellFieldURL() holt sich das Feld aus der Funktion GetCellFieldURL...

Mit GetCellFieldURL1 (Enumeration der Textfelder) wird das Feld zwar gefunden, es unterstützt aber offenbar nicht den Service URL. Warum nicht?

Mit GetCellFieldURL2 (Enumeration der Absatzelemente) wird das Feld gefunden und zurückgegeben. Die Änderung der Properties URL und Representation wird ohne Fehler akzeptiert, kommt aber nicht in der Zelle an. Warum nicht?

Erst mit GetCellFieldURL3 (Enumeration der Textfelder und Auslesen der URL-Property mit Fehlerbehandlung) erreiche ich, was ich will. Irgendwie empfinde ich diese Methode aber als unsauber.

Code: Alles auswählen

Function GetCellFieldURL1(oCell)
  Dim oEnum, oField
  Dim sURL As String
  oEnum = oCell.TextFields.createEnumeration()
  Do While oEnum.hasMoreElements()
    oField = oEnum.nextElement()
    If oField.supportsService("com.sun.star.text.TextField.URL") Then
      Print oField.Representation & ": " & oField.URL
      GetCellFieldURL1 = oField
      Exit Function
    End If
  Loop
End Function

Function GetCellFieldURL2(oCell)
  Dim oText, oParEnum, oParElement
  Dim oEnum, oElement, oField
  oParEnum = oCell.getText().createEnumeration()
  Do While oParEnum.hasMoreElements()
    oParElement = oParEnum.nextElement()
    oEnum = oParElement.createEnumeration()
    Do While oEnum.hasMoreElements()
      oElement = oEnum.nextElement()
      If oElement.TextPortionType = "TextField" Then
        oField = oElement.TextField
        If oField.supportsService("com.sun.star.text.TextField.URL") Then
          Print oField.Representation & ": " & oField.URL
          GetCellFieldURL2 = oField
          Exit Function
        End If
      End If
    Loop
  Loop
End Function

Function GetCellFieldURL3(oCell)
  Dim oEnum, oField
  Dim sURL As String
  oEnum = oCell.TextFields.createEnumeration()
  On Local Error Goto NoURL
  Do While oEnum.hasMoreElements()
    oField = oEnum.nextElement()
    sURL = oField.URL
    Print oField.Representation & ": " & oField.URL
    GetCellFieldURL3 = oField
    Exit Function
    NoURL:
  Loop
End Function

Sub WriteCellFieldURL()
  Dim oCell, oField
  oCell = ThisComponent.Sheets(0).getCellByPosition(0, 0)
  oField = GetCellFieldURL1(oCell)
  'oField = GetCellFieldURL2(oCell)
  'oField = GetCellFieldURL3(oCell)
  If Not IsEmpty(oField) Then
    oField.Representation = "Neue Datei"
    oField.URL = "file:///home/volker/neuedatei.pdf"
    Print oField.Representation & ": " & oField.URL
  Else
    Print "Leer"
  End If
End Sub
Mache ich etwas falsch?
Schöne Grüße
Volker

Nach oben