Funktion Der Funktionsbaustein  /guixt/dbselect bietet eine komfortable Möglichkeit, Datenbankzugriffe in GuiXT Scripten durchzuführen.

Der Baustein wird im Script über Call aufgerufen. Sowohl Einzelsatzzugriffe als auch Mengenzugriffe sind unterstützt.

Voraussetzung:

  • Der Funktionsbaustein ist in das betreffende SAP-System importiert (siehe unten "Import des Funktionsbausteins")
     
  • Der RFC-Benutzer verfügt über die nötigen Berechtigungen (siehe unten "Benutzerberechtigungen")
Import des
Bausteins
Berechtigungen Sie können für den Aufruf des Funktionsbausteins entweder den im GuiXT Profile hinterlegten RFC-Benutzer oder den aktuell angemeldeten Benutzer (Call-Anweisung mit Zusatzoption -currentUser)  für die RFC-Verbindung verwenden.

Die folgenden Berechtigungen sind erforderlich (entweder für den RFC-Benutzer oder bei Option -currentUser für den angemeldeten Benutzer):

Berechtigung zum RFC-Aufruf der Funktionsgruppe /GUIXT/DB01:
S_RFC
: RFC_TYPE=FUGR, RFC_NAME=/GUIXT/DB01, ACTVT=16

Berechtigung zum Lesen der jeweiligen Tabellengruppe:
S_TABU_DIS
: DICBERCLS=XXXXX, ACTVT=03
 

Dabei ist XXXX die Berechtigungsgruppe der zu lesenden Tabelle (abgelegt in SAP-Tabelle TDDAT).

Hinweis: Die Tabellen-Lese-Berechtigung S_TABU_DIS wird in gleicher Weise in den SAP-Transaktionen SE16, SM30 und im Standard-Funktionsbaustein RFC_READ_TABLE geprüft.
 

Parameter Folgende Parameter müssen angegeben werden:
  • in.table=  Tabellenname 
     
  • in.Condition=  Suchbedingung  (oder table.Conditiontable=)
     
  • in.Fields=  Feldliste

Optional sind:

  • in.orderBy=  Sortierung
     
  • in.Groupby=  Gruppierung in Verbindung mit SUM( )
  • in.Distinct=  "X" = Select Distinct
     
  • in.Maxcount=  Maximale Anzahl von Tabellenzeilen, die zurückgegeben werden soll.
     
  • in.Username=  Angabe eines Benutzers, dessen Aufbereitungsparameter (Dezimaltrennzeichen und Datumsdarstellung) für die Werte verwendet werden
     
  • in.Domnane1
    in.Domvalue1 
    Angabe einer Domäne aus dem SAP Data Dictionary, z.B. KUNNR und eines Wertes in externer Darstellung, z.B. 1032. In der Suchbedingung wird dann @KUNNR durch ein Literal mit dem internen Wert, z.B. '0000001032', ersetzt.
     
  • in.Domnane2 bis in.Domnane8
    in.Domvalue2 bis in.Domvalue8 analog weitere Domänen und Werte.
    Falls eine Domäne z.B KUNNR mit mehreren verschiedenen Werten in der Suchbedingung benötigt wird, können Sie den Domänennamen mit einem Punkt abtrennen, z.B. KUNNR.X1 und KUNNR.X2.
     
  • out.Found"X"=Mindestens ein Satz gefunden
     
  • out.ReccountAnzahl gefundener Sätze 0,1,2,...

     
  • table.Values= Aus der Datenbank gelesene Werte (als Langtext formatiert, eine Zeile pro Wert)
     
  • table.Conditiontable= Suchbedingung  (als Langtext)
 in.table= Name der Tabelle oder des Tabellenviews, der gelesen werden soll. Beispiel: 

... in.
table=
"T001"

Hilfreich sind auch die zu den Suchhilfen generierten Views M_... (z.B. M_MAT11) sowie Views, die einen Join mehrerer Tabellen darstellen. Zum Beispiel liefert der View "VBAKUK" zu einem Kundenauftrag sowohl allgemeine Informationen aus Tabelle VBAK als auch Statusinformationen aus Tabelle VBUK.

Join mehrerer Tabellen
Ebenfalls möglich ist, mehrere Tabellen in einem Join zu kombinieren. Es handelt sich dabei um einen "inner join", d.h. in der Resultatmenge erscheinen nur die Werte, für die in allen beteiligten Tabellen entsprechende Werte existieren, welche die join-Bedingung erfüllen. So würden in Beispiel 4 (unten) Kunden fehlen, falls zu dem Länderkürzel in KNA1 keine Länderbezeichnung in Tabelle T005T existiert.

Bei einem Join wird die Berechtigung für alle beteiligten Tabellen geprüft.
 

in.Condition= Suchbedingung im ABAP-Format der Select-Anweisung. Beispiel:

...
in.Condition="BUKRS = '1000' ".

Bitte beachten, daß Strings in ABAP in einfache Hochkommata eingeschlossen werden.
Variablen wie üblich mit &V[varname] angeben:

...
in.Condition="BUKRS = '&V[mybukrs]' ".

Falls Sie eine Spalte mit dem Inhalt einer zweiten Spalte vergleichen möchte, geht das über die Notation table~spalte, z.B.:

... in.Condition="PARVW = 'RE' AND KUNNR <> KNVP~KUNN2"

Weitere Details siehe Dokumentation der ABAP-Select-Anweisung.

 

Eine Suchbedingung muß immer angegeben sein, entweder über in.Condition=  oder über table.Conditiontable=.

Bei  in.Condition= ist die Gesamtlänge der Bedingung auf 4000 Byte beschränkt. Wenn Sie sehr viele Schlüssel übergeben wollen, z.B. 1000 Kundennummern, verwenden Sie bitte table.Conditiontable=.

Als Werte müssen Sie immer die interne Darstellung wählen, also z.B. als Kundennummer '0000001032' und nicht '1032'.
Durch Verwenden derParameter domname1, domname2,... und domvalue1, domvalue2,... erfolgt die Konvertierung von externem nach internehm Format in dem Baustein /guixt/dbselect.

Beispiel:
in.Condition="KUNNR = @KUNNR"   in.Domnane1="KUNNR"  in.Domvalue1="1032"

Siehe auch Beispiel 5 (unten).

in.Fields= Liste von beliebig vielen Feldnamen, durch Komma voneinander getrennt. Nur die angegebenen Felder werden aus der Datenbank gelesen.  Beispiel:

...
in.Fields="KUNNR,NAME1,NAME2,ORT01,STRAS,PSTLZ,LAND1".
 

Die Felder werden in aufbereiteter Form zurückgeliefert. Durch einen * vor dem Feldnamen kann man angeben, dass der Wert nicht aufbereitet werden soll. Datumsangaben werden dann im Format YYYYMMDD und Zahlen mit '.' als Dezimaltrennzeichen zurückgegebem,  Kontonummern, Materialnummern etc. mit führenden Nullen, z.B.  0000002000 statt 2000. Das ist sinnvoll, wenn die Werte für weitere Datenbankzugriffe verwendet werden.

Es ist auch möglich, einen Feldnamen sowohl mit als auch ohne * anzugeben; dann werden beide Darstellungen geliefert. Beispiel:

...
in.Fields="KUNNR,*KUNNR,NAME1,NAME2,ORT01,STRAS,PSTLZ,LAND1".


Falls keine Feldliste angegeben ist, wird die Anzahl der Sätze, welche die angegebene Bedingung erfüllen, im Ausagebparameter Reccount zurückgeliefert.

Feldnamen und Join

Falls über "join" Daten aus mehreren Tabellen gelesen werden, bitte die Feldnamen mit dem jeweiligen Tabellennamen und dem ~ Zeichen angeben, z.B.:

... in.Fields="KNA1~KUNNR,KNA1~NAME1,T005T~LANDX".

Falls einige der Felder den Typ P (dezimal gepackt) I (integer), D (Datum) oder T (Zeit) haben, muss der Typ explizit angegeben werden. Das geht entweder über den Zusatz "type P", "type I", "type D",  "type T", z.B.

...  in.fields="KNA1~KUNNR,S001~UMNETWR type P,S001~STWAE"

oder mit der Klausel "as x", wobei für x die Bezeichnungen P1,...P30, I1,...I30, D1,...D30, T1,...T30 verwendet werden können, aus denen der Typ dann abgeleitet wird. Die Variante mit "as ..." hat den Vorteil, dass damit auch abgeleitete Werte wie SUM( ... ) in der orderby-Klausel verwendet werden können, siehe Beispiel 6 (unten).
Bei Charakter-Feldern kann  "as F1", "as F2",... bei Bedarf verwendet werden.

in.Orderby=
  • Optionale Liste von Feldnamen, durch Komma voneinander getrennt, nach denen die Resultattabelle aufsteigend sortiert wird. Beispiel:

    ...
    in.Orderby="ORT01,NAME1".

Hinter jedem Feldnamen kann durch den Zusatz "DESCENDING" eine absteigende Sortierung erreicht werden. Beispiel:

...
in.Orderby="NAME1 DESCENDING, ORT01 DESCENDING".

in.Groupby= Optionale Liste von Feldnamen, durch Komma voneinander getrennt, nach denen die Resultattabelle gruppiert wird. Das ist bei der Verwenung von Aggregatfunktionen wie SUM( ) in der Feldliste nötig; siehe auch Beispiel 6 (unten).
in.Distinct= Mit Wert "X" wird ein "Select Distinct" ausgeführt.
in.Maxcount= Maximale Anzahl der zurückzuliefernden Sätze. Bei keiner Angabe oder "0": keine Beschränkung.
in.Username= Angabe eines Benutzers, dessen Aufbereitungsparameter (Dezimaltrennzeichen und Datumsdarstellung) für die Werte verwendet werden. Falls nichts angegeben, wird der RFC-Bnutzer verwendet. Meist ist
... in.Username="&V[user]"
sinnvoll, also der gerade angemeldete Benutzer.
out.Found= Erhält den Wert "X", wenn mindestens ein Satz zurückgeliefert wurde, sonst "".
out.Reccount= Anzahl der zurückgelieferten Sätze
table.Values= Enthält die zurückgelieferten Werte. Pro Zeile wird jeweils eines der mit in.Fields spezifizierten Felder ausgegeben. Falls mehrere Tabellenzeilen gelesen wurden, wiederholen sich dann pro gelesener Tabellenzeile alle Felder.
table.
Conditiontable=

 

Suchbedingung im ABAP-Format der Select-Anweisung. Im Unterschied zu in.Condition= übergeben Sie hier eine Langtextvariable, die beliebig viele Zeilen enthalten kann.

Bitte beachten:

  • Pro Zeile maximal 8000 Zeichen
  • Es gibt pro Datenbanksystem eine Maximalzahl von Bedingungen pro Select-Anweisung, in HANA z.B.16 000 oder 32 000 Bedingungen je nach Version.

Beispiel:

Aus einer Liste von Kontonummern in einer Langtextvariablen "kns" wird die Bedingung für den Select-Aufruf in einer Langtextvariablen "ctab" zusammengestellt:

Set text[ctab] ""
Set V[i] 1

label next
CopyText fromText="kns" toString="kn" line="&V[i]"
if Q[ok]
   if V[i=1]
  
Set V[condline] "KUNNR = '&V[kn]'"
   else
      Set V[condline] "OR KUNNR = '&V[kn]'"
   endif

 CopyText fromString="condline" toText="ctab" -appendLine
  Set V[i] &V[i] + 1
 
goto next

endif

Call /guixt/dbselect in.table="KNA1" in.fields="KUNNR,NAME1,ORT01"   table.conditiontable="ctab" ...
 

Beispiel 1  Lesen aller Kunden in Ort "Heidelberg" mit Testausgabe:

// Ausgabetabelle löschen (wichtig wegen Performance)
Clear text[r]

// Daten lesen
Call
/guixt/dbselect in.table="KNA1" in.fields="KUNNR,NAME1,NAME2,PSTLZ,ORT01,LAND1" in.condition="ORT01 = 'Heidelberg'" table.values="r"

// Testausgabe
Message
"&text[r]"

 

Beispiel 2  Lesen von Bezeichnung und Ort zu einem Werk

// Zum Testen
Set
V[plant] "1000"

// Ausgabetabelle löschen (wichtig wegen Performance)
Clear text[r]

Call /guixt/dbselect cache="session" _
 
in.table="T001W" _
  in.
Condition="WERKS = '&V[plant]'" _
 
in.Fields="NAME1,ORT01" _
 
table.Values="r"

CopyText fromText="r" toString="pname" line=1
CopyText fromText="r" toString="pcity" line=2

Message "Werk &V[plant]: &V[pname], &V[pcity]"

 

Beispiel 3  Lesen aller Kunden über Name oder Ort und Anzeige in einer eigenen Tabelle:

// GuiXT Script
InputField (1,10) "Name" (1,24) size=30 name="mcod1" -upperCase
InputField (2,10) "Ort" (2,24) size=30 name="mcod3" -upperCase

Pushbutton (1,56) "Suchen" process="search_customers.txt" size=(2,20)

if V[rcount]
  Table (4,10) (20,182) name="rtab" Title="&V[rcount] Kunden gefunden" rows="&V[rcount]"
  Column "Kunde" size=12 name="kunnr" -readOnly
  Column "Name" size=32 name="name1" -readOnly
  Column "Pstlz" size=12 name="pstlz" -readOnly
  Column "Ort" size=32 name="ort01" -readOnly
  Column "Strasse" size=32 name="stras" -readOnly
  Column "Datum" size=12 name="erdat" -readOnly
endif

//InputScript
if not V[mcod1] and not V[mcod3]
  Message "E: Bitte Name oder Ort eingeben" -statusline
  Return
endif

// clear result table (performance!)
Clear text[r]

// clear table control data
Clear V[rtab.*]

// read data. Set maximum record count because of table control limitation.
Call /guixt/dbselect
in.
table="KNA1" in.fields="KUNNR,NAME1,PSTLZ,ORT01,STRAS,ERDAT" in.username="&V[user]" in.maxcount=100
in.
condition="MCOD1 like '&V[mcod1]%' and MCOD3 like '&V[mcod3]%'"
out.reccount="rcount" table.values=
"r"

// fill table control
Set V[k] 0
Set V[row] 0

label nextrow
Set V[row] &V[row] + 1
Set V[k] &V[k] + 1

CopyText fromText="r" toString="rtab.cell.kunnr.&V[row]" line="&V[k]"

if Q[ok]
  Set V[k] &V[k] + 1
  
CopyText fromText="r" toString="rtab.cell.name1.&V[row]" line="&V[k]"

 
Set V[k] &V[k] + 1
 
CopyText fromText="r" toString="rtab.cell.pstlz.&V[row]" line="&V[k]"

 
Set V[k] &V[k] + 1
 
CopyText fromText="r" toString="rtab.cell.ort01.&V[row]" line="&V[k]"

 Set V[k] &V[k] + 1
 
CopyText fromText="r" toString="rtab.cell.stras.&V[row]" line="&V[k]"

 Set V[k] &V[k] + 1
 
CopyText fromText="r" toString="rtab.cell.erdat.&V[row]" line="&V[k]"

  goto nextrow
endif

Return

Beispiel 4  Join: Lesen von Kunden mit Länderbezeichnung aus KNA1 und T005T

// Ausgabetabelle löschen
Clear text[r]

// Tabellen KNA1 und T005T als Join lesen
Call "/guixt/dbselect" _
  in.
table="KNA1 join T005T on KNA1~LAND1 = T005T~LAND1"
_
 
in.fields="KNA1~KUNNR,KNA1~NAME1,KNA1~LAND1,T005T~LANDX" _
 
in.condition="KNA1~LAND1 EQ 'CH' AND T005T~SPRAS = 'D'" _
 
table.values="r"

// Testausgabe
Message "&text[r]"

Beispiel 5  Verwendung von Domänen: Lesen des Textes zu einem technischen Platz

Die externe Bezeichnung eines technischen Platzes kann ganz anders sein als der interne Schlüssel, da SAP hier einen Konvertierungsexit verwendet.

// Ausgabetabelle löschen
Clear text[r]

// Text aus Tabelle IFLOTX lesen
Call "/guixt/dbselect" cache="session" _
  in.
TABLE="IFLOTX"
_
  in.CONDITION="SPRAS = '&V[_language]' AND TPLNR = @TPLNR" _
 
in.DOMNAME1="TPLNR" in.DOMvalue1="&V[iw_tplnr]" in.FIELDS="PLTXT" _
 
table.VALUES="r"

// Testausgabe
Message "&text[r]"

Beispiel 6  Verwendung diverser Optionen

Zu einer Materialnummer werden die 10 Kunden ermittelt, welche im Jahr 2017 den höchsten Umsatz mit diesem Material hatten. Dazu werden die Tabellen S001 (Umsatzstatistik), MAKT (Materialtext) und KNA1 (Kunden) in einem Join verbunden.

// Eine Materialnummer zum Testen setzen
Set
V[mymaterial] "M-01"

// Ausgabetabelle löschen
Clear text[r]

Call "/guixt/dbselect" _
 
in.table="S001 join KNA1 on KNA1~KUNNR = S001~KUNNR join MAKT on           MAKT~MATNR = S001~MATNR" _
 
in.fields="KNA1~KUNNR,KNA1~NAME1,MAKT~MATNR,MAKT~MAKTX,S001~STWAE,sum( S001~UMNETWR ) as P1" _      in.groupby="KNA1~KUNNR,KNA1~NAME1,MAKT~MATNR,MAKT~MAKTX,S001~STWAE" _
 
in.orderBy="P1 descending" _
 
in.condition="S001~MATNR = @MATNR and S001~SPMON like '2017%' and MAKT~SPRAS = 'D'" _
 
in.domname1="MATNR" in.domvalue1="&V[mymaterial]" _
 
in.maxcount="10" _
 
table.values="r"

// Testausgabe
Message "&text[r]"

Komponente GuiXT + InputAssistant