Calc -> Formular-Steuerelement -> Schaltfläche -> Zuweisung einer Tastenkombination

Hallo *,

kann mir bitte jemand sagen, wie in Calc für das Formular-Steuerelement "Schaltfläche" eine Tastenkombination (hier: Strg-Alt+F) zugewiesen werden kann (oder geht das nur über ein Makro)?

LO: LibreOffice 3.4.4 OOO340m1 (Build:402)
OS: Windows 7 Prof 64 Bit

Gruß

Jochen

Hallo
probiere es mal unter:
Extras->Anpassen->Calc->Tastatur->Kontrollelemente->Grafische Schaltflächen
und dann einer Freien Tastenkombination zuweisen.

Gruß Frieder

Hallo Frieder,

probiere es mal unter:
Extras->Anpassen->Calc->Tastatur->Kontrollelemente->Grafische Schaltflächen
und dann einer Freien Tastenkombination zuweisen.

Ich habe mir mal Deinen Lösungsvorschlag angeschaut. Aber ich komme nicht weiter, zumal ich nicht verstehe, warum die Zuweisung einer Tastenkombination helfen sollte.

Mein Ziel ist folgendes:
ich habe in Calc ein Formular-Steuerelement "Schaltfläche" erstellt (Modus "Formular-Entwurf). Beim Klick auf dieses Steuerelement soll eine Tastenkombination (hier: Strg-Alt+F) ausgeführt werden.

Meine Frage ist:
Ist die Zuweisung einer Tastenkombination über das Kontrollfeld des Formular-Steuerelementes mittels eines Ereignisses wie z.B. "Maus innerhalb" möglich und oder geht das nur über ein Makro?

Gruß

Jochen

Hallo Jochen
Ich habe dich wohl falsch versanden.

Hallo Frieder,

Ich habe mir mal Deinen Lösungsvorschlag angeschaut. Aber ich komme nicht weiter, zumal ich nicht verstehe, warum die Zuweisung einer Tastenkombination helfen sollte.

Mein Ziel ist folgendes:
ich habe in Calc ein Formular-Steuerelement "Schaltfläche" erstellt (Modus "Formular-Entwurf). Beim Klick auf dieses Steuerelement soll eine Tastenkombination (hier: Strg-Alt+F) ausgeführt werden.

Meine Frage ist:
Ist die Zuweisung einer Tastenkombination über das Kontrollfeld des Formular-Steuerelementes mittels eines Ereignisses wie z.B. "Maus innerhalb" möglich und oder geht das nur über ein Makro?

Nein das geht weder durch das zuweisen eines Ereignisses, noch über ein Makro, da es in LO die Funktion Send- Key nicht gibt.
Ich denke du willst wahrscheinlich die "suchen und ersetzen" Funktion aufrufen wollen.
Das könnte eventuell über ein Makro gehen, ich weiß im Moment aber nicht wie.
Tastenkombinationen können aber grundsätzlich nicht über ein Makro ausgeführt werden.

Gruß Frieder

Hallo Frieder,

Nein das geht weder durch das zuweisen eines Ereignisses, noch über ein
Makro

o.k. Das erklärt, warum ich nicht weiter gekommen bin.

da es in LO die Funktion Send- Key nicht gibt.

Ja. Ich weiß.

Ich denke du willst wahrscheinlich die "suchen und ersetzen" Funktion
aufrufen wollen.

Ja.

Das könnte eventuell über ein Makro gehen, ich weiß im Moment aber nicht
wie.

Ja. IMHO habe ich mir das schon gedacht. Aber ich habe die Syntax nicht gefunden. Ich bin aber überzeugt, dass es in der API einen Befehl dafür gibt. Ansonsten könnte ja in der UI kein "Suchen und Ersetzen"-Befehl ausgeführt werden können.

Gruß

Jochen

Hallo Jochen,

Das könnte eventuell über ein Makro gehen, ich weiß im Moment aber nicht
wie.

Ja. IMHO habe ich mir das schon gedacht. Aber ich habe die Syntax nicht
gefunden. Ich bin aber überzeugt, dass es in der API einen Befehl dafür
gibt. Ansonsten könnte ja in der UI kein "Suchen und Ersetzen"-Befehl
ausgeführt werden können.

Ich weiß immer nicht, wie ich die Sachen aus der API richtig einbauen
soll. Aber es gibt da
com.sun.star.util.SearchDescriptor
com.sun.star.util.XSearchDescriptor
com.sun.star.util.XSearchable

und auch einen ReplaceDescriptor

Das geht dann beispielsweise so:

oDoc = ThisComponent
aSuche = oDoc.createReplaceDescriptor
With oSuche
  .setSearchString("Suchbegriff")
  .setReplaceString("Ersatzbegriff")
End With
oDoc.replaceAll(oSuche)

Die Begriffe würde ich über 2 Eingabeelemente zuführen.

Ansosnten kann ich noch die Seite von Michael Dannenhöfer empfehlen:
http://www.starbasicfaq.de/WiekannmaninCalc-Dokumentensuchenunderse.html#Zweig225

Gruß

Robert

Hallo,

Das könnte eventuell über ein Makro gehen, ich weiß im Moment aber nicht
wie.

Ja. IMHO habe ich mir das schon gedacht. Aber ich habe die Syntax nicht
gefunden.

Ich habe jetzt den Dispatcher benutzt. Dadurch ist die Generierung eines funktionierendes Makros möglich (s. weiter unten).

Gruß

Jochen

sub Suchen_Ersetzen()
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dim args1(17) as new com.sun.star.beans.PropertyValue
args1(0).Name = "SearchItem.StyleFamily"
args1(0).Value = 2
args1(1).Name = "SearchItem.CellType"
args1(1).Value = 0
args1(2).Name = "SearchItem.RowDirection"
args1(2).Value = true
args1(3).Name = "SearchItem.AllTables"
args1(3).Value = false
args1(4).Name = "SearchItem.Backward"
args1(4).Value = false
args1(5).Name = "SearchItem.Pattern"
args1(5).Value = false
args1(6).Name = "SearchItem.Content"
args1(6).Value = false
args1(7).Name = "SearchItem.AsianOptions"
args1(7).Value = false
args1(8).Name = "SearchItem.AlgorithmType"
args1(8).Value = 0
args1(9).Name = "SearchItem.SearchFlags"
args1(9).Value = 65536
args1(10).Name = "SearchItem.SearchString"
args1(10).Value = "Heim"
args1(11).Name = "SearchItem.ReplaceString"
args1(11).Value = ""
args1(12).Name = "SearchItem.Locale"
args1(12).Value = 255
args1(13).Name = "SearchItem.ChangedChars"
args1(13).Value = 2
args1(14).Name = "SearchItem.DeletedChars"
args1(14).Value = 2
args1(15).Name = "SearchItem.InsertedChars"
args1(15).Value = 2
args1(16).Name = "SearchItem.TransliterateFlags"
args1(16).Value = 1280
args1(17).Name = "SearchItem.Command"
args1(17).Value = 0

dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args1())

rem ----------------------------------------------------------------------
dim args2(17) as new com.sun.star.beans.PropertyValue
args2(0).Name = "SearchItem.StyleFamily"
args2(0).Value = 2
args2(1).Name = "SearchItem.CellType"
args2(1).Value = 0
args2(2).Name = "SearchItem.RowDirection"
args2(2).Value = true
args2(3).Name = "SearchItem.AllTables"
args2(3).Value = false
args2(4).Name = "SearchItem.Backward"
args2(4).Value = false
args2(5).Name = "SearchItem.Pattern"
args2(5).Value = false
args2(6).Name = "SearchItem.Content"
args2(6).Value = false
args2(7).Name = "SearchItem.AsianOptions"
args2(7).Value = false
args2(8).Name = "SearchItem.AlgorithmType"
args2(8).Value = 0
args2(9).Name = "SearchItem.SearchFlags"
args2(9).Value = 65536
args2(10).Name = "SearchItem.SearchString"
args2(10).Value = "Heim"
args2(11).Name = "SearchItem.ReplaceString"
args2(11).Value = ""
args2(12).Name = "SearchItem.Locale"
args2(12).Value = 255
args2(13).Name = "SearchItem.ChangedChars"
args2(13).Value = 2
args2(14).Name = "SearchItem.DeletedChars"
args2(14).Value = 2
args2(15).Name = "SearchItem.InsertedChars"
args2(15).Value = 2
args2(16).Name = "SearchItem.TransliterateFlags"
args2(16).Value = 1280
args2(17).Name = "SearchItem.Command"
args2(17).Value = 0

dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args2())

end sub

Hallo Jochen,

Hallo Frieder,

Nein das geht weder durch das zuweisen eines Ereignisses, noch über ein
Makro

o.k. Das erklärt, warum ich nicht weiter gekommen bin.

da es in LO die Funktion Send- Key nicht gibt.

Ja. Ich weiß.

Ich denke du willst wahrscheinlich die "suchen und ersetzen" Funktion
aufrufen wollen.

Ja.

Das könnte eventuell über ein Makro gehen, ich weiß im Moment aber nicht
wie.

Ja. IMHO habe ich mir das schon gedacht. Aber ich habe die Syntax nicht
gefunden. Ich bin aber überzeugt, dass es in der API einen Befehl dafür
gibt. Ansonsten könnte ja in der UI kein "Suchen und Ersetzen"-Befehl
ausgeführt werden können.

So ganz verstehe ich deinen Wunsch nicht. Soll das heißen, dass du einen Button einfügen willst, der dasselbe macht wie der Menüpunkt Bearbeiten>Suchen&Ersetzen? Für einen einzigen eingesparten Mausklick?

Über die API kannst du natürlich Suchen und Ersetzen. Dazu benötigst du aber entsprechende Such- und Ersetzendeskriptoren. Und die musst du vom Benutzer abfragen. Du brauchst also einen Dialog. Womit wir wieder beim Menü sind.

Vielleicht kann dir jemand einen passenden Tipp geben, wenn du die Problemstellung beschreibst. Ich kann mir jedenfalls nicht vorstellen, dass es nur um den einen Mausklick geht.

Schöne Grüße
Volker

Hallo Volker,

So ganz verstehe ich deinen Wunsch nicht. Soll das heißen, dass du einen
Button einfügen willst, der dasselbe macht wie der Menüpunkt
Bearbeiten>Suchen&Ersetzen? Für einen einzigen eingesparten Mausklick?

Ja. Warum ist das so ungewöhnlich.
1) Ein prominentes Button wie z.B. "Begriff suchen" innerhalb einer Tabelle ist doch einfacher anzuklicken, als "Bearbeiten -> Suchen & Ersetzen"

2) Ich habe vor, eine InputBox zu generieren, über die der gesuchte Begriff eingegeben werden kann.

3) Und dann eins MsgBox, die abfragt, ob der Suchbegriff gefunden worden ist bzw. ob eine Folgesuche erfolgen soll.

Diese drei Punkte sind es mir Wert, ein Button mit der von mir gewünschten Funktion zu erstellen.

Hast Du einen Beispiel-Code, der nicht über den dispatcher erstellt worden ist?

Ich werde mir jetzt folgenden Code näher anschauen.

Gruß

Jochen

Sub Main
   Dim vDescriptor
   Dim vFound

   oDoc = ThisComponent

   REM Create a descriptor from a searchable document.
   vDescriptor = oDoc.createSearchDescriptor()

   REM Set the text for which to search and other
   REM http://api.openoffice.org/docs/common/ref/com/sun/star/util/SearchDescriptor.html
   With vDescriptor
     .SearchString = "-"
     .SearchWords = false
     .SearchCaseSensitive = false
     .SearchBackwards = false
   End With
   REM Find the first one, or last one as it were!
   vFound = oDoc.findFirst(vDescriptor)
   Do While Not IsNull(vFound)
     if not IsEmpty(vFound.CharFontName) then
       if vFound.CharFontName = "Times New Roman" then
         vFound.CharFontName = "Symbol"
         endif
       endif
     vFound = oDoc.findNext( vFound.getEnd(), vDescriptor)
   Loop

End Sub

Hallo *,

bei dem unten aufgeführten Quellcode besteht folgendes Problem:

"Variable = oDoc.createSearchDescriptor()" ruft einen BASIC-Laufzeitfehler hervor ("Eigenschaft oder Methode nicht gefunden"). In der Tat ist im Xray-Tool keine Eigenschaft oder Methode "SearchDescriptor" aufgeführt.
Allerdings hat Ptonyak in einem Makro (http://www.oooforum.org/forum/viewtopic.phtml?p=65730#65730) genau diesen Muster-Quellcode verwendet.

Kann mal bitte jemand versuchen, diesen Quellcode zu testen.

Gruß

Jochen

Hallo Jochen,

gehe einmal dem folgenden Link nach:

http://www.starbasicfaq.de/WiekannmaninCalc-Dokumentensuchenunderse.html#Zweig225

"Innerhalb eines Calc-Dokumentes muß man vorher festlegen in welchem
Bereich (Zellbereich oder Arbeitsblatt) man ersetzen will. Erst dann
steht der Replacedescriptor zur Verfügung, der ein Suchen und Ersetzen
ermöglicht."

Da ist ein Unterschied zwischen Writer und Calc - allein schon wegen der
Tabellenblätter.

Gruß

Robert

Hallo Robert,

gehe einmal dem folgenden Link nach:
http://www.starbasicfaq.de/WiekannmaninCalc-Dokumentensuchenunderse.html#Zweig225

Ja. Das war ein wichtiger Hinweis. In Calc verhält sich die Suchfunktion anders als in Writer.

Der unten stehende Quellcode führt dazu, dass "Musterwort" gefunden wird und die Schrift in der Zelle ausgetauscht wird, die das Wort "Musterwort" enthält. Dies ist natürlich nicht das Ziel.
Wenn ich die Schleife remme - also von "Do " bis "Loop" passiert nichts, d.h. es fehlt jetzt nur noch, dass die Zelle aktiviert wird.

Hat das jemand einen Tipp?

Gruß

Jochen

sub Suchen_Ersetzen()
  oSheet =ThisComponent.sheets(0)
  Dim vDescriptor
  Dim vFound
  vDescriptor = oSheet.createSearchDescriptor()
   REM Set the text for which to search and other
   REM http://api.openoffice.org/docs/common/ref/com/sun/star/util/SearchDescriptor.html
   With vDescriptor
     .SearchString = "Musterwort"
     msgBox .SearchString
     .SearchWords = false
     .SearchCaseSensitive = false
     .SearchBackwards = false
   End With
   REM Find the first one, or last one as it were!
   vFound = oSheet.findFirst(vDescriptor)
   Do While Not IsNull(vFound)
     if not IsEmpty(vFound.CharFontName) then
       if vFound.CharFontName = "Times New Roman" then
         vFound.CharFontName = "Symbol"
         endif
       endif
     vFound = oSheet.findNext( vFound.getEnd(), vDescriptor)
   Loop
End Sub

Hallo *,

ich bin einen Schritt weitergekommen. Ich kann jetzt die genaue Zell-Adresse bestimmen lassen (vFound.AbsoluteName)
Jetzt fehlt nur noch der Sprung in diese Zelle. hat da jemand einen Tipp für mich?

Gruß

Jochen

sub Suchen_Ersetzen()
  oSheet =ThisComponent.sheets(0)
  Dim vDescriptor
  Dim vFound
  vDescriptor = oSheet.createSearchDescriptor()
  With vDescriptor
     .SearchString = "Heim"
  'msgBox .SearchString
     .SearchWords = false
     .SearchCaseSensitive = false
     .SearchBackwards = false
   End With
   vFound = oSheet.findFirst(vDescriptor)
  msgBox vFound.AbsoluteName 'Zell-Adresse
End Sub

Probiere es doch mal damit:

sub Suchen_Ersetzen()

  oSheet =ThisComponent.sheets(0)
  Dim vDescriptor
  Dim vFound
  vDescriptor = oSheet.createSearchDescriptor()
  With vDescriptor
     .SearchString = "tot"
     'msgBox .SearchString
     .SearchWords = false
     .SearchCaseSensitive = false
     .SearchBackwards = false
   End With
   vFound = oSheet.findFirst(vDescriptor)
     msgBox vFound.AbsoluteName 'Zell-Adresse
     oSheet.getCellRangeByName(vFound.AbsoluteName).String="rrr"

End Sub

Gruß Frieder

Hallo,

ich habe fertig (Quellcode s. unten).
Mittels dieses Makro kann ein bestimmte Begriff (hier: "Suchbegriff") gefunden werden.
Der Suchbegriff kann noch in einer InputBox zuvor abgefragt werden.

Gruß

Jochen

sub Suchen_Ersetzen()
  oSheet =ThisComponent.sheets(0)
  Dim vDescriptor
  Dim vFound
  vDescriptor = oSheet.createSearchDescriptor()
   With vDescriptor
     .SearchString = "Heim"
     .SearchWords = false
     .SearchCaseSensitive = false
     .SearchBackwards = false
   End With
   vFound = oSheet.findFirst(vDescriptor)
  myDoc = thisComponent
  myView = myDoc.CurrentController
   Reihenzahl = vFound.getCellAddress.Row
   Spaltenzahl = vFound.getCellAddress.Column
   mycell = oSheet.getCellByPosition(Spaltenzahl,Reihenzahl)
   myView.Select(mycell)
End Sub

Soll der Benutzer gezwungen sein, vorwärts zu suchen? Soll er gezwungen sein, auf Groß- und Kleinschreibung zu verzichten? Soll er gezwungen sein, auf ganze Zellen zu prüfen? Soll er bei einer weiteren Suche den Suchbegriff wieder neu in eine InputBox eingeben? Und was ist mit regulären Ausdrücken, Ähnlichkeitssuche und Suche nach Vorlagen?

Ich würde mich beschweren, wenn ich so bevormundet würde. Gut, ein Mausklick ist ein weiterer Weg zur Sehnenscheidenentzündung. Aber dagegen wurde ja die Tastenkombination erfunden.

Kopfschüttel.

Tschüss
Volker

Noch ein paar Argumente gegen ein solches Vorhaben?

- Mit einer InfoBox kann nicht zwischen Abbruch und leerer Eingabe unterschieden werden.

- Eine InfoBox verschwindet nach der Eingabe. Der Benutzer kann keine falsche Eingabe überprüfen. Wenn die Suche nicht funktioniert, kann er nicht wissen, woran es lag, denn wenn er um seine Fehleingabe wüsste, hätte er sie nicht gemacht.

- Was geschieht überhaupt nach einer negativen Suche? Dann muss eine Info an den Benutzer erfolgen. Am besten mit der Möglichkeit, direkt die Suche mit anderen Werten zu wiederholen. Der vorher eingegebene Wert sollte gespeichert sein und zur erneuten Suche angeboten werden.

- Das Suchsystem muss vielfach getestet werden. Ein Errorhandler wäre vernünftig.

- Eine Suchfunktion ist nur notwendig bei großen, nicht auf dem Bildschirm direkt überschaubaren Tabellen. Wo soll dann der Auslösebutton sein? Wenn er beim Scrollen verschwindet, verschwindet auch der Ein-Mausklick-Vorteil. Und den Button auf die Zeilen- oder Spaltenköpfe zu legen und ihn mit den Köpfen zu fixieren, erscheint mir sehr unschön.

- Der Benutzer verwendet Calc mit großer Wahrscheinlichkeit auch für andere als für diese Sonderanwendung. Er sollte die Grundfunktionen in Calc kennen, wozu auch die Suchen&Ersetzen-Funktion gehört. Und er wird dieselbe Funktion auch immer an derselben Stelle erwarten.

- usw. usw.

Der Aufwand steht in keinem Verhältnis zum Ergebnis. Zumal eine sichere und millionenfach in der Praxis erprobte Methode gegen eine mit Sicherheit nicht fehlerresistente Methode ersetzt werden soll, die darüber hinaus (zumindest nach meiner Meinung) benutzerunfreundlich ist.

Jochen, ich will dich nur aus einer Arbeit herausreden, die aus meiner Sicht sinnfrei ist. Etwas anderes wäre es, wenn du versuchen würdest, das Suchen&Ersetzen nachzubauen. Das sollte zwar nicht eingesetzt werden, denn es wäre mit Abstand nicht ausreichend getestet und würde viel langsamer ablaufen als das mit C geschriebene Original. Aber du würdest eine Menge lernen über Dialoge, API, Basic usw., das du mit großem Gewinn für andere Zwecke anwenden kannst.

Schöne Grüße
Volker

Hallo Jochen,
ich gebe Volker vollkommen Recht.

Du kannst das ganze auch viele einfacher haben,
wenn der Schalter nicht in einer Tabelle sein soll,
sondern oben in der Symbolleiste.
Extras->Anpassen->Symbolleiste->suchen->Häkchen bei ."Suchen und ersetzen"->OK
Unter Ansicht->Symbolleiste->Häkchen bei "Suche"
Es erscheint ein neues Symbol in der Symbolleiste.

Gruß Frieder