von balu » So, 03.05.2015 13:52
Mahlzeit !
Karolus hat geschrieben:
Ich hätte es ausführlicher schreiben sollen, natürlich kann LO-basic das nicht direkt als String auswerten,
Okay, verstanden.
Karolus hat geschrieben:
natürlich kann Basic aber auch syntaktisch richtigen Quelltext auswerten, auch ohne einen oFunctionAccess.callFunction drumrum zu schachteln.
Das stimmt!
Ergibt 17,9568. Das nur so als Beispiel.
Aber da stehe zumindest ich vor einem Problem (wahrscheinlich stelle ich mich aber momentan einfach nur zu dumm an), denn im Tabellenblatt steht ja in einer Zelle (((0,300+0,260+0,300)*1,740)*12,000) also Dezimaltrenner Komma, anstatt wie im Makro so üblich Dezimaltrenner Punkt und ich weiß momentan nicht den richtigen Weg um einerseits den String so umzuwandeln das er kein String mehr ist und gleichzeitig dabei auch noch Komma durch Punkt zu ersetzen. Wobei Komma durch Punkt ginge ja sehr einfach mit replace.
Code: Alles auswählen
Sub Main
sOld ="(((0,300+0,260+0,300)*1,740)*12,000)"
sGewandelt = replace(sOld, ",", ".")
print sGewandelt
End Sub
Aber damit lässt sich ja nicht weiter rechnen, da es sich noch immer um einen String handelt.
Und das Vorhaben von Stephan ist ja; String einlesen und umwandeln in eine direkt ausführbare Rechenoperation, anschließend das Ergebnis in eine Tabellenblattzelle schreiben.
Nun, ich hatte mir folgendes gedacht.
Mittels replace die Zahlen der Stringformel zu wandeln, wie eben gezeigt.
Die Operatoren zählen, für den nächsten Schritt.
Die Zahlen in ein Array schreiben. Da dies Array ja von vornherein nicht fest steht, muss mittels der gezählten Operatoren plus 1 dies Array erstellt werden. Plus 1 deshalb, weil für eine simple Rechenoperation 2 Zahlen (Werte) und ein Operator benötigt wird. Also bei 5 Zahlen müssen 4 Operatoren vorhanden sein.
Als nächstes alle vorhandenen Zahlen {0.300 bis 12.000} durch einen Platzhalter ersetzen (#).
Jetzt eine "Rechenformel" neu aufbauen. Dazu den gewandelten String mit den Platzhaltern auslesen, und wenn kein Platzhalter gefunden wird das dementsprechende Zeichen aus dem String herausnehmen, und bei einem Platzhalter die dementsprechende Zahl aus dem Array nehmen. Das alles aneinander gereiht sollte dann die neue "Rechenformel" ergeben.
Das geht ja auch so weit alles. Nur das Dumme daran ist, ich habe wieder nur einen String mit dem es sich nicht rechnen lässt. Das hatte ich mir irgendwie anders vorgestellt. Ganze Arbeit umsonst

.
Mit den Zahlen im Array lässt es sich aber durchaus rechnen. Ich brauche dazu nur ein VAL voranstellen, und das würde dann Beispielsweise so aussehen.
Code: Alles auswählen
print val(aGewandelteZahlen(4)) * val(aGewandelteZahlen(5))
Also die 4. mit der 5. Zahl aus dem Array aGewandelteZahlen multiplizieren.
Na ja, auch wenn ich nicht wirklich weiter gekommen bin als erhofft, so hänge ich den momentanigen Code (der ja auch nur ein Testcode ist) jetzt mal hier rein. Vielleicht lässt sich ja darauf irgendwie aufbauen, und wenn nicht, auch egal.
Code: Alles auswählen
Dim aOperatorenArray (3)
Dim sNeuerString as string
Dim iRechnen as Integer, iGefundeneOperatoren as Integer
Sub Main
aOperatorenArray(0) = "*" : aOperatorenArray(1) = "+" : aOperatorenArray(2) = "-" : aOperatorenArray(3) = "/"
sKlammer = "(((0,300+0,260+0,300)*1,740)*12,000)"
sNeuerString = replace(sKlammer, ",", ".")
iRechnen = len(sNeuerString)
ZaehlOperatoren '*************************************************sprung zur Sub ZaehlOperatoren
Dim aGewandelteZahlen (1 to iGefundeneOperatoren+1)
iVari = ""
iGZ = 0
sTempString = sNeuerString
for i = 1 to iRechnen
zCodeAuslesen = asc(mid(sNeuerString, i, 1))
sZeichen = mid(sNeuerString, i, 1)
if zCodeAuslesen >= 48 and zCodeAuslesen <= 57 or zCodeAuslesen = 46 then
iVari = iVari & sZeichen
else
if i = iRechnen then
iGZ = iGZ +1
aGewandelteZahlen(iGZ) = iVari
sTempErsetz = replace(sTempString, aGewandelteZahlen(iGZ), "#", 1, 1)
sTempString = sTempErsetz
REM print "temp = " & sTempString
iVari = ""
end if
end if
if sZeichen ="*" OR sZeichen ="+" OR sZeichen ="-" OR sZeichen ="/" then
iGZ = iGZ +1
aGewandelteZahlen(iGZ) = iVari
sTempErsetz = replace(sTempString, aGewandelteZahlen(iGZ), "#", 1, 1)
sTempString = sTempErsetz
REM print "temp = " & sTempString
iVari = ""
end if
next i
REM print "tempEnde = " & sTempString
REM print "Länge sTempString = " & len(sTempString)
REM print "Rechnen = " & val(aGewandelteZahlen(4)) * val(aGewandelteZahlen(5))
'------------------------------------------------------------------------------ab hier die neue "Rechenformel"
w = len(sTempString)
dim tmpKette as variant
iA = 1
for m = 1 to w
if mid(sTempString, m, 1)<> "#" then
tmpKette = tmpKette + mid(sTempString, m, 1)
else
if mid(sTempString, m, 1) = "#" then
tmpKette = tmpKette + aGewandelteZahlen(iA)
iA = iA +1
end if
end if
next m
print "tmpKette = " & tmpKette
End Sub
'
'***********************************************************************************************************
'
Sub ZaehlOperatoren
iGefundeneOperatoren = 0
for iZO = 1 to iRechnen
zCodeAuslesenZO = asc(mid(sNeuerString, iZO, 1))
sZeichenZO = mid(sNeuerString, iZO, 1)
for iO = 0 to 3
If sZeichenZO = aOperatorenArray(iO) then
iGefundeneOperatoren = iGefundeneOperatoren +1
end if
next Io
next iZO
REM print iGefundeneOperatoren
End sub
'
'***********************************************************************************************************
'
Gruß
balu
Mahlzeit !
[quote="Karolus"]
Ich hätte es ausführlicher schreiben sollen, natürlich kann LO-basic das [b]nicht[/b] direkt als String auswerten,
[/quote]
Okay, verstanden.
[quote="Karolus"]
natürlich kann Basic aber auch syntaktisch richtigen Quelltext auswerten, [u]auch ohne[/u] einen [i]oFunctionAccess.callFunction[/i] drumrum zu schachteln.
[/quote]
Das stimmt!
[code]
print (((0.300+0.260+0.300)*1.740)*12.000)
[/code]
Ergibt 17,9568. Das nur so als Beispiel.
Aber da stehe zumindest ich vor einem Problem (wahrscheinlich stelle ich mich aber momentan einfach nur zu dumm an), denn im Tabellenblatt steht ja in einer Zelle (((0,300+0,260+0,300)*1,740)*12,000) also Dezimaltrenner Komma, anstatt wie im Makro so üblich Dezimaltrenner Punkt und ich weiß momentan nicht den richtigen Weg um einerseits den String so umzuwandeln das er kein String mehr ist und gleichzeitig dabei auch noch Komma durch Punkt zu ersetzen. Wobei Komma durch Punkt ginge ja sehr einfach mit replace.
[code]
Sub Main
sOld ="(((0,300+0,260+0,300)*1,740)*12,000)"
sGewandelt = replace(sOld, ",", ".")
print sGewandelt
End Sub
[/code]
Aber damit lässt sich ja nicht weiter rechnen, da es sich noch immer um einen String handelt.
Und das Vorhaben von Stephan ist ja; String einlesen und umwandeln in eine direkt ausführbare Rechenoperation, anschließend das Ergebnis in eine Tabellenblattzelle schreiben.
Nun, ich hatte mir folgendes gedacht.
Mittels replace die Zahlen der Stringformel zu wandeln, wie eben gezeigt.
Die Operatoren zählen, für den nächsten Schritt.
Die Zahlen in ein Array schreiben. Da dies Array ja von vornherein nicht fest steht, muss mittels der gezählten Operatoren plus 1 dies Array erstellt werden. Plus 1 deshalb, weil für eine simple Rechenoperation 2 Zahlen (Werte) und ein Operator benötigt wird. Also bei 5 Zahlen müssen 4 Operatoren vorhanden sein.
Als nächstes alle vorhandenen Zahlen {0.300 bis 12.000} durch einen Platzhalter ersetzen (#).
Jetzt eine "Rechenformel" neu aufbauen. Dazu den gewandelten String mit den Platzhaltern auslesen, und wenn kein Platzhalter gefunden wird das dementsprechende Zeichen aus dem String herausnehmen, und bei einem Platzhalter die dementsprechende Zahl aus dem Array nehmen. Das alles aneinander gereiht sollte dann die neue "Rechenformel" ergeben.
Das geht ja auch so weit alles. Nur das Dumme daran ist, ich habe wieder nur einen String mit dem es sich nicht rechnen lässt. Das hatte ich mir irgendwie anders vorgestellt. Ganze Arbeit umsonst [img]http://smilie-land.de/t/a-d/brutal/brut0001.gif[/img].
Mit den Zahlen im Array lässt es sich aber durchaus rechnen. Ich brauche dazu nur ein VAL voranstellen, und das würde dann Beispielsweise so aussehen.
[code]
print val(aGewandelteZahlen(4)) * val(aGewandelteZahlen(5))
[/code]
Also die 4. mit der 5. Zahl aus dem Array aGewandelteZahlen multiplizieren.
Na ja, auch wenn ich nicht wirklich weiter gekommen bin als erhofft, so hänge ich den momentanigen Code (der ja auch nur ein Testcode ist) jetzt mal hier rein. Vielleicht lässt sich ja darauf irgendwie aufbauen, und wenn nicht, auch egal.
[code]
Dim aOperatorenArray (3)
Dim sNeuerString as string
Dim iRechnen as Integer, iGefundeneOperatoren as Integer
Sub Main
aOperatorenArray(0) = "*" : aOperatorenArray(1) = "+" : aOperatorenArray(2) = "-" : aOperatorenArray(3) = "/"
sKlammer = "(((0,300+0,260+0,300)*1,740)*12,000)"
sNeuerString = replace(sKlammer, ",", ".")
iRechnen = len(sNeuerString)
ZaehlOperatoren '*************************************************sprung zur Sub ZaehlOperatoren
Dim aGewandelteZahlen (1 to iGefundeneOperatoren+1)
iVari = ""
iGZ = 0
sTempString = sNeuerString
for i = 1 to iRechnen
zCodeAuslesen = asc(mid(sNeuerString, i, 1))
sZeichen = mid(sNeuerString, i, 1)
if zCodeAuslesen >= 48 and zCodeAuslesen <= 57 or zCodeAuslesen = 46 then
iVari = iVari & sZeichen
else
if i = iRechnen then
iGZ = iGZ +1
aGewandelteZahlen(iGZ) = iVari
sTempErsetz = replace(sTempString, aGewandelteZahlen(iGZ), "#", 1, 1)
sTempString = sTempErsetz
REM print "temp = " & sTempString
iVari = ""
end if
end if
if sZeichen ="*" OR sZeichen ="+" OR sZeichen ="-" OR sZeichen ="/" then
iGZ = iGZ +1
aGewandelteZahlen(iGZ) = iVari
sTempErsetz = replace(sTempString, aGewandelteZahlen(iGZ), "#", 1, 1)
sTempString = sTempErsetz
REM print "temp = " & sTempString
iVari = ""
end if
next i
REM print "tempEnde = " & sTempString
REM print "Länge sTempString = " & len(sTempString)
REM print "Rechnen = " & val(aGewandelteZahlen(4)) * val(aGewandelteZahlen(5))
'------------------------------------------------------------------------------ab hier die neue "Rechenformel"
w = len(sTempString)
dim tmpKette as variant
iA = 1
for m = 1 to w
if mid(sTempString, m, 1)<> "#" then
tmpKette = tmpKette + mid(sTempString, m, 1)
else
if mid(sTempString, m, 1) = "#" then
tmpKette = tmpKette + aGewandelteZahlen(iA)
iA = iA +1
end if
end if
next m
print "tmpKette = " & tmpKette
End Sub
'
'***********************************************************************************************************
'
Sub ZaehlOperatoren
iGefundeneOperatoren = 0
for iZO = 1 to iRechnen
zCodeAuslesenZO = asc(mid(sNeuerString, iZO, 1))
sZeichenZO = mid(sNeuerString, iZO, 1)
for iO = 0 to 3
If sZeichenZO = aOperatorenArray(iO) then
iGefundeneOperatoren = iGefundeneOperatoren +1
end if
next Io
next iZO
REM print iGefundeneOperatoren
End sub
'
'***********************************************************************************************************
'
[/code]
Gruß
balu