String in einen "Befehl" umwandeln

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

Moderator: Moderatoren

Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

String in einen "Befehl" umwandeln

Beitrag von balu »

Hallo liebe Gemeinde,

Ich habe da mal ein kleineres Problem in Calc.

Mit folgendem Code-Schnipsel kann ich nach der Erstellung eines Diagramm mir diverse Werte des Diagramms auslesen.

Code: Alles auswählen

	Dim rect As new com.sun.star.awt.Rectangle
	myDoc = ThisComponent
	oBlatt2 = myDoc.Sheets.GetByName("Blatt2")
	mycell1 = oBlatt2.getCellRangeByName("B2")
	mycell2 = oBlatt2.getCellRangeByName("B3")
	mycell1.value = rect.X
	mycell2.value = rect.Y
Dadurch bekomme ich die Lageposition für das Diagramm ausgegeben. Also kein Problem.


Wenn ich jedoch das anders versuchen will, dann bekomme ich an gewünschter Stelle (Spalte B) nichts (0) ausgegeben.

Code: Alles auswählen

	Dim rect As new com.sun.star.awt.Rectangle
	Dim Mase(2 to 3) as Variant
	myDoc = ThisComponent
	oBlatt2 = myDoc.Sheets.GetByName("Blatt2")
	Mase(2) = "rect.x"
	Mase(3) = "rect.Y"

	For mi = 2 to 3
		ZelleN = oBlatt2.getCellRangeByName("A" & mi)
		ZelleN.string = Mase(mi)	
		ZelleM = oBlatt2.getCellRangeByName("B" & mi)		
		ZelleM.value = Mase(mi)
	next mi
In Spalte A wird wie gewünscht "rect.x" und dann "rect.y" als Text ausgegeben, jedoch aber in Spalte B nicht der dazugehörige Werte. Klingt für mich jetzt mitlerweile auch schon Logisch, da ja Mase(mi) einen String zurückgibt, aber keinen auszuführenden Befehl (oder wie auch immer das jetzt heißen mag).

Habe auch bei Dannenhöfer mal reingeschaut um den Text umzuwandeln, aber ohne Erfolg.
http://www.starbasicfaq.de/WelcheRuntim ... btes..html

Ich frage jetzt euch, wie wandle ich den String in einen Befehl um?
Versteht ihr was ich Meine?

Ich freue mich auf eure Antworten.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: String in einen "Befehl" umwandeln

Beitrag von Karolus »

Hallo Balu

mase( mi ) enthält das was du an der Stelle reingeschrieben hast -
Im Fall rect.x(ohne Quotes) wird das ein Integer sein, im Fall "rect.x"(mit Quotes) ist das eben der Text zwischen den Anführungszeichen: "rect.x"...

?
Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
Frieder D.
****
Beiträge: 115
Registriert: Di, 10.01.2012 10:51
Kontaktdaten:

Re: String in einen "Befehl" umwandeln

Beitrag von Frieder D. »

Hallo balu
Ich frage jetzt euch, wie wandle ich den String in einen Befehl um?
Gar nicht!! Das Geht nicht.

Du könntest statt "Dim Mase(2 to 3) as Variant" Setzen: "Dim Mase(2 to 3) as new com.sun.star.beans.PropertyValue".

Code: Alles auswählen

Dim rect As new com.sun.star.awt.Rectangle
Dim Mase(2 to 3) as new com.sun.star.beans.PropertyValue
Mase(2).Name= "rect.x"
Mase(2).Value=rect.x
Mase(3).Name= "rect.Y"
Mase(3).Value=rect.Y

   myDoc = ThisComponent
   oBlatt2 = myDoc.Sheets.GetByName("Blatt2")

   For mi = 2 to 3
      ZelleN = oBlatt2.getCellRangeByName("A" & mi)
      ZelleN.string = Mase(mi).Name  
      ZelleM = oBlatt2.getCellRangeByName("B" & mi)      
      ZelleM.value = Mase(mi).Value
   next mi
Gruß Frieder
gogo
*****
Beiträge: 207
Registriert: Mi, 10.11.2010 13:11

Re: String in einen "Befehl" umwandeln

Beitrag von gogo »

Doch, da stehen die richtigen Werte drin.

Ich hab das Makro mal umgewandelt, damit Du weisst was ich meine, und wie's funktionieren kann

Code: Alles auswählen

Dim rect As new com.sun.star.awt.Rectangle
   Dim Mase(2 to 3) as Variant
   myDoc = ThisComponent
   oBlatt2 = myDoc.Sheets.GetByName("Tabelle2")
   Mase(2) = "rect.x"
   Mase(3) = rect.Y
xray(rect)
xray(Mase())
   For mi = 2 to 3
      ZelleN = oBlatt2.getCellRangeByName("A" & mi)
      ZelleN.string = Mase(mi)   
      ZelleM = oBlatt2.getCellRangeByName("B" & mi)      
      ZelleM.value = Mase(mi)
   next mi
ergibt:

Code: Alles auswählen

         A        B

1        rect.x   0
2        '0       0     <=== Beachte das Hochkomma!

rect ist zum Zeitpunkt des Eintragens in die Zellen noch:

Code: Alles auswählen

Height                    long                          0   
Width                     long                          0   
X                         long                          0   
Y                         long                          0   
g
LucidLynx/WinXP LibreOffice v3.3.2 ab 03/12 v3.3.2 & v3.4.5
Frieder D.
****
Beiträge: 115
Registriert: Di, 10.01.2012 10:51
Kontaktdaten:

Re: String in einen "Befehl" umwandeln

Beitrag von Frieder D. »

Hallo gogo
gogo hat geschrieben:Doch, da stehen die richtigen Werte drin.
...
Ich weis nicht, was ich auf so einen Unsinn antworten soll.
Was Dein Makro macht, ist ganz bestimmt nicht das, was blau will.

Gruß Frieder
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: String in einen "Befehl" umwandeln

Beitrag von balu »

Hallo Leute,

erstmal ein Danke schön vorweg für eure Antworten.:)

Ich seh das es doch nicht so einfach ist, wie ich es mir dachte. Liegt aber wohl auch daran das ich nicht weiß wie ich es besser beschreiben und Erklären kann, und ich vielleicht ein zu simples Beispiel gegeben habe. Sorry dafür.
Und deshalb 2 Dateien im Anhang die das besser verdeutlichen können.

In der Datei Werteausgabe-direkt.ods wende ich dieses Verfahren an.

Code: Alles auswählen

	mycell1 = oBlatt2.getCellRangeByName("B2")
	mycell1.value = oDiagram.xAxis.getPosition.X
Und dadurch werden mir die dazugehörigen Werte von z.B. rect.X ausgegeben. Und es geht mir nicht dabei um 2 oder 3 "Eigenschaften" und deren Werte, sondern um einige mehr (über 20). Und ich wollte mir das ersparen das ich für jede "Eigenschaft" im Vorfeld eine einzelne Zelle defeniere.
Und wenn ich schon so gesehen ein Array mit den "Eigenschaften" erstelle, dann dachte ich mir "2 Fliegen mit einer Klappe schlagen." Eine Spalte mit den Eigenschaften-Namen und eine Spalte mit den Eigenschaften-Werten.
Deshalb kam ich auf die Ide mit diesem Code.

Code: Alles auswählen

	Mase(2) = "oDiagram.xAxis.getPosition.X"
	Mase(3) = "oDiagram.xAxis.getPosition.Y"

	For mi = 2 to 3
		ZelleN = oBlatt2.getCellRangeByName("A" & mi)
		ZelleN.string = Mase(mi)	
		ZelleM = oBlatt2.getCellRangeByName("B" & mi)		
		ZelleM.value = Mase(mi)
	next mi
Das habe ich versucht in der Datei Werteausgabe-indirekt_versuch.ods anzuwenden, was aber nur teilweise funktioniert, Eigenschaften-Namen in die Spalte A.


@Karo
Im Fall rect.x(ohne Quotes) wird das ein Integer sein
Na ja, sagen wir es mal so rum. Es ist ein Zahlenwert; mal Integer, mal Double. Also mal mit und mal ohne Nachkommastellen.
im Fall "rect.x"(mit Quotes) ist das eben der Text zwischen den Anführungszeichen: "rect.x"...
Und das würde ich gerne so umwandeln, das es eben kein Text mehr ist, sondern ein Befehl, Anweisung oder wie man das nun nennen kann.


@Fieder
Dein Vorschlag mit new com.sun.star.beans.PropertyValue bringt leider nicht das was ich wollte. Ich bekomme nämlich auch in diesem Falle 0. Vielleicht habe ich ja auch was verkehrt gemacht. Sollte es aber dennoch prinzipiell damit funktionieren, dann wäre mir der Aufwand dafür aber zu hoch. Denn dann kann ich genau so gut bei meinem Ursprünglichem Verfahren bleiben.


@gogo
rect ist zum Zeitpunkt des Eintragens in die Zellen noch:

Code: Alles auswählen

Height                    long                          0   
Width                     long                          0   
X                         long                          0   
Y                         long                          0   
Falsch!
Ich zitiere mich mal selber.
balu hat geschrieben: Mit folgendem Code-Schnipsel kann ich nach der Erstellung eines Diagramm mir diverse Werte des Diagramms auslesen.
rect hat zu dem Zeitpunkt wo ich es mit der Ursprünmglichen Methode aufrufe schon längst einen Wert. Und dieser ist eben nicht Null. Oder wolltest Du mir jetzt damit was anderes sagen?


Ich hoffe das Durch die Dateien jetzt einiges verständlicher wird. Die letzt genannte ist diejenige mit meinem Problem.

Ach ja, Datei!
Datei öffnen, und auf den Grünen Button klicken. Dann wird automatisch auf Blatt2 gewechselt, und die Spalte B wird bei der einen mit verschiedenen Werten gefüllt, und bei der anderen lauter Nullen (0). Und beide geben anschließend eine Meldung aus: "Diagramm ist Fertig."

Und bitte tut mir doch einen Gefallen. Streitet euch nicht! :wink:



Gruß
balu
Dateianhänge
Werteausgabe-indirekt_versuch.ods
(18.27 KiB) 121-mal heruntergeladen
Werteausgabe-direkt.ods
(18.2 KiB) 114-mal heruntergeladen
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: String in einen "Befehl" umwandeln

Beitrag von Karolus »

Hallo Balu

Es wird Zeit das du dich mit Python beschäfstigst, da gibts den sehr nützlichen Datencontainer "Dictionary".
z.B:
# dict definieren:
mase = {'coordinates': 42 , 'Name': 'Part-1-1', 'label': 1}

# die Schlüssel als Liste:
print mase.keys()
→['Name', 'coordinates', 'label']

# die Liste der Werte:
print mase.values()
→['Part-1-1', 42 , 1]

# einen Wert von mase ändern
mase['coordinates'] = 88
print mase
→{'Name': 'Part-1-1', 'coordinates': 88, 'label': 1}


Und ja, einen zweispaltigen Bereich*** aus Calc kann man einfachst mit:
mase = dict( oRange.getDataArray() )
in ein fertiges Dictionary wandeln.
***die Schlüssel aus der ersten Spalte dürfen nicht mehrfach vorkommen.

Gruß Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
gogo
*****
Beiträge: 207
Registriert: Mi, 10.11.2010 13:11

Re: String in einen "Befehl" umwandeln

Beitrag von gogo »

oder einfach so:

Code: Alles auswählen

If ThisComponent.BasicLibraries.hasByName( "Standard" ) Then

sText = thiscomponent.url

   myLib = ThisComponent.BasicLibraries.getByName( "Standard" )

	Makrotext= "sub test" & chr$(10) & "print " & chr$(34) & "Balu's episches Sondermakro ;)" &_
	  chr$(34) & " & chr$(10) & " & chr$(34) & "Diese Datei: " & sText &_
	  chr$(34) & " & chr$(10) & " & chr$(34) & " --- ACHTUNG! ---" &_
	  chr$(34) & " & chr$(10) & " & chr$(34) & "Self-Destruction bei Klick auf <OK> !!!" & chr$(34) &_
	  ":end sub"

	mylib.insertbyname("007Makro", Makrotext)
	call test
    mylib.removeByName("007Makro")
    
end if
Fängst Du damit was an?
g
LucidLynx/WinXP LibreOffice v3.3.2 ab 03/12 v3.3.2 & v3.4.5
DPunch
*******
Beiträge: 1112
Registriert: Mo, 02.11.2009 16:16
Wohnort: Marburg

Re: String in einen "Befehl" umwandeln

Beitrag von DPunch »

Servus

Ohne Weiteres ist das, was Du vorhast, nicht möglich.
Eine Variante wäre die CoreReflection (auf der auch die Ausgabe von xRay basiert), wofür Du allerdings immer das entsprechende Objekt mitliefern müsstest, um die Properties als String auszulesen.
Die andere ist die Herangehensweise, wie gogo sie auch vorschlägt. Dafür müssen die relevanten Objekte allerdings mindestens Modulweit bekannt sein, und dafür wiederum darf die entsprechende Variable nicht neu deklariert werden.

Ich hab Dir mal 'ne funktionierende Beispieldatei für letzteres angehängt, schau mal, ob Du damit was anfangen kannst.
(Änderungen zu Deinem Code sind in den ersten Zeilen vermerkt).
Dateianhänge
Werteausgabe-indirekt_versuch_working_workaround.ods
(20.09 KiB) 160-mal heruntergeladen
Benutzeravatar
balu
********
Beiträge: 3812
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: String in einen "Befehl" umwandeln

Beitrag von balu »

Hallo ihr lieben Helfer!

@Karo
Weißt Du eigentlich das ich Angst vor Schlangen habe, und insbesondere vor Würgern?
Nun, deinen Vorschlag werde ich aber dennoch mal ausprobieren. Alleine des Lernen wegens. Und Gott-sei-Dank ist dieses Thema hier nur für mich, ich brauche also auf andere keine Rücksicht zu nehmen, von wegen Python mit einzubeziehen. Das erleichtert mich.


@gogo
oder einfach so:
Öhm! Damit hab ich mein Verständigungsproblem. War noch nicht so recht dadurch gestiegen was Du mir damit sagen wolltest. Werds aber noch mal versuchen.


@DPunch
Ohne Weiteres ist das, was Du vorhast, nicht möglich.
Du bringst es auf den Punkt! Zumal ich selber auch noch mal mit den unmöglichsten Dingen experimentiert hatte. Unter anderem hatte ich mal ganz blöd gedacht, versuchs mal mit Formula. Aber ich glaub das ich mein Ergebnis nicht großartig kundtun muss, da es wohl sehr offensichtlich ist. Ich weiß das es blöd war, aber ich wollt halt selber mal was ausprobieren.

Es soll jetzt kein Wutausbruch, oder Beleidigung sein. Aber wenn ich deinen zusätzlichen Code sehe, dann fällt mir nur folgender Spruch ein: "Ich seh Rot!"
Man-oh-Man! Das ist ja echt heftig. Damit hatte ich nicht gerechnet. Aber es funktioniert, was natürlich sehr viel Wert ist.

balu hat geschrieben: Ich habe da mal ein kleineres Problem in Calc.
Hatte doch nicht damit gerechnet das das solche Ausmaße annimt :shock: . Ich dachte anfangs das es sich um eine kleinigkeit handeln würde um mein Problem zu beseitigen. Da kann man mal wieder sehen wie schnell man sich vertut.


Eine besondere Frage habe ich da noch an euch.
Habt ihr für eure Lösungsvorschläge sehr lange gebraucht, oder ging das ziemlich leicht über die Finger?
Für mich sehen eure Lösungsvorschläge nach meiner letzten Antwort doch noch sehr Komplex und Kompliziert aus.


Ein besonderes Danke schön an gogo und DPunch wegen den kleinen Schmunzlern. :D

Balu's episches Sondermakro ; )
Self-Destruction bei Klick auf <OK>
sLibName = "DeleteMeIfYouSeeMe"
sModuleName = "IAmUseless"
sFunktionName = "WhatAmIDoingHere"
Auch wenn ich jetzt sehr viel zu Studieren habe, so möchte ich mich noch mal bei euch allen recht Herzlich für eure Bemühungen bedanken.
Danke schön.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D
gogo
*****
Beiträge: 207
Registriert: Mi, 10.11.2010 13:11

Re: String in einen "Befehl" umwandeln

Beitrag von gogo »

gaaaanz kurz geschrieben:

Der wichtige Befehl ist ".insertbyname"

Dieser Befehl generiert in einer Basic-Bibliothek ein Modul (zur Laufzeit!) und füllt es mit Text.

Bibliothek: ThisComponent.BasicLibraries.getByName( "Standard" )
zu generierendes Modul: "IAmNotUseless" (Name ist egal, sollte bloß noch nicht vorhanden sein ;) "Module1" haben wohl die meisten Bibliotheken)
Text: da kommt jetzt Dein Befehl rein, den Du als Text zur Laufzeit generierst z.B.

Dein "Befehl" um den Wert der Property "Y" von "rect" in die Variable "Y_von_Rect" zu bringen lautet:

Code: Alles auswählen

Y_von_Rect = rect.Y
Alles was Du brauchst ist jetzt die Kennzeichnung, dass das ein Befehl sein soll, und die lautet allgemein:

Code: Alles auswählen

Sub Prozedurname
...
End Sub
Statt "Prozedurname" verwenden wir jetzt mal "HoleDenWert". Vereinfacht kann man in Basic auch den ":" als Zeilentrenner verwenden, also dann:

Code: Alles auswählen

Sub HoleDenWert:Y_von_Rect = rect.Y:End Sub
Das was dann noch zu beachten ist, ist dass
"rect.Y" und "Y_von_Rect" dem neuen Modul ("IAmNotUseless") natürlich nicht bekannt sind, da sie ja Objekt bzw. Variable Deines Moduls "Module1" sind.

Wenn Du aber mit

Code: Alles auswählen

Global rect
Global Y_von_Rect
(oder besser "Public" oder einfach "Dim" - jedenfalls ausserhalb einer Prozedur) "rect" und "Y_von_Rect" als bibliotheksweit (Bibliothek: "Standard") verfügbare Variablen definierst, dann kann die Prozedur "HoleDenWert" in Deinem neu erzeugten Modul ("IAmNotUseless") drauf zugreifen.

Das ganze Makro sieht dann in Minimalversion so aus:

Code: Alles auswählen

Public rect
Public Y_von_Rect

Sub DiagrammErstellen
rect = CreateObject("com.sun.star.awt.Rectangle")

ThisComponent.BasicLibraries.getByName( "Standard" ).insertbyname("IAmNotUseless", "Sub HoleDenWert:Y_von_Rect = rect.Y:End Sub")

'Das Modul "IAmNotUseless" wurde erzeugt, in ihm befindet sich die Prozedur HoleDenWert, wir können diese also jetzt ausfuehren:
call HoleDenWert

End Sub
Fragen?
g
LucidLynx/WinXP LibreOffice v3.3.2 ab 03/12 v3.3.2 & v3.4.5
Frieder D.
****
Beiträge: 115
Registriert: Di, 10.01.2012 10:51
Kontaktdaten:

Re: String in einen "Befehl" umwandeln

Beitrag von Frieder D. »

Hallo Ihr alle

Ich habe mir die variante von DPunch angeschaut, und finde sieh sehr interesannt.
Aber es ist definitive mehr Arbeit , als wenn man einen User-Type Verwendet, und außerdem viel Fehleranfälliger.

deshalb habe ich eine Variante Mit User-Type Erstellt, und um nicht alle 22 eingräte von Mase() per Hand ändern zu müssen,
habe ich die Umwandlung per Formel in der Tabelle3 gemacht.
Also : Mase(2) = "rect.x" -> Mase(2).sString = "rect.x" -> Mase(2).vValue = rect.x

Hier Die Datei mit funktionierendem Makro:
(auf Tabelle3 könnt ihr noch sehen, wie ich die Umwandlung gemacht habe.
Werteausgabe-Einfaches_workaround.ods
(22.19 KiB) 144-mal heruntergeladen
Gruß Frieder
gogo
*****
Beiträge: 207
Registriert: Mi, 10.11.2010 13:11

Re: String in einen "Befehl" umwandeln

Beitrag von gogo »

Coole Sache mit dem Usertyp - vermutlich gibt's aber noch mehr Lösungen um Werte auszulesen und Werte wieder zurückzuschreiben ;)
Dateianhänge
Werteausgabe-Einfaches_workaround 2DimArray.ods
(20.51 KiB) 149-mal heruntergeladen
g
LucidLynx/WinXP LibreOffice v3.3.2 ab 03/12 v3.3.2 & v3.4.5
Frieder D.
****
Beiträge: 115
Registriert: Di, 10.01.2012 10:51
Kontaktdaten:

Re: String in einen "Befehl" umwandeln

Beitrag von Frieder D. »

Hallo Gogo

Ja mit einem 2D-Array geht das natürlich genauso.

Gruß Frieder
P.S. Dein Dateianhang existiert nicht mehr.
P.P.S. Jetzt existiert er wieder.
gogo
*****
Beiträge: 207
Registriert: Mi, 10.11.2010 13:11

Re: String in einen "Befehl" umwandeln

Beitrag von gogo »

Frieder D. hat geschrieben:...
P.S. Dein Dateianhang existiert nicht mehr.
P.P.S. Jetzt existiert er wieder.
War kurz weg, weil ich das Diagramm und auf Blatt2 die Inhalte gelöscht hab' - so ist klarer was der Klick auf "Diagramm erstellen" für den User eigentlich macht.

Grüße aus dem eiskalten OÖ
g
LucidLynx/WinXP LibreOffice v3.3.2 ab 03/12 v3.3.2 & v3.4.5
Antworten