Ansicht
Dokumentation
CNV_INT_SCHEME_INSTANTIATE - Umstellung: Schema-Initialisierung mit Daten aus dem Generierungsprogramm
BAL Application Log Documentation Fill RESBD Structure from EBP Component StructureDiese Dokumentation steht unter dem Copyright der SAP AG.
Anmerkungen
Die Dokumentation wurde vom Funktionsbaustein SCHEME_INSTANTIATE aus dem Release 4.6A übernommen.
Die Funktionalität wurde gegenüber diesem Funktionsbaustein dahin gehend erweitert, dass nun auch durch OR oder AND zusammengesetzte Bedingungen erlaubt sind.
Funktionalität
Die Funktion SCHEME_INSTANTIATE instantiiert ein Schema mit den globalen Daten des aufrufenden Programms.
Schemata bieten eine einfache, wartbare Methode zur Generierung von Texten, insbesondere auch von ABAP-Programmen. Ein Schema ist vergleichbar mit der Angabe eines regulären Ausdrucks mit Variablen, Alternativen, Schleifen und Subschema-Aufrufen.
Mit Schemata werden Datenbesorgung im aufrufenden Programm und Syntaxdefinition im Schemaprogramm streng getrennt, so daß Änderungen der Syntax sehr einfach zu machen sind. Zudem ist die Syntax in einem Schema relativ leicht ersichtlich, im Gegensatz zu einem programmgesteuerten Zusammenbau von Zeilen mit concatenate und append.
Technik
Aus einem Schemaprogramm s wird ein Programm /1SAP1/SCMG_s generiert, das für jedes Schema in s eine Form enthält, die die Instantiierung durchführt. Das Programm wird nur bei Änderung des Schemaprogramms oder des Schema-Parsers neu generiert.
Mit dieser Technik sind Lade- und Laufzeiten von Schema-Instantiierungen sehr performant.
Auch für fehlerhafte Schemata wird eine Form generiert, die dann bei Instantiierung einen Fehler zurückliefert. Daher können alle korrekten Schemata korrekt instantiiert werden, auch wenn fehlerhafte Schemata in dem Schemaprogramm enthalten sind.
Schema-Syntax
Im folgenden werden die Default-Steuerzeichen benutzt. Diese können aber auch pro Schemaprogramm umdefiniert werden.
Schemaprogramm
Ein Schemaprogramm ist ein (mit SE38 erstellter) ABAP-Report, der ein oder mehrere Schemata enthält. Dieser Report ist vom Typ I(nclude), da Schemata nicht der ABAP-Syntax genügen.
- Es ist günstig zusammengehörige Schemata in einem Programm zusammenzufassen, da dann nur ein Programm geladen werden muß, um diese Schemata zu instantiieren.
- Die Länge des Namens für Schemaprogramme ist begrenzt auf 18 Zeichen (Datenelement SCHEMEPROG), da der Präfix für die daraus generierten Programme 12 Zeichen lang ist.
Schema
Ein Schema wird geklammert durch die Zeilen
/>schema_name
...
/>END
- Die Klammerungszeilen dürfen keine führenden Blanks und keinen weiteren Text oder Kommentar haben.
- 'END' ist ein reservierter Name und kann nicht als Schemaname verwendet werden.
- Die Länge des Schemanamens ist bestimmt durch das Datenelement SCHEMENAME, z.Z. 30-stellig.
Variablen
In einem Schema können globale Variablen vom Typ C oder string (und nur die!) des aufrufenden Programms referenziert werden. Variablen im Schema werden mit '&' begrenzt:
&varname&
Für eine Variable wird ihr Wert substituiert, wobei trailing blanks abgeschnitten werden, während führende blanks erhalten bleiben (wie bei dem ABAP-Befehl CONCATENATE).
- Wird dem Variablennamen ein '-' vorangestellt, so wird der Wert der Variable mit lower case Konvertierung instantiiert.
Beispiel:
data: VAR(4) value ' cD '. "im aufrufenden Programm
'ab&VAR&ef' -> 'ab cDef'
'ab&-VAR&ef' -> 'ab cdef'
Kontrollstrukturen
In Schemata können Bedingungen, Schleifen und Subschema-Aufrufe definiert werden. Eine Kontrollstruktur hat die Form:
{x$control$ ... $ .... .... }
wobei x angibt, um welche Kontrollstruktur es sich handelt und die einzelnen Bestandteile der Kontrollstruktur durch das Separatorzeichen '$' getrennt sind. 'Control' ist der kontrollierende Ausdruck.
Die Anzahl der Bestandteile hängt von der jeweiligen Kontrollstruktur ab - sie muß aber strikt eingehalten werden, auch wenn bestimmte Teile leer sind. Ansonsten ist die Syntax des Schemas fehlerhaft.
- Bei der Instantiierung werden die steuernden Elemente ausgewertet, produzieren aber keinerlei Ausgabe, auch keine Blanks.
- Innerhalb von '{x$control$' darf kein Zeilenvorschub erfolgen.
Conditional
Ein Conditional hat die Form:
{C$condition$then$else}
'Condition' kann eine einfache Variable sein. Dies hat die Bedeutung von 'not(variable is initial)'. Der 'then'-Teil wird instantiiert, wenn die Variable nicht initial ist; ansonsten der 'else'-Teil.
Beispiel:
{C$sy-subrc$error$ok} -> 'error', falls sy-subrc <> 0
-> 'ok' , falls sy-subrc = 0
'Condition' kann auch ein einfacher Ausdruck der Form 'a op b' sein, wobei 'a' eine Variable und 'b' eine Variable, ein String oder eine integer ist. 'Op' muß eine höchstens zweistellige ABAP-Operation sein, z.B. =, <, LE, CA, ... . Vor und nach 'op' muß ein Blank stehen.
Beispiel:
data: a value 'D', b value 'D'.
{C$a = b $eq$neq} -> 'eq'
{C$a <> 'D'$neq D $eq D} -> 'eq D'
- Mit diesem Konstrukt läßt sich auch 'if ... elseif ...' abbilden:
{C$sy-subrc = 0$ok${C$sy-subrc = 4$warning$error}}
- Sowohl 'then' als auch 'else'-Teile können leer sein. Es müssen aber auf jeden Fall alle Separatoren angegeben sein:
{C$condition$then$} bzw. {C$condition$$else}.
Table Loop
Eine Table Loop hat die Form:
{T$table$pre1$pre$main$post$postn} oder
{T$table WHERE condexpr$pre1$pre$main$post$postn}
Dabei ist 'table' der Name einer internen Tabelle des aufrufenden Programms. Diese Tabelle muß dort global sein und eine Kopfzeile haben.
'Condexpr' ist ein einfacher Ausdruck der Form 'f op b', wobei f der Name eines Feldes von 'table' ist und 'op' und 'b' wie bei bei Conditional beschrieben sind.
Es wird über diese Tabelle geloopt und folgende Ausgabe produziert:
'pre1mainpost' für die 1.Zeile
'premainpost' für die 2. - (n-1). Zeile
'premainpostn' für die n. Zeile
Beispiel:
{T$fieldtab$DATA: $
$fieldtab-fieldname like ... $,$.}
-> DATA: field1 like ... ,
field2 like ... ,
field3 like ... .
Sollen nur die Schlüsselfelder berücksichtigt werden, so könnte die Table Loop wie folgt aussehen
{T$fieldtab WHERE key = 'X'$DATA: $ ... }
- Achtung: Die Nicht-Existenz der Tabelle im aufrufenden Programm führt zu der Ausnahme 'TABLE_NOT_EXISTS'.
- Hat die Tabelle keinen (passenden) Eintrag, so ist das Ergebnis des Table Loops leer.
- Hat die Tabelle genau einen (passenden) Eintrag, so ist das Ergebnis: 'pre1mainpostn'.
- In den Teilen pre1, pre, post, postn können auch Variablen und sogar Kontrollstrukturen benutzt werden. In allen Teilen haben die Variablen die Werte des aktuellen Schleifendurchlaufs. Die Verwendung von Variablen oder Kontrollstrukturen in post kostet allerdings etwa 20% Performance.
Function Loop
Eine Function Loop hat die Form:
{F$function$pre1$pre$main$post$postn}
Dabei ist 'function' eine im aufrufenden Programm definierte Form mit einem Parameter 'CHANGING
Die Form wird zunächst mit
- Die Anmerkungen bei table loop gelten analog für function loop.
- Function loop kann z.B. benutzt werden, wenn selektiv nur für bestimmte Einträge einer Tabelle Ausgabe produziert werden soll:
form next_entry changing idx type i.
loop at tab from idx where .... . " start search from idx
idx = sy-tabix. " set idx to found entry
exit. " at next call idx is incremented by 1
endloop.
if sy-subrc <> 0.
idx = 0. " no entry found, set idx=0 to end loop
endif.
endform.
- Ohne Selektion auf der Tabelle ist die Table Loop zu bervorzugen, da nur etwa 60% der Laufzeit der Function Loop benötigt wird.
Subscheme Call
Ein Subscheme Call hat die Form:
{S$scheme}
Dabei ist 'scheme' der Name eines Schemas im gleichen Schemaprogramm. An der Stelle, an der der Subscheme Call steht, wird das angegebene Schema instantiiert.
Dabei wird das instantiierte Subschema so weit eingerückt, wie der Aufruf selbst. Beginnt eine Zeile des Subschemas mit dem Kommentarzeichen '*', so bleibt dies an erster Zeilenposition.
Beginnt die Zeile des Subschema-Aufrufs mit '*', so beginnen alle Zeilen des instantiierten Subschemas ebenfalls mit '*'.
Beispiele: siehe Schemaprogramm SCHEME_SAMPLE, das mit dem Report SCHEME_TEST zu instantiieren ist.
Weitere Features
Kommentare
Da Schemata geklammert sind, können Zeilen zwischen den Schemata als Kommentar benutzt werden.
Innerhalb eines Schemas können Kommentarzeilen eingestreut werden, die mit '*:' beginnen müssen. Sonstige mit '*' beginnende Zeilen werden normal instantiiert, um auch ABAP-Kommentare ins Ergebnis generieren zu können.
Kommentare am Zeilenende beginnen mit '":'. Der Rest der Zeile wird dann nicht in die Instantiierung übernommen.
Groß-/Kleinschreibung
Da der ABAP-Editor eine upper case Konvertierung vornimmt, ist die Möglichkeit vorgesehen, dies zu umgehen. Dazu muß die Zeile mit '"%' beginnen. Für den ABAP-Editor ist dies Kommentar und die Kleinschreibung bleibt erhalten. Der Schema-Instantiierer überliest diese Zeichen.
Wird ein Editor ohne Konvertierung benutzt (ab 4.6A), so ist diese Kennzeichnung nicht mehr notwendig.
Fortsetzungszeile und Einrückung
Um mehrere Zeilen eines Schemas auf eine Instantiierungszeile abzubilden, sind die Schemazeilen mit
dem Zeichen '\' abzuschließen. Damit entfällt der folgende Zeilenvorschub in der Instantiierung der Schemazeile.
- Dies wird benötigt, wenn durch Kontrollstrukturen oder lange Variablennamen das Schema für eine instantiierte Zeile nicht auf eine Schemazeile paßt.
Um das Schema leserlicher zu gestalten, gibt es auch die Möglichkeit, Zeilen einzurücken,
ohne daß die Einrückung in das Ergebnis übernommen wird. Dazu beginnt man die Zeile nach der Einrückung mit '\'.
- Dies ist insbesondere nützlich um Fortsetzungszeilen einzurücken.
Beispiel:
"% This is a long text over several \
"% \lines which is idented in the scheme.
Fluchtsymbol
Das Zeichen '#' dient als Fluchtsymbol und maskiert die Bedeutung der Zeichen '{}$&'
Beispiel:
control: #{x#$...#}. Variable: #&var#&'. Escape: ##.'
-> 'control: {x$...}. Variable: &var&. Escape: #.'
- Ansonsten wird '#' in Schemazeilen einfach überlesen.
- Die Bedeutung anderer Zeichen wird nicht maskiert. Insbesondere dürfen Zeichen, die am Zeilenanfang stehen müssen, nicht durch das Fluchtsymbol von dieser Position verdrängt werden.
Kommentarzeichen der Zielsprache
Dieses einstellbare Zeichen, mit Default '*' für die Generierung von ABAP-Programmen, wird sonderbehandelt bei der Einrückung von Subschemata und beim automatischen Zeilenumbruch.
Falls eine Subschema-Zeile mit diesem Zeichen beginnt, bleibt es auch bei Einrückung an 1. Stelle stehen - die Einrückung findet hinter diesem Zeichen statt.
Muß eine instantiierte Zeile umgebrochen werden und hat diese Zeile das Kommentarzeichen an 1. Position, so haben auch die Folgezeilen dieses Zeichen an 1. Stelle.
Automatischer Zeilenumbruch
Wird eine instantiierte Zeile zu lang, so wird ein automatischer Zeilenumbruch gemacht, so daß die Zeilen in RESULT_TAB passen.
Ein Umbruch findet statt bei space oder, wenn dies nicht möglich ist, vor '({[' oder nach ',.)]}'. Dabei wird space durch linefeed ersetzt, bei den anderen Zeichen wird linefeed davor bzw. danach eingefügt.
Beispiel:
{t$fieldtab$DATA:$$ fieldtab-fieldname like ... $,$.}
-> DATA: field1 like ... , field2 like ... , ... ,
field5 like ... , ...
- Alle Folgezeilen werden so weit eingerückt wie die Originalzeile.
- Ist die Originalzeile eine Kommentarzeile, so sind auch alle Folgezeilen Kommentarzeilen.
- Fehlerfall: Kann die Zeile nicht an den angegebenen Zeichen umgebrochen werden und ist die Zeile
keine Kommentarzeile, so wird die Ausnahme FORCED_LINESPLIT gesetzt. Die Instantiierung wird aber auf jeden Fall vollständig durchgeführt und in RESULT_TAB zurückgegeben.
- Eine instantiierte Zeile darf vor dem Umbruch bis zu 8000 Zeichen lang werden (Feld SCINSTLINE-TEXT).
Steuerzeichen
Hier der Überblick über die Default-Steuerzeichen für Schemata
Zeichen Bedeutung Länge Anmerkung
# Fluchtsymbol 1 3
/> Schemadefinition-Anfang 2 1
Schemadefinition-Ende 2
{ Kontrollstruktur-Anfang 1 3
} Kontrollstruktur-Ende 1 3
$ Kontrollstruktur-Separator 1 3
& Variablenbegrenzer 1 3
- Kleinschreibung von Variablen 1 2
\ Linefeed-Escape, Ident-Escape 1 4
*: Kommentarzeile 2 1
": Restzeilenkommentar 2
"% Zeile mit Kleinschreibung 2 1
* Kommentarzeichen der Zielsprache 1 5
! Eingabevariable im interaktiven Modus 1 2, 6
"! Zeile nur für interaktiven Modus 2 1, 6
Anmerkungen
- Zeichen wirkt nur am Zeilenanfang
- Zeichen wirkt nur innerhalb von Variablen vor dem Variablennamen.
- Zeichen kann mit Fluchtsymbol maskiert werden.
- Zeichen wirkt nur am Zeilenende und als erstes Zeichen nach beliebig vielen Spaces.
- Zeichen hat keine Sonderrolle in Schemata, aber bei der Instantiierung.
- Wird zur Zeit noch nicht benutzt, aber bei syntaktischer Analyse schon berücksichtigt.
Kommt es zu Konflikten mit dem Schemainhalt, so können die Steuerzeichen in dem Schemaprogramm auch umdefiniert werden. Dazu wird in der 1. Zeile ab der 1. Spalte angegeben:
:SET # /> { } $ & - \ *: ": "% * ! "!
Nach :SET werden alle oder ein Anfangsstück der Steuerzeichen in der oben angegebenen Reihenfolge und Länge(!) angegeben. Blanks werden entfernt und der String wird der Delimeter-Leiste (siehe Dictionary-Struktur SCMDELIMA) zugewiesen. Für die am Ende fehlenden Steuerzeichen wird weiter der Default benutzt. Um die Sonderbehandlung des Kommentarzeichens der Zielsprache abzuschalten, ist dort 'N' anzugeben.
Schemagesteuerte Generierung
Für die schemagesteuerte Generierung benötigt man 2 Programme - das Schemaprogramm und ein Treiberprogramm. Das Treiberprogramm stellt die in dem Schemaprogramm verwendeten Variablen, Tabellen und Funktionen zur Verfügung und ruft dann die Schema-Instantiierung auf. Der Aufbau eines Treiberprogramms ist weiter unten beschrieben.
Vorgehen
- Die benötigten Schemata in einem Schemaprogramm erstellen. Eine Möglichkeit besteht
darin, zunächst ein lauffähiges Programm für ein fixes Beispiel zu erstellen und dann die generischen Teile mit Schemasyntax zu generalisieren.
- Parallel dazu fügt man in das Treiberprogramm die von dem Schema benötigten Variablen, Tabellen und Funktionen ein.
- Das erstellte Schemaprogramm mit dem Report SCHEME_TEST im Modus 'symbolische Instantiierung' überprüfen.
Dabei werden die eventuell vohandenen Syntaxfehler ausgegeben und das Layout läßt sich anhand der symbolischen Instantiierung überprüfen. Der Wert für die Conditions und die Anzahl der Durchläufe für Loops läßt sich variieren. Zumindest sollten auch die Extremfälle 0 und 1 geprüft werden.
- Dann das Treiberprogramm zusammen mit dem Schemaprogramm prüfen.
Dabei kann man zunächst auch den Baustein DD_SCHEME_TEST statt SCHEME_INSTANTIATE aufrufen, wobei die zusätzlichen Parameter dieses Bausteins nicht versorgt werden. Dieser gibt dann das Ergebnis und Fehlermeldungen auf den Bildschirm aus.
Fehler
Alle Ausnahmen setzen die System-Variablen, um die Fehlermeldung über MESSAGE auszugeben.
Die Ausnahmen SYNTAX_ERROR und GENERATE_ERROR lassen sich meist vermeiden, wenn das Schemaprogramm vorher mit dem Report SCHEME_TEST geprüft wird.
Aufrufendes Programm
Für ein Schemaprogramm gibt es normalerweise ein Treiberprogramm, das die notwendigen Daten besorgt und für die Instantiierung bereit stellt.
Dieses Programm sieht im Aufbau etwa wie folgt aus:
** global variables usable in schemes
data: var1, ..., varn.
** global tables usable in table loops of schemes
data: tab1 type table of ... with header line,
...
tabm type table of ... with header line.
** functions used in function loops of schemes
form fct1 changing idx type i. ... endform.
...
form fctk changing idx type i. ... endform.
** variables for scheme instantiation
data: thisprog like sy-repid,
schemeprog type schemeprog value 'myschemes',
scheme type schemename,
result_tab type abapprog.
**** for each scheme S in schemeprog a form instantiate_S
form instantiate_S using ... .
* 1. set global variables and tables used in S
...
* 2. call instantiation
thisprog = sy-repid. "important to fix value of sy-repid here
scheme = 'S'.
refresh result_tab.
call function 'SCHEME_INSTANTIATE'
exporting
calling_prog = thisprog
scheme_program = schemeprog
scheme_name = scheme
tables
result_tab.
exceptions
when others = 8.
if sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
endif.
* 3. use result_tab
...
endform.
Beispiel
Beispiele sind in dem Report SCHEME_SAMPLE, fehlerhafte Beispiele in SCHEME_ERROR zu finden.
Diese Beispiele wie auch selbstgeschriebene Schemaprogramme lassen sich testen mit dem Report SCHEME_TEST.
Parameter
CALLING_PROGRAMRESULT_TAB
SCHEME_NAME
SCHEME_PROGRAM
Ausnahmen
FORCED_LINESPLITGENERATE_ERROR
NO_AUTHORITY
SCHEMEPROG_NOT_FOUND
SCHEME_NOT_FOUND
SCHEME_SYNTAX_ERROR
TABLE_NOT_EXISTS
Funktionsgruppe
CNV_BASIS_SCHEMEFill RESBD Structure from EBP Component Structure CPI1466 during Backup
Diese Dokumentation steht unter dem Copyright der SAP AG.
Length: 33479 Date: 20240523 Time: 124851 sap01-206 ( 290 ms )