4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50...

66
SAP R/3 Remote Function Call 49 4 SAP R/3 Remote Function Call Es gibt verschiedene Begriffsvarianten für RPC, so heißt es bei SAP Remote Function Call (RFC) und bei Java Remote Method Invokation (RMI). RFC ist Grundlage für den Erfolg von R/3 Es ist sicher nicht vermessen, zu sagen, dass der andauernde Erfolg von SAP R/3 zu einem großen Teil dessen RFC-Funktionalität zu verdanken ist. RFC hat SAP R/3 zu einem offenen System gemacht und das ist es, was die IT-Welt benötigt. Keine Software ist so integriert und perfekt, dass sie alle Fälle und Sonderfälle eines Geschäftszweiges abdecken kann. Die Möglichkeit, mit einem Programm all das zu erzielen, was man auch durch eine Benutzereingabe erreichen kann, ist eine Grundforderung an ein modernes Software-Paket. RFC ist Grundlage für IDoc/ALE und BAPI RFC bildet auch die Grundlage der R/3-Technologien ALE/IDoc und BAPI. In beiden Fällen kommuniziert SAP R/3 mit einem externen Programm, im Falle von ALE/IDocs durch asynchronen Austausch von Nachrichten, im Falle von BAPIs durch direkten Aufruf eines Funktionsbausteins. 4.1 Was ist RFC? RFC baut auf CPI-C auf Die SAP-Technologie RFC ist eine auf dem IBM-Protokoll CPI-C aufbau- ende Schnittstellentechnologie, die es externen Programmen oder ande- ren R/3-Instanzen erlaubt, auf eine bestimmte R/3-Instanz zuzugreifen. RFC ist ein sicheres, bidirek- tionales Protokoll Das RFC-Protokoll ist ein bidirektionales, synchrones Kommunikations- protokoll zum Austausch von Nachrichten über ein Netzwerk. RFC sen- det dazu Datagramme von einem Client zu einer Server-Applikation über ein UDP/IP-Netzwerk. Grundsätzlich tut RFC nichts anderes als HTTP, nur die benutzte Codierung und Konvention unterscheiden sich. Genaue Kenntnis der Details des RFC-Protokolls sind für einen Entwickler normalerweise nicht notwendig. Um den Zugriff auf RFC zu erleichtern, stellt SAP eigene RFC-Bibliotheken für die verschiedenen Frameworks zur Verfügung. Derzeit gibt es RFC-Libraries für alle Plattformen, auf denen SAP R/3 läuft, namentlich Windows, UNIX, Linux, AS/400 und z/OS. RFC erlaubt es einem Programm, R/3-Funktionen in einem anderen R/3-System oder einer weiteren R/3-Instanz aufzurufen Kap04.fm Seite 49 Dienstag, 22. April 2003 2:31 14

Transcript of 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50...

Page 1: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

SAP R/3 Remote Function Call 49

4 SAP R/3 Remote Function Call

Es gibt verschiedene Begriffsvarianten für RPC, so heißt es bei SAP Remote Function Call (RFC) und bei Java Remote Method Invokation (RMI).

RFC ist Grundlage für den Erfolg von R/3

Es ist sicher nicht vermessen, zu sagen, dass der andauernde Erfolg vonSAP R/3 zu einem großen Teil dessen RFC-Funktionalität zu verdanken ist.RFC hat SAP R/3 zu einem offenen System gemacht und das ist es, wasdie IT-Welt benötigt. Keine Software ist so integriert und perfekt, dass siealle Fälle und Sonderfälle eines Geschäftszweiges abdecken kann. DieMöglichkeit, mit einem Programm all das zu erzielen, was man auchdurch eine Benutzereingabe erreichen kann, ist eine Grundforderung anein modernes Software-Paket.

RFC ist Grundlage für IDoc/ALE und BAPI

RFC bildet auch die Grundlage der R/3-Technologien ALE/IDoc und BAPI.In beiden Fällen kommuniziert SAP R/3 mit einem externen Programm,im Falle von ALE/IDocs durch asynchronen Austausch von Nachrichten,im Falle von BAPIs durch direkten Aufruf eines Funktionsbausteins.

4.1 Was ist RFC?RFC baut auf CPI-C auf

Die SAP-Technologie RFC ist eine auf dem IBM-Protokoll CPI-C aufbau-ende Schnittstellentechnologie, die es externen Programmen oder ande-ren R/3-Instanzen erlaubt, auf eine bestimmte R/3-Instanz zuzugreifen.

RFC ist ein sicheres, bidirek-tionales Protokoll

Das RFC-Protokoll ist ein bidirektionales, synchrones Kommunikations-protokoll zum Austausch von Nachrichten über ein Netzwerk. RFC sen-det dazu Datagramme von einem Client zu einer Server-Applikation überein UDP/IP-Netzwerk. Grundsätzlich tut RFC nichts anderes als HTTP, nurdie benutzte Codierung und Konvention unterscheiden sich.

Genaue Kenntnis der Details des RFC-Protokolls sind für einen Entwicklernormalerweise nicht notwendig. Um den Zugriff auf RFC zu erleichtern,stellt SAP eigene RFC-Bibliotheken für die verschiedenen Frameworks zurVerfügung. Derzeit gibt es RFC-Libraries für alle Plattformen, auf denenSAP R/3 läuft, namentlich Windows, UNIX, Linux, AS/400 und z/OS.

RFC erlaubt es einem Programm,

� R/3-Funktionen in einem anderen R/3-System oder einer weiterenR/3-Instanz aufzurufen

Kap04.fm Seite 49 Dienstag, 22. April 2003 2:31 14

Page 2: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

50 SAP R/3 Remote Function Call

� R/3-Funktionen von Nicht-SAP-Programmen aufzurufen, zum BeispielJava, C++ oder Visual Basic

� externe Programme außerhalb eines SAP-Systems von SAP R/3 aus auf-zurufen

Die folgenden Abschnitte zeigen konkrete Beispiele zum Aufruf von Pro-grammen über RFC. Den Zugriff von externen Computern zeigen wirunter Verwendung von DCOM für alle Windows-Betriebssysteme undvon Java aus. Grundsätzlich gibt es auch Zugriffsmöglichkeiten von allenBetriebssystemen aus, die auch eine R/3-Instanz unterstützen, zum Bei-spiel einer AS/400 oder von IBM/390. Allerdings werden diese Zugriffs-variationen so selten in der Praxis verwendet, dass auch die Unterstüt-zung dafür leidet. Für all diese Betriebssysteme ist es empfehlenswerter,die Kommunikation über einen HTTP-Proxy-Server durchzuführen.

Abbildung 4.1 Remote Program Calls als Kernfunktionalität einer Client-Server-Landschaft

������

���������

������

������

���������

���� �������

���������

���������������

������� �

������

���������

!"#��$%

�������$&�

������

�����������

����������&�

"���������

����������&�

"���������

������

'����������

���

���

���

���

Kap04.fm Seite 50 Dienstag, 22. April 2003 2:31 14

Page 3: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

R/3-RFC von einer anderen R/3-Instanz 51

4.2 R/3-RFC von einer anderen R/3-InstanzRFCs via R/3-Destination werden in SM59 definiert

Eine R/3-Verbindung von einer anderen SAP R/3-Instanz aus erfolgtimmer über die Angabe einer Destination. Eine Destination wird in Trans-aktion SM59 gepflegt und kann dann von allen ABAPs dieser Instanzbenutzt werden. Im Beispiel in Listing 4.1 definieren wir eine RFC-Verbin-dung zu einem R/3-Computer, in diesem Fall ist es der SAPOSS-Server.

Funktionsaufrufe erhalten den Parameter DESTINATION

Für alle nachfolgenden Aufrufe in das Remote-System brauchen wir unsfortan nicht mehr um die Logon-Daten zu kümmern, da grundsätzlich aufdie Angabe in SM59 zurückgegriffen wird. Ein RFC-Aufruf von ABAP indas Remote-System fügt dann dem CALL FUNCTION einfach noch denParameter DESTINATION hinzu (siehe Listing 4.1). Wenn Sie keine Desti-nation definiert haben, aber dennoch einen RFC testen wollen, könnenSie die vordefinierte Destination NONE verwenden, die immer auf daseigene System verweist und implizit vorhanden ist und demnach nichterst mit SM59 angelegt werden muss.

Listing 4.1 Aufruf einer RFC-Function von ABAP via Destination NONE (= eigenes System)

DATA: from_curr_range TYPE STANDARD TABLE OF bapi1093_3.DATA: to_currncy_range TYPE STANDARD TABLE OF bapi1093_4.DATA: exch_rate_list TYPE STANDARD TABLE OF bapi1093_0 WITH HEADER LINE.DATA: return TYPE STANDARD TABLE OF bapiret1 WITH HEA-DER LINE.CALL FUNCTION 'BAPI_EXCHRATE_GETCURRENTRATES' DESTINATION ‘NONE’ EXPORTING date = sy-datum TABLES from_curr_range = from_curr_range to_currncy_range = to_currncy_range exch_rate_list = exch_rate_list return = return.LOOP AT exch_rate_list. WRITE: / exch_rate_list-from_curr. WRITE: exch_rate_list-to_currncy. WRITE: exch_rate_list-exch_rate.ENDLOOP.

Kap04.fm Seite 51 Dienstag, 22. April 2003 2:31 14

Page 4: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

52 SAP R/3 Remote Function Call

4.2.1 Interne Destination NONE

RFC-DestinationNONE

R/3 hat bereits einige RFC-Destinationen fest vorgegeben, unter ande-rem die Destination NONE. Gibt man NONE als Ziel des Aufrufs an, wird einRFC in das rufende, also das eigene System ausgeführt. Hierzu sind natür-lich keine Logon-Daten erforderlich. NONE eignet sich zum Testen vonRFC-Aufrufen, wenn das entfernte System nicht zur Verfügung steht. Alsbesonderen Nebeneffekt gestattet es aber auch ein Entkoppeln des Auf-rufs von der laufenden Transaktion.

Jeder RFC öffneteine eigene LUW

Ein RFC startet grundsätzlich einen eigenen Programmkontext (LogicalUnit of Work, LUW). Sie können somit aus einer laufenden Transaktionheraus mehrere RFC-Bausteine mit Destination NONE aufrufen. ZumAbschluss können Sie dann mit den BAPI-Bausteinen BAPI_COMMIT_WORK beziehungsweise BAPI_ROLLBACK_WORK die Remote-Aufrufe been-den, ohne dass sich der COMMIT auf die rufende Transaktion auswirkt.

4.3 Windows-zu-R/3-Connectivity mit DCOMZugriff auf R/3

erfolgt via DCOMDer Zugriff von Windows-Systemen aus nach R/3 via RFC bedient sicheiner Reihe von DLLs, die mit dem SAP GUI oder dem RFC-Software-Development-Kit (RFCSDK) ausgeliefert werden. Diese DLLs basieren auf

Abbildung 4.2 Definition einer RFC-Destination mit SM59

Kap04.fm Seite 52 Dienstag, 22. April 2003 2:31 14

Page 5: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 53

DCOM, dem Distributed Common Object Protocol von Microsoft, mit demalle Kommunikationen zwischen Applikationen innerhalb einer Win-dows-Umgebung durchgeführt werden.

Für den Zugriff auf SAP R/3 müssen beim Aufbau der Connection immerdie richtigen Anmeldedaten (englisch Logon-Credentials) angegeben wer-den. Dies erledigen Sie normalerweise im SAP-Logon-Panel, das dieDaten wiederum in der Konfigurationsdatei SAPLOGON.INI abspeichert.

Befindet sich eine solche SAPLOGON.INI (normalerweise im Windows-System-Ordner, zum Beispiel C:\WINNT) auf Ihrem Rechner, können auchdie auf der librfc32.dll basierenden Libraries wie wdtlog.ocx oder der Java-Connector darauf zurückgreifen; es müssen nur noch UserID und Pass-word explizit angegeben werden. Wollen Sie nicht auf die SAPLOGON.INIzurückgreifen, müssen Sie alle Logon-Credentials selbst vollständig ange-ben. Abbildung 1.5 zeigt, wie die Credentials aus dem SAP Logon ent-nommen werden können.

Abbildung 4.3 Angabe der Credentials in SM59

Kap04.fm Seite 53 Dienstag, 22. April 2003 2:31 14

Page 6: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

54 SAP R/3 Remote Function Call

4.3.1 R/3-Logon mit VBA

Zugriff von Win-dows erfolgt über

ActiveX

Das Logon von einer Windows-Applikation – also auch von VBA aus –erfolgt grundsätzlich über die SAP.LogonCtrl (in wdtlog.ocx) oder aufunterster Ebene durch die zentrale RFC-Library librfc32.dll. Wir beschrän-ken uns hier immer auf das SAP.LogonCtrl.

Alle folgenden Beispiele für Windows wurden entweder mit Visual Basicfor Applications (VBA) oder Visual Basic Script (VBS) erstellt.

Aufruf eines BAPIvon VBA

Das Beispiel, das jetzt folgt, zeigt zunächst ein ganz einfaches VB-Pro-gramm, das einen Logon zu R/3 durchführt, und zwar ohne Verwendungvon Klassen. Das Programm beschafft sich ein Connection-Objekt zu R/3,setzt die Parameter und führt den Logon durch. Anschließend ruft esnoch den Funktionsbaustein BAPI_EXCHRATE_GETCURRENTRATES mitdem aktuellen Datum auf.

Listing 4.2 Logon zu R/3 und Aufruf des Funktionsbausteins BAPI_EXCHRATE_GET-CURRENTRATES

' Example calling BAPI BAPI_EXCHRATE_GETCURRENTRATESOption ExplicitPublic Functions As SAPFunctionsOCX.SAPFunctions

Abbildung 4.4 Mapping der Logon-Credentials mit SAPLOGON.INI

Kap04.fm Seite 54 Dienstag, 22. April 2003 2:31 14

Page 7: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 55

Private LogonControl As SAPLogonCtrl.SAPLogonControlPrivate R3Connection As SAPLogonCtrl.ConnectionDim Func As SAPFunctionsOCX.FunctionPublic iDATE As SAPFunctionsOCX.ParameterPublic tEXCH_RATE_LIST As SAPTableFactoryCtrl.TablePrivate Sub Main() Dim ix As Integer Dim retcd As Boolean Dim SilentLogon As Boolean Set LogonControl = CreateObject("SAP.LogonControl.1") Set Functions = CreateObject("SAP.Functions") Set R3Connection = LogonControl.NewConnection R3Connection.Client = "000" R3Connection.ApplicationServer = "192.168.69.111" R3Connection.Language = "EN" R3Connection.User = "DEVELOPER" R3Connection.Password = "19920607" R3Connection.System = "WAS" R3Connection.SystemID = "$WebAS" R3Connection.SystemNumber = "18" R3Connection.UseSAPLogonIni = False SilentLogon = True retcd = R3Connection.Logon(0, SilentLogon) If retcd <> True Then MsgBox "Logon failed": Exit Sub Functions.Connection = R3Connection Set Func = Functions.Add("BAPI_EXCHRATE_GETCURRENTRATES") Set iDATE = Func.Exports("DATE") Set tEXCH_RATE_LIST = Func.Tables("EXCH_RATE_LIST") iDATE.Value = "20030101" Func.Call For ix = 1 To tEXCH_RATE_LIST.RowCount Debug.Print tEXCH_RATE_LIST.Cell(ix, 2), Debug.Print tEXCH_RATE_LIST(ix, 3), 'Different ways to access matrix Debug.Print tEXCH_RATE_LIST(ix, "EXCH_RATE")

Kap04.fm Seite 55 Dienstag, 22. April 2003 2:31 14

Page 8: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

56 SAP R/3 Remote Function Call

Next R3Connection.logoffEnd Sub

4.3.2 Anatomie der RFC- und BAPI-Aufrufe von Windows

RFC-Aufruf mitRFC_READ_TABLE

In diesem Abschnitt gehen wir noch einmal ins Detail und sezieren dieRFC-Aufrufe von einer Visual-Basic-Applikation aus. Dazu nehmen wirdieses Mal den RFC-Baustein RFC_READ_TABLE, mit dem man den Inhaltfast jeder beliebigen R/3-Tabelle via RFC lesen kann. Das verwendete Bei-spiel wird RFC_READ_TABLE von VBA aufrufen und den Inhalt der SAP-Mandantentabelle T000 lesen. Wenn Sie dieses Beispiel verstandenhaben, dürfte es Ihnen keine Schwierigkeit mehr bereiten, eine Anwen-dung mit Zugriff auf einen beliebigen anderen RFC-Baustein zu entwi-ckeln.

Daten einer belie-bigen SAP R/3-

Tabelle mit RFC_READ_TABLE

lesen

Listing 4.3 Lesen einer beliebigen R/3-Tabelle via RFC

Sub R3RFC_READ_TABLE(pQueryTab)'------------------------------------------------------' Add the R/3 RFC function RFC_READ_TABLE to the collec-tion'------------------------------------------------------Set RFC_READ_TABLE = funcControl.Add("RFC_READ_TABLE")'------------------------------------------------------' Create objects for each parameter'------------------------------------------------------Set eQUERY_TAB = RFC_READ_TABLE.Exports("QUERY_TABLE")Set TOPTIONS = RFC_READ_TABLE.Tables("OPTIONS") 'Set TDATA = RFC_READ_TABLE.Tables("DATA") 'Set TFIELDS = RFC_READ_TABLE.Tables("FIELDS") 'eQUERY_TAB.Value = pQueryTab ' pQueryTab is the R/3 name of the tableTOPTIONS.AppendRow ' new item lineTOPTIONS(1, "TEXT") = "MANDT EQ '000'"If RFC_READ_TABLE.Call = True Then If TDATA.RowCount > 0 Then MsgBox "Call to RFC_READ_TABLE successful! Data found" MsgBox TDATA(1, "WA") Else MsgBox "Call to RFC_READ_TABLE successful! No

Kap04.fm Seite 56 Dienstag, 22. April 2003 2:31 14

Page 9: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 57

data found" End IfElse MsgBox "Call to RFC_READ_TABLE failed!"End IfEnd Sub

SAP stellt uns eine Anzahl von ActiveX-Controls und DLLs zur Verfügung,die als intelligenter Proxy für die gesamte Kommunikation mit R/3 die-nen. Ein ActiveX-Control ist ein DCOM-Objekt und deshalb auch kom-patibel mit Visual Basic oder anderen DCOM-Anwendungen. Somiterscheint SAP R/3 aus der Sicht eines ActiveX-Entwicklers wie jedesandere DCOM-Objekt, wird also genauso behandelt wie etwa ein ADO-oder ein DAO-Objekt. Mit anderen Worten ist aus der Sicht eines Ent-wicklers die SAP R/3-Instanz nichts weiter als ein Datenbankserver unddie Funktionsbausteine entsprechen aus dieser Sicht in etwa den StoredProcedures eines Datenbanksystems.

DCOM ist das RPC-Protokoll von Windows

DCOM ist das Zugriffsprotokoll von Windows für verteilte Objekte, imGrunde das Gleiche wie RFC, aber für Windows.

Hauptgrund für Fehler: korrupte Installation der DLLs

Sollte es dennoch Probleme geben, die ActiveX-Controls von SAP aufzu-rufen, liegt das Problem mit sehr großer Sicherheit bei der Installation derControls oder an einer mangelhaften Windows-Installation.

Über SAP ActiveX-Controls brauchen Sie außer den Logon Credentials unddem Namen des aufzurufenden Funktionsbausteins nichts weiter zu wis-sen. Die Controls bauen eine Session mit R/3 auf, und sobald Sie denFunktionsbaustein dem lokalen Repository des ActiveX-Controls hinzufü-gen, können Sie alle Eigenschaften des Bausteins einschließlich derNamen und Typen der Parameter abfragen.

Visual-Basic-Code zum Lesen von Tabelle T000 via RFC

Die folgenden kommentierten Code-Zeilen geben Ihnen Schritt fürSchritt einen Überblick über die einzelnen Methoden der RFC-Controlsam Beispiel eines einfachen Visual-Basic-Programms. Das Beispiel ver-zichtet auf die Typisierung der Variablen und ist somit auch unter VisualBasic Script ausführbar. Dazu muss der Code nur in einer ASCII-Datei mitder Dateierweiterung .vbs abgespeichert sein. Ein Doppelklick auf dieDatei vom Windows-Explorer aus führt das Script dann aus.

Kap04.fm Seite 57 Dienstag, 22. April 2003 2:31 14

Page 10: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

58 SAP R/3 Remote Function Call

Declarations

Zunächst deklarieren wir eine neue R/3-Logon-OCX-Komponente:

Dim LogonControl As SAPLogonCtrl.SAPLogonControl

Deklarieren einesConnection-

Objekts

Das Connection-Objekt ist das Gateway zwischen lokaler Instanz undR/3. Über die Connection wird zu Beginn eine Session durch Übermitt-lung der Anmeldedaten hergestellt. Grundsätzlich kann die Verbindungvon beliebig vielen Routinen gleichzeitig verwendet werden (Connec-tion-Pooling):

Dim conn As SAPLogonCtrl.Connection

Deklarieren einesPointers auf ein

R/3 RFC-Reposi-tory-Objekt

Diesem Pointer wird später eine Referenz auf die Verwaltungsinformatio-nen der gewünschten Funktionsbausteine zugewiesen. Die Eigenschaftender Funktion werden demnach dynamisch bestimmt:

Dim funcControl As SAPFunctionsOCX.SAPFunctions

Dies ist der Pointer zum aktuellen R/3 RFC-Funktionsbaustein:

Dim RFC_READ_TABLE As SAPFunctionsOCX.Function

Als nächstes folgt die Deklaration eines Pointers für jeden Parameter:

Dim eQUERY_TAB As SAPFunctionsOCX.ParameterDim TOPTIONS As SAPFunctionsOCX.TableDim TDATA As SAPFunctionsOCX.TableDim TFIELDS As SAPFunctionsOCX.Table

Logon-Routine

Das Logon zu R/3 fassen wir in einer eigenen Unterroutine zusammen.Darin legen wir eine neue Connection zu R/3 an, die die Verbindungsda-ten über die ganze Programmlaufzeit hinweg hält und die Anmeldung anR/3 zur Applikation hin abschottet.

Sub R3Logon()

Erzeugen einerneuen Connection

Eine neue Connection muss mit der Methode NewConnection angelegtwerden. Das Anlegen eines Connection-Objekts mit CreateObjectfunktioniert ausdrücklich nicht, weil es durch die fehlende Vererbung inVisual Basic nicht möglich ist, das Objekt mit CreateObject sauber zuinitialisieren.

Set conn = LogonControl.NewConnection

Kap04.fm Seite 58 Dienstag, 22. April 2003 2:31 14

Page 11: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 59

Angabe der Logon-Credentials

Lediglich die Angabe von Applikationsserver und Systemnummer istzwingend, alle anderen Daten werden gegebenenfalls in einem Popupabgefragt. Selbstverständlich ist dies in einer automatisierten Umgebungnicht wünschenswert, weshalb Sie schließlich dann doch alle Angabenmachen oder in der SAPLOGON.INI auf dem Server hinterlegen müssen.

conn.ApplicationServer = "R3Linux"' IP or DNS-Name of the R/3 application server conn.System = "00" ' System ID of the instance, usually 00 conn.Client = "100" ' opt. Client number to logon to conn.Language = "EN" ' opt. Your login language conn.User = "" ' opt. Your user id conn.Password = "" ' opt. Your password

Dann folgt der Aufruf der Logon-Methode:

retcd = conn.Logon(0, False)

Und schließlich die Prüfung, ob das Login erfolgreich war:

If retcd <> True Then MsgBox " Cannot log on! " MsgBox retcd Stop else MsgBox " Logon OK." End IfEnd Sub

Aufruf eines RFC-Funktionsbausteins

RFC-Aufruf benutzt die zuvor eröffnete Connec-tion

Der RFC-Funktionsbaustein wird über die Connection aufgerufen, die wirim Logon-Schritt erzeugt haben. Das Coding lässt die lokalen Pointer aufdie Parameter des Funktionsbausteins verweisen. Das ist zwar nicht wirk-lich notwendig, macht aber das Programm lesbarer, als wenn immer derganze Parameterkontext angegeben werden muss. Hat ein RFC-Funkti-onsbaustein Tabellenparameter, erscheinen die in Visual Basic wie ADO-Recordsets und werden auch wie solche behandelt. Die Typisierung derRecordsets erfolgt automatisch beim Hinzufügen des Funktionsbausteinszum lokalen RFC-Repository:

Kap04.fm Seite 59 Dienstag, 22. April 2003 2:31 14

Page 12: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

60 SAP R/3 Remote Function Call

Sub R3RFC_READ_TABLE(pQueryTab)

Erzeugen einerneuen Collection

für den Funktions-baustein

Alle zu verwendenden Funktionsbausteine müssen einer lokalen Collec-tion hinzugefügt werden, die als Cache für die Parameterinformationdient:

Set RFC_READ_TABLE = funcControl.Add("RFC_READ_TABLE")

Als Nächstes wird ein Pointer auf die Import- und Exportparametergesetzt:

Set eQUERY_TAB = RFC_READ_TABLE.Exports("QUERY_TABLE") Set TOPTIONS = RFC_READ_TABLE.Tables("OPTIONS") ' Set TDATA = RFC_READ_TABLE.Tables("DATA") ' Set TFIELDS = RFC_READ_TABLE.Tables("FIELDS") '

Import-, Export- und Tables-Parameter werden durch einen Visual-Basic-Pointer referenziert. Die function collection, die wir oben mit funcCont-rol.Add erzeugt haben, stellt uns dynamisch einen Proxy für die Metho-den und Pointer auf alle Parameter des Funktionsbausteins zur Verfügung.

Bevor wir den Funktionsbaustein aufrufen, müssen wir den Parameterndie gewünschten Werte zuweisen:

Lesen undSchreiben der

Parameterwerte

eQUERY_TAB.Value = pQueryTab ' pQueryTab is the R/3 name of the table TOPTIONS.AppendRow ' new item line TOPTIONS(1,"TEXT") = "MANDT EQ '000'"

Sobald den Parametern gültige Werte zugewiesen wurden, kann derFunktionsbaustein aufgerufen werden. Der Aufruf retourniert TRUE oderFALSE, je nachdem, ob der Aufruf erfolgreich war oder nicht:

If RFC_READ_TABLE.Call = True Then

Wenn der RFC-Aufruf erfolgreich war, können die Werte weiter verarbei-tet werden. Im Beispiel hier zeigen wir jeweils die erste Zeile der Tabellein einer VB Messagebox an.

Ausgabe desErgebnisses

If TDATA.RowCount > 0 Then MsgBox "Call to RFC_READ_TABLE successful! Data found" MsgBox TDATA(1, "WA")

Kap04.fm Seite 60 Dienstag, 22. April 2003 2:31 14

Page 13: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 61

Else MsgBox "Call to RFC_READ_TABLE successful! No data found" End If Else MsgBox "Call to RFC_READ_TABLE failed!" End IfEnd Sub

Hauptprogramm

Damit hätten wir den spannenden Teil des Codings auch schon hinteruns. Im Folgenden packen wir dem Ganzen noch eine Main-Routinehinzu:

Main() procedureSub Main()

Nun erzeugen wir noch eine Instanz der SAP.LogonControl-Klasse(Version 1)

Set LogonControl = CreateObject("SAP.LogonControl.1")

Dieses Statement hat eine neue Instanz des Logon-Objekts erzeugt. DieNummer 1 am Ende des Klassennamens SAP.LogonControl.1 ist dieVersionsnummer der Klasse. Normalerweise gibt man die Version einerKlasse nur an, wenn man wirklich explizit die Verwendung einerbestimmten Version erzwingen will. Im Falle des SAP.LogonControlgibt es nur die eine Version.

Nun erzeugen wir eine Instanz der SAP.Functions collection:

Set funcControl = CreateObject("SAP.Functions")

Als Nächstes erfolgt der Aufruf der Logon-Routine:

call R3Logon

Und dann die Zuweisung des Connection-Objekts:

funcControl.Connection = conn

Dann wird der RFC-Call ausgeführt und es folgt der Logoff:

call R3RFC_READ_TABLE("T000") conn.Logoff MsgBox " Logged off from R/3! " End Sub

Kap04.fm Seite 61 Dienstag, 22. April 2003 2:31 14

Page 14: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

62 SAP R/3 Remote Function Call

Start des Programms

Call Main() Abhängig davon, welche Visual-Basic-Variante Sie verwenden, ist derAufruf leicht unterschiedlich. Im Falle von VBS müssen Sie dem Script-File noch das Statement Call Main() hinzufügen, um das Hauptpro-gramm explizit aufzurufen.

ASP

Call Main() ineiner ASP-Seite

Falls Sie das VBS-Script in eine ASP-Seite einbinden wollen, können Siedas Coding in der VBS-Datei lassen und mit dem #include-Befehl vonASP in die HTML-Seite einbinden:

<HTML> <HEAD> <#include RfcReadTable.vbs > </HEAD><BODY><%>Call Main()<%></BODY>

Funktionsaufruf im Überblick

Das nachstehende Beispiel zeigt noch einmal den Aufruf eines Funktions-baussteins im Überblick. Diesmal wurde ein anderer Funktionsbaustein(RFC_GET_TABLE_ENTRIES) ausgewählt, der ebenfalls den Inhalt einerbeliebigen SAP R/3-Tabelle ausliest, jedoch etwas andere Parameter alsRFC_READ_TABLE hat.

Listing 4.4 Vollständiges Coding zum Aufruf der RFC-Funktion RFC_READ_TABLE

Dim LogonControl 'As SAPLogonCtrl.SAPLogonControlDim conn 'As SAPLogonCtrl.ConnectionDim funcControl 'As SAPFunctionsOCX.SAPFunctionsDim TableFactoryCtrl 'As SAPTableFactoryCtrl.SAPTableF-actory'------------------------------------------------------' Pointer to functions'------------------------------------------------------Dim RFC_READ_TABLE'------------------------------------------------------' Pointers to function parameters'------------------------------------------------------Dim eQUERY_TABDim TOPTIONSDim TDATADim TFIELDS

Kap04.fm Seite 62 Dienstag, 22. April 2003 2:31 14

Page 15: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 63

'******************************************************' Main Program'******************************************************Call Main'******************************************************' Subroutines'******************************************************Sub Main()Set LogonControl = CreateObject("SAP.LogonControl.1")Set funcControl = CreateObject("SAP.Functions")Set TableFactoryCtrl = CreateObject("SAP.TableFac-tory.1")Call R3LogonfuncControl.Connection = connCall R3RFC_READ_TABLE("T000")conn.LogoffMsgBox " Logged off from R/3! "End Sub Sub R3Logon()Set conn = LogonControl.NewConnectionconn.ApplicationServer = "r3dev" ' IP or DNS-Name of the R/3 application serverconn.System = "00" ' System ID of the instance, usually 00conn.Client = "100" ' opt. Client number to logon toconn.Language = "EN" ' opt. Your login languageconn.User = "" ' opt. Your user idconn.Password = "" ' opt. Your password

retcd = conn.Logon(0, False)If retcd <> True Then MsgBox " Cannot log on! " MsgBox retcd StopElse MsgBox " Logon OK."End IfEnd Sub

Kap04.fm Seite 63 Dienstag, 22. April 2003 2:31 14

Page 16: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

64 SAP R/3 Remote Function Call

Sub R3RFC_READ_TABLE(pQueryTab)'------------------------------------------------------' Add the R/3 RFC function RFC_READ_TABLE to the collec-tion'------------------------------------------------------Set RFC_READ_TABLE = funcControl.Add("RFC_READ_TABLE")'------------------------------------------------------' Create objects for each parameter'------------------------------------------------------Set eQUERY_TAB = RFC_READ_TABLE.Exports("QUERY_TABLE")Set TOPTIONS = RFC_READ_TABLE.Tables("OPTIONS") 'Set TDATA = RFC_READ_TABLE.Tables("DATA") 'Set TFIELDS = RFC_READ_TABLE.Tables("FIELDS") 'eQUERY_TAB.Value = pQueryTab ' pQueryTab is the R/3 name of the tableTOPTIONS.AppendRow ' new item lineTOPTIONS(1, "TEXT") = "MANDT EQ '000'"If RFC_READ_TABLE.Call = True Then If TDATA.RowCount > 0 Then MsgBox "Call to RFC_READ_TABLE successful! Data found" MsgBox TDATA(1, "WA") Else MsgBox "Call to RFC_READ_TABLE successful! No data found" End IfElse MsgBox "Call to RFC_READ_TABLE failed!"End IfEnd Sub

Das nachstehende Programmbeispiel zeigt noch einmal den Aufruf einesRFC-Bausteins an einem Stück. Um ein Vergleichsbeispiel zu haben, ver-wendet es diesmal den Aufruf des Bausteins RFC_GET_TABLE_ENTRIES.

Listing 4.5 Einfacher Aufruf von RFC_GET_TABLE_ENTRIES via RFC und VB

' Example calling BAPI RFC_GET_TABLE_ENTRIESOption ExplicitPublic Functions As SAPFunctionsOCX.SAPFunctionsPrivate LogonControl As SAPLogonCtrl.SAPLogonControlPrivate R3Connection As SAPLogonCtrl.Connection

Kap04.fm Seite 64 Dienstag, 22. April 2003 2:31 14

Page 17: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Windows-zu-R/3-Connectivity mit DCOM 65

Dim Func As SAPFunctionsOCX.FunctionPublic iTABLE_NAME As SAPFunctionsOCX.ParameterPublic eNUMBER_OF_ENTRIES As SAPFunctionsOCX.ParameterPublic tENTRIES As SAPTableFactoryCtrl.Table

Private Sub Main() Dim ix As Integer Dim retcd As Boolean Dim SilentLogon As Boolean Set LogonControl = CreateObject("SAP.LogonControl.1") Set Functions = CreateObject("SAP.Functions") Set TableFactory = CreateObject("SAP.TableFactory.1") Set R3Connection = LogonControl.NewConnection R3Connection.Client = "000" R3Connection.ApplicationServer = "192.168.69.111" R3Connection.Language = "EN" R3Connection.User = "DEVELOPER" R3Connection.Password = "19920607" R3Connection.System = "WAS" R3Connection.SystemID = "$WebAS" R3Connection.SystemNumber = "18" R3Connection.UseSAPLogonIni = False SilentLogon = True retcd = R3Connection.Logon(0, SilentLogon) If retcd <> True Then MsgBox "Logon failed": Exit Sub Functions.Connection = R3Connection Set Func = Functions.Add("RFC_GET_TABLE_ENTRIES") Set iTABLE_NAME = Func.Exports("TABLE_NAME") Set eNUMBER_OF_ENTRIES = Func.Imports("NUMBER_OF_ENTRIES") Set tENTRIES = Func.Tables("ENTRIES") iTABLE_NAME.Value = "TCURR" Func.Call Debug.Print eNUMBER_OF_ENTRIES For ix = 1 To tENTRIES.RowCount

Kap04.fm Seite 65 Dienstag, 22. April 2003 2:31 14

Page 18: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

66 SAP R/3 Remote Function Call

Debug.Print tENTRIES(ix, 1) Next R3Connection.logoffEnd Sub

4.4 Helper-Klassen für den Zugriff auf R/3 via RFC

Hilfsklassen fürwiederkehrende

Arbeiten

Um Programme klarer zu gestalten und von immer wiederkehrendenRoutinearbeiten zu säubern, macht es Sinn, sich eine Reihe von Hilfsklas-sen zu erstellen. Im Folgenden sind ein paar Ideen aufgezeigt, wie solcheHelper-Klassen aussehen können. Diese sind weniger dazu gedacht,direkt und unverändert übernommen zu werden, vielmehr sollen sieAnregungen geben, was man alles machen kann oder bedenken sollte.

4.4.1 Class R3LogonObj

Logon von VBdurch die Klasse

R3LogonObj

In unseren Beispielen führen wir das Logon zu SAP R/3 von Visual Basicdurchweg mit einer selbst geschriebenen Proxy-Klasse R3LogonObjdurch. Diese Klasse führt den Logon zu SAP R/3 zentral durch, so dass wiruns nur an dieser Stelle um Logon-Daten wie Name des Applikationsser-vers, UserID, Passwort usw. kümmern müssen.

Referenz aufein Objekt

SAPFunctions-OCX.Functions

Die Klasse selbst exportiert dann im Wesentlichen das Objekt Functionsas SAPFunctionsOCX.Functions, das das zentrale Gateway zur RFC-Funktionsbibliothek von SAP R/3 darstellt.

Listing 4.6 Class R3LogonObj

Public Functions As SAPFunctionsOCX.SAPFunctionsPublic TableFactory As SAPTableFactoryCtrl.SAPTableFac-toryPublic SilentLogon As Boolean'------------------------------------------------------Private LogonControl As SAPLogonCtrl.SAPLogonControlPrivate myCredentials As New R3CredentialsPrivate retcdPrivate err As New ErrObjectPublic Property Get R3Connection() As SAPLogonCtrl.con-nection Set R3Connection = Me.Functions.connectionEnd Property

Kap04.fm Seite 66 Dienstag, 22. April 2003 2:31 14

Page 19: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Helper-Klassen für den Zugriff auf R/3 via RFC 67

Private Property Set R3Connection(conn As SAPLogonC-trl.connection) Set Functions.connection = connEnd PropertyPublic Sub R3Logon() retcd = R3Connection.Logon(0, SilentLogon) If retcd <> True Then Exit Sub Else' MsgBox " Logon OK." End IfEnd SubPublic Sub R3logoff() R3Connection.logoffEnd SubPrivate Sub Class_Initialize() Set LogonControl = CreateObject("SAP.LogonControl.1") Set Functions = CreateObject("SAP.Functions") Set TableFactory = CreateObject("SAP.TableFactory.1") Set R3Connection = LogonControl.NewConnection myCredentials.Read R3Connection Me.SilentLogon = FalseEnd SubPrivate Sub Class_Terminate() Me.R3logoffEnd Sub

4.4.2 Class R3Credentials

Logon-Credenti-als stecken in R3Credentials

Die eigentlichen Logon-Credentials sind noch einmal in einer eigenenKlasse, den R3Credentials, realisiert. Das erlaubt uns, einen geheimenMechanismus zu implementieren, um die Logon-Daten zu verstecken.Diese Klasse kann dann in den Verantwortungsbereich der Systemadmi-nistration gegeben werden, die ohnehin die Logon-Daten verwaltet,ohne dass sie dem Anwendungsentwickler bekannt sind, denn der weistdie Daten durch die Methode READ automatisch dem Connection-Objektzu, ohne sie im Detail zu kennen.

Kap04.fm Seite 67 Dienstag, 22. April 2003 2:31 14

Page 20: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

68 SAP R/3 Remote Function Call

Listing 4.7 Class R3Credentials

Sub Read(ByRef oR3 As SAPLogonCtrl.Connection) Set LogonDataWS = Excel.Worksheets("LogonData") Set LogonData = LogonDataWS.Columns(2) R3Connection.Client = "000" R3Connection.ApplicationServer = "192.168.69.111" R3Connection.Language = "EN" R3Connection.User = "DEVELOPER" R3Connection.Password = "06071992" R3Connection.System = "WAS" R3Connection.SystemID = "$WebAS" R3Connection.SystemNumber = "18" R3Connection.UseSAPLogonIni = False Set LogonData = Nothing Set LogonDataWS = NothingEnd SubSub Class_Initialize()End SubSub Class_Terminate()End Sub

4.4.3 Alternative R3Credentials-Class

Zugriff überExcel-Sheet

Für den Zugriff von Visual Basic benutzen wir in unserer Entwicklungsum-gebung ein Excel-Sheet, das wir einfach mit den Zugriffsdaten mehrererSAP R/3-Systeme füllen. So können wir unsere Anwendung ohne vielAufwand auf mehreren SAP R/3-Systemen testen.

Im folgenden Beispiel sehen Sie ein VBA-Programm, das die Daten ausdem Excel-Sheet herausliest und den Parametern unserer Logon-Klassezuweist.

Listing 4.8 Class R3Credentials mit Daten aus Excel

Private LogonDataWS As Excel.WorksheetPrivate LogonData As Excel.RangeSub Read(ByRef oR3 As SAPLogonCtrl.Connection) Set LogonDataWS = Excel.Worksheets("LogonData") Set LogonData = LogonDataWS.Columns(2) oR3.ApplicationServer = LogonData.Cells(2) ' IP or DNS-Name of app server oR3.System = LogonData.Cells(3) ' System

Kap04.fm Seite 68 Dienstag, 22. April 2003 2:31 14

Page 21: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Helper-Klassen für den Zugriff auf R/3 via RFC 69

ID of the instance oR3.SystemNumber = LogonData.Cells(4) ' Number of Database instance oR3.Client = LogonData.Cells(5) ' opt. Client number to logon to oR3.Language = LogonData.Cells(6) ' opt. Your login language oR3.User = LogonData.Cells(7) ' opt. Your user id oR3.Password = LogonData.Cells(8) ' opt. Your password oR3.SystemID = LogonData.Cells(9) ' System ID of the instance oR3.UseSAPLogonIni = True Set LogonData = Nothing Set LogonDataWS = NothingEnd SubSub Class_Initialize()End SubSub Class_Terminate()End Sub

Die Logon-Daten zu R/3 entsprechen denen aus der saplogon.ini.

Name Wert

Application server 192.168.69.111

System ID WAS

System Number 18

Client 000

Language EN

User DEVELOPER

Password ********

System Web AS

Silent Login FALSCH

Use SAPLOGON.INI FALSCH

Gateway

Tabelle 4.1 Beispiel für Logon-Daten (für die Web AS-Testversion)

Kap04.fm Seite 69 Dienstag, 22. April 2003 2:31 14

Page 22: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

70 SAP R/3 Remote Function Call

4.5 R/3 Java Connectivity

4.5.1 SAP R/3 Java Connector JCo

Der Zugriff von Java auf SAP R/3 erfolgt über den Java Connector (JCo). Jenach Plattform gibt es dafür eine kompatible Implementierung, so dass dieAufrufe von Java auf SAP R/3 unabhängig von der Umgebung bleiben. Ineiner Windows-Umgebung ist der Java Connector eine Java-Klassenbib-liothek, die über das JNI (Java Native Interface) die Funktionen der RFC-Library librfc32.dll aufruft.

JCo ist die einzigeempfohleneRFC-Klasse

Der Java Connector ist die einzige unterstützte RFC-Schnittstelle von Javanach SAP R/3. Alle früheren Java-Tools für RFC werden von SAP nichtmehr unterstützt. Der Java Connector wurde ursprünglich von ThomasSchüssler, http://arasoft.de, entwickelt und kann von Kunden und regist-rierten SAPNet-Usern über http://service.sap.com heruntergeladen wer-den. JCo ist derzeit für alle NT-Varianten verfügbar sowie für UNIX, AIXund Linux. Die früher noch unterstützte Bibliothek jRFC wird von SAPnicht mehr ausgeliefert und es wird empfohlen, Anwendungen auf JCoumzustellen.

4.5.2 SAP R/3-Logon mit Java

JCo unterstütztXML-Konver-

tierung

Im nachstehenden Listing erfolgt der Aufruf auf das BAPI BAPI_EXCHRATE_GETCURRENTRATES von Java. Eine Besonderheit des Java-Connectors ist es, dass die Funktionsbausteinparameter bereits eineintrinsische Konvertierung nach XML unterstützen und wir deshalb durchAufruf der Methode toXML() das Ergebnis sofort in XML ausgeben kön-nen:

System.out.println(myFunc.tEXCH_RATE_LIST.toXML());

Listing 4.9 Einfacher Aufruf von BAPI_EXCHRATE_GETCURRENTRATES via RFC und Java

package R3;import com.sap.mw.JCo.*;public class R3Test extends Object { public static BAPI_EXCHRATE_GETCURRENTRATES myFunc; public static void main (String args[]) { R3RFCfunctions funcs = new R3RFCfunctions(); System.out.println("** SYS: Repository created.");

Kap04.fm Seite 70 Dienstag, 22. April 2003 2:31 14

Page 23: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

R/3 Java Connectivity 71

funcs.Logon(); myFunc = new BAPI_EXCHRATE_GETCURRENTRATES (funcs, "BAPI_EXCHRATE_GETCURRENTRATES"); myFunc.iDATE.setValue("20030101"); myFunc.Execute(); System.out.println(myFunc.tEXCH_RATE_LIST. toXML()); } }

package R3;import com.sap.mw.JCo.*;public class BAPI_EXCHRATE_GETCURRENTRATES // extends R3RFCfunctions{ public JCO.Function func; private R3RFCfunctions functions; public JCO.Field iDATE; public JCO.Table tEXCH_RATE_LIST; public BAPI_EXCHRATE_GETCURRENTRATES( R3RFCfunctions funcRepository, String funcname) { functions = funcRepository; func = functions.add(funcname.toUpperCase());//---- Set vectors to the appropriate parameters iDATE = func.getImportParameterList() .getField("DATE"); tEXCH_RATE_LIST = func.getTableParameterList() .getTable("EXCH_RATE_LIST"); try functions.add(funcname. toUpperCase()); } catch (Exception ex) { } } public void Execute() {functions.R3session.Connection.execute(func);} }

package R3;import com.sap.mw.JCo.*;public class R3RFCfunctions extends R3RFCrepository

Kap04.fm Seite 71 Dienstag, 22. April 2003 2:31 14

Page 24: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

72 SAP R/3 Remote Function Call

{ public R3RFCfunctions() {} public JCO.Function add(String name) { try { return super.R3session.Func-tions.getFunctionTemplate (name.toUpperCase()).getFunction();} catch (Exception ex) {} return null; } public class R3RFCrepository{ public R3LogonObj R3session; public R3RFCrepository() { R3session = new R3LogonObj(); } public R3RFCrepository(R3LogonObj ActiveSession) { R3session = ActiveSession; } public void Logon() { R3session.Connection.connect();} public void Logoff() { R3session.Connection.disconnect();} }

package R3;import com.sap.mw.JCo.*;public class R3LogonObj {public JCO.Repository Functions; public boolean SilentLogon; public JCO.Client Connection; public R3LogonObj() { try {R3.R3Credentials myCred = new R3.R3Credentials(); Connection = myCred.Connect(); } catch (Exception ex) { ex.printStackTrace();System.exit(1);} try {Functions = new JCO.Repository("logosworld", Connection);} catch (Exception ex) { ex.printStackTrace();System.exit(1);} } }

Kap04.fm Seite 72 Dienstag, 22. April 2003 2:31 14

Page 25: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Das SAP RFC-Gateway 73

4.6 Das SAP RFC-GatewayRFC-ListenerMit Hilfe des SAP RFC-Gateways können Sie einem externen Programm,

dem RFC-Listener, erlauben, sich selbst als Proxy-Server bei SAP R/3 anzu-bieten. Dadurch müssen in SAP R/3 selbst keine Verbindungsdaten zumListener gepflegt werden. SAP R/3 spricht den Listener über das Gatewayals eine RFC-Destination mit dem Namen an, unter dem der Listener sichzuvor bei SAP R/3 registriert hat.

4.6.1 Registrierung eines RFC-Listeners beim SAP-Gate-way

Folgendes ist ein Beispiel einer Registrierung am Gateway:

Srfcserv –aMYHOST.srfcserv –gSAPR3.logosworld.com –xSAPGW00 –t

Das gezeigte Beispiel registriert sich selbst über Gateway SAPGW00 beider SAP R/3-Instanz mit dem Namen SAPR3.logosworld.com.

Der Name des SAP-Gateways ist von der Form SAPGWxx, wobei xx dieSystem-Nummer der zugehörigen SAP R/3-Instanz ist. SAPGW00 gehörtalso zur Datenbank-Instanz »00«. Das Gateway des Demo-Web AS istSAPGW18, da dieses sich auf Datenbankinstanz 18 installiert.

Parameter können auch in saprfc.ini hinterlegt werden

Anstatt die Parameter in der Kommandozeile anzugeben, können dieseauch in der Datei saprfc.ini hinterlegt werden. saprfc.ini muss im selbenVerzeichnis wie der zu registrierende RFC-Server liegen.

Listing 4.10 Beispiel einer SAPRFC.INI

/*===================================================*//* Type R: Register a RFC server program at a SAP gateway *//* or connect to an already registered RFC server program *//*===================================================*/DEST=RFCEXT_LISTENERTYPE=RPROGID=SAPR3.srfcservGWHOST=SAPr3.logosworld.comGWSERV=sapgw00RFC_TRACE=0

Kap04.fm Seite 73 Dienstag, 22. April 2003 2:31 14

Page 26: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

74 SAP R/3 Remote Function Call

SMGW zeigtregistrierte

Gateway-Dienste

Eine Übersicht der aktuell angemeldeten Dienste am SAP-Gateway liefertdie Transaktion SMGW unter dem Menüpunkt Logged Systems.

Listing 4.11 Optionen der Registrierung eines RFC-Servers an einem SAP-Gateway

C:\Programme\sapgui46b\SAPGUI\RFCSDK\bin>srfcservSyntax for start and run in register mode: srfcserv [options] with options = -D<destination with type 'R' in saprfc.ini> = -t RFC-Trace on or options = -a<program ID> e.g. <own host name>.srfcserv = -g<SAP gateway host name> e.g. hs0311 = -x<SAP gateway service> e.g. sapgw53 = -t RFC-Trace on = -L<SNC library, optional> = -S<SNC myname, optional> = -Q<SNC quality of protection, optional> Option L, S and Q can be set if working with SNC (Secure Network Communication).

4.6.2 Anlegen einer RFC-Destination für einen registrier-ten Listener

Um auf einen SAP-Gateway-Service zugreifen zu können, müssen Sie inder rufenden Instanz das Gateway als Destination in Transaktion SM59bekannt machen. An Stelle der festen IP-Adresse des zu rufenden Serversgeben Sie in diesem Fall den Namen an, unter dem sich das Gateway beiseiner Registrierung bei SAP bekannt macht.

4.6.3 Eigene RFC-Listener erstellen

Kompletter Codeeines Gateway-

Servers imRFC-SDK

Das SAP RFCSDK listet den kompletten Sourcecode der in C geschriebe-nen RFC-Listener rfcexec und srfcserv. Die ausführliche Dokumenta-tion zur Entwicklung eines Listeners findet sich in der Hilfe zum RFCSDKin saprfc.hlp.

Kap04.fm Seite 74 Dienstag, 22. April 2003 2:31 14

Page 27: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Das SAP RFC-Gateway 75

Listing 4.12 Abbildung 1.10Extrakte aus der Implementierung des rfcexec-Servers

static RFC_RC DLL_CALL_BACK_FUNCTION _loadds remote_pipe( RFC_HANDLE handle );static RFC_RC DLL_CALL_BACK_FUNCTION _loadds remote_file( RFC_HANDLE handle );static RFC_RC DLL_CALL_BACK_FUNCTION _loadds remote_exec( RFC_HANDLE handle );static RFC_RC DLL_CALL_BACK_FUNCTION _loadds mail ( RFC_HANDLE handle );/* main function for an RFC server program *//*ARGSUSED*/main( int argc, char ** argv ){ /* initialized data */ static RFC_ENV env; RFC_HANDLE handle; RFC_RC rc; if (argc == 1) { help(); return 0; }/* install error handler */ env.errorhandler = myErrorhandler; RfcEnvironment( &env );/* accept connection * (command line argv must be passed to RfcAccept) */ handle = RfcAccept( argv );/* static function to install offered function modules */ rc = install(handle); if( rc != RFC_OK ) {/* if error occured, close connection with error mes-sage and exit */ RfcAbort( handle, "Initialization error" ); exit(1); }static RFC_RC DLL_CALL_BACK_FUNCTION _loadds remote_pipe( RFC_HANDLE handle ){ char command[256]; RFC_PARAMETER parameter[4]; RFC_TABLE table[2]; RFC_RC rc;

Kap04.fm Seite 75 Dienstag, 22. April 2003 2:31 14

Page 28: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

76 SAP R/3 Remote Function Call

RFC_CHAR read_flag = 0; int mode; memset( command, 0, sizeof( command ) ); parameter[0].name = "COMMAND"; parameter[0].nlen = 7; parameter[0].addr = (void *) command; parameter[0].leng = sizeof(command); parameter[0].type = RFCTYPE_CHAR; parameter[1].name = "READ"; parameter[1].nlen = 4; parameter[1].addr = (void *) &read_flag; parameter[1].leng = sizeof(read_flag); parameter[1].type = RFCTYPE_CHAR; parameter[2].name = NULL; table[0].name = "PIPEDATA"; table[0].nlen = 8; table[0].type = RFCTYPE_CHAR; table[0].leng = table_size; table[0].itmode = RFC_ITMODE_BYREFERENCE; table[1].name = NULL; rc = RfcGetData( handle, parameter, table ); if( rc != RFC_OK ) return rc;#ifdef SAPonWINDOWS RfcAbort(handle, "Function RFC_REMOTE_PIPE is not supported on Windows"); exit(1);#endif if( read_flag != 'X' ) mode = RUN_WAIT; else mode = RUN_READ; rc = run( handle, command, sizeof(command), table[0].ithandle, mode, (RFC_INT *)0 ); if( rc != RFC_OK ) return rc; parameter[0].name = NULL; rc = RfcSendData( handle, parameter, table ); return rc;} /* remote_pipe */

Kap04.fm Seite 76 Dienstag, 22. April 2003 2:31 14

Page 29: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Troubleshooting RFC 77

4.7 Troubleshooting RFCSRFCTEST zum Testen von RFC

Es existiert ein Standard-ABAP in SAP R/3, SRFCTEST, in dem die wich-tigsten RFC-Möglichkeiten sehr gut demonstriert werden und auch gleichgetestet werden können.

Lokaler TestWenn ein Zugriff via SAP R/3 permanent versagt, testen Sie diegewünschte Funktionalität immer zunächst lokal im Zielsystem. Zum Bei-spiel setzen die Aufrufe über LOCAL_EXEC voraus, dass rfcexec.exe sichim Zugriffspfad des SAP GUI auf der Workstation befindet. In diesem Fallsollten Sie auf der Arbeitsstation ein DOS-Fenster öffnen und versuchen,rfcexec von einem beliebigen Verzeichnis auszuführen. Klappt diesnicht, müssen Sie rfcexec.exe in eines der Verzeichnisse kopieren, die mitdem PATH-Kommando angezeigt werden, oder Sie müssen den Suchpfadentsprechend erweitern.

Klappt das lokale Ausführen der Programme, haben Sie vermutlich einProblem mit der RFC-Verbindung an sich. Denkbar sind folgende häufigeStörgründe:

� Bei Aufrufen über Frontend ist die Wahrscheinlichkeit groß, dass dasSAP GUI unvollständig oder fehlerhaft installiert wurde. Hier empfiehltsich immer eine Neuinstallation des SAP GUI, um zu sehen, ob dasvielleicht schon den Fehler behebt.

� Prüfen Sie auch die TCP/IP-Verbindungsstrecke vom SAP-Applikations-server zur RFC-Destination. Das können Sie tun, indem Sie auf demApplikationsserver TELNET aufrufen, sich als SAP-Administrator anmel-den (normalerweise USER=SAPsid, wobei sid die System-ID ist) undvon dort einen PING auf die IP-Adresse der RFC-Destination durchfüh-ren. Auch das TRACEROUTE-Utility zum Anzeigen aller Verbindungs-knoten vom Aufrufer bis zum Ziel kann weitere Erkenntnisse geben(Name in Windows: tracert.exe).

Abbildung 4.5 Aufruf von rfcexec.exe über eine DOS-Box

Kap04.fm Seite 77 Dienstag, 22. April 2003 2:31 14

Page 30: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

78 SAP R/3 Remote Function Call

4.8 Aufruf von Remote Programs aus R/3 Via RFC

4.8.1 RFC via Remote Shell

Um Programme auf einem entfernten Rechner auszuführen, muss dieserzunächst dafür eingerichtet werden, Remote Program Calls zu akzeptie-ren. Dazu muss ein TCP/IP-Port auf dem Zielrechner so konfiguriert sein,dass er ankommende Nachrichten als Programmaufruf akzeptiert.

UNIX unterstütztstandardmäßig

RPC-Aufrufe

Um von einem UNIX-Rechner ein Programm auf einem anderen UNIX-Rechner aufzurufen, können Sie das Programm RSH (manchmal auchRSHELL) benutzen. RSH nimmt als Parameter die IP-Adresse des Zielrech-ners und einen String, der eine gültige Kommandozeile auf dem Zielrech-ner darstellen muss. Beachten Sie, dass RSH auf dem R/3-Applikationsser-ver ausgeführt wird, gegebenenfalls müssen Sie den Namen desZielrechners explizit spezifizieren.

Abbildung 4.6 Erfolgreicher und nicht erfolgreicher PING eines Remote-Computers

Abbildung 4.7 TRACERT zum Finden eines IP-Hosts

Kap04.fm Seite 78 Dienstag, 22. April 2003 2:31 14

Page 31: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Aufruf von Remote Programs aus R/3 Via RFC 79

UNIX nach Windows

Falls der Zielrechner ein Windows-Rechner ist, müssen Sie auf diesem einUtility installieren, das die RSH-Aufrufe entgegennimmt. Ein bewährtesTool ist der ATAMAN-Manager von ATAMAN.COM.

Windows nach Windows

Falls R/3 und die zu rufende Applikation beide auf einem Windows NT/2000-System laufen, können Sie für den Aufruf auch DCOM verwenden.

Rfcexec für einfache Anwendungen

Falls Sie wenig Erfahrung mit solchen Remote-Aufrufen haben, sollten Siedie Aufrufe immer durch das SAP-Utility rfcexec durchführen. Dies istnormalerweise als RFC-Destination SERVER_EXEC vordefiniert. Zuvortesten Sie dann den Aufruf des Programms auf dem Remote-System vonder Kommandozeile des SAP-Applikationsservers aus. Denn die Aufruf-Kette ist immer die folgende:

1. R/3 bestimmt über die in Transaktion SM59 gegebene Definition, wel-ches Programm aufgerufen werden soll, im Fall der DestinationSERVER_EXEC findet R/3 das Programm rfcexec.

2. Der R/3-Kernel führt jetzt das Programm rfcexec zusammen miteventuellen Parametern auf dem Rechner aus, dessen IP-Adresse inSM59 angegeben wurde.

3. rfcexec ruft eine Command-Shell auf und übergibt dieser die Parame-ter zur Ausführung.

4. rfcexec fängt die Ergebnisse ab und gibt sie an das rufende R/3-Sys-tem zurück.

4.8.2 RFC über Webserver

Sicherheit durch Gateway-Proxies

Im Zuge der Standardisierung von RPC-Aufrufen hat es sich heutebewährt, Daten und Programmaufrufe ausschließlich über HTTP auszu-tauschen. Dazu wird auf allen potenziellen Zielrechnern für unsereRemote-Aufrufe ein HTTP-Server installiert, sofern diese nicht ohnehinschon eingerichtet sind, wie es bei fast allen modernen Windows NT/2000-Systemen und den meisten Linux-Systemen der Fall ist.

Alle Remote-Aufrufe sind fortan ausschließlich HTTP-GET- oder HTTP-POST-Requests, die vom HTTP-Server interpretiert werden. Diegewünschte Aktion wird dann durch die aufgerufene ASP, JSP oder CGI-Page durchgeführt. Damit reduziert sich die Installation der RFCs auf SAP-Seite auf die Konfiguration der HTTP-Server.

Kap04.fm Seite 79 Dienstag, 22. April 2003 2:31 14

Page 32: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

80 SAP R/3 Remote Function Call

4.8.3 Aufruf eines Programms auf der Workstation mit RFC

R/3 verwendet die klassische Client-Server-Technik, um Programme aufeinem Remote-Rechner aufzurufen, wobei die Applikation auf demRemote-Rechner den Server darstellt und R/3 in die Client-Rolle schlüpft.

Rfcexec.exe dientals RFC-Server

für R/3

Dabei muss das zu rufende Programm den Konventionen des RFC-Proto-kolls entsprechen. Um Ihnen zu ersparen, jedes Mal dieses Protokoll inIhre Anwendung einzubinden, existiert ein Standard-RFC-Server rfce-xec, der als Proxy zwischen R/3 und einem Betriebssystemkommandodient.

rfcexec stellt festeFunktionsaufrufe

bereit

Das rfcexec-Objekt stellt die in der folgenden Tabelle aufgelistetenMethoden zur Verfügung. Diese erlauben im Wesentlichen, ein auszufüh-rendes Betriebssystemkommando zu übergeben und je nach Methodewahlweise den Ergebnisdatenstrom abzufangen und im rufenden Pro-gramm zur Verfügung zu stellen.

Methode Beschreibung

RFC_REMOTE_PIPEFUNCTION 'RFC_REMOTE_EXEC' IMPORTING command EXCEPTIONS system_failure communication_failure

Programm mit rfcexec ausführen.

RFC_REMOTE_PIPEFUNCTION 'RFC_REMOTE_PIPE' IMPORTING command TABLES pipedata(80) EXCEPTIONS system_failure communication_failure

Ein Programm ausführen, das Eingabe-daten durch die Inputpipe übernimmt und die Ergebnisse der Resultpipe zurückgibt. Die Resultpipe ist gewöhn-lich der Textdatenstrom, der von einer UNIX- oder DOS-Box zurückgegeben wird. Wenn Sie z.B. dir > mydata.txt aus-führen, wird das Ergebnis in die Datei mydata.txt umgeleitet. RFC_REMOTE_PIPE fängt diesen Datenstrom ab und tritt somit an die Stelle des Ausgabefiles.

file: = Name der Remote-Datei

pipedata: = Daten, die in die Input-pipe geschrieben werden

Tabelle 4.2 Vordefinierte Methoden des rfcexec.exe-Programms

Kap04.fm Seite 80 Dienstag, 22. April 2003 2:31 14

Page 33: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Aufruf von Remote Programs aus R/3 Via RFC 81

Syntaktisch sind interne und externe RFC gleich

Für ABAP sieht der Aufruf von rfcexece wie jeder andere RFC-Funkti-onsbaustein aus. Dem ABAP-Programm können Sie also nicht ansehen,dass der gerufene Funktionsbaustein kein R/3-Funktionsbaustein ist. DieDestination des Aufrufs wird mit dem Parameter Destination angege-ben und muss zuvor mit Transaktion SM59 definiert worden sein.

rfcexec.exe über Destination LOCAL_EXEC auf-rufen

In SAP R/3 ist standardmäßig eine RFC-Destination LOCAL_EXEC vorde-finiert, die das Programm rfcexec auf der Workstation des aktuellenUsers aufruft. SAP R/3 kommuniziert dazu über das SAP GUI, das dannüber OLE die gewünschte Aktion ausführt. rfcexec ist ein RFC-Server-program, das ein als Parameter mitgegebenes Programm auf der Kom-mandozeile von Windows ausführt und den zurückerhaltenen Daten-strom an SAP R/3 zurückmeldet.

Listing 4.13 Ausführen eines Programms auf einer Workstation von R/3 aus mit RFC_REMOTE_EXEC

DATA: command(256) DEFAULT 'echo Hello World. >> rfc-test.dat'DATA: rfc_mess(128).CALL FUNCTION 'RFC_REMOTE_EXEC' DESTINATION rfcdest EXPORTING command = command EXCEPTIONS system_failure = 1 MESSAGE rfc_mess communication_failure = 2 MESSAGE rfc_mess.

RFC_REMOTE_FILE

FUNCTION 'RFC_REMOTE_FILE' IMPORTING file(256) Write(1) TABLES filedata(80)

EXCEPTIONS system_failure

communication_failure

Lesen und Schreiben einer Datei via RFC.

file: = Name der Remote-Datei

write: = falls write=’X’, wird file-data in die Datei geschrieben, ansons-ten wird die Datei gelesen und deren Inhalt in filedata retourniert.

filedata: = Inhalt der Datei

Methode Beschreibung

Tabelle 4.2 Vordefinierte Methoden des rfcexec.exe-Programms

Kap04.fm Seite 81 Dienstag, 22. April 2003 2:31 14

Page 34: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

82 SAP R/3 Remote Function Call

Listing 4.14 Ausführen eines Programms auf einer Workstation von R/3 aus mit RFC_REMOTE_PIPE

DATA: command(256) DEFAULT 'echo Hello World. >> rfc-test.dat'DATA: rfc_mess(128).DATA: pipedata(80) occurs 0 with header line.CALL FUNCTION 'RFC_REMOTE_PIPE' DESTINATION rfcdest EXPORTING command = command read = 'X' TABLES pipedata = pipedata EXCEPTIONS system_failure = 1 MESSAGE rfc_mess communication_failure = 2 MESSAGE rfc_mess.

Listing 4.15 Lesen einer Datei von der Workstation von R/3 aus mit RFC_REMOTE_FILE

DATA: command(256) DEFAULT 'echo Hello World. >> rfc-test.dat'DATA: rfc_mess(128).DATA: pipedata(80) occurs 0 with header line.CALL FUNCTION 'RFC_REMOTE_FILE' DESTINATION rfcdest EXPORTING file = filename write = write "space: read the file; 'X': save filedata to filename TABLES filedata = filedata EXCEPTIONS system_failure = 1 MESSAGE rfc_mess communication_failure = 2 MESSAGE rfc_mess.

Kap04.fm Seite 82 Dienstag, 22. April 2003 2:31 14

Page 35: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Aufruf von Remote Programs aus R/3 Via RFC 83

Abbildung 4.8 Settings der vordefinierten RFC-Destination LOCAL_EXEC in SM59

Abbildung 4.9 Settings der vordefinierten RFC-Destination SERVER_EXEC in SM59

Kap04.fm Seite 83 Dienstag, 22. April 2003 2:31 14

Page 36: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

84 SAP R/3 Remote Function Call

4.8.4 Aufruf eines HTTP-Webservers von SAP R/3

DestinationSAPHTTPA

Um einen HTTP-Server aufzurufen, stellt SAP R/3 bereits geeignete RFC-Utilities zur Verfügung. Dabei handelt es sich um ein Utility SAPHTTP, dasauf dem SAP R/3-Applikationsserver ausgeführt wird. Alternativ kannSAPHTTP auch auf dem Frontend über SAP GUI ausgeführt werden.

FunktionenHTTP_GET und

HTTP_POST

Standardmäßig ist eine RFC-Destination SAPHTTPA bereits mit Transak-tion SM59 vordefiniert. Über diese können Sie dann HTTP-Anfragen ver-senden. Die beiden Funktionsbausteine HTTP_GET und HTTP_POSTerleichtern Ihnen dabei die Arbeit (siehe Listing ### und Listing ###).

Listing 4.16 Abruf einer URL mit ABAP

DATA: ABSOLUTE_URI(128) type c.data: response_headers(80) occurs 0 with header line.data: RESPONSE_ENTITY_BODY(120) occurs 0 with header line.ABSOLUTE_URI ='http://xml.amazon.com/onca/xml2?t=webservices-20' &'&tag=logosworldcom&dev-t=D2H3YO46KJJ615' &'&AsinSearch=3528057297&type=lite&f=xml'.CALL FUNCTION 'HTTP_GET' EXPORTING ABSOLUTE_URI = ABSOLUTE_URI RFC_DESTINATION = 'SAPHTTPA' PROXY = '192.168.69.64:8080'* IMPORTING* STATUS_CODE =* STATUS_TEXT =* RESPONSE_ENTITY_BODY_LENGTH = TABLES* REQUEST_ENTITY_BODY = RESPONSE_ENTITY_BODY = RESPONSE_ENTITY_BODY RESPONSE_HEADERS = RESPONSE_HEADERS* REQUEST_HEADERS = EXCEPTIONS CONNECT_FAILED = 1 TIMEOUT = 2 INTERNAL_ERROR = 3 TCPIP_ERROR = 4

Kap04.fm Seite 84 Dienstag, 22. April 2003 2:31 14

Page 37: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Aufruf von Remote Programs aus R/3 Via RFC 85

DATA_ERROR = 5 SYSTEM_FAILURE = 6 COMMUNICATION_FAILURE = 7 OTHERS = 8 .IF SY-SUBRC <> 0. write: / sy-subrc.ENDIF.loop at response_entity_body. write: / response_entity_body.endloop.

Listing 4.17 Ergebnis der HTTP-Anfrage mit HTTP_GET

Test for function group SFTP Function module HTTP_GET Upper/lower case Import parameters Value ABSOLUTE_URI http://localhost/postinfo.html REQUEST_ENTITY_BODY_LENGTH 0 RFC_DESTINATION SAPHTTP PROXY PROXY_USER PROXY_PASSWORD USER PASSWORD BLANKSTOCRLF Export parameters Value STATUS_CODE 200 STATUS_TEXT OK RESPONSE_ENTITY_BODY_LENGTH 2.651 Tables Value REQUEST_ENTITY_BODY 0 Entries Result: 0 Entries RESPONSE_ENTITY_BODY 0 Entries Result: 14 Entries RESPONSE_HEADERS 0 Entries

Kap04.fm Seite 85 Dienstag, 22. April 2003 2:31 14

Page 38: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

86 SAP R/3 Remote Function Call

Result: 11 Entries REQUEST_HEADERS 0 Entries Result: 0 Entries

Die HTTP-Header-Daten werden in genau der gleichen Form zurückgege-ben, wie sie im HTTP-Datenstrom empfangen werden:

Listing 4.18 HTTP-Header in Tabelle RESPONSE_HEADERS

HTTP/1.1 200 OK Server: Microsoft-IIS/5.0 Cache-Control: no-cache Expires: Sat, 08 Sep 2001 12:36:33 GMT Date: Sat, 08 Sep 2001 12:36:33 GMT Content-Type: text/html Accept-Ranges: bytes Last-Modified: Sun, 21 Jan 2001 14:24:08 GMT ETag: "0b4b1d0b583c01:96a" Content-Length: 2651 <blank line>

4.8.5 Proxy-Settings in ABAP

Proxy-Settings inTabelle THTTP

Falls ABAP die HTTP-Aufrufe über einen HTTP-Proxy ausführen muss,kann der Proxy für den ganzen Mandanten in der Tabelle THTTP vordefi-niert werden. Dabei geht SAP davon aus, dass der erste Eintrag in THTTPdie Angaben des System-Proxy darstellt.

Listing 4.19 Standardcoding zum Bestimmen des Proxy für ABAP-HTTP-Requests

form set_http_proxy using uri proxy proxy_user proxy_password. data: proxyflag type c. if proxy ne space. exit. endif. select single * from thttp. if thttp-exitfunc ne space. call function thttp-exitfunc exporting absolute_uri = uri importing proxy = proxyflag. if proxyflag eq 'X'. proxy = thttp-proxy.

Kap04.fm Seite 86 Dienstag, 22. April 2003 2:31 14

Page 39: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

RFC von SAP R/3 auf Windows 87

proxy_user = thttp-puser. proxy_password = thttp-ppassword. endif. endif.endform.

Zum besseren Verständnis sehen Sie hier die Struktur der Tabelle THTTP:

4.9 RFC von SAP R/3 auf Windows

4.9.1 Kommunikation mit Excel via OLE/2 und HTTP-Server

Excel ist eines der Akzeptanztools für PCs

Eines der beliebtesten Tools im Enterprise-Computing ist die Tabellenkal-kulation. Die einfache und einleuchtende Bedienung und die Möglich-keit, wiederkehrende Berechnungen in einer WYSIWYG-Umgebung ohneHilfe von EDV-Spezialisten vorzunehmen, ist etwas, das Sachbearbeiter inhohem Maße schätzen.

Da entsteht sehr rasch der Wunsch, die Daten in Excel zu erfassen, aberdoch sofort in SAP zur Verfügung zu haben, ohne diese mehrfach zuerfassen. Zur Lösung dieses Problems gibt es wie so oft mehrere Ansätze.SAP R/3 ist sehr wohl in der Lage, auf ein beliebiges DCOM-Objekt einesWindows-Rechners zuzugreifen und darauf OLE-Befehle abzusetzen. Esgibt auch hier die Möglichkeit eines 2-Tier- und eines 3-Tier-Ansatzes.

2-Tier: Direkt-zugriff via R/3-OLE auf Excel

R/3 bietet eine RFC-zu-OLE-Brücke für ABAP an. Damit kann man überdas SAP GUI mit einem auf der Workstation des Benutzers befindlichenOLE-Objekt kommunizieren. Hinreichende Beispiele für jemanden, derein wenig von VBA-Programmierung in MS Excel, MS Word und so weiterversteht, finden sich in der Transaktion /nOLE2. Der Nachteil dieserLösung ist natürlich, dass das Arbeitsblatt von der Arbeitsstation desangemeldeten SAP R/3-Benutzers aus zugreifbar sein muss. Dies kannman allerdings leicht erreichen, indem man das Arbeitsblatt auf einemvon SAP R/3 zugreifbaren Netzwerk-Verzeichnis abspeichert.

MANDT MANDT CLNT Client

PROXY PROXY CHAR HTTP proxy host name

PUSER PROXY_USER CHAR User name for HTTP proxy

PPASSWORD PROXY_PWD CHAR Password for HTTP proxy

EXITFUNC RS38L_FNAM CHAR Name of function module

Tabelle 4.3 Struktur der Tabelle THTTP

Kap04.fm Seite 87 Dienstag, 22. April 2003 2:31 14

Page 40: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

88 SAP R/3 Remote Function Call

3-Tier: Zugriff viaMiddleware

Eine Alternative ist wiederum, die Kommunikation zwischen SAP R/3 undExcel über einen Middleware-Broker durchzuführen. Dazu schickt SAPR/3 seine Anfrage an den Broker, welcher die gewünschte Aufgabe mitExcel aushandelt und das Ergebnis an SAP R/3 zurückmeldet. DieseLösung ist in aller Regel leichter zu realisieren und vor allem ist sie deut-lich stabiler.

4.9.2 Zugriff auf ein Excel-Datenblatt von R/3

Beispiel zumdirekten Zugriff

In diesem Kapitel stellen wir eine Möglichkeit vor, direkt mit SAP R/3 aufein bestehendes Excel-Arbeitsblatt zuzugreifen, in diesem eine Kalku-lation anzustoßen und die Ergebnisse in SAP R/3 zu importieren. DieKommunikation findet dabei über die OLE2-Bridge des SAP GUI derArbeitsstation des Benutzers statt. Diese Technik funktioniert in dergeschilderten Weise nicht, wenn die Transaktion nicht online ausgeführtwird, weil dann kein SAP GUI im Zugriff ist.

Stücklisten-kalkulation als

Beispiel

Für das Beispiel haben wir ein Spreadsheet definiert, in dem eine Stück-liste aufgeführt ist. In dieser Stückliste kann man in einer Zelle eineMenge eintragen. Es sind Formeln hinterlegt, die aus der Eingabe dieMengen der Komponenten errechnen. Die einzelnen Sektionen sind inExcel benannt, so dass wir es einfacher haben, auf die einzelnen Bereichezuzugreifen.

Abbildung 4.10 Spreadsheet zur Berechnung der Stückliste (Bill of Material)

������� ��������������� �� ����

���� � ������ � ������� � ��� ���������� ������ ������������

� � ! ��� �����

� � ��� ��� ���� �� ��

� � ��� ��� ���� ������

� � ��� ��� ��� !���

" � � ��� ���#$%$�#� ���&'(�)

� � "�� �� ����*�+� !��'����

, � �� ��� ����-� (.���'

/ ��� /���� )�0 ��#� ��&

Kap04.fm Seite 88 Dienstag, 22. April 2003 2:31 14

Page 41: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

RFC von SAP R/3 auf Windows 89

Testprogramm in VBA

Zugriff auf die Daten durch ein VBA-Programm

Zum Zweck der Entwicklung entwerfen wir erst ein Testprogramm, dasdie gewünschten Aktionen durch ein VBA-Programm simuliert. Die Ent-wicklungsumgebung von VBA hilft uns dabei, durch die Intellisense-Hilfedie richtigen Befehle, Methoden und Properties der Excel-Objekte zu fin-den und im Debugger eine robuste Zugriffsform zu testen. Wenn wir dieAufrufe später von SAP R/3 aus machen, wird uns der Debugger nichtmehr zur Verfügung stehen, weshalb wir das Testen außerhalb von SAPR/3 vornehmen.

Listing 4.20 VBA-Routine zum Setzen und Auslesen der BOM-Werte

Sub Read_Values_From_EXCEL() Dim ix As Integer Dim cellvalue As String Dim rowcount As Integer Dim h_appl As Excel.Application Dim h_book As Excel.Workbook Dim h_books As Excel.Workbooks

Abbildung 4.11 Benannte Bereiche im Spreadsheet

Abbildung 4.12 Formeln zur Berechnung

������� ��������������� �� ����

���� � ������ � ������� � ��� ���������� ������ ������������

� " ��� �����

� � ��� ���� 12()�&3������

� � ��� ���� 1�3���

� � ��� ��� ��&3���

" "� "� ��� ���#$%$�#� ���3���

� �� ��� ����*�+� 2�)( 3���

, � �� ����-� �� 3���

/ � �� ��#� ���&3��� ����������

4���&0�&&�.& ��4���&

��������� ��������������� �� ����

��������� �������� � ���������� ���������� ���������� ����������

� ��� ��� �����

� � ��������� ��� ���� �� ��

� ��������! ��� ��"� �#����

$ � ��������% ��� &��� '#��

( ���� ��� ���)*+*�)� ����,-�.

/ $ ���������� �� ����0"1� '#�,����

2 � ��������� 32 ��� ����4� -5���,

� /�� ���������$ .�6 ��)� ��� �

Kap04.fm Seite 89 Dienstag, 22. April 2003 2:31 14

Page 42: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

90 SAP R/3 Remote Function Call

Dim h_sheet As Excel.Worksheet Dim h_sheets As Excel.Sheets Dim h_range As Excel.Range Dim h_rows As Excel.Range Dim h_cell As Excel.Range Dim h_name As Excel.Name Set h_appl = New Excel.Application h_appl.Visible = False Set h_books = h_appl.Workbooks Set h_book = h_books.Open(FileName:="U:\_DEMO\BOM\BOM.XLS") Set h_sheets = h_book.Worksheets h_sheets.Select Set h_sheet = h_sheets.Item("SUPERSAVER") Set h_name = h_sheet.Names("QUANT") Set h_range = h_name.RefersToRange cellvalue = h_range(RowIndex:=1, ColumnIndex:=1).Value Debug.Print "Quant", cellvalue cellvalue = cellvalue + 5 h_range(RowIndex:=1, ColumnIndex:=1).Value = cellvalue h_appl.CalculateFull Set h_name = h_sheet.Names("RETURNS") Set h_range = h_name.RefersToRange Set h_rows = h_range.Rows rowcount = h_rows.Count For ix = 1 To rowcount cellvalue = h_range(RowIndex:=ix, ColumnIndex:=1).Value Debug.Print ix, cellvalue Next ix h_book.Close savechanges:=False h_appl.Quit Set h_appl = NothingEnd Sub

Kap04.fm Seite 90 Dienstag, 22. April 2003 2:31 14

Page 43: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

RFC von SAP R/3 auf Windows 91

Testprogramm in ASP

Aufruf als ASP-Skript

In einem nächsten Schritt versuchen wir, den Code aus einer anderenUmgebung aufzurufen. Dazu erzeugen wir ein ASP-Script, um die Datenals Webseite zu erhalten. Das gleiche Script können wir auch später vonSAP R/3 aufrufen und haben so bereits eine 3-Tier-Lösung für den Durch-griff von SAP R/3 auf Excel.

Listing 4.21 ASP-Script zum Setzen und Auslesen der BOM-Werte via OLE

<%Function Read_Values_From_EXCEL_VBS(myquant, filename) Dim Resultstr Dim ix Dim cellvalue Dim rowcount Dim h_appl Dim h_book Dim h_books Dim h_sheet Dim h_sheets Dim h_range Dim h_rows Dim h_cell Dim h_name resultstr = myquant & Chr(13) & Chr(10) Set h_appl = CreateObject("Excel.Application")' h_appl.Visible = False Set h_books = h_appl.Workbooks Set h_book = h_books.Open(filename) Set h_sheets = h_book.Worksheets h_sheets.Select Set h_sheet = h_sheets.Item("SUPERSAVER") Set h_name = h_sheet.Names("QUANT") Set h_range = h_name.RefersToRange cellvalue = h_range(1, 1).Value cellvalue = myquant h_range(1, 1).Value = cellvalue h_appl.CalculateFull

Kap04.fm Seite 91 Dienstag, 22. April 2003 2:31 14

Page 44: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

92 SAP R/3 Remote Function Call

Set h_name = h_sheet.Names("RETURNS") Set h_range = h_name.RefersToRange Set h_rows = h_range.Rows rowcount = h_rows.Count For ix = 1 To rowcount cellvalue = h_range(ix, 1).Value resultstr = resultstr & CellValue cellvalue = h_range(ix, 3).Value resultstr = resultstr & "," & CellValue & chr(13) & chr(10) Next' h_book.Save h_book.Close False h_appl.Quit Set h_appl = Nothing Read_Values_From_EXCEL_VBS = resultstrEnd Function

Response.write Read_Values_From_EXCEL_VBS(105, "BOM.XLS")%>

Direktzugriff von SAP R/3 auf Excel

Zugriff viaOLE-Brücke

Die Syntax zum Setzen und Aufrufen von COM-Objekten aus SAP R/3heraus ist etwas von der in Visual Basic verschieden, weshalb wir dasCoding nicht 1:1 übernehmen können. In Listing ### ist die ABAP-Ver-sion zu sehen, die mit den VBA-Kommandos kommentiert ist.

Listing 4.22 ABAP-Routine zum Setzen und Auslesen der BOM-Werte via OLE

REPORT ydemo_excel_bom MESSAGE-ID sy.INCLUDE ole2incl. "<-- Contains the types for OLE-AccessPARAMETER: filename LIKE rlgrap-filename DEFAULT 'U:\_DEMO\BOM\BOM.xls'.* Dim h_appl As Excel.ApplicationDATA: h_appl TYPE ole2_object.* Dim h_books As WorkbooksDATA: h_books TYPE ole2_object.* Dim h_book As WorkbookDATA: h_book TYPE ole2_object.

Kap04.fm Seite 92 Dienstag, 22. April 2003 2:31 14

Page 45: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

RFC von SAP R/3 auf Windows 93

* Dim h_sheets As Excel.SheetsDATA: h_sheets TYPE ole2_object.* Dim h_sheet As WorksheetDATA: h_sheet TYPE ole2_object.DATA: x_sheet TYPE ole2_object.* Dim h_name As NameDATA: h_name TYPE ole2_object.* Dim h_range As RangeDATA: h_range TYPE ole2_object.* Dim h_rows As RangeDATA: h_rows TYPE ole2_object.* Dim h_cell As RangeDATA: h_cell TYPE ole2_object.DATA: cellvalue(29).DATA: rowcount TYPE i.START-OF-SELECTION.* Set h_appl = New Excel.Application CREATE OBJECT h_appl 'EXCEL.APPLICATION'. IF sy-subrc NE 0. MESSAGE i002 WITH sy-msgli. ENDIF.* h_appl.Visible = True SET PROPERTY OF h_appl 'VISIBLE' = 1 .* Set h_books = h_appl.Workbooks GET PROPERTY OF h_appl 'WORKBOOKS' = h_books .* Set h_book = h_books.Open(Filename:= "\BOM.*XLS") CALL METHOD OF h_books 'OPEN' = h_book EXPORTING #filename = filename.* GET PROPERTY OF h_appl 'ACTIVEWORKBOOK' = h_book.* Set h_sheets = h_book.Worksheets GET PROPERTY OF h_book 'WORKSHEETS' = h_sheets .* Set h_sheet = h_sheets.Item("SUPERSAVER")* GET PROPERTY OF h_book 'ACTIVESHEET' = h_sheet. CALL METHOD OF h_sheets 'ITEM' = h_sheet EXPORTING #index = 'SUPERSAVER' .****** Modify the Pivot Cell *************************** Set h_name = h_sheet.Names("QUANT") CALL METHOD OF h_sheet 'NAMES' = h_name EXPORTING #index ='QUANT' .* Set h_range = h_name.RefersToRange GET PROPERTY OF h_name 'REFERSTORANGE' = h_range.

Kap04.fm Seite 93 Dienstag, 22. April 2003 2:31 14

Page 46: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

94 SAP R/3 Remote Function Call

CALL METHOD OF h_range 'CELLS' = h_cell EXPORTING #1 = 1 #2 = 1. GET PROPERTY OF h_cell 'VALUE' = cellvalue. WRITE: / 'Old value':, cellvalue. cellvalue = cellvalue + 5. WRITE: / 'New value':, cellvalue. ULINE. SET PROPERTY OF h_cell 'VALUE' = cellvalue. CALL METHOD OF h_appl 'CALCULATEFULL'.****** Now, Pick up results **************************** Set h_name = h_sheet.Names("SUBQUANT") CALL METHOD OF h_sheet 'NAMES' = h_name EXPORTING #index ='RETURNS'.* Set h_range = h_name.RefersToRange GET PROPERTY OF h_name 'REFERSTORANGE' = h_range.* GET PROPERTY OF h_appl 'ACTIVECELL' = h_range.* cellvalue = h_cell.Value CALL METHOD OF h_range 'ROWS' = h_rows.* Set h_rows = h_range.Rows CALL METHOD OF h_rows 'COUNT' = rowcount.

DO rowcount TIMES. CALL METHOD OF h_range 'CELLS' = h_cell EXPORTING #1 = sy-index #2 = 1.* EXPORTING #rowindex = 1 #columnindex = sy-index. CALL METHOD OF h_cell 'VALUE' = cellvalue. WRITE: / sy-index, cellvalue. ENDDO.* h_book.Close false* CALL METHOD OF h_book 'SAVE'. CALL METHOD OF h_book 'CLOSE' EXPORTING #1 = 0.* h_appl.Quit CALL METHOD OF h_appl 'QUIT'.* Set h_appl = Nothing FREE OBJECT h_appl.

Kap04.fm Seite 94 Dienstag, 22. April 2003 2:31 14

Page 47: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 95

4.10 Business-Objekte und BAPI

Eine der großen Stärken von SAP R/3 liegt darin, dass es Geschäftspro-zesse de facto standardisiert. Solche Quasi-Standards werden als Busi-ness-Objekte bezeichnet. Um auf die Business-Objekte zugreifen zu kön-nen, wurden für diese Schnittstellen geschaffen, die als BAPI bezeichnetwerden.

Business-Objekte sind formale Modelle von realen Prozessen

Eines der Kernziele einer modernen Business-Software ist die Geschäfts-prozessmodellierung mit Hilfe einer Programmiersprache. Damit soll eineStandardisierung der Geschäftsprozesse möglich werden. SAP ist alleindurch seine Marktmacht dazu prädestiniert, solche Business-Modelle vor-zugeben und zu vereinheitlichen. Business-Objekte sind solche Modellie-rungen von realen Geschäftsprozessen innerhalb von SAP-Systemen. Busi-ness-Objekte beschreiben und implementieren die Methoden, Propertiesund Interfaces dieser Prozesse mit den Mitteln von ABAP Objects.

Geschäftsmodelle aus Sicht eines Entwicklers

Aus der Sicht eines Entwicklers besteht ein Geschäftsprozessmodell ausden drei Elementen:

� DatabaseHier werden die Daten in proprietärer Form abgespeichert.

� Business-ObjektEine abstrakte Projektion der Realität mit den Mitteln der Program-miersprache.

� Application Programming Interface (API)Schnittstelle für den Zugriff auf die Business-Objekte von einer Pro-grammiersprache aus.

Zugriff über Business-API

Der Zugriff auf die Business-Objekte erfolgt über eine öffentlich bekannteBusiness-API – das Business Application Programming Interface, kurzBAPI – und ist technisch eine Untermenge der RFC-fähigen Funktions-bausteine in R/3. BAPIs sind die offizielle Außenschnittstelle, mit derZugriffe von Fremdsystemen auf R/3 erfolgen sollen.

4.10.1 Business-Objekte und Modellsichten

Business-Objekte sind die technische Beschreibung einer der Modellsich-ten auf einen Prozess. In einfachen Fällen kommen wir mit den folgendenModellsichten aus:

Kap04.fm Seite 95 Dienstag, 22. April 2003 2:31 14

Page 48: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

96 SAP R/3 Remote Function Call

� Technische Sicht (Komponentensicht)In der Technischen Sicht werden die Objekte beschrieben, wie sie tat-sächlich auf dem Computer realisiert werden. Hier bestimmen wir also,welche Tabellen in der Datenbank angelegt werden, welche Daten-bank-Engine überhaupt verwendet wird, welche Protokolle zum Aus-tausch der Daten benutzt werden, und in welcher Programmierspra-che wir arbeiten.

� Anwendungsfall (Use Case) Die Anwendungsfälle beschreiben die Operationen, die wir auf denDaten durchführen wollen, etwa einen Logon, Aufträge speichern,nach Aufträgen suchen und so weiter.

� Business View (Logische Sicht)Der Business View ist die abstrakte Ebene, die versucht, unbelastet vonden technischen Details die logischen Komponenten einer Applikationzu beschreiben. Dabei denken wir an die Organisation in Stammdaten,an Kundenaufträge oder einen Internetshop. Wichtig dabei ist, dassdie Logische Sicht zunächst frei von Restriktionen formuliert werdendarf, also so nah wie möglich dem Denken bei der realen Arbeit ent-sprechen soll.

Abbildung 4.13 Beispiel für Modellsichten

��������������� ����� ���������������

� �����!����������� "���#���������

$%&� ��������� '�(�� ��������(���

�)�**���� ���

�����)

)��+�'"�

������� �����7*�& ���*����7*�&

-+���)��)��� ��8*� ��)�

� � �

��09��)�7*�& �������� :�4*�1�7*�&

��;*�;�� *;) �&���4�+<11� :�4*�;�� *;)

��(��!��,�

Kap04.fm Seite 96 Dienstag, 22. April 2003 2:31 14

Page 49: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 97

Formale Beschrei-bung eines Business-View

Ein Business-Objekt ist nun eine formale Beschreibung eines BusinessViews. Demnach gibt es Business Views für jede logische Entität, zum Bei-spiel für den Materialstamm, Kundenstamm, Kundenaufträge oder füreine ganze Shopping-Cart-Applikation. Materialstamm, Kundenstammund Kundenaufträge sind als Business-Objekte schon in SAP R/3 definiertund dafür gibt es auch schon die passenden BAPIs.

Business Object Repository – BOR

Alle öffentlichen Business-Objekte sind im SAP R/3 Business Object Repo-sitory (BOR) registriert. Dieses mit den Transaktionen BAPI und SWO1(Business Object Builder) zugängliche Verzeichnis zeigt die vorhandenenBusiness-Objekte, deren Methoden und die Implementierung an.

Die Shopping-Cart-Applikation als Business-Objekt ist eine Sonderent-wicklung von Logos! Informatik GmbH und Casabac GmbH. Näheres undeinen Download der neuesten Versionen finden Sie unter shopping-cart.logosworld.com.

Abbildung 4.14 Business-Sichten in SAP R/3

����������� �������� ������������ ����� �� �������� �� �������������������������������

������������� ���������

�������������� ���� ���� ����� ��

��� �!�"����

���#�!�"$�����%�!�& ����

���� '���� ��

���� �������

���� � ������

�������������� ���� ���� ����� ��

(&� �!�"����(&�#�!�"$��

(&�%�!�& ����

���� ������ ��

����������� ���� ���� ����� ��

�)� �!�"����

�)�#�!�"$���)�%�!�& ����

�� � '���$���

*���� ��

�����!��������

��������"��

�#�� #$�� ����� ��

�+ �!�"����

�+ #�!�"$���+ %�!�& ����

#$�# '���$���

*���� ��

����%������

����������� ����� ��� ����

Kap04.fm Seite 97 Dienstag, 22. April 2003 2:31 14

Page 50: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

98 SAP R/3 Remote Function Call

Abbildung 4.15 Business-Objekte in SAP R/3-SD

Abbildung 4.16 Business-Objekt BUS1093 (ExchangeRate) in Transaktion BAPI

����������� �� ��� ����

�������� �

����������

�����������

���

���

� ���

���������� �� ���� ����

�������� �

����������

�����������

���� � ���

����������

���������

�� ��� ����

������������� ���� �������� �

����������

�����������

��� � ���

������� � �!� ����

�������� �

����������

�����������

�!� � ���

�"����������� #�$ ���� ����

�������� �

����������

�����������

���� � ���

����%������&��

!�'"����

#�$ �#�$( ���� ����

�������� �

����������

�����������

��� ���

�! ���

���� � ���

�"����������� #�$ ���� ����

�������� �

����������

�����������

���� � ���

�#���� ��$�%� �%%�&��'%�� �()*��+

Kap04.fm Seite 98 Dienstag, 22. April 2003 2:31 14

Page 51: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 99

4.10.2 Technische Kriterien eines BAPI

BAPI ist die Implementierung eines Business-Objekts

Ein BAPI ist eine Implementierung eines Business-Objekts, die öffentlicheMethoden zur Verfügung stellt. In der Realisierung verbirgt sich hinterjeder Methode ein Funktionsbaustein. Zusätzlich erhält aber jedeMethode noch eine zum SAP Business Workflow kompatible Objekt-schnittstelle in SWO1. Wenn von BAPI die Rede ist, ist selten das Busi-ness-Objekt selbst gemeint, sondern meistens der BAPI-Funktionsbau-stein, der eine der vielen Methoden eines BAPI implementiert. So istbeispielsweise das BAPI zum Kundenauftragsmodell BUS2032, und BAPI_SALESORDER_CREATEFROMDAT2 ist der BAPI-Funktionsbaustein zurMethode CreateFromDat2.

Technisch ist eine BAPI-Funktion ein RFC-Funktions-baustein

Aus technischer Sicht besteht kein Unterschied zwischen einem BAPI-Funktionsbaustein und gewöhnlichen RFC-Bausteinen. Allerdings unter-wirft SAP ein BAPI gewissen Konventionen, die jeder beachten sollte, derstandardkonforme BAPIs entwickeln möchte:

� Ein BAPI führt niemals ein COMMIT WORK oder einen ROLLBACK WORKaus. Der Sinn davon ist, dass eine externe Applikation eigene Transak-tionen als Sequenzen von BAPI-Methoden ausführen kann.

� Das Ende einer Transaktion wird durch die speziellen BAPI-Funktions-bausteine BAPI_TRANSACTION_COMMIT und BAPI_TRANSACTION_ROLLBACK erreicht.

� Alle Schnittstellenparameter sollen einen aussagekräftigen, englischenNamen haben.

Abbildung 4.17 Business-Objekt BUS1093 (ExchangeRate) in Transaktion SWO1

Kap04.fm Seite 99 Dienstag, 22. April 2003 2:31 14

Page 52: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

100 SAP R/3 Remote Function Call

4.10.3 Anwendungsbeispiel: Das Sales-Order-BAPI

Kundenaufträgesind zentral für SD

Wir haben als Beispiel für die Anwendung eines BAPI das Sales-Order-Objekt ausgewählt, das ein ganz zentrales Business-Objekt in SAP ist.Dieses wird verwendet für das Anlegen, Ändern und Anzeigen von

� Kundenaufträgen

� Angebotsanfragen (Request for quotation – RFQ)

� Gut- und Lastschriftenanforderungen

� AuslieferungsaufträgenAuslieferungsaufträge sind Aufträge, die automatisch eine Lieferungerzeugen. Man verwendet sie unter anderem zum Ausliefern in meh-reren Einzellieferungen. Dabei wird der Auslieferungsauftrag mit Bezugzum Originalauftrag angelegt. Der Auslieferungsauftrag ist so einge-stellt, dass automatisch eine Auslieferung (Objekt LIKP) erstellt wird,gegebenenfalls mit anschließendem automatischen Versand.

� Anstoßen von Auslieferungen Das Business-Objekt-Konzept von SAP R/3 sieht es nicht vor, Ausliefe-rungen direkt durch eine Schnittstelle anzulegen. Der zentrale Einstiegs-punkt für jede SD-Transaktion ist das Sales-Order-BAPI. Dazu muss derKundenauftrag bestimmte Customizing-Anforderungen erfüllen:

� Der Kundenauftragstyp (TVAK-AUART) muss auf automatischesAnlegen einer Auslieferung eingestellt sein.

� Das Anlegen der Auslieferung muss vom Status des Kundenauftragsabhängig sein, zum Beispiel durch Setzen des Feldes Liefersperre imKopf (VBAK-LIFSK) oder Position (VBAP-LIFSP).

� Anstoßen von Fakturen.

� Der Kundenauftragstyp (TVAK-AUART) muss auf automatischesAnlegen einer Faktura eingestellt sein.

� Das Anlegen der Faktura muss vom Status des Kundenauftragsabhängig sein, zum Beispiel durch Setzen des Feldes Fakturasperreim Kopf (VBAK-FAKSK) oder Position (VBAP-FAKSP)

Kundenauftragsbestand abfragen

� Methode: SalesOrder.GetList

� Funktion: BAPI_SALESORDER_GETLIST

Die BAPI-Methode gibt eine Liste aller Kundenaufträge eines bestimmtenKunden zurück. Die Liste kann auf Materialnummern und bestimmteZeiträume eingeschränkt werden.

Kap04.fm Seite 100 Dienstag, 22. April 2003 2:31 14

Page 53: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 101

Kundenauftrag anlegen

� Methode: SalesOrder.CreateFromDat2

� Funktion: BAPI_SALESORDER_CREATEFROMDAT2

Diese BAPI-Methode legt einen Kundenauftrag komplett neu an und ver-wendet dazu die übergebenen Daten. Die Methode kann alle business-relevanten Daten aufnehmen und erlaubt es, einen Kundenauftrag aufeinen Schlag anzulegen.

Erst Kopf, dann Position anlegen

In unseren Beispielen weiter unten zeigen wir einen Mehrschritt-Ansatz,indem wir zunächst den Auftragskopf (also nur VBAK) ohne Verkaufspo-sitionen (VBAP) anlegen. Später fügen wir die Positionen mit derMethode BAPI_SALESORDER_CHANGE hinzu.

Kundenauftrag ändern

� Methode: SalesOrder.Change

� Funktion: BAPI_SALESORDER_CHANGE

Einzelnes Ändern von Feldwerten

Diese BAPI-Methode ermöglicht es, einen bestehenden Kundenauftrag inallen Einzelheiten zu ändern, also insbesondere auch Positionen oder Ein-teilungsdaten hinzuzufügen oder zu löschen und selbstverständlich allebereits bestehenden Werte einzeln zu ändern.

Kundenauftrag oder Kundenauftragspositionen löschen

Löschen: Updateflag = »D«

Löschen ist wie in jeder professionellen Datenbank oder Transaktionsum-gebung nur eine Variante des Änderns. Dazu muss lediglich dasUpdateflag = "D" für Delete gesetzt werden.

4.10.4 Beispiel: BAPI_SALESORDER_GETLIST

Liste aller Kun-denaufträge

Im Folgenden sehen Sie ein fertiges Rahmenprogramm zum Aufruf desBAPIs, das eine Liste aller Kundenaufträge zu einem Kunden zurückgibt.

Listing 4.23 ABAP: Call BAPI_SALESORDER_GETLIST

'**** Functions in LibraryPublic func As SAPFunctionsOCX.FunctionPublic XMLDOC As New MSXML2.DOMDocumentPrivate myR3 As R3LogonObjPrivate XMLhelp As New XMLhelper'**** ParametersPublic iCUSTOMER_NUMBER As SAPFunctionsOCX.Parameter

Kap04.fm Seite 101 Dienstag, 22. April 2003 2:31 14

Page 54: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

102 SAP R/3 Remote Function Call

Public iDOCUMENT_DATE As SAPFunctionsOCX.ParameterPublic iDOCUMENT_DATE_TO As SAPFunctionsOCX.ParameterPublic iMATERIAL As SAPFunctionsOCX.ParameterPublic iPURCHASE_ORDER As SAPFunctionsOCX.ParameterPublic iPURCHASE_ORDER_NUMBER As SAPFunctionsOCX.Para-meterPublic iSALES_ORGANIZATION As SAPFunctionsOCX.ParameterPublic iTRANSACTION_GROUP As SAPFunctionsOCX.ParameterPublic eRETURN As SAPFunctionsOCX.StructurePublic tSALES_ORDERS As SAPTableFactoryCtrl.Table

Public Sub Class_Initialize() Set myR3 = New R3LogonObj myR3.R3Logon'*************** Creating the object reference for the RFC Functions'==================================================== Set func = myR3.Functions.Add("BAPI_SALESORDER_GETLIST")'*************** Creating the object reference for the Parameters'=================================================='**** Importing Parameters Set iCUSTOMER_NUMBER = func.Exports("CUSTOMER_NUMBER") Set iDOCUMENT_DATE = func.Exports("DOCUMENT_DATE") Set iDOCUMENT_DATE_TO = func.Exports("DOCUMENT_DATE_TO") Set iMATERIAL = func.Exports("MATERIAL") Set iPURCHASE_ORDER = func.Exports("PURCHASE_ORDER") Set iPURCHASE_ORDER_NUMBER = func.Exports("PURCHASE_ORDER_NUMBER") Set iSALES_ORGANIZATION = func.Exports("SALES_ORGANIZATION") Set iTRANSACTION_GROUP = func.Exports("TRANSACTION_GROUP")'**** Exporting Parameters Set eRETURN = func.Imports("RETURN")'**** Table Parameters

Kap04.fm Seite 102 Dienstag, 22. April 2003 2:31 14

Page 55: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 103

Set tSALES_ORDERS = func.Tables("SALES_ORDERS")End Sub ' Class_Initialize()

Public Sub Class_Terminate() Set func = Nothing Set myR3 = NothingEnd Sub ' Class_Terminate()

Public Sub Execute() func.CallEnd Sub ' Class_Initialize()

Public Sub Connect()End Sub ' Connect

Public Function toXMLDoc() As MSXML2.DOMDocument Set toXMLDoc = XMLhelp.toXMLDoc(func)End Function

Public Function toXML() As String toXML = toXMLDoc.XMLEnd Function

Listing 4.24 ABAP: Anlegen eines Auftragskopfs mit BAPI_SALESORDER_CREATEFROMDAT2

*&----------------------------------------------------**& Report YDEMO_BAPI_2032_CREATE_HEADER*&----------------------------------------------------**& This routines demonstrates the use of the BAPI **& BAPI_SALESORDER_CREATEFROMDAT2*& It calls the BAPI and creates the header of a sales *& orders*& w/o creating any items so far.*&----------------------------------------------------*REPORT YDEMO_BAPI_2032_CREATE_HEADER.TYPE-POOLS: SYDES.PARAMETERS: VBELN LIKE VBCOM-VBELN OBLIGATORY MEMORY ID AUN.PARAMETERS: AUART LIKE VBCOM-AUART OBLIGATORY MEMORY ID AUA.

Kap04.fm Seite 103 Dienstag, 22. April 2003 2:31 14

Page 56: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

104 SAP R/3 Remote Function Call

PARAMETERS: KUNAG LIKE VBCO2-KUNNR OBLIGATORY MEMORY ID KUN.PARAMETERS: KUNWE LIKE VBCO2-KUNWE OBLIGATORY MEMORY ID WEM.PARAMETERS: VKORG LIKE VBCOM-VKORG OBLIGATORY MEMORY ID VKO.PARAMETERS: VTWEG LIKE VBCOM-VTWEG OBLIGATORY MEMORY ID VTW.PARAMETERS: SPART LIKE VBCOM-SPART OBLIGATORY MEMORY ID SPA.PARAMETERS: AUDAT LIKE VBCOM-AUDAT OBLIGATORY MEMORY ID AUD.PARAMETERS: REFVBELN LIKE VBCOM-VBELN MEMORY ID AUB.PARAMETERS: REFVGTYP LIKE VBAK-VGTYP DEFAULT 'C'.

DATA: ORDER_HEADER_IN LIKE BAPISDHD1.DATA: ORDER_HEADER_OUT LIKE BAPISDHD1.DATA: SALESDOCUMENT LIKE BAPIVBELN-VBELN.DATA: RETURN LIKE STANDARD TABLE OF BAPIRET2 WITH HEADER LINE.DATA: ORDER_ITEMS_IN LIKE STANDARD TABLE OF BAPISDITM WITH HEADER LINE.DATA: ORDER_PARTNERS LIKE STANDARD TABLE OF BAPIPARNR WITH HEADER LINE.

START-OF-SELECTION. PERFORM BAPI_SALESORDER_CREATE USING VBELN AUART KUNAG KUNWE VKORG VTWEG SPART AUDAT REFVBELN REFVGTYP.*ERFORM bapi_salesorder_getcreate WRITE: / 'Returned sales order number:' , SALESDOCUMENT COLOR COL_TOTAL. ULINE. LOOP AT RETURN. CALL FUNCTION 'MESSAGE_TEXT_BUILD' EXPORTING MSGID = RETURN-ID MSGNR = RETURN-NUMBER MSGV1 = RETURN-MESSAGE_V1 MSGV2 = RETURN-MESSAGE_V2

Kap04.fm Seite 104 Dienstag, 22. April 2003 2:31 14

Page 57: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 105

MSGV3 = RETURN-MESSAGE_V3 MSGV4 = RETURN-MESSAGE_V4 IMPORTING MESSAGE_TEXT_OUTPUT = SY-LISEL EXCEPTIONS OTHERS = 1. WRITE: / SY-LISEL COLOR COL_NORMAL.. ENDLOOP.*-----------------------------------------------------*FORM BAPI_SALESORDER_CREATE USING VALUE(DOCNO) LIKE VBCOM-VBELN VALUE(DOC_TYPE) LIKE VBCOM-AUART VALUE(SOLDTO) LIKE VBCOM-KUNNR VALUE(SHIPTO) LIKE VBCOM-KUNNR VALUE(SALESORG) LIKE VBCOM-VKORG VALUE(DISTRCHANNEL) LIKE VBAK-VTWEG VALUE(DIVISION) LIKE VBCOM-SPART VALUE(ORDERDATE) LIKE VBCOM-AUDAT VALUE(REFDOCNO) LIKE VBCOM-VBELN VALUE(REFDOC_TYPE) LIKE VBAK-VGTYP.

REFRESH ORDER_ITEMS_IN. REFRESH ORDER_PARTNERS. CLEAR ORDER_HEADER_IN. CLEAR RETURN. CLEAR SALESDOCUMENT.

SALESDOCUMENT = VBELN. IF NOT REFDOCNO IS INITIAL. ULINE. FORMAT RESET COLOR COL_NEGATIVE. WRITE:/ 'The reference does not work in 40B HP65 due to an error when'. WRITE:/ 'calling SD_SALES_DOCU_SAVE from SD_SALES_DOCUMENT_MAINTAIN. '. ULINE. FORMAT RESET. ENDIF. ORDER_HEADER_IN-REFOBJTYPE = 'BUS2032'. ORDER_HEADER_IN-REFOBJKEY = REFDOCNO. ORDER_HEADER_IN-REFDOCTYPE = REFDOC_TYPE. ORDER_HEADER_IN-DOC_TYPE = AUART.

Kap04.fm Seite 105 Dienstag, 22. April 2003 2:31 14

Page 58: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

106 SAP R/3 Remote Function Call

ORDER_HEADER_IN-SALES_ORG = SALESORG. ORDER_HEADER_IN-DISTR_CHAN = DISTRCHANNEL. ORDER_HEADER_IN-DIVISION = DIVISION. ORDER_HEADER_IN-REQ_DATE_H = ORDERDATE.

ORDER_PARTNERS-PARTN_ROLE = 'AG'. ORDER_PARTNERS-PARTN_NUMB = SOLDTO. APPEND ORDER_PARTNERS. ORDER_PARTNERS-PARTN_ROLE = 'WE'. ORDER_PARTNERS-PARTN_NUMB = SHIPTO. APPEND ORDER_PARTNERS.

CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2' EXPORTING SALESDOCUMENT = SALESDOCUMENT ORDER_HEADER_IN = ORDER_HEADER_IN* ORDER_HEADER_INX =* SENDER =* BINARY_RELATIONSHIPTYPE = ' '* INT_NUMBER_ASSIGNMENT = ' '* BEHAVE_WHEN_ERROR = ' '* LOGIC_SWITCH = ' '* TESTRUN = ' '* CONVERT = ' ' IMPORTING SALESDOCUMENT_EX = SALESDOCUMENT TABLES RETURN = RETURN* order_items_in = order_items_in* ORDER_ITEMS_INX = ORDER_PARTNERS = ORDER_PARTNERS* ORDER_SCHEDULES_IN =* ORDER_SCHEDULES_INX =* ORDER_CONDITIONS_IN =* ORDER_CFGS_REF =* ORDER_CFGS_INST =* ORDER_CFGS_PART_OF =* ORDER_CFGS_VALUE =* ORDER_CFGS_BLOB =* ORDER_CFGS_VK =

Kap04.fm Seite 106 Dienstag, 22. April 2003 2:31 14

Page 59: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 107

* ORDER_CFGS_REFINST =* ORDER_CCARD =* ORDER_TEXT =* ORDER_KEYS =* EXTENSIONIN =* PARTNERADDRESSES = EXCEPTIONS OTHERS = 1. COMMIT WORK.

ENDFORM.

Die Auftragspositionen können jederzeit an einen bestehenden Auftragangefügt werden. Das wird genau wie das Ändern eines Auftrags durchden BAPI BAPI_SALESORDER_CHANGE erledigt:

Listing 4.25 ABAP: Zufügen von Auftragspositionen mit BAPI_SALESORDER_CHANGE

TYPE-POOLS: SYDES.FORM BAPI_SALESITEM_ADD USING VALUE(DOCNO) LIKE VBCOM-VBELN VALUE(POSNR) LIKE VBAP-POSNR VALUE(MATNR) LIKE VBAP-MATNR VALUE(QUANT) LIKE VBAP-KWMENG VALUE(VRKME) LIKE VBAP-VRKME VALUE(CONDI) LIKE KONV-KSCHL VALUE(NETPR) LIKE VBAP-NETPR VALUE(CURR_ISO) LIKE BAPISDITM-CURR_ISO. DATA: ORDER_HEADER_IN LIKE BAPISDH1. DATA: ORDER_HEADER_INX LIKE BAPISDH1X. DATA: ORDER_HEADER_OUT LIKE BAPISDHD1. DATA: SALESDOCUMENT LIKE BAPIVBELN-VBELN. DATA: ORDER_ITEMS_IN LIKE STANDARD TABLE OF BAPISDITM WITH HEADER LINE. DATA: ORDER_ITEMS_INX LIKE STANDARD TABLE OF BAPISDITMX WITH HEADER LINE. DATA: SCHEDULE_LINES LIKE STANDARD TABLE OF BAPISCHDL WITH HEADER LINE. DATA: SCHEDULE_LINESX LIKE STANDARD TABLE OF BAPISCHDLX WITH HEADER LINE. DATA: CONDITIONS_IN LIKE STANDARD TABLE OF

Kap04.fm Seite 107 Dienstag, 22. April 2003 2:31 14

Page 60: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

108 SAP R/3 Remote Function Call

BAPICOND WITH HEADER LINE. DATA: CONDITIONS_INX LIKE STANDARD TABLE OF BAPICONDX WITH HEADER LINE. DATA: RETURN LIKE STANDARD TABLE OF BAPIRET2 WITH HEADER LINE. REFRESH: ORDER_ITEMS_IN, ORDER_ITEMS_INX. REFRESH: SCHEDULE_LINES, SCHEDULE_LINESX. CLEAR: ORDER_HEADER_IN, ORDER_HEADER_INX. CLEAR: SCHEDULE_LINES, SCHEDULE_LINESX. CLEAR: RETURN, SALESDOCUMENT. SALESDOCUMENT = DOCNO. ORDER_HEADER_INX-UPDATEFLAG = 'U'. ORDER_ITEMS_IN-ITM_NUMBER = POSNR. ORDER_ITEMS_IN-MATERIAL = MATNR. ORDER_ITEMS_IN-TARGET_QTY = QUANT. ORDER_ITEMS_IN-TARGET_QU = VRKME. ORDER_ITEMS_IN-SALES_UNIT = VRKME. ORDER_ITEMS_IN-TARGET_VAL = PRICE. ORDER_ITEMS_IN-CURR_ISO = CURR_ISO. ORDER_ITEMS_INX-ITM_NUMBER = ORDER_ITEMS_IN- ITM_NUMBER. ORDER_ITEMS_INX-UPDATEFLAG = 'I'. APPEND ORDER_ITEMS_IN.*-----------------------------------------------------* SCHEDULE_LINES-ITM_NUMBER = ORDER_ITEMS_IN- ITM_NUMBER. SCHEDULE_LINES-REQ_DATE = SY-DATUM + 7. SCHEDULE_LINES-REQ_QTY = QUANT. APPEND SCHEDULE_LINES. SCHEDULE_LINESX-ITM_NUMBER = SCHEDULE_LINES- ITM_NUMBER. SCHEDULE_LINESX-UPDATEFLAG = 'I'. APPEND SCHEDULE_LINESX.*-----------------------------------------------------* IF NOT ( PRICE IS INITIAL OR CONDI IS INITIAL ). CONDITIONS_IN-ITM_NUMBER = ORDER_ITEMS_IN- ITM_NUMBER. CONDITIONS_IN-COND_TYPE = CONDI. CONDITIONS_IN-COND_VALUE = PRICE. CONDITIONS_IN-CURR_ISO = CURR_ISO.

Kap04.fm Seite 108 Dienstag, 22. April 2003 2:31 14

Page 61: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Business-Objekte und BAPI 109

APPEND CONDITIONS_IN. CONDITIONS_INX-ITM_NUMBER = CONDITIONS_IN- ITM_NUMBER. CONDITIONS_INX-UPDATEFLAG = 'I'. APPEND CONDITIONS_INX. ENDIF.*-----------------------------------------------------* CALL FUNCTION 'BAPI_SALESORDER_CHANGE' EXPORTING SALESDOCUMENT = SALESDOCUMENT ORDER_HEADER_IN = ORDER_HEADER_IN ORDER_HEADER_INX = ORDER_HEADER_INX TABLES RETURN = RETURN ORDER_ITEM_IN = ORDER_ITEMS_IN SCHEDULE_LINES = SCHEDULE_LINES SCHEDULE_LINESX = SCHEDULE_LINESX CONDITIONS_IN = CONDITIONS_IN CONDITIONS_INX = CONDITIONS_INX.ENDFORM.

4.10.5 VBA-Beispiel zu BAPI_SALESORDER_GETLIST

Liste aller Kundenaufträge

Hier folgt nun zum Vergleich die Auflistung der Kundenaufträge mit Hilfeeines VBA-Programms.

Listing 4.26 VBA: Call BAPI_SALESORDER_GETLIST

'**** Functions in LibraryPublic func As SAPFunctionsOCX.FunctionPublic XMLDOC As New MSXML2.DOMDocumentPrivate myR3 As R3LogonObjPrivate XMLhelp As New XMLhelper'**** ParametersPublic iCUSTOMER_NUMBER As SAPFunctionsOCX.ParameterPublic iDOCUMENT_DATE As SAPFunctionsOCX.ParameterPublic iDOCUMENT_DATE_TO As SAPFunctionsOCX.ParameterPublic iMATERIAL As SAPFunctionsOCX.ParameterPublic iPURCHASE_ORDER As SAPFunctionsOCX.ParameterPublic iPURCHASE_ORDER_NUMBER As SAPFunctionsOCX.Para-meterPublic iSALES_ORGANIZATION As SAPFunctionsOCX.Parameter

Kap04.fm Seite 109 Dienstag, 22. April 2003 2:31 14

Page 62: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

110 SAP R/3 Remote Function Call

Public iTRANSACTION_GROUP As SAPFunctionsOCX.ParameterPublic eRETURN As SAPFunctionsOCX.StructurePublic tSALES_ORDERS As SAPTableFactoryCtrl.Table

Public Sub Class_Initialize() Set myR3 = New R3LogonObj myR3.R3Logon'*************** Creating the object reference for the RFC Functions'==================================================== Set func = myR3.Functions.Add("BAPI_SALESORDER_GETLIST")'*************** Creating the object reference for the Parameters'=================================================='**** Importing Parameters Set iCUSTOMER_NUMBER = func.Exports("CUSTOMER_NUMBER") Set iDOCUMENT_DATE = func.Exports("DOCUMENT_DATE") Set iDOCUMENT_DATE_TO = func.Exports("DOCUMENT_DATE_TO") Set iMATERIAL = func.Exports("MATERIAL") Set iPURCHASE_ORDER = func.Exports("PURCHASE_ORDER") Set iPURCHASE_ORDER_NUMBER = func.Exports("PURCHASE_ORDER_NUMBER") Set iSALES_ORGANIZATION = func.Exports("SALES_ORGANIZATION") Set iTRANSACTION_GROUP = func.Exports("TRANSACTION_GROUP")'**** Exporting Parameters Set eRETURN = func.Imports("RETURN")'**** Table Parameters Set tSALES_ORDERS = func.Tables("SALES_ORDERS")End Sub ' Class_Initialize()

Public Sub Class_Terminate() Set func = Nothing Set myR3 = NothingEnd Sub ' Class_Terminate()

Kap04.fm Seite 110 Dienstag, 22. April 2003 2:31 14

Page 63: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

SAP Interface Repository 111

Public Sub Execute() func.CallEnd Sub ' Class_Initialize()

Public Sub Connect()End Sub ' Connect

Public Function toXMLDoc() As MSXML2.DOMDocument Set toXMLDoc = XMLhelp.toXMLDoc(func)End Function

Public Function toXML() As String toXML = toXMLDoc.XMLEnd Function

4.11 SAP Interface Repository Alle BAPIs sind im IFR dokumentiert

Alle offiziell von SAP freigegebenen BAPIs, IDocs und RFC-Bausteine sindim Interface Repository von SAP dokumentiert, das unter der URL http://ifr.sap.com abrufbar ist. Es ist für jedermann zugänglich und gibt dieStruktur der BAPIs sowohl in Textform als auch als formales XML-Doku-ment zurück.

Anfrage in Form einer Canonical URL

Zum Abrufen der Information verwendet SAP so genannte CanonicalURLs, die im Wesentlichen eine vom W3C abgesegnete Variante der CGI-Spezifikation zur Codierung von Parametern in eine URI sind. Eine Ver-sion des IFR kann auch mit der Transaktion BAPI in einer SAP R/3-Instanzaufgerufen werden.

Typische Anfrage an das IFR

Das nachstehende Beispiel ist eine typische Anfrage an das IFR, die unsein XML-Schema für die GetList-Methode des Sales-Order-BAPIszurückgibt.

Listing 4.27 Eine typische Anfrage an das IFR

http://ifr.sap.com/catalog/query.asp?namespace=urn:sap-com:ifr:LO:46C&type=bapi&name=SalesOrder.GetList&xml=schema.w3c-2000-04&xdir=response

Tabelle 4.4 erläutert die Bestandteile der Canonical URLs, Tabelle 4.5 lis-tet die möglichen Werte für die einzelnen Elemente auf, und Tabelle 4.6die verwendeten Objekttypen.

Kap04.fm Seite 111 Dienstag, 22. April 2003 2:31 14

Page 64: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

112 SAP R/3 Remote Function Call

Element Bedeutung

http://ifr.sap.com/cata-log/query.asp?

Einstiegs-URL ins IFR

namespace=urn:sap-com:ifr:LO:46C

Namespace für das XML-Dokument

&type=bapi Anfrage nach einem BAPI

&name=SalesOrder.GetList Name des BAPI

&xml=schema.w3c-2000-04 Anfrage nach XML-Schema gemäß W3C-Spezifika-tion

&xdir=response Anfrage nach Schema für die Antwort

Tabelle 4.4 Objekt-Typen, die in den Canonical URLs von SAP verwendet werden

Element Erlaubte Werte

type= bobj | bapi | rfc | imsg | idoc | iseg | area | docu

name= Name des Objekts

key= Schlüssel des Dokuments, zum Beispiel Auftragsnummer

param= Parameter, die kein Schlüsselfeld sind, zum Beispiel Auftragsdatum

language= Sprache des Ergebnisdokuments, falls sinnvoll

xml= schema | template [W3C-Version]

xdir= send | response

Tabelle 4.5 Mögliche Werte innerhalb der Canonical URL

type= Bedeutung

area Area

bapi BAPI

bobj Business Object

idoc Intermediate Document (IDoc)

imsg IDoc message type

iseg IDoc segment

Rfc Remote Function Call

Tabelle 4.6 Objekt-Typen, die in den Canonical URLs von SAP verwendet werden

Kap04.fm Seite 112 Dienstag, 22. April 2003 2:31 14

Page 65: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

SAP Interface Repository 113

Folgendermaßen gestaltet sich die Abfrage des XSD-Schemas für RFCIDOCTYPE_READ-COMPLETE:

http://ifr.sap.com/catalog/query.asp?namespace=urn:sap-com:ifr:BASIS:46C&type=rfc&name=IDOCTYPE_READ_COM-PLETE&xml=SCHEMA&xdir=SEND<?xml version="1.0" encoding="utf-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XML-Schema" xmlns="urn:sap-com:document:sap:rfc:functions" targetNamespace="urn:sap-com:document:sap:rfc:func-tions" version="1.0"> <xsd:element name="IDOCTYPE_READ_COMPLETE"> <xsd:annotation> <xsd:documentation>Read IDoc type with segments (RFC-compatible)</xsd:documentation> </xsd:annotation> <xsd:complexType> <xsd:all> <xsd:element name="PI_IDOCTYP"> <xsd:annotation> <xsd:documentation>Basic type</xsd:documentation> </xsd:annotation> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:maxLength value="30"/> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="PI_CIMTYP" minOccurs="0">...

Name Name

Param Parameter

docu Documentation

type= Bedeutung

Tabelle 4.6 Objekt-Typen, die in den Canonical URLs von SAP verwendet werden (Forts.)

Kap04.fm Seite 113 Dienstag, 22. April 2003 2:31 14

Page 66: 4 SAP R/3 Remote Function Call - Logosworld | Project ...logosworld.com/docs/GALILEO/049-114.pdf50 SAP R/3 Remote Function Call R/3-Funktionen von Nicht-SAP-Programmen aufzurufen,

Kap04.fm Seite 114 Dienstag, 22. April 2003 2:31 14