Python
Einleitung
Dieses Dokument beschreibt die grundsätzliche Verwendung des in der dab:Exporter 3 Version 3.0.112 eingeführten Filters „Skript“. Mit diesem Filter können Python Skripte hinterlegt werden, aus denen die Filterkriterien gebildet werden. Dieses Dokument dient dazu eine Übersicht der Funktionalitäten zu schaffen sowie mögliche einzelne Filterbeispiele aufzuzeigen.
Grundsätzliche Arbeitsweise
Im Packagemanagement kann ein Filter mit der Filterbedingung „Skript“ angelegt werden. Diese Filterbedingung funktioniert nur mit den „Feldherkunft“-Typen „Eingabe“ und „Scheduler“. Bei den „Filterfelddefinitionen“ können sämtlichen Datentypen ausgewählt werden, es sollte jedoch nur eine „Filterfelddefinition“ angelegt werden.
Das Python-Skript wird beim Download mit drei Variablen aufgerufen. Bei diesen Variablen handelt es sich um
- die jeweilige Filterzuordnung
- „von Datum“ (Eingabe / Scheduler-Berechnung)
- „bis Datum“ (Eingabe / Scheduler-Berechnung)
Das Python-Skript muss die Rückgabe in eine Variable als Zeichenkette schreiben, die einen gültigen „ABAP-Filter“ nach dem Muster “FELDNAME = ‘WERT‘“ darstellt. Beispiel:
“MANDT = ‘800‘“
Das Hinterlegte Skript wird für jede manuelle Eingabe (mehrere Zeiträume möglich) / Scheduler-Berechnung pro Filterzuordnung je Tabelle separat aufgerufen und als eigene Filterbedingung verwendet.
Warnung: Liefert wie im Beispiel oben das Skript einen konstanten Filter zurück und wird dieses Skript durch manuelle Eingaben mehr als einmal aufgerufen, so werden Datensätze entsprechend öfter extrahiert.
Filtererstellung im Packagemanagement
Die Python-Skript Filter können wie gewohnt im Packagemanagement bei den Filtergruppen angelegt werden.
Im Bereich „Parameter zum Testen“ können für die Entwicklung des Filters die Variablen, die dem Skript übergeben werden beeinflusst werden.
Der Feldname entspricht dem Namen des Feldes auf den der Filter in der Tabelle zugeordnet wurde. Der Wiederholungstyp beeinflusst die Berechnung der Datumswerte ausgehend von dem Schedule-Datum.
Der Skript-Bereich ist in zwei Teile aufgeteilt. Im oberen Bereich wird das Skript eingegeben. Beim erstmaligen Öffnen wird der Skript-Eingabebereich mit einem Standard-Skript vorbelegt. Dieses Standard-Skript gibt alle übergebenen Variablen auf der Konsole aus und befüllt die „Result“-Variable. In diese Variable muss der gültige ABAP-Filter zurückgegeben werden. Im unteren Skript-Bereich werden die Konsolenausgaben des Python-Interpreters hineingeschrieben (print-Anweisungen), nachdem der Button „Eval“ zum Ausführen des Skripts gedrückt wurde. Das Ergebnis der Auswertung oder Fehler werden in dem Ergebnisbereich dargestellt. Nach erfolgreicher Skriptausführung kann man mit dem Button „Übern.“ Das Skript dem Filter zuweisen, d.h. das Skript wird nur für den Filter übernommen, wenn das Skript zum einen erfolgreich ausgewertet werden konnte und zum anderen erst wenn der Benutzer dies wünscht. Mit dem „Zurück“-Button wird der Editor wieder geschlossen.
1Auch wenn Uhrzeiten angezeigt werden, so ist nur das Datum für die Berechnung zu verwenden! Die Korrektheit der Uhrzeit ist nicht vorauszusetzen!
2Dieser Wert wird nicht durch den Scheduler gefüllt und dient zur Simulation von Benutzereingaben
3Hier wird ausschließlich die Daily Datumsberechnung für „jeden Tag“ verwendet
Hinweise zur Skript-Erstellung
Mit dem Skript-Filter wurde die Möglichkeit geschaffen komplexe Filter mit der Programmiersprache Python hinterlegen zu können. Die Implementierung macht keine Einschränkungen für die Sprache, d.h. hier steht eine komplette Programmiersprache zur Verfügung.
Die Implementierung der Skript-Auswertung geht davon aus, dass diese nach einer endlichen Zeit terminiert, d.h. Endlosschleifen oder Programmierfehler können das Programm zum Absturz bringen (oder Download-Slot belegen). Ferner ist es nicht empfehlenswert mit dem Skript auf Fremdressourcen zuzugreifen, hierunter fallen unter anderem Datei-/Netzwerkzugriffe. Auch sollten keine Prozesse/Threads gestartet werden! Zudem dürfen keine „Fenster“ geöffnet oder auf Benutzereingaben gewartet werden.
Python-Implementierung
Im dab:Exporter wird .NET Implementierung (IronPython 2.7.4[4]) von Python verwendet. Die zugrundeliegende Python Version ist 2.6. Grundsätzlich sollte jegliche Dokumentation zu der Python Version 2.6 auch für die IronPython Version gelten:
http://www.tutorialspoint.com/python/
http://ironpython.net/documentation/
Da es sich bei der Python-Version um eine .NET Implementierung handelt kann aus dieser Python-Version heraus auch auf die gesamte .NET Klassenbibliothek zurückgegriffen werden. Die im Skript übergebenen Variablen „FromDate“ und „ToDate“ sind .NET Strukturen (System.DateTime).
Kurzeinführung in Python
Python ist eine interpretierte, dynamisch typisierte höhere Programmiersprache. Bei dieser Sprache wird jede Anweisung in eine eigene Zeile geschrieben. Zudem wird der Code nicht wie in C-ähnlichen Sprachen mit geschweiften Klammern strukturiert, sondern ausschließlich durch Einrückung. Diese Einrückung kann durch Leerzeichen oder TAB-Zeichen erfolgen, jedoch muss innerhalb eines Skripts die Einrückung nach dem gleichen Schema verlaufen. In den folgenden Beispielen wird das TAB-Zeichen verwendet und für die Erstellung eigener Skripte empfohlen.
Konsolenausgaben
Mit der „print“ Anweisung können auf der Konsole Werte ausgegeben werden. Nachfolgendes Beispiel gibt zweimal „Hello World“ auf der Konsole aus:
print „Hello World!“
a = „Hello World!“
print a
Während der Filter-Skript-Entwicklung kann somit zu jeder Zeit an jeder beliebigen Stelle der Inhalt von Variablen ausgegeben werden. Diese Konsolenausgaben werden nicht vom dab:Exporter ausgewertet und nur bei der Skript-Erstellung angezeigt
Kommentare
Kommentare beginnen mit einem „#“-Zeichen und gelten bis zum Zeilenende. Folgendes Beispiel gibt wiederum zweimal „Hello World!“ aus:
#kommentar
print "Hello World!"
a = "Hello World!" #weiterer kommentar
print a
Variablennamen / Identifier
Variablen / Identifier sind Case-Sensitiv und müssen mit einem Buchstaben (A-Za-z) oder einem Unterstrich (_) beginnen. Danach können weitere Buchstaben, Zahlen oder weitere Unterstriche folgen. Die Zeichen @,$ und % dürfen nicht verwendet werden.
_ = "Hello World!"
a = "Hello a"
A = "Hello big a"
print _
print a
print A
Konsolenausgabe:
Hello World!
Hello a
Hello big a
Bei folgenden Wörtern handelt es sich um reservierte Wörter und dürfen nicht als Variablennamen / Identifier verwendet werden:
Liste der reservierten Wörter | ||||
and | assert | break | class | continue |
def | del | elif | else | except |
exec | finally | for | from | global |
if | import | in | is | lambda |
not | or | pass | raise | |
return | try | while | with | yield |
Datentypen
Zeichenketten werden in Python entweder mit einem einfachen oder doppelten Hochkomma begonnen. Die Zeichenkette muss lediglich wieder mit dem gleichen Zeichen geschlossen werden. Wenn innerhalb einer Zeichenkette das gleiche Symbol benötigt wird, so kann dies mit einem \ maskiert werden.
a = "hello"
b = 'hello'
c = "\""
d = '\''
Konsolenausgabe:
hello
hello
"
'
Zeichenketten können mit einem + konkateniert werden
a = "hello"
b = 'world'
print a + " " + b
Konsolenausgabe:
hello world
Zahlen können in Python mit der Funktion „str“ in eine Zeichenkette umgewandelt werden und eine Zeichenkette mit der Funktion „int“ in eine Ganzzahl oder „float“ in eine Gleitkommazahl. Eine Typkonvertierung von einer Gleitzahl in eine Gleitkommazahl findet in Python automatisch statt.
a = int("5")
b = float(str(2.5))
c = a+b
d = a/b
e = (float("2.5") + 2.5) * 2 / int(str(4))
print c
print d
print e
Konsolenausgabe:
7.5
2.0
2.5
Kontrollstrukturen
Eine bedingte Anweisung wird folgendermaßen geschrieben:
year = 2014
if (year == 2014) : print "year is 2014"
Konsolenausgabe:
year is 2014
Wenn mehr als eine Bedingung zutreffen kann sieht die Kontrollstruktur wie folgt aus (hier wurde mit dem TAB-Zeichen eingerückt)
year = 2013
if year == 2012:
print "year is 2012"
elif year == 2013:
print "year is 2013"
elif year == 2014:
print "year is 2014"
else:
print "year is something else"
Konsolenausgabe:
year is 2013
Bei obigem Beispiel sind die „elif“-Bedingungen optional und unter jeder Bedingung können mehr als eine Anweisung stehen, diese sind ebenfalls einzurücken.
Weitere Zeichenketten-Funktionen
Es ist möglich formatierte Zeichenketten zu erstellen, denen man Parameter übergeben kann. Hierbei erstellt man eine Zeichenkette mit Platzhaltern (%-Formatierungsanweisung) und übergibt anschließend die auszufüllenden Parameter.
print "%s = '%s'" % ('MANDT', 800)
Konsolenausgabe:
MANDT = '800'
Hierbei können unter anderem folgende Formatierungsanweisungen verwendet werden
Formatierungssymbol | Konvertierung |
%c | Zeichen |
%s | Zeichen mit vorherigem Aufruf von str-Funktion |
%i | Vorzeichenbehaftete Ganzzahl |
%d | Vorzeichenbehaftete Ganzzahl |
%u | Positive Ganzzahl |
%o | Oktale Darstellung Ganzzahl |
%x | Hexadezimale Darstellung (kleingeschrieben) |
%X | Hexadezimale Darstellung (großgeschrieben) |
%e | Exponentielle Darstellung (kleines e) |
%E | Exponentielle Darstellung (großes E) |
%f | Gleitkommazahl |
Weitere Zeichenketten-Funktionen
http://www.tutorialspoint.com/python/python_strings.htm
ABAP-Filter
In die „Result“-Variable muss ein gültiger ABAP-Filter als Zeichenkette geschrieben werden. Der dab:Exporter kümmert sich um die richtige Verkettung der Filter, d.h. der mit dem Skript-Filter entstehende Filter darf kein vorangestelltes „AND“, „OR“ o.Ä. enthalten. Diese Operatoren können aber grundsätzlich innerhalb dem Filter entsprechend verwendet werden. Folgende Operatoren / Symbole werden vom dab:Exporter als gültig erkannt:
( | ) | AND | OR | BETWEEN | IN | = |
NOT LIKE | LIKE | > | >= / => | < | <= / =< | <> / >< |
Bei jedem Operator / Symbol muss sowohl vorher als auch nachher ein Leerzeichen stehen!
[4] http://ironpython.codeplex.com/
Beispiel-Filter
Die folgenden Beispiele zeigen mögliche Verwendungen des Skript-Filters auf
Geschäftsjahr
Das Geschäftsjahr wird durch die Jahreszahl des Startdatums – 1 gebildet
gjahr = FromDate.Year - 1
resultStr = "%s = '%s'" % (Fieldname, gjahr)
print resultStr
Result = resultStr
Konsolenausgabe bei folgenden Parametern
- Feldname = Fieldname
- Wiederholungstyp = Daily
- Schedule-Datum: 14.11.2014
Fieldname = '2013'
Zeitintervall für TCURF GDATU
Die Umrechnung erfolgt indem von der Zahl 99999999 das Datum im Format YYYYMMDD abgezogen wird
def convert(param):
formatted = str(param.Year)
formatted += str(param.Month)
formatted += str(param.Day)
return 99999999 - int(formatted)
formattedFrom = convert(FromDate)
formattedTo = convert(ToDate)
resultStr = "%s >= '%s' AND %s <= '%s'" % (Fieldname, formattedFrom, Fieldname, formattedTo)
print resultStr
Result= resultStr
Konsolenausgabe bei folgenden Parametern
- Feldname = Fieldname
- Wiederholungstyp = Daily
- Schedule-Datum: 14.11.2014
Fieldname >= '79858886' AND Fieldname <= '79858886'
Bitte beachten Sie, dass kein Umbruch im Code bei der Variable „resultStr“ erfolgen darf!