000, übernehmen Sie
Perl hat sich zur Fernsteuerung vieler Anwendungen einen festen Platz erobert. Auch SAPs R/3 läßt sich inzwischen mit der Script-Sprache bedienen - ABAP/4-Kenntnisse vorausgesetzt.
- Bernd Lewerenz
Für den Zugriff auf ein R/3-System bietet SAP das RFC-Protokoll (Remote Function Call) an, wobei R/3 Client wie Server sein kann. Mit diesem Protokoll können zum Beispiel über ein Netzwerk verbundene R/3-Systeme Daten austauschen und in ABAP/4 geschriebene Funktionsbausteine auf dem entfernten System ausführen. Mit seiner Software liefert SAP eine C-API für das RFC-Protokoll in Form einer Bibliothek und einer Header-Datei.
Da die Verwendung von C bei jeder Änderung der Quellen ein Übersetzen und Binden erfordert und Fehler in Scripts leichter zu finden sind, suchte ich nach einer Möglichkeit, von Perl aus die SAP-Schnittstelle verwenden zu können. Die Recherche im CPAN verlief zwar erfolglos, doch in der Newsgroup comp.lang.perl.modules war die Quelle eines Perl-Moduls für SAP/R3 zu erfahren. Erhältlich ist es beim Autor Garth Kennedy. Ein kurzes Script soll seine Benutzung hier erläutern. Ziel ist es, einen R3-Benutzer abzumelden ("löschen" in SAP-Terminologie).
Nach Anpassung der Makefiles und der Installation per
perl Makefile.PL
make rfcperl
make install
gibt es einen neuen Perl-Interpreter. Dieser heißt im folgenden rfcperl. Anders als in den begleitenden READMEs beschrieben, kann man jedoch durchaus auf diesen neuen Interpreter verzichten und die Erweiterung als normales, dynamisch ladbares Perl-Modul bauen. Dazu reicht es, in den beiden Makefile.PL die Zeile
"LINKTYPE" => "static"
auszukommentieren. Um nun die Erweiterung nutzen zu können, muß man zunächst eine Datei namens sideinfo erstellen, die man zum Testen in dem Verzeichnis ablegt, von dem aus das Script user_del.pl aufgerufen wird. Diese Datei enthält Informationen zum R3-System:
DEST=SID
GWHOST=hostname
GWSERV=sapgw00
LISTING 2, user_del.pl
#!/usr/bin/perl
# Perl Script zum Ausloggen eines R/3-Benutzers
# über die RFC-Schnittstelle
# RFC-Module einbinden
use SAP_RFC;
# Kommandozeile prüfen
if ($#ARGV != 0) {
print "Aufruf:\n";
print "rfcperl user_del.pl <Benutzername>\n";
exit 1;
};
# SAP möchte groß geschriebene Worte
$ARGV[0] =~ tr/a-z/A-Z/;
# Verbindungsaufbau und
# Abfrage der Kennungsdaten
print "Benutzername: ";
chop ($u = <<STDIN>);
$u =~ tr/a-z/A-Z/;
system "stty -echo";
print "Paßwort: ";
chop($word = <<STDIN>);
$word =~ tr/a-z/A-Z/;
print "\n";
system "stty echo";
# Ausloggen des Benutzers
print $ARGV[1];
$open_ret = &SAP_RFC::open("XSR","000",$u,
$word,"NO");
# Testen, ob Einloggen erfolgreich war
if ($open_ret != 0)
{
print "SAP::open() - fehlgeschlagen!! \n";
print "Stimmen die Angaben? \n";
print "Liegt die sideinfo-Datei ".
"im Arbeitsverzeichnis?\n";
print "Bye Bye \n";
exit;
}
($ping_ret, $ping_str) = &SAP_RFC::ping();
if ($ping_ret != 0)
{
print "SAP::ping() - FAILED !! \n";
print "Ping-Fehler: \n";
print "Haben Sie die richtigen Daten ".
"für den Login eingegeben?\n";
print "Bye Bye \n";
exit;
}
($ret,$ret2) = &SAP_RFC::callrx1("Z_DELUSR",$ARGV[0]);
# ABAP hat Exception ausgelöst.
if ($ret2 =~ m/keine/) {
print "Keine Berechtigung\n";
} else {
# ABAP hat keine Exception ausgelöst
# aber andere Fehler (Benutzer nicht angemeldet etc.)
# werden in dieser Version noch nicht abgefangen.
print "Habe den Benutzer ",$u," abgemeldet\n";
}
# Schließen der RFC-Verbindung
&SAP_RFC::close();
Dabei ist GWHOST der Name des Rechners, auf dem der SAP-Gateway-Service läuft, GWSERV ist der Name des Gateway-Dienstes aus /etc/services (im allgemeinen sapgw00), und DEST enthält die SID. Das ist der eindeutige Name des SAP-Systems, gleichzeitig der der SAP-Datenbank.
LISTING 1
FUNCTION Z_DELUSR.
*"---------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(IMPORT_STRING) LIKE SY-UNAME
*" EXPORTING
*" VALUE(EXPORT_STRING) LIKE ACC_TEXTE-MSGTEXT
*"---------------------------------------------------------------------
* in import_string steht der user
* wenn exportstring nicht leer ist, dann keine Berechtigung
CALL FUNCTION 'TH_DELETE_USER' EXPORTING USER = IMPORT_STRING
CLIENT = '000'
EXCEPTIONS
AUTHORITY_ERROR = 1.
IF SY-SUBRC = 1.
EXPORT_STRING = 'keine Berechtigung'.
ELSE.
EXPORT_STRING = ''.
ENDIF.
ENDFUNCTION.
Nun ist der Funktionsbaustein aus Listing 1 zu erstellen. Dazu muß man die R/3-Transaktion se37 aufrufen und in den abgefragten Verwaltungsdaten ankreuzen, daß diese Funktion rfc-fähig sein soll. Schließlich ist (immer noch in der se37) die Schnittstelle zu definieren. Dazu kann man den Kommentar (hinter den Sternchen) als Vorlage verwenden. Wichtig ist, daß die importierten und exportierten Werte IMPORT_STRING beziehungsweise EXPORT_STRING heißen - die im Perl-Script benutzte Funktion callrx1 erwartet diese Namen. Näheres zu Transaktionen und se37 enthält der Kasten. Jetzt sollte der Aufruf
rfcperl user_del.pl <Username>
funktionieren. Zunächst erfragt das Perl-Script Namen und Paßwort des Anwenders, der die Berechtigung zum Abmelden eines Benutzers haben sollte. Anschließend versucht es, mit SAP_RFC::open() eine Verbindung zum R/3-Server herzustellen und prüft mit SAP_RFC::ping(), ob das geklappt hat. Die Fehlerkontrolle im Script prüft zweierlei: Ob überhaupt eine Verbindung zum System herzustellen war (nach open()) und ob der Anwender sich anmelden konnte (nach ping()).
Geheimnisvolles se37
se37 ist der Name einer R/3-Transaktion, die das Erstellen und Bearbeiten benutzerdefinierter Funktionen ermöglicht. Dabei ist eine Transaktion im allgemeinen eine Art Anwendung innerhalb von R/3, die für bestimmte Aufgaben zuständig ist. Die Umgebung zur Erstellung von Funktionsbausteinen in der R/3-Programmiersprache ABAP/4 ist eben se37.
Gibt man den Code se37 im Kommandobereich des Hauptfensters ein, landet man in einem Dialog, der direkt die Anwahl der Schnittstellendefinition gestattet, aus dem heraus man aber auch in den Quelltext verzweigen kann. All dies geschieht mausgesteuert, und die Online-Hilfe steht jederzeit bereit.
Lizenz zum Abmelden nötig
Schließlich führt der Aufruf
&SAP_RFC::callrx1("Z_DELUSR",$ARGV[0]);
die ABAP-Funktion Z_DELUSR aus Listing 1 aus. Hat der Anwender die entsprechende Berechtigung, wird der Benutzer <Username> aus R/3 abgemeldet. Das Beispiel benutzt den Mandanten 000, der in user_del.pl und ix1.abap fest verdrahtet ist, um die Scripts für Demo-Zwecke kurz- und einfachzuhalten. Mandanten in R/3 sind etwa den Gruppen in Unix vergleichbar, und Nummer 000 ist für viele Administrationsaufgaben zuständig. Aus Gründen der Einfachheit behandelt das Beispiel zudem alle Benutzer so, als ob sie auf einem einzigen Applikationsserver beziehungsweise einer Zentralinstanz angemeldet wären.
Da Perl etwa mit dem in iX vorgestellten Penguin-Modul ein sicheres Aufrufen von Scripts auf entfernten Rechnern erlaubt, könnte auf diesem Wege ein SAP-Client zumindest für Administrationszwecke auch auf Rechnern entstehen, auf denen die R/3-Bibliotheken nicht verfügbar sind - beispielsweise Linux.
BERND LEWERENZ
ist Dipl.-Mathematiker und arbeitet als R/3-Administrator für die Stadtreinigung Hamburg.
(ck)