Eigenschaften der
CIS ABAP Schnittstelle
Die CIS ABAP Schnittstelle
bietet eine einfach handhabbare und schnelle Möglichkeit, SAP-Daten
in ABAP zu besorgen und die Visualisierung anschließend in VB.NET und
HTML zu implementieren.
Aus VB.NET wird eine ABAP-Routine des Funktionsbausteins /GUIXT/CISADDON_INTERFACE
aufgerufen. Alle Input-Parameter werden als Strings in festgelegter Reihenfolge
übergeben, z.B.
1. Parameter: Kundennummer
2. Parameter: Auftragsnummer
Zurückgegeben wird eine Tabelle, in der in der Regel jede Tabellenzeile,
abgeteilt durch Tabulator-Zeichen, mehrere Einzelfelder enthält (CSV-Format).
Sie können auch Langtexte oder Daten in XML-Format zurückliefern.
Vor- und Nachteile:
- ABAP-Kenntnisse werden
benötigt
- Sehr gute Performance
erzielbar
- Komplexe
Select-Zugriffe und Aufruf von SAP Funktionsbausteinen möglich
- Bündelung mehrerer
Zugriffe in einen physischen Request möglich
- Zusätzliche
Berechtigungsprüfungen können im ABAP-Coding erforderlich sein
- Relativ schnelle
Implementierung
- Sehr variabel
- Insbesondere für CIS
Reports sehr gut geeignet
In der aufgerufenen
ABAP-Routine können Sie alle Daten besorgen, die für die
spezielle Anzeige benötigt werden, insbesondere auch die anzuzeigenden Texte zu
den jeweiligen Schlüsseln.
|
Beispiel 1:
Daten für Bestandsübersicht besorgen
Zu einer Materialnummer wollen
wir den Lagerbestand tabellarisch anzeigen:

Im Artikel
Add-on Bestandsübersicht ist beschrieben,
wie Sie dieses Add-on in CIS mobile integrieren; hier konzentrieren wir
uns nun auf das Besorgen der Daten.
Bekannt ist die Materialnummer; zurückgegeben werden soll eine Tabelle mit Werk,
Lager, Name von Werk und Lager und die jeweiligen Mengen ("Frei
verfügbar" etc.).
Als erstes wählen wir einen
Namen für die Datenbeschaffung, z.B. "MaterialStock".
Als nächstes legen wir die Schnittstelle fest:
Eingabe: Materialnummer
Ausgabe: Jeweils eine
Zeile pro Werk/Lager mit den Angaben: Werk, Bezeichnung Werk, Lager,
Bezeichnung Lager, Lagerbestand frei verfügbar, Bestand in Umlagerung,
Bestand Q-Prüfung, Bestand Retouren.
Als nächstes überlegen wir,
wie die Datenbeschaffung in ABAP aussieht. Bei Daten, die
1:1 in der Datenbank zu finden sind, bietet sich ein ABAP-Select an.
Sind es dagegen Informationen, die eine komplexere Logik erfordern,
halten wir eher nach existierenden Funktionsbausteinen (oft BAPIs)
Ausschau.
In unserem Fall ist die
Datenbeschaffung mit Select aus der Datenbank relativ einfach:
- Die Lagerbestände
stehen in Tabelle MARD
- Die Werksbezeichnung
in Tabelle T001W
- Die Lagerbezeichnung
in Tabelle T001L
Aus Performancegründen ist
es ratsam, mit einem oder wenigen Select-Zugriffen auszukommen. Hierzu
stehen in ABAP komplexe Varianten der Select-Anweisung zur Verfügung,
z.B. Subquery und Join. Bei Tabelle, von denen wir annehmen können, dass
sie im Cache des Applikationsservers zu finden sind (z.B. kleinere
Customizingtabellen), können wir statt eines Joins auch Einzelzugriffe
durchführen.
In unserem Fall nehmen wir
an, dass T001W und T001L im SAP-Cache liegen, im Unterschied zu MARD,
die sehr groß werden kann (viele Materialstämme). Wir entscheiden uns
deshalb für die Lösung, zunächst Tabelle MARD zu lesen und dann jeweils
pro Werk/Lagerort die Texte dazu zu lesen. Alternativ könnten wir auch
alle Daten mit einem einzigen "inner Join" der drei Tabellen besorgen,
was in diesem Fall aber wohl nicht schneller wäre und auf jeden Fall die
Datenbank etwas stärker belastet.
Insgesamt sieht unser
ABAP-Coding wie folgt aus:

ABAP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
* Stock quantities for each plant
*
* In
* 1 MATNR Material number
*
* Out
* Stok quantities
form MaterialStock tables reqparm resparm
changing rc type c msg type c.
data: wa(8000).
data: parmatnr like mard-matnr.
Read Table reqparm index 1 into parmatnr.
* Stock quantities
data: begin of stock occurs 10,
werks like mard-werks,
lgort like mard-lgort,
labst like mard-labst,
umlme like mard-umlme,
insme like mard-insme,
retme like mard-retme,
end of stock.
* Texts
Data: werks_text like t001w-name1,
lgort_text like t001l-lgobe.
* Quantities, character format
Data: labst_char(16),
umlme_char(16),
insme_char(16),
retme_char(16).
select * from mard into corresponding fields of table stock
where matnr = parmatnr and labst > 0.
Sort stock.
Loop at stock.
* Authority check
AUTHORITY-CHECK OBJECT 'M_MATE_WRK'
ID 'WERKS' FIELD STOCK-WERKS
ID 'ACTVT' FIELD '03'.
* not authorized?
if sy-subrc NE 0.
UNPACK 4 to rc.
if msg = space.
Concatenate 'Missing authorization for plant:' STOCK-WERKS
into msg separated by space.
else.
Concatenate MSG STOCK-WERKS into msg separated by ','.
endif.
else.
* read texts
Select single name1 from t001w into werks_text
where werks = stock-werks.
Select single lgobe from t001l into lgort_text
where werks = stock-werks and lgort = stock-lgort.
* character format of quantities
Write:
stock-labst to labst_char decimals 0,
stock-umlme to umlme_char decimals 0,
stock-insme to insme_char decimals 0,
stock-retme to retme_char decimals 0.
* output result
Concatenate
stock-werks
werks_text
stock-lgort
lgort_text
labst_char
umlme_char
insme_char
retme_char
into wa
separated by cl_abap_char_utilities=>horizontal_tab.
Append wa to resparm.
endif.
Endloop.
Endform.
|
|
Durch "Authority-Check" prüfen wir dabei die
Berechtigung des Benutzers zur Anzeige von Daten in dem jeweiligen Werk. |
Beschreibung der Schnittstelle in ABAP
Alle ABAP-Routinen liegen im
Funktionsbaustein /GUIXT/CISADDON_INTERFACE. Die Schnittstellen der
aufgerufenen Routinen sind immer gleich:
form xxxx tables reqparm resparm changing rc type c msg type c.
Dabei ist reqparm
die Eingabetabelle und resparm die Ausgabetabelle. Mit Returncode
rc=0 teilen wir mit, dass die Routine normal abgelaufen ist,
während rc>0 einen Fehler anzeigt; in diesem Fall können wir in
msg einen Fehlertext zurückgegeben.
Die Eingabeparameter werden
über die Parameternummer gelesen. Wenn zum Beispiel an eine Routine drei
Schlüsselfelder VKORG, VTWEG und SPART aus VB.NET übergeben werden,
lesen wir sie mit
Read Table reqparm index 1 into vkorg.
Read Table reqparm index 2 into vtweg.
Read Table reqparm index 3 into spart.
in die drei ABAP-Felder
vkorg, vtweg und spart ein.
Die Ausgabetabelle resparm
enthält Zeilen des ABAP-Typs C mit maximaler Länge 8000. Der Inhalt ist
im Prinzip beliebig; es hat sich aber als praktikabel erwiesen pro
Zeile einzelne Werte, durch ein TAB-Zeichen getrennt, abzulegen. Beim
Auslesen von SAP-Langtexten, die ja größer als 8000 Zeichen sein
dürfen, ist die Übergabe etwas anders, siehe Beispiel 3.
|
Beschreibung der Schnittstelle in VB.NET
Zum Aufruf der ABAP-Routine in
VB.NET stellt man die Eingabeparameter als einzelne Zeilen der
Eingabetabelle bereit, ruft die Routine auf und verarbeitet dann die
Ausgabetabelle. Für das Beispiel oben ("MATERIALSTOCK") sieht das wie
folgt aus:

VB.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| ' Stock overview
Public Function BuildMaterialStock(ByVal keys_
As Dictionary(Of String, String), _
ByRef buttons As String) As String
' We use CIS addon ABAP function to read the stock quantities
' Clear input/output
rfc_input.Clear()
rfc_output.Clear()
' Build up input
Dim s As addonsimplestring = _
DirectCast(rfc_input.AddNew(), addonsimplestring)
s.content = GetItem(keys, "MATNR")
' Request data
ic.RfcRequest("CISADDON.MATERIALSTOCK", "S", rfc_input, _
rfc_output, deferred:=True)
' execute all requests (one only in our case)
ic.RfcExecuteDeferredCalls(rfcmessages)
For Each line As addonsimplestring In rfc_output
...
Next
End Function
|
Das gesamte VB.NET-Coding
finden Sie im Artikel Add-on Bestandsübersicht
und in dem mit CIS mobile ausgelieferten VB.NET Add-on-Projekt. |
Beispiel 2:
Preisfindung pro Kunde
Unser nächstes Beispiel ist
die Datenbeschaffung des Reports "Preisfindung":

Wir gehen wie in Beispiel 1
vor:
Als erstes wählen wir einen
Namen für die Datenbeschaffung, z.B. "PRICING".
Als nächstes legen wir die Schnittstelle fest:
Eingabe:
Verkaufsorganisation, Vertriebsweg, Sparte, Kundennummern (beliebig
viele, jeweils eine Kundennummer pro Eingabezeile)
Ausgabe: Jeweils eine
Zeile pro Kunde mit den Angaben: Kundennummer, Preisgruppe, Text dazu,
Kundenschema, Text dazu, Preisliste, Text dazu.
Als nächstes überlegen wir,
wie die Datenbeschaffung in ABAP aussieht:
- Die
Preisfindungsangaben pro Kunde stehen in Tabelle KNVV
- Die Bezeichnungen von
Preisgruppe, Kundenschema und Preisliste stehen in den Tabellen
T188T, TVKDT und T189T.
Wie bekommen Sie heraus,
wie die benötigten SAP-Tabellen heißen? Hilfreich ist oft die Suche im
Internet, da in Foren oft derartige Fragestellungen besprochen werden.
Zweitens die Hilfefunktion F1 im SAP-System auf den entsprechenden
Feldern der jeweiligen Transaktion. Drittens die SAP-Trace-Funktion, mit
der Sie pro Transaktion die Datenbankzugriffe aufzeichnen können. Das
sind in der Regel allerdings ziemlich viele. Viertens Sekundärliteratur
zum SAP-System (Bücher, Internet).
Zum Nachprüfen, ob ein
Tabellenname stimmt, mit SE11 die Tabellenstruktur und dort die Inhalte
anzeigen.
Zum Lesen der Daten pro
Kunde ist bei allen Datenbeschaffungsroutinen für CIS mobile Reports
wichtig, den Einzelzugriff pro Kunde zu vermeiden, da dann
bei z.B. 100 Kunden auch 100 einzelne Datenbankaufrufe stattfinden.
Stattdessen nutzen wir die Möglichkeit der ABAP-Select-Anweisung, eine
Menge von Datenbankschlüsseln auf einen Schlag an die
Select-Schnittstelle weiterzureichen (Option "FOR ALL ENTRIES IN ...").
Insgesamt sieht unser
ABAP-Coding wie folgt aus:

ABAP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
* Pricing
* In
* 1 VKORG
* 2 VTWEG
* 3 SPART
* 4 KUNNR and following: customer numbers
*
* Out
* KUNNR KONDA KONDATEXT KALKS KALKSTEXT PLTYP PLTYPTEXT
form PRICING tables reqparm resparm
changing rc type c msg type c.
data: wa(8000).
data: vkorg like knvv-vkorg,
vtweg like knvv-vtweg,
spart like knvv-spart.
Read Table reqparm index 1 into vkorg.
Read Table reqparm index 2 into vtweg.
Read Table reqparm index 3 into spart.
Read Table reqparm index 4 into wa.
* Customer numbers
data: begin of customers occurs 10,
kunnr like kna1-kunnr,
end of customers.
Data: k type i value 4.
Read Table reqparm index k into customers-kunnr.
While sy-subrc EQ 0.
Append customers.
k = k + 1.
Read Table reqparm index k into customers-kunnr.
Endwhile.
* no customers?
if customers[] is initial.
exit.
endif.
* Result tables
data: begin of r1 occurs 10,
kunnr like knvv-kunnr,
konda like knvv-konda,
kalks like knvv-kalks,
pltyp like knvv-pltyp,
end of r1.
Select kunnr konda kalks pltyp
from knvv
into corresponding fields of table r1
for all entries in customers
where vkorg = vkorg
and vtweg = vtweg
and spart = spart
and kunnr = customers-kunnr.
sort r1.
Data: kondatext like t188t-vtext,
kalkstext like tvkdt-vtext,
pltyptext like t189t-ptext.
Loop at r1.
kondatext = ''.
kalkstext = ''.
pltyptext = ''.
Select single vtext from t188t into kondatext
where spras = sy-langu and konda = r1-konda.
Select single vtext from tvkdt into kalkstext
where spras = sy-langu and kalks = r1-kalks.
Select single ptext from t189t into pltyptext
where spras = sy-langu and pltyp = r1-pltyp.
* output result
Concatenate
r1-kunnr
r1-konda
kondatext
r1-kalks
kalkstext
r1-pltyp
pltyptext
into wa separated by cl_abap_char_utilities=>horizontal_tab.
Append wa to resparm.
Endloop.
Endform.
|
Bitte im ABAP-Coding beachten:
Die Abfrage
* no customers?
if
customers[]
is initial.
exit.
endif
ist erforderlich, da bei einer leeren Tabelle die Option "FOR ALL
ENTRIES IN ..:" in der Select-Anweisung ignoriert wird und damit alle
Kunden gelesen würden. |
Beispiel 3:
Lesen des Langtextes zum Fertigungsauftrag
Zum Lesen von Langtexten zu
SAP-Objekten ist das folgende Beispiel eine nützliche Vorlage. Wir lesen
im Add-on "Fertigungsauftrag"
den Langtext zum Fertigungsauftrag:

Wir gehen wieder wie in
Beispiel 1 vor:
Als erstes wählen wir einen
Namen für die Datenbeschaffung, z.B. "ADDON_AUFK_LONGTEXT".
Als nächstes legen wir die Schnittstelle fest:
Eingabe: Auftragsnummer
Ausgabe: Langtext,
jeweils eine Textzeile in einer Ausgabezeile
Als nächstes überlegen wir,
wie die Datenbeschaffung in ABAP aussieht:
- Zum Lesen des Textes
nutzen wir den Funktionsbaustein READ_TEXT
- Zur Umwandlung vom
internen SAP-textformat in reinen Text (ohne Formatierung) nehmen
wir den Standardbaustein CONVERT_ITF_TO_ASCII
Wir suchen den Text
zunächst in der Anmeldesprache des Benutzers und, falls nicht gefunden,
dann in Englisch und in Deutsch.

ABAP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
* Read longtext of productionorder (CO03)
form ADDON_AUFK_LONGTEXT tables reqparm resparm
changing rc type c msg type c.
DATA: AUFNR like aufk-aufnr.
* 1st parameter: document number
Read Table reqparm index 1 into AUFNR.
* texts
DATA: BEGIN OF T_HEAD.
INCLUDE STRUCTURE THEAD.
DATA: END OF T_HEAD.
* text lines
DATA: BEGIN OF T_LINES OCCURS 0.
INCLUDE STRUCTURE TLINE.
DATA: END OF T_LINES.
* Order number with client
DATA: BEGIN OF CLIENTAUFNR,
CLIENT LIKE SY-MANDT,
AUFNR LIKE AUFK-AUFNR,
END OF CLIENTAUFNR.
CLIENTAUFNR-CLIENT = SY-MANDT.
CLIENTAUFNR-AUFNR = AUFNR.
* Read long text
Perform set_textkeys using 'AUFK' CLIENTAUFNR 'KOPF'.
T_HEAD-TDID = textkeys-tdid.
T_HEAD-TDNAME = textkeys-tdname.
T_HEAD-TDSPRAS = textkeys-tdspras.
T_HEAD-TDOBJECT = textkeys-tdobject.
CALL FUNCTION 'READ_TEXT'
EXPORTING
ID = T_HEAD-TDID
LANGUAGE = T_HEAD-TDSPRAS
NAME = T_HEAD-TDNAME
OBJECT = T_HEAD-TDOBJECT
IMPORTING
HEADER = T_HEAD
TABLES
LINES = T_LINES
EXCEPTIONS
OTHERS = 1.
CALL FUNCTION 'CONVERT_ITF_TO_ASCII'
TABLES
ITF_LINES = T_LINES.
LOOP AT T_LINES.
Append T_LINES-TDLINE TO RESPARM.
ENDLOOP.
endform.
|
Dabei benutzen wir eine Hilfsroutine "set_textkeys"
Perform
set_textkeys
using
'AUFK'
CLIENTAUFNR
'KOPF'.
die bereits in dem Programm enthalten ist und den Textzugriff
zunächst mit der Anmeldesprache, dann in Englisch und Deutsch
realisiert:

ABAP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
Form set_textkeys using tdobject tdname tdid.
Clear textkeys.
Select single * from stxh into corresponding fields of textkeys
where tdobject = tdobject and tdname = tdname
and tdid = tdid and tdspras = sy-langu.
* try English
if sy-subrc ne 0 and sy-langu ne 'E'.
Select single * from stxh into corresponding fields of textkeys
where tdobject = tdobject and tdname = tdname
and tdid = tdid and tdspras = 'E'.
endif.
* try German
if sy-subrc ne 0 and sy-langu ne 'D'.
Select single * from stxh into corresponding fields of textkeys
where tdobject = tdobject and tdname = tdname
and tdid = tdid and tdspras = 'D'.
endif.
Endform.
|
|