Scripting Formularobjekte adressieren

Aus SAP-Wiki
Zur Navigation springenZur Suche springen

Siehe JavaScript und FormCalc Scripting im LiveCycle Designer.

Möchte man Objekte in einem Formular ansprechen, dann muss die Laufzeitumgebung konkret wissen, welches Objekt man meint. Um diese Objekte (Variablen, Teilformulare, Seiten, Textfelder etc.) anzusprechen, gibt es verschiedene Möglichkeiten.

xfa.record (Kontextobjekt)

Manchmal will man eine Variable direkt im Kontext ansprechen.

Z. B. hier eine boolesche Variable, die anzeigt, ob eine Krankenkassenseite ausgegeben werden soll oder nicht. Sie ist nur zur Steuerung nötig und ansonsten wird diese Variable nicht im Formular ausgegen. Insofern ist sie nicht im LiveCycle Designer nötig.

Über den Befehl "xfa.record.<variable>.value" lässt sich eine Variable im Kontext auslesen.


Zu Beachten:

  • die Variable im Kontext wird nicht mit "<variable>.rawValue" angesprochen, sondern mit „<variable>.value“.
  • Ferner ist man nicht in ABAP, wo ein Feld einer Tabelle z. B. mit "VBAK-VBELN" angesprochen wird, sondern im LiveCycle Designer mit JavaScript/FormCalc würde man hier "VBAK.VBELN" mit einem Punkt als Trennzeichen schreiben !!


JavaScript

if ( xfa.record.GV_KRANKENKASSE.value == "X" )
{
  this.presence = "visible";
}
else
{
  this.presence = "hidden";
}

Oder umgekehrt (Abfrage mit || als OR-Operator)

if ( xfa.record.GV_KRANKENKASSE.value == "" || xfa.record.GV_KRANKENKASSE.value == null )
{
  this.presence = "hidden";
}
else
{
  this.presence = "visible";
}


FormCalc

if ( xfa.record.GV_KRANKENKASSE.value == "X" ) then
  $.presence = "visible"
else
  $.presence = "hidden"
endif

Oder umgekehrt (Abfrage mit | als OR-Operator)

if ( xfa.record.GV_KRANKENKASSE.value == ""  | xfa.record.GV_KRANKENKASSE.value == null ) then
  $.presence = "hidden"
else
  $.presence = "visible"
endif


Noch einfacher ist das Coding, wenn man davon ausgeht, dass die Felder standardmäßig sichtbar sind und man sie nur bei Bedarf auf "hidden" setzt.

JavaScript

if (xfa.record.GV_KRANKENKASSE.value == "" || xfa.record.GV_KRANKENKASSE.value == null)
{
  this.presence = "hidden";
}

FormCalc

if (xfa.record.GV_KRANKENKASSE.value == ““ | xfa.record.GV_KRANKENKASSE.value == null) then
  $.presence = "hidden"
endif

Man muss hier allerdings vorsichtig sein, dass das Kontextobjekt wirklich existiert und auch nicht nur durch Bedingungen ausgeschaltet wird. Sonst funktioniert das Coding in der Routine nicht mehr.

Es wäre also keine gute Idee dies zu tun:

Scriptdebugging7.jpg


Dann sollte man besser das Scripting umstellen und nach der gesetzten booleschen Variable abfragen. Dann braucht man an die Variable im Kontext keine Bedingung auf sich selbst einfügen.

xfa.resolveNode (Kontextobjekt)

  • Sehr ähnlich zum xfa.record wird auch beim "xfa.resolveNode" ein Kontextobjekt angesprochen
  • Hier soll bei einem nicht gefüllten Feld im Kontext oder bei einer Gutschrift ein Teilformular auf "hidden" gesetzt werden.

JvaScript

var oAccount = xfa.resolveNode("xfa.record.GS_QRBILL_DETAILS.ACCOUNT_NO");

if ( (oAccount.isNull) || (xfa.record.BIL_PRT_COM.HEAD_DETAIL.VBDKR.VBTYP.value == "O") ) {
	this.presence = "hidden";
}

SOM-Ausdruck

Oftmals möchte man jedoch auch Objekte ansprechen, die nicht im selben Ereignisobjekt sich befinden. Man hat dann die Wahl, entweder einen absoluten (kompletten) Pfad einzugeben oder einen relativen Pfad in Bezug zum Objekt, in dem der geschriebene Code sich befindet.

Der SOM-Ausdruck bezeichnet den Pfad zum Objekt in der Formularhierarchie. Der SOM-Ausdruck kann absolut (komplett) angegeben werden oder relativ. Die einzelnen Objekte im SOM-Ausdruck werden mit einem "." getrennt.

Absolute SOM-Ausdrücke

Der komplette hierarchische Pfad zum Objekt wird angegeben. Er hat den Vorteil, dass man den Pfad direkt aus dem Coding eines Knotens kopieren kann.

SOM1.JPG

In diesem Fall ist der absolute SOM-Ausdruck vom Knoten X10 "data.BODY.Positionen.HEADER.X10".

Den absoluten SOM-Ausdruck sollte man allerdings nur verwenden, wenn die Hierarchie nicht sehr tief ist. Sonst ist die Wahrscheinlich recht groß, dass im späteren Entwicklungverlauf einmal eine Umbenennung eines Knotens im Pfad vorgenommen wird, und sofort sind alle Scriptings nicht mehr gültig, die im absoluten SOM-Ausdruck diesen Knoten enthalten. Ferner wird das Coding nicht mehr funktionieren, wenn man das Coding in ein anderes Formular kopiert. Bei relativen SOM-Ausdrücken wird eventuell das Scripting noch gültig bleiben.

In JavaScript

if (data.BODY.Positionen.HEADER.X10.rawValue == null | data.BODY.Positionen.HEADER.X10.rawValue == "")
 {
  this.presence = "hidden";
 }

in FormCalc

if (data.BODY.Positionen.HEADER.X10.rawValue == null | data.BODY.Positionen.HEADER.X10.rawValue == "") then
  $.presence = "hidden"
endif

Relative SOM-Ausdrücke

Die relative Pfadangabe ist bei tiefen Hierarchiepfaden weniger fehleranfällig und funktioniert häufig auch, wenn ein Objekt/Teilformular verschoben wird. Daher wird man in aller Regel statt eines absoluten SOM-Ausdrucks die relative Pfadangabe (relativer SOM-Ausdruck) bevorzugen.

in JavaScrip

Textfeld.rawValue = "Test";

in FormCalc

Textfeld.rawValue = "Test"

Eigenes Objekt (this/$)

Am einfachsten ist es, wenn ein Objekt angesprochen wird, in dem das Coding sich befindet.

Es wird in Java-Script eine Selbstreferenz mit "this" erzeugt.

if (this.rawValue == null)  //Java-Script
  {
  this.presence = "hidden";
  }

In Form-Calc wird die Selbstreferenz erzeugt mit “$“

if ($ == null) then //Form-Calc (oder $.rawValue)
 $.presence = "hidden"
endif

Diese Schreibweise ist sehr komfortabel, schnell und funktioniert auch, wenn ein Objekt umbenannt oder verschoben wird oder wenn das Coding kopiert und an anderer Stelle (bzw. in einem anderen Formular) eingefügt wird. Diese Schreibweise sollte man daher nach Möglichkeit immer verwenden.

Objekt auf gleicher Ebene

Wenn man ein Objekt "Test" ansprechen will, welches sich im gleichen Teilformular/gleiche Hierarchiebene befindet:

In JavaSript

if (Test.rawValue == null)
  {
  Test.presence = "hidden";
  }

in Form-Calc

if (Test.rawValue == Null) then
  Test.presence = "hidden"
endif

Objekt auf unterer Ebene

Wenn man ein Objekt "Test" ansprechen will, welches sich im Teilformular befindet und man dann das komplette Teilformular mir allen Objekten ausblenden will.

In JavaSript

if (this.Test.rawValue == null)
  {
  this.presence = "hidden";
  }

in Form-Calc

if ($.Test.rawValue == Null) then
  $.presence = "hidden"
endif

DATA-Tabellenzeile ansprechen

Manchmal kann es sinnvoll sein eine ganze Tabellenzeile auszublenden in Abhängigkeit von einem oder mehreren Feldern unterhalb des DATA-Knotens.

In JavaSript

if (this.Feld.rawValue == null)
  {
  this.presence = "hidden";
  }

in Form-Calc

if ($.feld.rawValue == null) then
  $.presence = "hidden"
endif

Übergeordnetes Objekt (parent)

xfa.resolveNode

Mit dem Befehl "xfa.resolveNode" kann man auch Objekte im Formular direkt ansprechen, ohne die Hierarchiebeziehung des Objektes im Hierarchiebaum zu kennen. Das Objekt (z. B. Teilformular oder Textfeld) muss einen eindeutigen Namen im Hierarchiebaum haben, der nicht mehrfach vorkommt.

Hier wird das Textfeld "TextField1" mit einem Wert versorgt.

xfa.resolveNode("TextField1").rawValue = "Hello";

Von dieser Möglichkeit sollte man aus Performancegründen jedoch sparsam (oder gar nicht) gebrauchen. Während der Laufzeit muss der Hierarchiebaum durchsucht werden, um das Objekt in der Hierarchie zu finden. Dies kostet wertvolle Performance. Gerade bei großen und komplexen Formularen sollte „xfa.resolveNode“ daher nicht genutzt werden.

Tabellenzeile ansprechen mit resolveNode

Eine Tabelle ist nicht mit einem Array zu verwechseln.

Ein Array könnte man ansprechen mit

Objekt = Arrayobjekt[1];

Um das erste Elelement im Array „Arrayobjekt“ auszulesen.

In SAP im LiveCycle Designer wird man es jedoch häufiger mit Tabellen oder wiederholenden Teilformularen zu tun haben, deren Tabellenzeilen man auslesen möchte.

Um eine Tabellenzeile auszulesen, baut man sich mit einen String zusammenund lässt dann die Funktion resolveNode mit diesem Formularobjektnamen das passende Formularobjekt suchen, siehe Adobe LiveCycle® Designer ES2 und SAP Interactive Forms: Scripting für Nicht-Programmierer von Ulrich Bähr, S. 73.

iMeinInteger = 1;

sMeinObjektname = "meineTabellenzeile[" + iMeinInteger + "]";

oMeinGesuchtesObjekt = resolveNode(sMeinObjektname);

Wiederholendes Teilformular ansprechen

Ein sich wiederholendes Teilformular ist sehr ähnlich zu einer Tabelle. Das wiederholende Teilformular kann relativ einfach angesprochen werden über dessen Index. Der Index beginnt dabei bei 0. Im folgenden Fall würde man vom Teilformular „Zeile“ das Feld „Nummer“ von der dritten Zeile ansprechen.

Formular1.Seite.Tabelle.Zeile[2].Nummer

Oder hier von der ersten Zeile

Formular1.Seite.Tabelle.Zeile[0].Nummer

Siehe Adobe LiveCycle® Designer ES2 und SAP Interactive Forms: Scripting für Nicht-Programmierer von Ulrich Bähr, S. 74.

Vorsicht: Typische Fehler beim Scripting

  • Es wird JavaScript verwendet und FormCalc ist als Programmiersprache eingestellt (oder umgekehrt)
  • Es wird nicht zwischen Groß- und Kleinschreibung unterschieden (JavaScript und FormCalc unterschieden hier Groß-/Kleinschreibung)
  • Die Klammern sind nicht korrekt gesetzt

Web-Links

Literatur