Spreadsheet wert-Funktion

Hallo!


Ich soll eine Wert-Funktion schreiben, mit der ein psychologischer Schwellenpreis ermittelt wird.

Die Bedingungen sehen folgndermaßen aus:

  • unter 20€ soll nach dem Komma 90ct stehen
  • bei 20€ = 19,90
  • 20 bis 100 soll nach dem Komma 50ct stehen
  • bei 100€ = 100
  • über 100€ soll einfach auf einen glatten Btrag gerundet werde
Da ich komplett neu in dieser Art der Programmierung bin, habe ich noch nicht viel geschafft.

Das ist meine Lösung:

java.lang.Objectjava.lang.Enum<RoundingMode>java.math.RoundingMode var price =${MDMsellingprice!} <#if price << "20">price = ${round(price,2,"DOWN")}+0,90<#elseif price == "20">price = 19,90<#elseif price >> "20" && price<<"100">price = ${round(price,2,"DOWN")}+0,50<#elseif price == "100">price = 100<#elseif price >> "100">price = ${round(price,2,"DOWN")}<#else></#if>

Das ist die Fehlermeldung, die ich erhalte:

java.lang.RuntimeException: The value field contained invalid template syntax. Please correct the input. (Column: price)

Ich hoffe mir kann jemand helfen.

Vielen Dank und liebe Grüße

Natascha

Hallo Natascha,


erstmal Herzlich Willkommen.

Freemarker ist weitestgehend von der Zugrunde liegenden Java-Logik abgekoppelt.

Synesty stellt hier 2 verschiedene Funktionstypen bereit.

Einmal Freemarker Built_ins, also Funktionen die über die Freemarker Syntax über ein "?" angesprochen werden können und Template Fuktionen, von Synesty bereitgestellte java Funktionen, die über ein "." aufgerufen werden können.

Mehr informationen dazu: http://docs.synesty.com/display/SSUD/Spreadsheets#Spreadsheets-TemplateFunktionen


>java.lang.Objectjava.lang.Enum<RoundingMode>java.math.RoundingMode

Wie bereits oben beschrieben, wird der Zugriff auf die Java-Syntax über Freemarker wird so nicht funktionieren.

>var price =${MDMsellingprice!}

Zelleninterne Variablen können über ein <#assign> festgelegt werden.

In deinem Fall sähe das so aus: <#assign price=MDMsellingprice>

>${MDMsellingprice!}

Es handelt sich hierbei um eine Ausgabe Expression. Die wendest du an wenn du den in MDMsellingprice beinhalteten Wert ausgeben möchtest

> <#if price << "20">

Du versuchst hier zwei Strings zu vergleichen. Das wird so nicht funktionieren. Stattdessen musst du über ?number erst die Werte in Zahlen umwandeln.

Wenn du die 20 in "" setzt dann wird daraus Intern auch ein String. Du kannst die 20 auch ohne "" in deine Abfrage reinschreiben. Dann wird das automatisch als Zahl behandelt.

Um sicher zu Stellen dass der Parser sich bei "<" für kleiner als nicht verschluckt kannst du stattdessen ein "lt" für less then oder "lte" für "less then equals" verwenden. (gt |gte andersrum)

Also: <#if price?numer lt 20>

>price =

Hier musst du wieder ein <#assign> machen

>+0,90

Freemarker arbeitet mit Punkt statt Komma bei Zahlen. Wenn dein MDMsellingprice enthält dann musst du per Suchen & Ersetzen Funktion das entsprechend anpassen.

>${round(price,2,"DOWN")}+0,90

Wie bereits erwähnt, das ${} ist eine Expression um den beinhalteten Wert auszugeben.

Der Ausdrück müsste also wie folgt aussehen: ${round(price,2,"DOWN")+0.90}


Ich hoffe ich konnte weiterhelfen.


Viele Grüße

Stefan


Hey Stefan!


Vielen lieben Dank für deine super schnelle Antwort!

Ich hab jetzt versucht deine Anmerkungen umzusetzten... leider klappt es immer noch nicht.

<#assign price=MDMsellingprice><#if price?number lt 20><#assign price = ${price?floor+0.90}><#elseif price?number == 20><#assign price = 19.90><#elseif price?number gt 20 && price?number lt 100><#assign price = ${price?floor+0.50}><#elseif price?number == 100><#assign price = 100><#elseif price?number gt 100><#assign price = ${price?floor}><#else></#if>

Das ist jetzt dabei herausgekommen... Was ist falsch?


Lieben Gruß

Natascha

Hallo Natascha,

Achte mal auf folgenden Ausruck.

<#assign price = ${price?floor}>

Wie bereits oben beschrieben, darfst du in deinen assign keine Ausgabe machen. Das ist so als würdest in Java folgendes machen int zahl = System.out.print("432"); Das sollte eigentlich so aussehen <#assign price = price?floor>


In deinem Fall musst du in den If-Ausgaben auch kein Assign machen. Statt dessen reicht eine einfache Ausgabe: <#if price?number lt 20>${price?floor+0.9}<#elseif>...


Insgesamt also wie folgt:

<#assign price=MDMsellingprice>

<#if price?number lt 20>

${price?floor+0.90}

<#elseif price?number == 20>

19.90

<#elseif price?number gt 20 && price+?number lt 100>

${price?floor+0.50}

<#elseif price?number == 100>

100

<#elseif price?number gt 100>

${price?floor}

</#if>


Viele Grüße

Stefan

Hey Stefan!


Super hat jetzt geklappt! Vielen Dank nochmal!!

Musste nur noch satt price?floor ein round(Parameter) einsetzten :)

Tolle Hilfe!!


Liebe Grüße

Natascha

Nur noch eine kleine Ergänzung zur schreibweise der Bedingung:


<#if price?number gt 20 && price+?number lt 100>



Stefan verwendet in seinem Ausdruck gt, was für "greater than" und "lt" was für "lower than" steht und stellvertretend für ein Größerzeichen (> spitze Klammer nach rechts) bzw. Kleinerzeichen steht.


<#if (price?number > 20 && price+?number < 100)>


Man kann in Freemarker auch echte spitze Klammern verwenden, nur muss man dann noch den gesamten Ausdruck in Klammern einschließen.

Wir finden gt und lt sieht komisch aus und bevorzugen spitze klammern. Deshalb: Einfach angewöhnen immer alles in Klammern einschließen.


Das scheint eine Eigenheit von Freemarker zu sein, da Freemarker ohne die runden Klammern denkt, dass die schließende spitze Klammer das Tag schließt.

Hallo ich nochmal,


ich wollte den Code jetzt auf ein anderes Spreadsheet anwenden und es hat nicht funktioniert.

<#assign price=netpurchasepriceandcurrency!><#if (price?number < 20)>${round(price,2,"DOWN")+0.90}<#elseif (price?number = 20)>19.90<#elseif (price?number > 20 && price?number < 100)>${round(price,2,"DOWN")+0.50}<#elseif (price?number = 100)>100<#elseif (price?number > 100)>${round(price,2,"DOWN")}</#if>

So wie ich die Fehlermeldung verstehe hat er probleme dabei den string in einen wert umzuwandeln... ich verstehe aber nicht warum...

Hier die Fehlermeldung:

Script error: freemarker.core.NonNumericalException: Can't convert this string to number: "101.00 " The blamed expression: ==> price?number [in template "empty_7" at line 1, column 51] ---- FTL stac(...)...k trace ("~" means nesting-related): - Failed at: #if (price?number < 20) [in template "empty_7" at line 1, column 45] ----: <#assign price=netpurchasepriceandcurrency!><#if (price?number < 20)>${round(price,2,"DOWN")+0.90}<#elseif (price?number = 20)>19.90<#elseif (price?number > 20 && price?number < 100)>${round(price,2,"DOWN")+0.50}<#elseif (price?number = 100)>100<#elseif (price?number > 100)>${round(price,2,"DOWN")}</#if>


Dann hab ich es versucht mit dem ergebnis einer anderen Spalte zu ersetzten. Das funktionierte dann auch, jedoch hängt er meine 0.90 einfach hinten an und ich habe auf einmal zwei Kommata in der Zahl. Kann es sein, dass er da das dann an den "String" oder so einfach anhängt?


Schon mal herzlichen Dank für Hilfe. Bin begeistert wie schnell das bei euch geht!!

Lieben Gruß Natascha

Hallo Natasha,


> Can't convert this string to number: "101.00 " The

Du hast am Ende deiner price variable ein Leerzeichen.

Desegen kommt es hier zu fehlern.

Mach doch mal ein price?trim?number statt ein price?numer


Viele Grüße

Stefan



Hallo Stefan,


das funktioniert leider auch nicht.... :(

auch wenn ich das mit der suchen und ersetzten funktion rausfilter hat er immer noch probleme...

Hallo Natasha,


falls du den Fehler mit dem doppelten Punkt meinst, dann musst du vor mathematischen Operationen höchstwahrscheinlich noch ein ?number auf den gerundeten Wert setzen.


Siehe:

<#assign price=col0?trim>
<#if (price?number < 20)>${round(price,2,"DOWN")?number+0.90}
<#elseif (price?number = 20)>19.90
<#elseif (price?number > 20 && price?number < 100)>${round(price,2,"DOWN")?number+0.50}
<#elseif (price?number = 100)>100
<#elseif (price?number > 100)>${round(price,2,"DOWN")}
</#if>

image


Viele Grüße

Stefan

Scheinbar funktioniert das ${round()} nicht so wie gewollt. (vermutlich wird price dort nicht als Zahl erkannt).


Mit einem ?floor geht es aber.

<#assign price=col0?trim>
<#if (price?number < 20)>${price?number?floor+0.90}
<#elseif (price?number = 20)>
19.90
<#elseif (price?number > 20 && price?number < 100)>
${price?number?floor+0.50}
<#elseif (price?number = 100)>
100<#elseif (price?number > 100)>
${price?number?floor}</#if>

jap das runden war das Problem... dankeschön!!! :)

super Hilfe!


Liebe Grüße und schönes Wochenende!

Natascha