Werte an dynamischer Position aus ?split Zeichenkette ausgeben

Hallo Team,


ich bin mir sicher Ihr könnt mir weiterhelfen.


Gemäß eurem Cookbook https://support.synesty.com/support/solutions/articles/11000000439-spreadsheet-ich-habe-in-einer-spalte-kommagetrennte-werte-wie-kann-ich-nur-den-n-ten-wert-ausgeben-


kann ich mit

${SPALTENNAME?split(",")[0]}

den Wert der Zeichenkette an Position 0 ausgeben. Ist es denn möglich, die Position auch dynamisch anzugeben?

Ich habe im entsprechenden Mapper einen Counter verbaut, welcher anhand des identifiers von Position 0 beginnend hochzählt und bei auftreten eines neuen identifiers wieder auf 0 resettet. Nun würde ich gerne den Wert des Counters als Position im ?split Statement angeben, finde aber keine funktionierende Syntax:


${Menge!?split('<br/>')[Counter!]}
<!-- Sounds good, doesnt work -->


Wie komm ich hier zum Ziel?

Probier mal


${Menge!?split('<br/>')[Counter]}


ohne Ausrufezeichen (default value operator) am Ende. Das Ausrufezeichen macht ansonsten einen String aus der Zahl, aber die Position muss eine Zahl sein.


Alternativ würde auch gehen:


${Menge!?split('<br/>')[Counter!?number]}


Das wäre nur doppelt: erste zum String und dann wieder zu Zahl.

Danke für das schnelle Feedback!

Leider klappt es nicht. Anbei noch zwei Screenshots von beiden Tests des Flows.


${Menge!?split('<br/>')[Counter]}

Script error: The type of a value differs from what was expected. (Root Causes: NonHashException: For "...[...]" left-hand operand: Expected a hash, but this has evaluated to a sequence (wrapper: f.t.(...)...SimpleSequence): ==> Menge!?split('<br/>') [in template "Menge" at line 1, column 3] ---- FTL stack trace ("~" means nesting-related): - Failed at: ${Menge!?split("\lbr/\g")[Counter]} [in template "Menge" at line 1, column 1] ----): ${Menge!?split('<br/>')[Counter]}

Wandel ich den Inhalt zur Zahl klappt die Ausgabe für den Wert '0', für '1' erhalte ich aber nachfolgenden Fehler:

${Menge!?split('<br/>')[Counter?number]}

Script error: You have used ?number on a string-value which is not a number (or is empty or contains spaces). (Root Causes: NonNumericalException: Can't convert this string to number: " 1" The (...)...blamed expression: ==> Counter?number [in template "MengeNeu" at line 1, column 25] ---- FTL stack trace ("~" means nesting-related): - Failed at: ${Menge!?split("\lbr/\g")[Counter?num... [in template "MengeNeu" at line 1, column 1] ----): ${Menge!?split('<br/>')[Counter?number]}

Und das, obwohl ich vorher prüfe, ob die Werte numerisch sind...Ich steh grad irgendwie auf dem Schlauch

Hallo Marc,


die Ursache für den Fehler ist ein Leerzeichen in der Counter Spalte


Wenn du noch ein ?trim verwendest sollte es funktionieren.


${Menge!?split('<br/>')[Counter?trim?number]}




Viele Grüße

Torsten

Hallo Torsten,


das tut es! Danke. Jedoch stehe ich jetzt vor dem nächsten Phänomen. Wenn ich im Mapper als Mappingmode einstelle, dass nur die gemappten Spalten durchgereicht werden, erhalte ich im nachfolgenden Mapper das gewünschte Ergebnis:


image



Ändere ich jedoch den Mappingmode, dass ungemappte Spalten durchgereicht werden, kommt folgendes bei raus:


image



Laut Fehlermeldung haben die Spalten "Menge" und "Stückpreis ohne MwSt." dann keinen Inhalt mehr:


Script error: You have used ?number on a string-value which is not a number (or is empty or contains spaces). (Root Causes: NonNumericalException: Can't convert this string to number: "" 


Kannst du mal bitte Screenshots posten, wo deine Funktion sichtbar ist? aktuell ist es schwer nachzuvollziehen was wie wo passiert.

Vielleicht kannst du die involvierten Mapper auch nochmal kurz auflisten z.B. so:


Datenquelle

Mapper1 (mappingmode: passthrough, beinhaltet Funktion in Spalte xyz)

Mapper2 (dort erscheint die Fehlermeldung)





Gerne.


Im Anhang befindet sich die betroffene Datei. Pro Zeile eine Order. Orders können mehrere OrderItems haben, diese sind als Liste mit Listentrenner <br/> in der entsprechenden Orderzeile. Analog dazu gibt es zwei weitere Spalten mit Menge und Preis, ebenfalls als Liste mit Listentrenner. OrderItem auf Position 0 hat die entsprechende Bestellmenge und den entsprechenden Preis an Position 0 der jeweiligen Liste usw.

image


Um die OrderItems nun zeilenweise, inklusive den zugeordneten Mengen und Preisen, in den Datastore zu importieren, war die Idee:


1. ColumnSplitToRows - splitColumn: Produktreferenz; delimiter: <br/>
2. Mapper - Mit Counter, der anhand der Bestellreferenz-ID hochzählt und bei neuer ID resettet. Die Position soll dann als Angabe im ?split['Position'] Parameter der Spalten "Menge" und "Preis" dienen.

image



Ist der MappingMode auf "Standard", sodass nur die gemappten Spalten weitergereicht werden, erhalte ich im nächsten Step, hier zum testen ein weiterer Mapper, auch die korrekten Werte:


image


Ist der Mapper jedoch auf MappingMode "PassThrough" eingestellt, was er an dieser Stelle auch unbedingt sein muss, erhält der nächste Step folgenden Fehler als Input in Spalte "Menge":


image



Vielleicht bin ich auch schon zu sehr raus aus dem Thema und es gibt einen viel eleganteren Weg für meine Problemstellung? :o

Danke für das Beispiel.

Wir konnte es reproduzieren. Es scheint ein Problem zu geben, wenn man in einem Mapper mit mappingMode=passThrough auf eine Ergebnisspalte (result['Counter']) zugreift. Ursache noch unklar. Prüfen wir.


Workaround: einen zusätzlichen Mapper verwenden

1. Mapper 1 (mappingMode=passThrough) : Probier mal nur die Counter-Spalte zu berechnen. Die Spalte Menge mal erstmal durchschleifen (ohne Formel in Wert-Feld)

2. Mapper 2 (auch mappingMode=passThrough): hier dann die Menge berechnen aber eben normal auf die Quellspalte zugreifen: ${Menge!?split('<br/>')[Counter?number]}

Wir haben uns das jetzt genauer angesehen. Leider ist das so eine Grenzfall zwischen Bug und Feature.

Lösung ganz am Ende - etwas mehr Hintergrund davor :)


Zum Hintergrund:


Aktuell macht der "passThrough"-Modus folgendes:


  • die durchgereichten Spalten sind führend
  • gemappte Spalten (also die, die man im Mapper sieht und Funktionen einfügt) werden quasi über die durchgereichten Spalten drübergelegt. Dadurch erscheinen die Spalten im Output so wie in der durchgereichten Quelle, aber Spalten aus dem Mapping überschreiben quasi die entsprechenden Quellspalten.
  • Neue Spalten (das sind Spalten, die nicht in den durchgereichten Quellspalten vorkommen) z.B. umbenannte oder Hilfsspalten wie deine Counter-Spalte werden ans Ende ganz nach rechts gepackt. (und das ist der Fehler in den du läufst!!!)


D.h. die gemappten Spalten, tauchen an der gleichen Stelle auf, wie die entsprechende gleichbenannte und durchgeschliffene Quellspalte. Die Reihenfolge der Spalten im Mapping ist nahezu irrelevant.

Evtl. wäre dieser Modus mit "passThrough-Overlay" ggf. besser benannt.


Dadurch dass die neuen Spalten rechts aber ans Ende gepackt werden, schlägt der Zugriff auf die Ergebnisspalte mit ${result['Counter']} fehl, weil Ergebnisspalten immer links von der Spalte stehen müssen, in der sie verwendet werden. Das ist der Bug.


Warum ist das Verhalten so wie es ist?
Wir waren damals der Meinung, dass es einfach "schöner" aussieht, wenn sich die gemappten Spalten beim Durchschleifen einfach über die Originalspalten "drüberlegen" (Overlay).
An den Fall mit den Ergebnisspalten hatten wir nicht gedacht (Bug).


Lösungsansatz:

Wir sind leider einem Dilemma.


Unser Lösungsansatz wäre, dass wir die bisherige Logik anpassen und

  • die gemappten Spalten zuerst rausschreiben
  • und dannach die durchgeschleiften Quellspalten


Allerdings ändert sich dadurch bei allen Kunden die Reihenfolge der Spalten.

Da wir die Auswirkungen davon aktuell nicht abschätzen können, ob es bei Kunden zu Problemen führt, wählen wir eine defensivere Variante:


  • Wir werden einen neuen Mapping-Modus "passThroughMappedColumnsFirst" also "Gemappte Spalten zuerst, dann die durchgeschliffenen Spalten" (oder so ähnlich) erstellen.
  • Wir entscheiden dann in den nächsten Wochen ob wir langfristig beide passThrough-Modus aktiv lassen (was zu Verwirrung führen könnte, da der Unterschied schwer erklärbar ist...wie man an diesem Text hier sieht... )
  • Den bisherigen Modus werden wir evtl. als "deprecated" markieren und noch bis Ende 2020 erlauben. Einen Hinweis werden wir veröffentlichen, dass sie
  • Ab 2021 wird dann der neue Modus automatisch bei allen greifen.
  • Sobald unser Fix live ist, kannst du diesen dann verwenden und auf den neuen Modus wechseln.


Vielleicht können sich auch noch ein paar andere Kunden hier äussern, die den "Durchschleifen-Modus" derzeit benutzen.






Danke für die Aufklärung! Sehr interessant mal die Hintergründe für diese Logik zu erfahren.


Ich habe zwischenzeitlich den Workaround eingebaut, werde den neuen Modus dafür aber gerne ausprobieren.


Gruß,

Marc

Der neue MappingMode ist jetzt live und kann verwendet werden.



  • Dadurch erscheinen die gemappten Spalten im Ausgabe-Spreadsheet zuerst
  • Danach erscheinen alle durchgereichten Spalten der Quelle

Wie schon angekündigt, melde ich mich auch mal zu Wort.


Also Beispielszenario denke ich mir ein Mapper, welcher ein Quellspreadsheet mit 10 Spalten(1,2,3,...,10) kriegt. Wenn ich nicht explizit irgendwas anderes erwähne, geht es immer um die Konfiguration dieses Mappers.


Ich benutze den alten "Pass-through"-Modus an vielen Stellen und hänge deshalb durchaus daran, dass der in seiner Funktion erhalten bleibt. Finde auch, dass der Modus immernoch eine Daseins-Berechtigung hat.


Beispiel:

Ich möchte Spalte 9 modifizieren (mit aktiviertem Passthrough). Wenn ich dafür den neuen Mappingmodus verwende, muss ich im Anschluss einen zweiten Mapper-Schritt benutzten, um die alte Spaltenanordnung wieder herzustellen. Im alten Mappingmodus reicht ein Mapper, da die Anordnung erhalten bleibt.


Für mich liegt der Hauptunterschied zwischen den beiden Modi in der Handhabung von neuen Spalten. Im alten Modus werden diese hinten angehangen (was eben die Probleme bei der Verwendung der result-Variable verursacht) und im neuen Modus vorne.

Die Handhabung von überschriebenen Quellspalten im alten Modus finde ich einleuchtend und ist auch das Verhalten, was ich intuitiv erwarten würde.


Ob Quellspalten nun überschrieben werden oder auch am Anfang der Datei landen, ist nur in einem sehr seltenen Sonderfall relevant. Es folgt ein Beispiel (im alten Pass-through-Modus):

image


Da 1 die erste Spalte ist, ist der Zugriff auf Spalte 10 nicht möglich. Spalte 10 befindet sich im effektiven Mapping weiter rechts und kann deshalb auch nicht als Ergebnisspalte erreicht werden.



Mein Lösungsvorschlag wäre, die Handhabung von Quellspalten zu vereinheitlichen (beide Pass-through-Modi behalten die alten Spaltenanordnung bei). Sodas sich die beiden Modi nur noch in der Handhabung von neuen Spalten unterscheiden. Damit ist auch der Unterschied zwischen den Modi deutlich einfacher zu kommunizieren.


Den Fehler, der dann noch auftreten kann, ließe sich mit einem "Neudesign" des Spaltenkonfigurators vermeiden. Diese müsste dann zwischen neuen Spalten und überschriebenen Quellspalten unterscheiden. Das ist bestimmt mit massivem Aufwand verbunden, aber meiner Meinung nach die sauberste Lösung. Hier ein Mockup:

image

Im Bereich der Neudefinitionen kann man frei über Spaltenanordnung etc. entscheiden. Sollte man aber den Namen einer Quellspalte benutzt und dies überschreiben, landet diese im Bereich "Überschriebene Quellspalten". Dort kann man nicht frei über die Anordnung der Spalten entscheiden, sondern es wird die Anordnung der Quellspalten übernommen. Dies verhindert zum einen den o.g. Sonderfall und zum anderen ist die Anordnung von überschriebenen Quellspalten generell irrelevant, da im resultierenden Spreadsheet die Anordnung des Quellspreadsheets übernommen wird.


Ob das so überhaupt umsetzbar ist, müsst ihr entscheiden.

Vielen Dank Gustav für deinen Vorschlag.

Wir werden die nächsten Tage mal intern die Möglichkeiten besprechen. Wir machen es jetzt auch so, dass wir den bisherigen Modus auf jeden Fall erhalten und auch erstmal nicht mehr als "deprecated" markieren, bis wir eine Entscheidung haben.


Wir möchten das ganze hier gern mit euch zusammen weiter entwickeln und abstimmen, damit wir am Ende zu einer Lösung kommen, die für die meisten passt.


Hier noch ein Gedanke zu deinem einen Satz:

"Für mich liegt der Hauptunterschied zwischen den beiden Modi in der Handhabung von neuen Spalten. Im alten Modus werden diese hinten angehangen (was eben die Probleme bei der Verwendung der result-Variable verursacht) und im neuen Modus vorne."


Antwort:

Die Handhabung von neuen Spalten ist nur einer der Unterschiede.
Der andere Effekt des Overlay Modus ist, dass die Reihenfolge beim "Mappen" völlig irrelevant ist. Du kannst die Reihenfolge im Mapper wild vertauschen - die Spalte landet am Ende immer da, wo die gleichnamige Spalte in der Quelle ist ("drüberlegen" im Sinne von Overlay). D.h. angenommen die Reihenfolge der Quelle verschiebt sich, dann passt sich die drübergelegte Spalte auch an. Das kann dann bei den Result-Spalten ebenfalls zu dem Problem führen, dass eine Spalte plötzlich nicht mehr links sondern rechts ist und man hat das gleiche Problem. D.h. es wird dadurch unvorhersagbar.


Wir stecken nochmal die Köpfe zusammen.

Kurzes Update: Wir sind aufgrund einiger anderer Themen leider noch nicht groß dazu gekommen, das intern zu diskutieren.
Aber nach ersten Gesprächen tendieren wir in die Richtung beide Modus aktiv zu lassen. Der von Gustav vorgeschlagene UI-Umbau wird mit hoher Wahrscheinlichkeit nichts bzw. löst auch nicht alles bzw. führt zu neuen Problemen.


Hier mal unsere aktuelle interne Diskussion dazu:

  • Keep the "old" overlay mode (and maybe really rename it to "Overlay Pass-Through" mode or something like this) and add a warning, that usage of result-columns is discouraged, because of the dynamic nature of source columns. The overlay mode is completely dependent on the Source Spreadsheet, because it dictates the order of the columns
    • "dynamic" in this context means, that e.g. in CSV-Datasources, new columns can suddenly appear in the future, so a "new column" in the past could suddenly become an "existing overlayed" column in the future without the user realizing it. This can lead to surprises and same problem again.
    • Also order of columns in a datasource can change -> suddenly a column which was "to the left" in the past, could appear "to the right" in the future. Suddenly this would break result-columns again without the user noticing.
    • Result-columns only make sense on two completely new columns, which are not in the source.
    • Maybe disable the "result-variables" Tab in the overlay mode, or add a hint that the other Pass-Through Mode should be used.
  • also keep the new Pass-Through Mode and try to make its purpose more clear in the description / documentation