Seite 1 von 1

Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 00:10
von Thomas_
Moin!

In meinem Calc-Dokument wird per Makro aus der Zwischenablage Text eingefügt.
Sofern es sich dabei um reine Zahlen handelt, lassen diese sich ja sehr einfach in Zahlenwerte umwandeln.
In manchen Zellen steht aber als Text ein Konstrukt wie z.B.: "28+350" oder "1025+310".

Wie kann ich Calc dazu bringen, jede Formel, die als Text aus der Zwischenablage in eine Zelle eingefügt wird, tatsächlich zu berechnen?

Edit:
Das Thema hat mir dann doch keine Ruhe gelassen und nachdem ich die Frage hier reingestellt habe, habe ich nochmal ein bisschen rumprobiert.
Die Anforderungen sind folgende:
Der Text aus der Zwischenablage kann folgende Formen annehmen:
a) Positive Zahl
b) negative Zahl
c) 0
d) [LEER]
e) Formel (einfache Addition)

Was auch immer in der Zelle steht, es soll entweder der Wert als positive ganze Zahl ausgegeben werden, oder eben 0.

Um alle Eventualitäten abzudecken bin ich jetzt auf folgende Formel gekommen:

Code: Alles auswählen

=WENN(ABS(G3+1)>1;ABS(G3);WENN(ODER(G3="";G3=0);0;ABS(WERT(LINKS(G3;FINDEN("+";G3))))+ABS(WERT(TEIL(G3;FINDEN("+";G3);15)))))
Im Test hat die Formel auch alles korrekt verarbeitet, nur ist das Ding natürlich viel zu lang.
Die Frage lautet daher, gibt es hierfür eine Lösung, die noch einigermaßen überschaubar ist?

Gruß
Thomas

Re: Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 06:19
von Karolus
Hallo
Kannst du mal den Makrocode posten, evtl. lässt sich da schon etwas tun.

Gruß Karo

Re: Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 11:30
von Thomas_
Hallo Karo,

ich hab nun die Formel zumindest ein bisschen leserlicher gemacht, indem ich die erste Wenn-Abfrage durch ISTZAHL ersetzt habe. Genau das sollte ja das >=1 erledigen.

Was das Makro angeht, das habe ich mit dem Recorder aufgezeichnet, da ich die Sprache zwar einigermaßen lesen kann, aber noch nicht mal im Ansatz schreiben.
Das Makro erledigt folgende Aufgaben:
1.) Zwischenablage (Quelle: HTML) als unformatierten Text in Zelle A2 einfügen.
2.) Gesamten Bereich nach String durchsuchen und durch "" ersetzen.

Der Recorder hat daraus folgendes gezaubert:

Code: Alles auswählen

sub TextErsetzen
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(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$A$2"

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

rem ----------------------------------------------------------------------
dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Format"
args2(0).Value = 1

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

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

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


end sub
Gruß
Thomas

Re: Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 12:50
von Karolus
Hallo
Wenn ich dich richtig verstehe, fügst du ab A2 einen ganzen Bereich aus der Zwischenablage ein, und entfernst im gleichen Abwasch alle "[Safety resources]" Textinhalte ?
Falls ja, dann erweitere dein Makro doch einfach und pragmatisch um einen weiteren 'Suchen und Ersetzen-block' der alles findet was aus mindestens 3 Zeichen aus der Zeichengruppe 0 bis 9 oder '+-*/, ' besteht und stelle den Fundstellen ein =Gleichheitszeichen voran.
Oder in kurz:
[edit]
Versuchs mal mit folgendem, das sollte dann auch gleich die -minuszeichen am Anfang von Zellinhalten entfernen.

Code: Alles auswählen

sub TextErsetzen
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(0) as new com.sun.star.beans.PropertyValue
args1(0).Name = "ToPoint"
args1(0).Value = "$A$2"

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

rem ----------------------------------------------------------------------
dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Format"
args2(0).Value = 1

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


algtype = array( 0, 1, 1)
searchflag = array( 65536 , 71680 ,71680)
searchstring = array("[Safety resources]" , "^[0-9+\-*/, ]{3,}$" , "^-" )
replacestring = array( "", "=&" , "" )

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

dispatcher.executeDispatch(document, ".uno:ExecuteSearch", "", 0, args3())
next i
end sub
[edit_Ende]

Gruß Karo

Re: Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 19:56
von Thomas_
Hallo Karlo,

dein Makro habe ich 1:1 per copy/paste eingesetzt aber es lieferte mir einen Laufzeitfehler in

Code: Alles auswählen

args3(8).Value = algtyp( i )
Sub- oder Function-Prodezur nicht definiert.

Dafür hat mich das ganze aber auf eine andere Idee gebracht.
Die Zellen, in denen ein Additions-Term als Text eingetragen ist, haben die Gemeinsamkeit, dass ihnen allen ein Leerzeichen vorangestellt ist, welches ich fälschlicherweise beim Ersetzen des [Saftey resources]-String stehen gelassen habe.
Dieses Leerzeichen kann ich jetzt für mich nutzen. Ich hab einen Teil deines Codes verwendet um nach diesem Leerzeichen zu suchen und dort ein "=" einzusetzen.

Code: Alles auswählen

args4(10).Value = "^[:space:]+"
args4(11).Name = "SearchItem.ReplaceString"
args4(11).Value = "=&"
Keine Ahnung, ob der Code so richtig ist, da ich mich eben gerade erst in die regular expressions eingelesen habe, aber er funktioniert, mit ein paar unbedeutenden Kolletaralschäden, ziemlich zufriedenstellend. Soviel zum Thema "pragmatisch". ;)

Ich weiß leider nicht, warum dein Marko bei mir nicht läuft. Falls du Zeit und Lust hast, können wir dem Fehler ja noch mal gemeinsam auf die Spur gehen. Sollte sich heraus stellen, dass die Patchwork-Lösung, die ich jetzt zusammengeschustert habe, nicht Stand hält, wäre es beruhigend, auf eine professionelle Lösung zurückgreifen zu können. ;)

Bis hierhin erstmal vielen Dank für deine Unterstützung.

Gruß
Thomas

Re: Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 20:16
von Karolus
Hallo
Bei dem 'algtyp' hat sich ein Druckfehler eingeschlichen das müsste lauten 'algtype' - aber egal ich glaub ich wollte etwas zuviel auf einmal erledigen -das hat hier später auch nur mit diversen Piepsern getan oder auch nicht.

Definier doch noch mal genauer welche Inhalte vorkommen, was im einzelnen damit geschehen soll, und ob in dem Tabellenblatt noch andere Inhalte existieren die unangetastet bleiben sollen.

Wenn du ein oder mehrere Leerzeichen am Anfang der Zelle durch ein =Gleichheitszeichen ersetzen willst reicht auch:

Code: Alles auswählen

args4(10).Value = "^ +"
args4(11).Name = "SearchItem.ReplaceString"
args4(11).Value = "="

Re: Formel steht als Text in Zelle

Verfasst: Fr, 14.05.2010 21:12
von Thomas_
Hallo Karo,

danke für den Hinweis bzgl. des regulären Ausdrucks. Hab es jetzt verbessert.

Hier nochmal eine kurze Beschreibung der Aufgabe die ich lösen möchte:
(Aufs nötigste gekürzt, die Tabelle ist real natürlich deutlich größer)

1.) Quelle ist eine HTML-Tabelle, die in die Zwischenablage kopiert und als unformatierter Text eingefügt wird:
Bild

2.) Die Zahlenwerte sollen direkt unterhalb des eingefügten Textes in einer übersichtlicheren Darstellung ausgegeben werden:
(Hierfür ist unterhalb ausreichend Platz geschaffen)
Bild

Ein klein wenig nervig ist dabei die Zelle "B2" mit dem Textwert "+525-". Dieses Konstukt mit vorne "+" und hinten "-" taucht aber nur in dieser Zelle auf, deshalb ist das leicht lösbar und nicht weiter beachtenswert. Alle anderen Werte lassen sich nach dem Entfernen des Strings "[Saftey resources]" direkt als Zahlenwerte weiterverarbeiten.

Problematisch sind Werte wie der in Zelle "D2". Solche Werte können theoretisch in jeder Zelle auftauchen.
Nachdem der String "[Safety resources]" entfernt ist bleibt " 980 +500" übrig.
Um hieraus einen Zahlenwert zu machen habe ich inzwischen zwei Lösungsvarianten. Entweder die bereits Eingangs erwähnte Totschlagformel mit ABS, WERT, FINDEN, LINKS und TEIL oder einfach das Ersetzen des führenden Leerzeichens mit "=".

Ich hoffe, die Aufgabenstellung ist anhand der Bilder etwas deutlicher geworden.
Ob man sämtliche Eventualitäten für jede Zelle in einem einzigen Makro abdecken kann weiß ich nicht, aber das ist vermutlich auch den Aufwand nicht wert.
Die Kombination von Makro und Formeln, die ich jetzt mit deiner Hilfe geschaffen habe, scheint mir ganz sinnvoll, wenn auch noch nicht vollkommen ausgereift.

Gruß
Thomas