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:
|
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: 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:
Optional sind:
|
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
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'. |
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.
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.
...
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).
|
in.Orderby= |
Hinter jedem Feldnamen kann
durch den Zusatz "DESCENDING" eine absteigende Sortierung erreicht
werden. Beispiel: |
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.
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 nextCopyText 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)
// Daten lesen // 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) 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=1CopyText 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 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
// clear result table (performance!)
// clear table control data
// read data. Set maximum record count because of table control
limitation. 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[row] 0 label nextrowSet 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
// Tabellen KNA1 und T005T als Join lesen 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 |
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 // 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 |
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 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 |
Komponente | GuiXT + InputAssistant |