Via Macro erstellten Button via Macro löschen

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

Moderator: Moderatoren

gneiss
Beiträge: 2
Registriert: Di, 23.08.2022 19:08

Via Macro erstellten Button via Macro löschen

Beitrag von gneiss »

Wie im Betreff angedeutet erzeuge ich via Macro einen oder mehrere Buttons in einem SpreadSheet.
Wenn der User darauf klickt, soll ein bestimmter "Update" im Sheet ausgeführt werden und der Button anschließend wieder "verschwinden"
Der Button ist an die Sub 'BtnFunc' gebunden.
Die Zeile "form.removeByName( model.Name )" löscht aber offenbar nur den Event (danach reagiert der Button nicht mehr auf klick's.
Die "Darstellung" verbleibt im Sheet...
Daher gehe ich davon aus das ich irgendwie auch die beiden anderen Objekte (btn & shap) löschen muss.
Nur habe ich bisher dazu nichts gefunden.
Wo (in welchem Container) sind die ?

Ich habe den Objekten extra eindeutige Namen gegeben (cell.AbsoluteName & "_BTN" & shape.Name = cell.AbsoluteName & "_SHAPE").
Als model.Name zeigt mit Xray "..._BTN" an, ".._SHAE" finde ich jedoch nicht.
Wie komme ich an die ?

Code: Alles auswählen

Public Sub PlaceBtnOnCell( action As String, form As Object, cell As Object, btnTxt As String, Optional backColor As Long, Optional tag As String )  
  Dim btn As Object: btn = ThisComponent.createInstance( "com.sun.star.form.component.CommandButton" )
  Dim shape As Object: shape = ThisComponent.createInstance( "com.sun.star.drawing.ControlShape" )
  Dim script As Object: script = new com.sun.star.script.ScriptEventDescriptor
  
  Dim sheet As Object: sheet = cell.Spreadsheet

  btn.Name = cell.AbsoluteName & "_BTN"
  btn.Label = btnTxt
  btn.FocusOnClick = False
  If IsMissing( tag ) Then tag = cell.AbsoluteName & "_TAG"
  btn.Tag = tag

  shape.Name = cell.AbsoluteName & "_SHAPE"
  shape.Control = btn
  sheet.Drawpage.add( shape )
  shape.Anchor = cell
  shape.Size = GetSizeOfCellRange( cell )
  shape.Position = cell.Position
  shape.SizeProtect = True
  shape.MoveProtect = True
  If IsMissing( backColor ) Then backColor = cell.CellBackColor
  shape.ControlBackground = backColor
  shape.CharColor = cell.CharColor
  shape.CharFontName = cell.CharFontName
  shape.CharHeight = cell.CharHeight
  shape.CharWeight = cell.CharWeight

  script.ListenerType	= "com.sun.star.awt.XActionListener"
  script.EventMethod	= "actionPerformed"
  script.ScriptType		= "StarBasic"
  script.ScriptCode		= action
  
  form.registerScriptEvent( form.count - 1, script )
End Sub

Code: Alles auswählen

Sub BtnFunc( event As Variant )
  RemoveButton( event.Source.Model )
End Sub

Sub RemoveButton( model As Object )
  'Xray model

  Dim form As Object: form = model.Parent
  ' removes: form.registerScriptEvent( form.count - 1, script )
  'Done in PlaceBtnOnCell
  'form.removeByName( model.Name )	

  ' How to:
  ' get/remove shape ?
  ' get/remove btn ?
End Sub
Toxitom
********
Beiträge: 3768
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Re: Via Macro erstellten Button via Macro löschen

Beitrag von Toxitom »

Hey Gneiss,

hmm, so richtig steige ich in deiem Code nicht durch.
Also, Du übergibst der Funktion "PlaceBtnOnCell" ne Menge Parameter, unter anderem ein Formular? (form)??

Dann erzeugst Du eine Objekt (Einen Button) in der Größe einer Zelle und fügst diesen Button der Drawpage zu. So weit so gut.

Dann erzeugst Du noch einen "ActionListener" unf fügst ihm dem Formular zu. Auch ok.

Das das überhaupt funktioniert, ist schon erstaunlich - denn der Button ist m.A. nach gar nicht dem übergebene Formular zugefügt worden.
Hast Du das mal mit xray überprüft, ob der Button überhaupt Teil deiner "form" ist? Also, er wird sicher einem Formular zugeordnet - möglicherweise wurde aber auch ein neues erstellt.

Das Löschen ist dann tatsächlich zweistufig:

Zuerst wird der Button aus dem Formular gelöscht : osheet.drawpage.forms.getByIndex(0).removebyName(model.Name)

Annahme hier: nur ein Formular vorhanden, Index also 0. Du kannst das Formular auch über den Namen bekommen...

Jetzt ist der Button nicht mehr Teil des Formulars (also auch keine Action mehr), als shape aber immer noch Teil der Drawpage!

der kannst Du jetzt entfernen mit z.B. drawpage.getByindex(0).dispose() ...der Index muss halt entsprechend angepasst werden. der bessere Weg wäre im Übrigen die Methode "remove" der Drawpage - also drawpage.remove(xshape as object). Dazu brauchst Du halt das Objekt des Buttons - entweder über die Event-Funktion (event.Source) oder auch über das Formular und dann über den Namen.

Wichtig: Die elemente der Drawpage haben evt. auch Namen, die sind aber nicht identisch mit den Namen der Elemente im Formular!

Da musst Du ein wenig probieren :)

Viele Grüße
Tom
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
F3K Total
********
Beiträge: 3704
Registriert: Mo, 28.02.2011 17:49

CROSSPOSTING: Via Macro erstellten Button via Macro löschen

Beitrag von F3K Total »

Crossposting ohne Referenz ist unhöflich!
gneiss
Beiträge: 2
Registriert: Di, 23.08.2022 19:08

Re: Via Macro erstellten Button via Macro löschen

Beitrag von gneiss »

@F3K Total
Crossposting
Sorry,
Ich bin/war ich der Meinung das Crossposting nur innerhalb eines Forums gilt. Das ich auch woanders Anfrage ist IMHO normal. Wenn man hier eine Referenz will, OK; werde ich beim nächsten Mal drauf achten.
Dann muss ich hier aber auch noch einen Link zu einer Englischen Seite angeben:
https://ask.libreoffice.org/t/calc-dele ... acro/81066

@Toxitom
Das das überhaupt funktioniert, ist schon erstaunlich - denn der Button ist m.A. nach gar nicht dem übergebene Formular zugefügt worden.
Ja, darüber hatte ich mich auch gewundert. Aber das habe ich von irgend einem anderen Beispiel übernommen und das hat funktioniert.
Tatsächlich wird in den Fall einfach das ctrlModel (btn) automatisch zu (irgend)einem Formular hinzugefügt !?!
Und das war wohl auch das (Grund-)Problem.
Wenn ich vor dem "sheet.Drawpage.add" ein "form.insertByIndex( 0, btnModel )" einfüge ist das erst mal OK.
Dann kam noch ein anderes Problem hinzu (das ctrlModel hat nicht den Index 0!).

Beim löschen gilt übrigend auch:
- Das löschen des Buttons aus dem Formular ist nicht notwendig, das wird automatisch erledigt wenn man das ctlShape löscht !

Meine aktuelle Version von PlaceBtnOnCell findet Ihr hier: https://www.libreoffice-forum.de/viewto ... 418#p99487

Und hier die Lösch-Aktion (wird direkt aus dem Event aufgerufen):

Code: Alles auswählen

Public Sub RemoveButtonViaEvent( event As Object )
  Dim model As Object: model = event.Source.Model
  
  Dim drawPage	As Object:	drawPage	= GetDrawPageFromEvent( event )

  Dim i			As Integer
  For i = 0 to drawPage.Count - 1
    Dim shape	As Object:	shape		= DrawPage( i )
    If HasUnoInterfaces( shape, "com.sun.star.drawing.XControlShape" ) Then
      Dim ctrl As Object:	ctrl		= shape.Control
      If Not IsNull( ctrl ) Then
        If EqualUNOobjects( shape.Control, model ) Then
          drawPage.remove( shape )
          Exit For
        End If
      End If
    End If
  Next
End Sub

Public Function GetDrawPageFromEvent( event As Object ) As Object
  GetDrawPageFromEvent = Nothing
  Dim sheetIdx As Integer: sheetIdx = CInt( GetInfoFromExtendedAttributes( event.Source.AccessibleContext.AccessibleParent.ExtendedAttributes, "page-number" ) ) - 1
  GetDrawPageFromEvent = event.Source.Model.Parent.Parent.Parent.Sheets( sheetIdx ).DrawPage
End Function
Antworten