ABAP® – Das gibt’s ja nicht!

Ich wollte schon länger einmal über ein paar seltsame Dinge in ABAP schreiben. Es gibt nämlich ein paar Sachen in ABAP bei denen man sich einfach nur wundert. Na dann, fangen wir mal an:

BSEG, MARA oder DMBTR

Wer kennt sie nicht, die berühmten SAP ECC Tabellen BSEG oder MARA. Auch die Felder DMBTR oder GSBER sind sicher jedem bekannt.

Aber warum gibt es eigentlich solche komischen Kürzel, haben die Entwickler hier einfach ein paar Buchstabenwürfel verwendet? Natürlich nicht, das sind ganz einfach Relikte
aus R/2. Übrigens, DMBTR steht für „Deutsche Mark Betrag“!dmbtr

In R/2 waren nur 4stellige Tabellennamen und 5stellige Feldnamen erlaubt. SAP hat zwar damals mit R/3 eine völlig neue Technologie geliefert, aber viele ABAP Codes, Tabellen und Prozesse wurden einfach 1:1 übernommen. Und bis dato hat sich bei SAP offensichtlich niemand getraut hier einzugreifen.

Das älteste Programm das ich in einem aktuellen ECC gefunden habe, weißt Kommentare aus dem Jahr 1989 auf!

Bin schon jetzt gespannt, ob wir die Tabellen in S/4 HANA wiederfinden.

 

FOR ALL ENTRIES

Manche ABAP Entwickler schwören auf den FOR ALL ENTRIES Zusatz, manche verteufeln ihn. Ich bin da gespalten denn eigentlich mag ich das Zeug überhaupt nicht, aber andererseits komme auch ich manchmal nicht darum herum.

Aber was ich wirklich – sagen wir mal bescheiden – finde ist, wie ein SELECT mit FOR ALL ENTRIES reagiert, wenn die FOR ALL ENTRIES-Tabelle leer ist. Es werden einfach alle sonstigen Selektionsbedingungen komplett ignoriert und ein kompletter Tablescan durchgeführt. Ohne ersichtlichen Grund.

Hier ein Auszug aus der SAP Online Original Dokumentation:

Before using an internal table itab after FOR ALL ENTRIES, always check that the internal table is not initial. In an initial internal tables, all rows are read from the database regardless of any further conditions specified after WHERE. This is not usually the required behavior.

Nicht zu vergessen ist, dass FOR ALL ENTRIES auf unterschiedlichen Datenbanken teilweise ganz unterschiedlich performant ist. Es gäbe noch viele weitere Argumente (Bufferung, .. ) FOR ALL ENTRIES nicht zu verwenden, aber belassen wir es erst einmal dabei.

Man merke sich jedenfalls: Immer die Größe der FOR ALL ENTRIES Tabelle vor dem SELECT überprüfen – oder noch besser, über Alternativen wie JOINs oder Subselects nachdenken.

 

POOL/Cluster Tabellen

Oh, wie ich diese POOL und CLUSTER Tabellen liebe. Von der Technologie her betrachtet meiner Meinung nach einfach ein ziemlicher Schwachsinn. – Aber auch für diese Technologie gibt es einen triftigen Grund: Wie oben erwähnt waren in R/2 Tabellen nur max. 4stellig. Irgendwann ist SAP dann mit der 4stellen Limitierung einfach an Grenzen gestoßen und hat daher versucht hinter einer Tabelle mehrere Tabellen abzubilden. Das war die Geburt der POOL/CLUSTER Tabellen!

Aber es gibt Hilfe! Wenn wir dann einmal alle auf SAP Hana umstellen bekommen die POOL/CLUSTER Tabellen nach so vielen Jahren endlich ihren verdienten Ruhestand.

Es wäre aber nicht SAP wenn sie für den Vorgang nicht auch einen Namen gefunden hätte: „Depooling/Declustering“.

 

ABAP Open SQL und SQL92

SAP hat mit den aktuellen NetWeaver Releases 7.40 SP5, SP8 und SP12 bzw. NetWeaver 7.50 ein paar wichtige Erweiterungen in das ABAP Open SQL aufgenommen und nähert sich so nach und nach dem Standard SQL92. Manche ABAP Entwickler sind deswegen (SQL Expressions, CDS Views, … ) in heller „Juhu!“ Aufregung!

Liebe Entwickler, bitte vergesst nicht – das 92 hinter SQL Steht für das Jahr! Im Jahr 1992 wurde der Standard definiert. Diese jetzt aufgenommenen Erweiterungen werden von allen namhaften Datenbanken bereits seit Jahrzehnten unterstützt.

Ich meine, eine Erweiterung von ABAP Open SQL war seit Jahren längst überfällig!

 

TCURX

In der TCURX ist gecustomized, wie die Dezimalstelle von Währungen in einem SAP zu interpretieren sind. Wieso das?

Geboren wurde die Tabelle noch im R/2, als auch noch Währungen wie die italienische Lira existiert haben. Die Lira waren teilweise so „groß“ dass die Betragsfelder im R/2 nicht mehr ausgereicht hätten. Also hat man kurzerhand die Kommastellen laut Datenbank außer Kraft gesetzt und dafür die Tabelle TCURX erschaffen. Erst wenn eine Währung nicht in der TCURX enthalten ist, gelten für die Währung die 2 Nachkommastellen.

Im Bereich von Schnittstellen ist das immer wieder ein extra Aufwand – nur um die Betragfelder hin und her zu konvertieren. Beispielswiese für YEN.

Ob man hier nicht irgendwann einmal eine besser Lösung hätte finden können?

 

Jetzt also doch, CODE PUSH DOWN

Jahrelang hat SAP ihren Kunden und uns Entwickler gesagt, DB Nahe Operationen (EXEC SQL, DB Hints, … ) nur in begründeten Fällen und mit Vorsicht zu verwenden. Man verliere so die Unabhängigkeit zur Datenbank oder hat natürlich einen Adaptierungsaufwand wenn gleiches Coding mit verschiedenen Backend-Datenbanken laufen soll.

Nun, da SAP jetzt mit SAP Hana ja eine eigene tolle Datenbank hat, sieht die Sache natürlich etwas anders aus. Jetzt empfiehlt SAP sogar direkter auf der Datenbank „operieren“ um deren Vorteile auch wirklich nutzen zu können. Das Modewort dafür ist „Code Push Down“. Aus ABAP Sicht werden darunter die CDS Views, die AMDB Prozeduren und die SQL Expressions verstanden. Auf der SAP Hana ist darunter z.B. SQL Script zu verstehen.

Nicht falsch verstehen, ich bin ein großer Fan von SAP Hana. Die ist einfach – sorry für den Ausdruck – Sauschnell!

Ich find es halt einfach nur interessant.

 

SAP® CodeJam SAPUI5® hosted von Cadaxo

Am 5. November 2015 veranstalte die Firma Cadaxo gemeinsam mit der SAP die erste SAPUI5 CodeJam in Wien. Zweck dieser CodeJam war es Entwickler zusammenzubringen, um gemeinsam die neue SAP Technologie SAPUI5 kennenzulernen, gemeinsam auszuprobieren, praxisnah zu entwickeln und dabei Spaß haben.

Die SAP Expertin Denise Nepraunig führte diese Veranstaltung und stand den Teilnehmern mit Rat und Tat zur Seite. Nach einer kleinen Einführung in die Materie, dem Kennenlernen des WebIDE, der Entwicklungsumgebung für SAPUI5 Apps, ging es gleich ran an die Tasten.
Sowohl Erfahrene SAPUI5 Entwickler, als auch Beginner befassten sich intensiv mit dem Thema und konnten am Ende des Tages beachtliche, eigens-programmierte SAPUI5 Apps vorweisen.

IMG_0172 IMG_0173

 

Trotz der anstrengenden Arbeit, kam der Spaß nicht zu kurz:

IMG_0189 IMG_0117IMG_0151

Dieses hervorragende Mittagessen haben wir uns redlich verdient:

IMG_0250 IMG_0236 IMG_0248

Nach getaner Arbeit haben wir den Abend bei dem einen oder anderen Glas Bier und Wein, gemütlich ausklingen lassen…

IMG_0264

Wem die Fotos nicht genügen, hier noch ein kurzes Video über die SAPUI5 CodeJam: SAP CodeJam SAPUI5 Wien

Nach so viel positives Feedback, können wir beruhigt sagen, dass es ein gelungenes Event war, bei dem für jeden was dabei war. Ich freue mich schon auf die nächste SAP CodeJam in Wien.

Ich möchte mich auch bei allen Teilnehmern bedanken und natürlich aus bei Denise! CodeJam rocks!

 

HCP IoT Raspberry Demo

iotdemo0

Im Jahr 2015 ist mit dem  Begriff IoT ein neuer IT Trend vermehrt aufgetaucht. Gartner zählt IoT als einen der 10 wichtigsten IT Trends des Jahres 2016:

http://www.gartner.com/newsroom/id/3143521

Ich habe dies zum Anlass genommen und wollte die in der HCP zur Verfügung gestellten Services im IoT Bereich einem Praxistest unterziehen. Um den neuen IoT Service der HCP zu testen habe ich meinen RaspberryPi als Sensor Datenlieferant umfunktioniert.

Hierzu gibt es unzählige Guides und unterschiedliche Sensoren auf die ich hier nicht genauer eingehen möchte. Für mein Beispiel habe ich jedenfalls einen DHT22 (Temperatur/ Luftfeuchtigkeit) von AdaFruit verwendet. Er soll seine Daten später zum IoT-Service der HCP schicken.

 

Einrichten der HCP

Zuerst benötigen wir einen Account auf der HCP Trial. Dieser kann via https://account.hanatrial.ondemand.com erstellt werden. Haben wir unsere Zugangsdaten erhalten so aktivieren wir zuerst im Menüpunkt Services den „Internet of Things Service“:

iotdemo1

Die HCP generiert nun ein Schema und auch eine Java Applikation welche wir im über den Menüpunkt Subscriptions(iotcockpit) sehen können und auch starten wollen. Im IoT Cockpit ist es nun ganz wichtig im Menüpunkt Roles den eigenen User zuzuweisen. Da es hier bei mir immer zur Verwirrung gekommen ist habe ich kurzerhand beide User assigned die in der HCP immer wieder auftauchen(also s-User und s-User+trial).

iotdemo2

Ist dies erledigt finden wir im Punkt Overview die Start-URL zu unserem IoT Cockpit.

iotdemo3

Mit einem Klick auf die URL starten wir nun das Cockpit.

Devicekonfiguration

Im Cockpit müssen wir nun unsere Devices konfigurieren, damit unser IoT Service auch mitbekommt welche Geräte Sensordaten schicken dürfen.
Dazu bekommen wir pro registriertem Device einen Token, doch dazu später mehr. Im Device Management sehen wir nun die 3 Kacheln:

  • Device Types
  • Message Types
  • Devices

In dieser Reihenfolge werden wir nun auch vorgehen um unser IoT zu konfigurieren.

Device Types

Zuerst legen wir mit einem Klick auf die Kachel „Device Types“ den Device Type an. Am unteren Ende findet man einen Button mit einem Plus. Hier muss man sonst eigentlich nur einen Namen vergeben.

Message Types

Nun weiter zum Message Type. Hier definieren wir eine Struktur wie die Daten geliefert werden sollen. Mit dem Plus am unteren Ende können wir nun einen neuen Namen auswählen und im Folgeschritt die Struktur definieren. In meinem Fall habe ich hier den Namen temperatur gewählt mit 2 Feldern, temperatur(Temperatur) und humidity(Luftfeuchtigkeit).

iotdemo4

Device

Auch hier beim Device haben wir wieder ein ähnliches vorgehen. Mit dem Plus unten legen wir das neue Device an und wählen unseren Namen gemeinsam mit der Device Type die wir im Schritt 1 angelegt haben.

Ist das Device angelegt bekommen wir in einem Popup einen OAuth token angezeigt.

In der Registerkarte Information sehen wir nun eine generierte Device ID, diese gemeinsam mit dem OAuth token aus dem Poup im Anlegeprozess zuvor brauchen wir in einem späteren Schritt. Deshalb bitte Beides notieren.

Geschafft unser Device ist nun eingerichtet!

Zurück im Overview starten wir nun die Kachel „Deploy Message Management Service“.

iotdemo5

Auf Deploy klicken, Popup bestätigen und die angezeigte URL klicken, damit wird das HCP Cockpit gestartet.

iotdemo6

Hier sehen wir nun im Overview beim Punkt State, dass der Service am Starten ist. Es kann sein, dass es bis zu 5 Minuten dauert bis der Status auf Grün und gestartet ist.

Ist der Status einmal auf Grün so können wir von unserem Cockpit Daten zum IoT Service schicken.

Hierzu gibt es auf GitHub ein Starterkit(basierend auf PYTHON) welches man verwenden kann: https://github.com/SAP/iot-starterkit

Ich habe mich jedoch für PHP mit der cURL Extension entschieden, da ich bereits ein PHP Script hatte welches die Daten für einen anderen Service zur Verfügung stellte.

Die in eckige Klammern gesetzten Zeichen:

[USER]: HCP Trial User
[MessageTypeID]: Message Type ID aus dem Cockpit
[oAuth Token]: oAuth Token aus dem Cockpit des registrierten Device
[DeviceID]: DeviceID aus dem Cockpit des registrierten Device

Bitte mit den zuvor notierten Daten richtig versorgen:

Dieses Script habe ich in der Crontab des auf Linux basierenden Raspbian Betriebssystem eingetragen und wird in meinem Fall alle 5 Minuten aufgerufen.

Das Ergebnis können wir nun in unserem MMS Cockpit betrachten, welches wir aus dem iot Cockpit heraus mit der Entsprechenden Kachel starten können.

iotdemo7

Weiterführende Links

https://de.wikipedia.org/wiki/Internet_der_Dinge

https://help.hana.ondemand.com/iot/frameset.htm

CL_ABAP_GZIP – Komprimieren von Strings oder binären Inhalten in ABAP®

Allgemeines

Die Komprimierung von großen Dateien, die so genannte Datenkompression bzw. Datenkomprimierung, durch entsprechende Programme, ist im täglichen Gebrauch nicht mehr wegzudenken. Die Datenkomprimierung reduziert nicht nur wertvolle Speicherplätze, eine geringere Datenmenge beim Austausch zweier Systeme wirkt sich positiv auf die Übertragungszeit aus.

Komprimieren/Dekomprimieren in SAP

SAP hat mit dem Web AS 6.20 die Komprimierung innerhalb von ABAP™ verfügbar gemacht. In diesem CADAXO Development Tipp werde ich einen kurzen Überblick liefern.

Überblick CL_ABAP_GZIP / CL_ABAP_ZIP

Zwei Klassen stehen zur Verfügung. Die Klasse CL_ABAP_GZIP wird zum Komprimieren/Dekomprimieren von Texten, Strings oder binären Inhalten verwendet. Darüber hinaus gib es die Klasse CL_ABAP_ZIP mit welcher mehrere Objekte zu einem ZIP Ordner zusammengefasst werden können. Auf diese Klasse wird in diesem Development Tipp nicht weiter eingegangen.

Klasse CL_ABAP_GZIP

Zum Komprimieren von einzelnen Texten, Strings oder binären Inhalten kann die Klasse CL_ABAP_GZIP verwendet werden. Die Klasse bietet vier Methoden an:

  • COMPRESS_TEXT Komprimierung von Text in GZIP-Format
  • DECOMPRESS_TEXT Dekomprimierung von gezippten Textdaten
  • COMPRESS_BINARY Komprimierung von Binärdaten in GZIP-Format
  • DECOMPRESS_BINARY Dekomprimierung von gezippten Binärdaten

Methode COMPRESS_TEXT – Komprimierung von Texten bzw. Strings

Diese Methode wird verwendet, um einen Text/Textstring zu komprimieren. Der zu zippende Text muss in einem CSEQUENCE Typ vorliegen. Zur Erinnerung, bei CSEQUENCE handelt es sich um einen generischen, textartigen ABAP Typ wie STRING oder C.

Der Text wird durch den einzigen Pflichtparameter Parameter TEXT_IN übergeben. Als Ergebnis erhält man zwei Parameter nämlich GZIP_OUT und GZIP_OUT_LEN. Wie vermutet, wird mit GZIP_OUT der komprimierte Inhalt und in GZIP_OUT_LEN die Länge zurückgeliefert. Für GZIP_OUT ist ein XSEQUENCE Typ (X oder XSTRING) zu verwenden.

Nachfolgend ein Beispiel für eine Komprimierung eines Textes:

Die Methode bietet noch weitere optionale Eingabeparameter an:

  • TEXT_IN_LEN Wenn keine Textlänge angegeben ist, wird der gesamte übergebene Text komprimiert, ansonsten erfolgt die Komprimierung auf den Teilbereich des Textes.
  • COMPRESS_LEVEL Durch die Angabe des Komprimierungslevels kann die Größe und Geschwindigkeit der Komprimierung gesteuert werden. 1 bedeutet höchste Geschwindigkeit und 9 beste Komprimierung. Wenn keine Angabe erfolgt, wird 6 als Default-Wert gesetzt. 0 bedeutet keine Komprimierung.
  • CONVERSION Die Eingabedaten können vor der Komprimierung noch in eine andere Codepage konvertiert werden. Hier kann entweder die gewünschte Codepage, UTF-8, NONE oder DEFAULT angegeben werden. Bei DEFAULT wird in Unicode Systemen auf UTF-8 umgewandelt, in nicht Unicode Systemen erfolgt keine Konvertierung. DEFAULT ist als Default-Wert gesetzt.

Methode DECOMPRESS_TEXT – Dekomprimierung von Texten bzw. Strings

Um einen gezippten Text wieder in eine CSEQUENCE zu dekomprimieren, ist die Methode DECOMPRESS_TEXT zu verwenden. Die Methode verfügt über die gleichen Parameter wie COMPRESS_TEXT deshalb hier nur kurz die Parameter zusammengefasst:

  • GZIP_IN Hier wird der XSEQUENCE Typ mit dem gezippten Wert übergeben.
  • GZIP_IN_LEN Optionale Angabe der Länge.
  • CONVERSION Mit DEFAULT wird in einem Unicode-System auf UTF-8 umgewandelt, in nicht UNICODE-Systemen auf die Systemcodepage. Weitere mögliche Angabe NONE und eine gewünschte Codepage.
  • TEXT_OUT Liefert den dekomprimierten Text.
  • TEXT_OUT_LEN enthält die Länge des dekomprimierten Textes.

Beispiel:

Methoden COMPRESS_BINARY und DECOMPRESS_BINARY – Binärdaten

Die Komprimierung bzw. Dekomprimierung von Binärdaten unterscheidet sich nicht wesentlich von der Vorgehensweise mit Texten. Zum Komprimieren wird die Methode COMPRESS_BINARYverwendet. Die einzigen beide Unterschiede betreffen den Typ des zu komprimierenden/dekomprimierenden Feldes und das Fehlen der optionalen Parameter zur Codepage Konvertierung. Zur Dekomprimierung ist die Methode DECOMPRESS_BINARY zu verwenden.

Als Typ des zu komprimierenden/dekomprimierenden Feldes wird ein XSEQUENCE, also entweder ein Feld vom Typ X oder XSTRING, benötigt.

Anwendungsfälle

Wo ist nun eine Anwendung der Klasse denkbar und sinnvoll?

Beispielsweise werden in einer Anwendung Langtexte/Notizen erfasst oder Dokumente/Bilder hochgeladen. Komprimiert können diese wesentlich platzsparender in SAP Tabellen abgelegt werden. In Programmen verwendete XML Strings können auf diese Weise platzsparend im System abgelegt werden. Bei einer RFC Kommunikation zwischen zwei SAP Systemen bietet sich diese Technik an, um bei großen Datenmengen die Netzwerkbelastung wesentlich zu reduzieren und den Datenaustausch somit zu beschleunigen.

Einbinden von sap.m.page als Content in sap.m.IconTabBar funktioniert nicht

In das Control sap.m.IconTabBar können über die Aggregation content bzw. über die entsprechenden Content-Methoden SAPUI5 Controls eingebunden werden. Zumindest bis zum SAPUI5 Release 1.24 funktioniert das Einbinden von Objekten vom Typ sap.m.Page nicht korrekt, sondern liefert teilweise fehlerhafte Ergebnisse.

Stattdessen sollte ein SAPUI5 Layout-Control (Flex Box, … ) oder eine „echtes“ UI Control verwendet werden.

Hier ein Javascript Beispiel in dem eine Tabelle im eingebundenen View zurückgeliefert wird:

addviewtoicontab1

SubView: „zui5_demo_acc.ListOpportunitites“

addviewtoicontab2

Onlinekurs ABAP development for HANA

Onlinekurs „ABAP® development for HANA“

Wir, die Entwickler der Firma Cadaxo, beschäftigen uns seit einiger Zeit mit SAP HANA. Nach vielen gemeinsamen internen Know-how-Transfers und Diskussionen, haben wir uns entschieden, beim Onlinekurs „ABAP Development for HANA“ auf open.sap.com mitzumachen, um unser Know-how zu vertiefen.

Der Kurs erstreckte sich über vier Wochen und wurde von den Instruktoren Dr. Jasmin Gruschke und Jens Weiler auf Englisch gehalten. Wie es die Namen schon verraten, sind die beiden gebürtige Deutsche und wie man schon ahnen kann, drang der deutsche Akzent ziemlich stark durch – vor allem bei Jens Weiler, was mich immer bei guter Laune während des Vortrags hielt.

Im Kurs geht es hauptsächlich darum, was im SAP zu tun ist, wenn man HANA einführt. Bestehendes Coding zu analysieren, worauf man achten muss und mit welchen Tools man das am besten macht.

Der zweite große Teil behandelt Optimierungen – datenbankorientierte Programmierung und Verwendung von HANA-spezifischen Features.

Erst im Laufe des Kurses ist mir wirklich bewusst geworden, wie effizient HANA sein kann. Ein tieferer Blick in die Funktionsweise von HANA, ein paar Demos, in denen enorme Massendaten sekundenschnell aufbereitet und angezeigt werden – und man erkennt den signifikanten Unterschied zur traditionellen Datenbank.

Hier ein paar Themen, die mir am besten gefallen haben und auf die ich in weiteren Beiträgen näher eingehen werde:

  • Bestehendes Coding – was funktioniert nicht mit HANA und muss adaptiert werden
  • Performance von bestehendem Coding – Richtlinien und Ergänzungen
  • Core Data Services-Views – Was ist es und wofür kann ich es verwenden

Ich hoffe, dass auch für euch ein paar interessante Themen dabei sind!

Kundenindividueller Object Collector für den SAP®/ABAP® Code Inspector

Die Objekt-Selektion des Code-Inspectors kann durch einen eigenen Object Collector erweitert werden. Der Standard bietet zwar viele Selektionsmöglichkeiten, manchmal reichen dies aber einfach nicht aus.

ci_own_collector_1

Die notwendige Erweiterung gestaltet sich relativ einfach. Es muss lediglich eine Klasse mit dem Interface IF_CI_COLLECTOR implementiert werden. Üblicherweise wird die Super-Klasse CL_CI_COLLECTOR_ROOT vererbt. Das Interface verfügt über folgende Methoden:

Interface IF_CI_COLLECTOR Methoden

  • COLLECT In dieser Methode ist die Objekt-Selektion auszuprogrammieren und dem Export-Parameter P_OBJSLIST zu übergeben. Anwender können den Objekt-Collector mit Filterwerten starten, diese Werte stehen in den Parametern P_CONFINE_* zur Verfügung.
  • QUERY_ATTRIBUTES In dieser Methode werden Attribute wie der Titel der Selektion bzw. die Select-Options/Parameter definiert. Als Vorlage bei der Implementierung kann man sich die Implementierung der Klasse CL_CI_COLLECTOR_ST22 ansehen.
  • GET_ATTRIBUTES/SET_ATTRIBUTES Die Methoden dienen der Kommunkation zwischen Code Inspector Framework und dier implementierten Klasse. Mittels EXPORT/IMPORT from MEMORY werden die Attribute übergeben. Auch hier kann die Klasse CL_CI_COLLECTOR_ST22 als Vorlage verwendet werden.
  • DISPLAY_DOCUMENTATION Wenn der Collector über eine Dokumentation verfügt, kann hier die Anzeige der Dokumentation gestartet werden.

Interface IF_CI_COLLECTOR Attribute

Das Interface verfügt über einige Steuerparameter welche als globale Attribute umgesetzt wurden. Hier die wichtigsten Attribute:

  • DESCRIPTION Kurzbeschreibung des Object Collector.
  • NAME Name des Object Collectors
  • HAS_DOCUMENTATION ABAP_TRUE bzw. ABAP_FALSE je nachdem, ob der Collector über eine Dokumentation verfügt. Wenn ABAP_TRUE ist im Popup der Button für die Dokumentation aktiv. (siehe Methode DISPLAY_DOCUMENTATION)
  • HAS_ATTRIBUTES ABAP_TRUE/ABAP_FALSE je nachdem, ob der Collector über Attribute verfügt. Wenn ABAP_TRUE ist im Popup der Button für die Parameter aktiv.

Meine Empfehlung

Am Einfachsten und Schnellsten gestaltet sich die Implementierung, wenn man die vorhandenen Code Inspector Collectoren (CL_CI_COLLECTOR*) der SAP als Vorlage verwendet.

ABAP® 7.02 New Features – Neue Stringfunktionen

SAP hat mit SAP NetWeaver 7.02 im ABAP Stack einige neue, interessante Stringfunktionen hinzugefügt. Die neuen Funktionen ersetzen einerseits bestehende ABAP Kommandos, andererseits liefern die Funktionen teilweise völlig neue Funktionalitäten. Nachfolgend gehe ich auf die einzelnen Stringfunktionen näher ein und zeige anhand von Beispielen die Anwendung der Funktionen.

cmax/cmin – Zeichenartige Extremwertfunktion

Mit den neuen Extremwertfunktionen cmax bzw. cmin können bis zu 9 zeichenartige Argumente verglichen werden und man erhält die größte oder das kleinste der übergebenen Zeichen als Ergebnis. Verglichen werden die Zeichen auf Basis der verwendeten Codepage von links nach rechts.

Beispiele:

Ergebnis: AAAD

Ergebnis: AZAB

Ergebnis: AAAB

Ergebnis: 0AAC

condense – Verdichtungsfunktion

Die Zeichenkettenfunktion condense verdichtet den Inhalt einer Zeichenkette. Im Gegensatz zum ABAP Kommando bietet die Funktion darüber hinaus jedoch noch einige weitere Möglichkeiten. Beispielsweise können mit der Funktion auch führende oder endende Zeichen entfernt werden.

Nachfolgendes Beispiel entfernt die führenden und endenden X und verdichtet die X zwischen abc und def auf ein X:

Ergebnis: abcXdef

concat_lines_of – Verkettungsfunktion

Diese Funktion verkettet die Zeilen einer internen Tabelle in eine Zeichenkette. Mit dem Zusatz sep kann ein Separator als Trenner zwischen den Zeilen eingefügt werden. Mit dem folgenden Beispiel werden alle Zeilen der Tabelle TAB in einen String, getrennt durch einen Strichpunkt verkettet:

escape – Fluchtsymbolfunktion

Die Funktion escape ermöglicht das regelbasierte Ersetzen eines Strings durch Fluchtsymbole. Die möglichen Regeln sind in cl_abap_format als Konstanten definiert.

Ergebnis:

insert – Einfügefunktion

Diese Funktion ermöglicht das Einfügen einer Zeichenkette an der ersten oder einer bliebigen Stelle einer anderen Zeichenkette. Nachfolgend ein Beispiel mit dem an der bestehenden Zeichenkette an einer spezifischen Stelle eine andere Zeichenkette eingefügt wird. Nach Ausführen der folgenden Zeilen enthält l_string den Wert ‘News in ABAP‘.

match – Abgleichfunktion

Die Funktion match durchsucht einen Text nach einer bestimmten Regex-Übereinstimmung und liefert die gefundene Teilmenge zurück. Groß-/Kleinschreibung wird standardmäßig berücksichtigt, kann jedoch übersteuert werden. Für weitere Informationen zu Regex in SAP bitte die SAP Online Dokumentation verwenden.

repeat – Wiederholfunktion

Hier wird eine Zeichenkette zurückgegeben, welche den Inhalt einer anderen Zeichenkette beliebig oft wiederholt. Mir fällt aktuell keine sinnvolle Anwendung ein, aber hier jedenfalls ein Beispiel, welches die Zeichenkette ‘ABC‘ 5-mal wiederholt und in das Feld l_string stellt:

replace – Ersetzungsfunktion

Mit replace wird ein Teilbereich einer Zeichenkette durch eine Übergebene Zeichenkette ersetzt. Einerseits besteht die Möglichkeit den Teilbereich über eine Offset- bzw. Längenangabe oder über ein Regex zu ermitteln.

Beispiele:

Ergebnis: ‘ABAP xISx GOOD‘

Ergebnis: ‘ABAPISGOOD‘

reverse – Umdrehfunktion

Auch diese Funktion klingt zwar sehr interessant, aber in meinem bisherigen ABAP Leben hab ich so eine Funktion noch nicht vermisst. Trotzdem hier kurz ein Beispiel, welches als Ergebnis den Inhalt einer Zeichenkette komplett umdreht:

Ergebnis: ABAP

Für ältere SAP Systeme existiert der Funktionbaustein STRING_REVERSE welcher den gleichen Zweck erfüllt.

shift_left/shift_right – Verschiebefunktion

Diese neuen Funktionen ersetzen im Prinzip das Kommando SHIFT bieten aber mit dem SUB-Zusatz (Substring) eine zusätzliche Funktion.

Beispiele:

Ergebnis: ‘CD‘

Ergebnis: ‘CDAB‘

Ergebnis: ‘CD‘

substring, substring_… – Teilfeldfunktion

Mit Hilfe dieser neuen Funktionen kann aus einer übergebenen Zeichenkette ein Teilfeld ermittelt werden. Ein wesentlicher Vorteil dieser neuen Funktion liegt darin, dass hier auch Regular Expressions verwendet werden können. Nachfolgend Beispiele für alle vorhandenen Substring-Funktionen:

Ergebnis: ‘DEFG‘ – Bei dieser Variante ist es jedoch sinnvoller (und schneller) mit l_result = l_field+3(4) zu arbeiten.

Ergebnis: ‘DEFGH‘

Ergebnis: ‘GH‘

Ergebnis: ‘ABC‘

Ergebnis: ‘ABCDEF‘

to_upper, to_lower, to_mixed, from_mixed – Groß-/Kleinschreibungsfunktionen

Auch hier handelt es sich um Funktionen, die teilweise bestehende Kommandos ersetzen. „to_upper“ und „to_lower“ wandeln die Inhalte einer Zeichenkette in Groß- bzw. Kleinbuchstaben um. Völlig gleiches Ergebnis wie bei dem Kommando TRANSLATE TO UPPER/LOWER CASE.

Neu und interessant sind die beiden Funktionen to_mixed bzw. from_mixed. „to_mixed“ setzt alle Buchstaben ab der 2. Position in Kleinbuchstaben um. „from_mixed“ fügt von links nach rechts ab der 2. Position das erste im Zusatz sep angegebene Zeichen ein. Durch die Zusätze sep, case und min kann auf das Verhalten beider Funktionen Einfluss genommen werden.

Beispiel:

Ergebnis: ‘Cadaxo gmbh‘

translate – Umsetzfunktion

Auch hier wieder eine Funktion, die ähnlich zum bekannten ABAP Kommando TRANSLATE … USING … ist. Die Funktion liefert eine Zeichenkette zurück, bei der die Zeichen, die in FROM vorkommen durch das Zeichen ersetzt werden, welche in TO an der gleichen Stelle wie in FROM vorkommen. (Sorry für den verwirrenden Satz, einfach ein paar Mal durchlesen, dann wird’s klarer J )

Beispiel:

Ergebnis: ‘YBZD‘

distance – Ähnlichkeitsfunktion

Diese Funktion ist sehr interessant. Sie gibt den Editierabstand (Levenshtein-Distanz) zweier Zeichenketten zurück. Das ist die minimale Anzahl von Einfüge-, Lösch- oder Ersetzungsvorgängen, die notwendig sind, um die eine Zeichenkette in die andere Zeichenkette zu überführen. Mit dem Zusatz max kann ein Wert angegeben werden, der die Berechnung abbricht, sobald die Anzahl der Änderungsvorgänge größer wird. Die Verwendung der Funktion könnte z. B. bei Doublettenprüfungen interessant sein.

Beispiele:

Ergebnis: 2 (Ein „C“ und ein Leerzeichen müssen eingefügt werden)

Ergebnis: 4 (Alle Zeichen müssen ausgetauscht werden)

Erklärung und Anwendung von TIMESTAMPs in ABAP®/SAP®

Allgemeines zu den Timestamps

Gerade SAP Kunden sind meist global agierende Unternehmen, mit Mitarbeitern in verschiedenen Kontinenten bzw. Zeitzonen. Da leider immer noch viele Entwicklungen – auch im SAP Standard – nach wie vor nur mit sy-uzeit bzw. sy-datum arbeiten, habe ich mich entschlossen, hier ein paar Informationen zu Timestamps in ABAP bzw. SAP niederzuschreiben.

Die bereits erwähnten Systemfelder sy-datum und sy-uzeit sind für viele Anwendungen nicht ausreichend:

  • bei sy-datum und sy-uzeit handelt es sich um lokale Zeitangaben. Global agierende Unternehmen, mit Standorten in verschiedenen Zeitzonen müssen den Anwendern Zeiten in deren Zeitzone darstellen können.
  • sy-uzeit enthält die Zeit lediglich auf Sekunden genau.

Erzeugung eines Timestamps in ABAP bzw. SAP mit GET TIME STAMP

Für die Erzeugung eines aktuellen Timestamps in einem SAP System wird das ABAP Kommando get time stamp … verwendet. Das Kommando erzeugt einen Zeitstempel für die UTC-Zeit des aktuellen ABAP Systems. Entsprechend der Definition des Zielfeldes wird der Timestamp entweder in der Kurz- oder Langform erstellt. Üblicherweise werden für die Felddefinition der Timestamp-Felder die Datenelemente timestamp bzw. timestampl verwendet.

Im nachfolgenden Beispiel werden beide Timestamp-Formate erstellt:

Hinweis: Ein Timestamp ist nicht immer „eindeutig“. Sprich, ein Programm dass in kurzer Zeit mehrere Timestamps zieht, könnte unter Umständen die gleichen Timestamps ziehen.

Konvertierung/Umrechnung von Timestamps

Timestamps können mit Hilfe des Kommandos convert time stamp … in bzw. von Datum- bzw. Uhrzeitfeld (type d und t) konvertiert werden. Für die Konvertierung eines Timestamps in ein Datum- bzw. Uhrzeitfeld ist mit dem Zusatz time zone die Zeitzone anzugeben. Wie oben erwähnt, erhält man bei get time stamp den Zeitstempel in UTC Zeit. Bei der Konvertierung eines Datums bzw. Uhrzeit in einen Timestamp kann mit dem Zusatz time zone die Zeitzone für das Datum- bzw. Uhrzeitfeld mitgegeben werden.

Nachfolgendes Beispiel konvertiert einen Timestamp in ein Datum- bzw. Uhrzeitfeld. Als Ziel-Zeitzone wird die Zeitzone des Anwenders sy-zonlo verwendet. Die Zeitzone kann in den persönlichen Einstellungen am Userstamm eingestellt werden.

Nachfolgend das Gegenstück, ein Beispiel zur Konvertierung eines Datum- bzw. Uhrzeitfeldes in einen Timestamp:

Manchmal besteht die Anforderung darin, ein Datum/Zeit von einer Zeitzone in eine andere Zeitzone zu konveriteren. Ich verwende dazu als Hilfe die Konvertierung in einen Timestamp. Sprich, zuerst Konvertierung von Datum/Uhrzeit der Ausgangszeitzone in einen Timestamp, dann Konvertierung des Timestamps in Datum/Uhrzeit der Zielzeitzone.

Zusatz DAYLIGHT SAVING TIME field

Mit diesem Zusatz erhält man die Information, ob sich der Zeitstempel für die angegebene Zeitzone in der Sommerzeit befindet.

Klasse cl_abap_tstmp – Berechnungen von Timestamps

Für verschiedene Berechnungen, Prüfungen oder Konvertierungen steht in einem ABAP System die Klasse cl_abap_tstmp zur Verfügung. Die Klasse bietet verschiedene Methoden an, nachfolgende Methoden sind hervorzuheben:

  • add Addition von x Sekunden zu einem Timestamp
  • subtract Subtraktion eines Timestamps von einem anderen Timestamp
  • subtractsec Subtraktion von x Sekunden von einem Timestamp
  • compareVergleich von zwei Timestamps

Für weitere Informationen zu den restlichen Methoden bitte direkt in die Klasse/Methode einsteigen und die Dokumentation aufrufen.

Weitere Informationen stehen auch in der SAP Hilfe unter https://help.sap.com/docs/SAP_NETWEAVER_700/109dcbed6c531014bc94b876083bbe59/4d591ec163e444b4e10000000a42189e.html?locale=de-DE zur Verfügung

Ab 7.53 gibt es einen neuen Timestamp ABAP-Typ UTCLONG. – Details dazu unter  https://www.cadaxo.com/high-class-development/abap-7-54-neuer-timestamp-utclong/

ABAP-Klasse CL_BCS – Mailversand aus ABAP

Verwendung der Klasse CL_BCS zum Versenden von eMails aus ABAP™ Anwendungen über das Business Communication Service.

Mit unseren Development Tipps behandeln wir spezielle, praxisbezogene Themen rund um das spannende und unerschöpfliche Thema Softwareentwicklung.
Gültig für: SAP NetWeaver ABAP Web AS ab 6.10

Inhalt

  • Allgemeines
  • Mail versenden aus SAP bzw. ABAP
  • Klasse CL_BCS
    • Methode CREATE_PERSISTENT: Anlegen eines Sendeauftrags
    • Methode SET_DOCUMENT: Anfügen von Text, Dateien und anderen Objekten
    • Methode ADD_ATTACHMENT: der Klasse CL_DOCUMENT_BCS
    • Methode ADD_RECIPIENT: Übergabe der Empfänger 4
    • Methode SEND: Senden der E-Mail
  • Anwendungsfälle

Allgemeines

Oft ist es wichtig, benötigte Informationen schnell zur Verfügung zu haben, um rasch und richtig reagieren zu können. Besonders, wenn die Informationsbeschaffung, etwa ein Report, lange dauert und nicht ständig überwacht werden kann, ist es sinnvoll nach Beendigung eine Aktion auszulösen. Das kann z. B. eine eMail mit dem Status eines Batchjobs oder gar schon der fertigen ABAP-Liste sein.

Mail versenden aus SAP bzw. ABAP

SAP hat mit dem Web AS 6.10 (6.20) die Business Communication Services (BCS) zum Versenden von Objekten aus ABAP Anwendungen zur Verfügung gestellt. Dieses objektorientierte Interface ist der Nachfolger des Business Communication Interface (BCI), das über Objekte des Business Object Repository (BOR) realisiert ist.

In diesem CADAXO Development Tipp werde ich einen kurzen Überblick zum E-Mail Versand mittels BCS geben.

 

Klasse CL_BCS

Über das BCS können unterschiedlichste Objekte mit Anhängen und Notizen an mehrere Empfänger und auf unterschiedliche Kommunikationsarten geschickt werden. Dementsprechend komplex ist das Interface – die Klasse CL_BCS – auch aufgebaut. In diesem Development Tipp beschränken wir uns auf das Versenden einer E-Mail mit Anhang.

Ein Sendevorgang gliedert sich üblicherweise in folgende Schritte.

  1. Erzeugen des Sendeauftrags
  2. Anfügen eines Objekts
  3. Auswahl der Empfänger
  4. Versenden der Nachricht

Für all diese Aufgaben stellt die Klasse CL_BCS Methoden zu Verfügung:

  • CREATE_PERSISTENT Anlegen eines Sendeauftrags
  • SET_DOCUMENT Anfügen von Text, Dateien und anderen Objekten
  • ADD_RECIPIENT Übergabe der Empfänger
  • SEND Senden der E-Mail

Methode CREATE_PERSISTENT – Anlegen eines Sendeauftrags

Diese Methode erzeugt einen Sendeauftrag und liefert diesen als Objekt der Klasse CL_BCS zurück. Alle weiteren Schritte werden auf dieses Objekt angewendet.

Methode SET_DOCUMENT – Anfügen von Text, Dateien und anderen Objekten

Mit dieser Methode wird der Content, also der eigentliche Text und Dateianhänge der E-Mail, übergeben. Die Methode erwartet ein Objekt mit dem Interface IF_DOCUMENT_BCS. Auch Attachments werden über dieses Objekt übergeben.

Über die statische Methode CREATE_DOCUMENT der Klasse CL_DOCUMENT_BCS kann man sich ein entsprechendes Objekt erzeugen lassen. Die Methode erwartet zumindest folgende Parameter:

  • I_TYPE: Typ der übergebenen Daten, z. B. HTM für eine HTML Datei, TXT für Textdateien, BIN für Binärdaten, etwas PDFs
  • I_TEXT/I_HEX: Eine Tabelle mit dem eigentliche Text bzw. den Binärdaten, je nach gewähltem Typ
  • I_SUBJECT: Betreff der E-Mail

Methode ADD_ATTACHMENT der Klasse CL_DOCUMENT_BCS

Diese Methode ist ähnlich der CREATE_DOCUMENT zu verwenden:

  • I_ATTACHMENT_TYPE: Typ der übergebenen Daten, z. B. HTM für eine HTML Datei, TXT für Textdateien, BIN für Binärdaten, etwas PDFs
  • I_ATTACHMENT_TEXT/I_ATTACHMENT_HEX: Eine Tabelle mit dem eigentliche Text bzw. den Binärdaten, je nach gewähltem Typ
  • I_ATTACHMENT_SUBJECT: Name der Attachmentdatei

Methode ADD_RECIPIENT – Übergabe der Empfänger

Je nach Kommunikationsart und Typ der versendeten Objekte können unterschiedliche Empfänger an die Nachricht übergeben werden. Es kann zum Beispiel keine Business Objekt Verknüpfung per E-Mail verschickt werden.

Die Methode erwartet zumindest ein Objekt, das das Interface IF_RECIPIENT_BCS implementiert:

  • I_RECIPIENT: Empfängeradresse (Interface IF_RECIPIENT_BCS)
  • I_EXPRESS: Expressnachricht; ist der Empfänger ein SAP Benutzer, so erhält er bei der nächsten Prozessierung des PBO-Events eine Pop-up mit dem Hinweis auf eine neue Nachricht
  • I_COPY: Der Empfänger erhält die Nachricht als Kopie
  • I_BLIND_COPY: Der Empfänger erhält die Nachricht als Blindkopie
  • I_NO_FORWARD: keine Weiterleitung; ist der Empfänger ein SAP Benutzer, so kann dieser die Nachricht nicht weiterleiten

Die beiden wichtigsten Empfängertypen sind wahrscheinlich E-Mailadressen und SAP Benutzer. Die entsprechenden Objekte werden durch folgende statische Methoden erzeugt:

  • CL_SAPUSER_BCS=>CREATE Für SAP Benutzer
  • CL_CAM_ADDRESS_BCS=>CREATE_INTERNET_ADDRESS Für E-Mailadressen

Methode SEND – Senden der eMail

Die Nachricht wird an SAPconnect übergeben und über das entsprechende Interface verschickt. Der eigentliche Sendeprozess wird üblicherweise durch einen Batchjob mit dem Programm RSCONN01 eingeplant, der periodisch alle anstehenden Nachrichten verschickt. Um die Wartezeit bis zur nächsten Jobausführung zu umgehen, kann die Nachricht als „sofort zu verschicken“ gekennzeichnet werden: Methode SET_SEND_IMMEDIATELY( abap_true ) des Sendeauftrags.

Methode SHORT_MESSAGE

Mit dieser Methode öffnet sich der SAPOffice Dialog für neue Nachrichten, auf dem der Benutzer selbst Empfänger, Text, Attachments und deren Einstellungen pflegen kann. Über Parameter können Vorschlagswerte für die entsprechenden Felder und Objekte, z. B. Empfängeradressen beim Aufruf mitgegeben werden, die dann in der Nachricht angezeigt werden.

Anwendungsfälle

Wo ist nun eine Anwendung der Klasse CL_BCS denkbar und sinnvoll?

  • Anwender können informiert werden, oder bereits Ergebnisse zugeschickt bekommen, wenn eine Auswertung, die als Hintergrundjob eingeplant war, fertig ist.
  • In Fehlersituationen bei kritischen Anwendungen oder Schnittstellen können die zuständigen Personen sofort benachrichtigt werden und somit viel schneller reagieren.