Sie sind auf Seite 1von 16

4 User-Exits und BAdIs im Reporting

Die bisher behandelten Exits sind zweifellos sehr mächtig und bieten Ihnen
die Möglichkeit, die Daten so aufzubereiten, dass viele typische Reporting-
Anforderungen damit erfüllt werden können. Jedoch gibt es immer wieder
Anforderungen, die Berichte durch die Eingabe von Variablen flexibler zu
gestalten. So würde beispielsweise kein SAP NetWeaver BW-Berater emp-
fehlen, pro Kostenstelle im Unternehmen einen eigenen Bericht zu definie-
ren, sondern die Kostenstelle als einzugebende Variable zu bestimmen.

Andererseits soll diese Flexibilität aber nicht auf den Anwender abgewälzt
werden, sodass er mit einer Vielzahl von Variablen überfordert wird. Daher
können Sie versuchen, dem Anwender möglichst die Kostenstelle(n) vorzu-
schlagen, die er abhängig von seiner Position und Verantwortung vermutlich
in dem Bericht sehen möchte.

Im Folgenden wird daher erklärt, wie Sie durch geschickte Programmierung


Variablenwerte ableiten und Vorschlagswerte setzen. Danach werden Sie
sich mit virtuellen Merkmalen und Kennzahlen sowie mit dem Thema Vir-
tualProvider auseinandersetzen. Während die Variablen die Auswahl der
Werte zum Zeitpunkt der Berichtsauswertung flexibilisieren, gehen diese
beiden Techniken noch einen Schritt weiter und ermöglichen es, die Daten
selbst zum Berichtszeitpunkt anzupassen. Dazu ist jedoch auch eine komple-
xere Form der Implementierung notwendig. Abschließend lernen Sie kurz
alle weiteren Techniken kennen, die mittels ABAP eine Anpassung des
Reportings erlauben.

4.1 Variablen-Exit RSR00001


Der User-Exit RSR00001 enthält im Kern den Funktionsbaustein EXIT_
SAPLRRS0_001, der mehrere verschiedene Funktionen rund um die Variab-
leneingabe erfüllt. Dieser Exit hat dasselbe Problem wie der User-Exit zur
Extraktorerweiterung in Abschnitt 2.3, »User-Exit RSAP0001«: In einem
typischen BW-System wächst und wächst der User-Exit. Daher sollten Sie
schon zu Beginn darauf achten, dass Sie die Implementierung nicht im
Include ZXRSRU01 vornehmen, sondern die Implementierung vom Include

103
4 User-Exits und BAdIs im Reporting

lösen. Das können Sie zum Beispiel tun, indem Sie aus dem Variablennamen
den Namen eines Funktionsbausteins ableiten.

In der Schnittstelle des User-Exits gibt es jedoch zwei zentrale Parameter:


Neben dem Namen der Variablen I_VAR ist außerdem der Aufrufschritt I_STEP
entscheidend. Dabei handelt es sich um einen Zähler, denn der User-Exit wird
mehrmals an insgesamt bis zu vier verschiedenen Stellen aufgerufen. Zu die-
sen unterschiedlichen Zeitpunkten können Sie verschiedene Funktionen im-
plementieren. Vor der eigentlichen Behandlung der Implementierung soll
deshalb zunächst der Parameter I_STEP erklärt werden:

왘 I_STEP = 1
Der erste Aufruf des User-Exits dient dazu, Vorschlagswerte zu berech-
nen, das heißt die Werte, die in den eingabebereiten Variablen als Vor-
schlag für den Benutzer angezeigt werden. Dazu wird der Exit einmal pro
Variable des Typs Customer-Exit aufgerufen. Dies ist zugleich eine große
Schwäche des Exits. Möchten Sie einer bestehenden Eingabevariablen
nachträglich einen Vorschlagswert geben, sind Sie gezwungen, eine neue
Variable vom Typ Customer-Exit anzulegen und diese eingabebereit zu
machen. Es wäre wünschenswert, wenn in diesem Schritt auch die ande-
ren eingabebereiten Variablen versorgt werden könnten.
Auch wenn in diesem Schritt normalerweise Vorschlagswerte bestimmt
werden, können ebenso Variablen gefüllt werden, die nicht eingabebereit
sind. Dies ist jedoch nur interessant, wenn Sie die Werte in Schritt 2 benö-
tigen, um weitere Variablen abzuleiten.
왘 I_STEP = 2
Dieser Schritt wird nicht für alle Variablen vom Typ User-Exit aufgerufen,
sondern nur für die Variablen vom Typ User-Exit, die nicht eingabebereit
sind. In diesem Schritt werden die endgültigen Variablenwerte bestimmt.
Dazu wird für jede nicht eingabebereite Variable der User-Exit einmal auf-
gerufen. Sie können daher in diesem Schritt keine Eingaben des Benutzers
überschreiben. Dies ist generell nicht möglich, weil ein derartiges Verhal-
ten meist zu einer starken Verunsicherung des Anwenders führt. Daher
sollten Sie entweder gar keine Benutzereingabe zulassen oder die Benut-
zereingabe mit einer Fehlermeldung zurückweisen.
왘 I_STEP = 3
Der dritte Schritt wird im Gegensatz zu den ersten beiden Schritten nicht
pro Variable aufgerufen, sondern nur einmal insgesamt. Dabei werden
Ihnen sämtliche Variableninhalte übergeben, um diese zu validieren. Sie
können demnach überprüfen, ob die »Periode von« kleiner gleich der

104
Variablen-Exit RSR00001 4.1

»Periode bis« ist, wenn sie nicht als Intervall, sondern in zwei verschiede-
nen Variablen eingegeben werden. Diese Technik ist für eine flexible Vali-
dierung unerlässlich, das heißt eine Überprüfung, ob die Eingabewerte
zueinander passen, jedoch für eine saubere Trennung nach Querys oder
wenigstens Projekten hinderlich, da Variablen möglichst projektübergrei-
fend verwendet werden sollten, um ihre Anzahl zu reduzieren. Daher
müssen Sie ein anderes Feld verwenden, um eine Trennung in der Imple-
mentierung zu erreichen.
왘 I_STEP = 0
Der Schritt 0 wird nur selten eingesetzt. Er wird bei allen Aufrufen ver-
wendet, die nicht in Zusammenhang mit dem Variablenbild stehen. In
SAP NetWeaver 7.x und in SAP BW 3.x gibt es dazu drei Anwendungen:
왘 Zum einen nutzen Sie diesen Schritt, wenn Variablen im InfoPackage für
die Selektion verwendet werden.
왘 Zum anderen wird der Schritt für die Bestimmung der Filterwerte im
Navigationsblock der Query angewendet.
왘 Zum dritten und vielleicht wichtigsten dient er dazu, Variablen zu fül-
len, die in Berechtigungen genutzt werden. Dies ist besonders dann
nützlich, wenn Berechtigungen aus Tabellen gefüllt werden sollen, die
in ein DataStore-Objekt geladen wurden, oder wenn die Berechtigun-
gen aus Stammdaten abgeleitet werden sollen.
In diesem Buch wird ausschließlich der letzte Fall behandelt, da die ande-
ren Fälle in der Praxis zu selten vorkommen.

4.1.1 Interface des Funktionsbausteins EXIT_SAPLRSR0_001


Nachdem die Bedeutung des Parameters I_STEP geklärt ist, lernen Sie die
komplette Schnittstelle kennen. Der Kopf des Funktionsbausteins sieht dabei
wie in Listing 4.1 aus.

FUNCTION EXIT_SAPLRRS0_001.
*"---------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(I_VNAM) LIKE RSZGLOBV-VNAM
*" VALUE(I_VARTYP) LIKE RSZGLOBV-VARTYP
*" VALUE(I_IOBJNM) LIKE RSZGLOBV-IOBJNM
*" VALUE(I_S_COB_PRO) TYPE
*" RSD_S_COB_PRO
*" VALUE(I_S_RKB1D) TYPE
*" RSR_S_RKB1D

105
4 User-Exits und BAdIs im Reporting

*" VALUE(I_PERIV) TYPE


*" RRO01_S_RKB1F-PERIV
*" VALUE(I_T_VAR_RANGE) TYPE
*" RRS0_T_VAR_RANGE
*" VALUE(I_STEP) TYPE I DEFAULT 0
*" EXPORTING
*" VALUE(E_T_RANGE) TYPE RSR_T_RANGESID
*" VALUE(E_MEEHT) LIKE RSZGLOBV-MEEHT
*" VALUE(E_MEFAC) LIKE RSZGLOBV-MEFAC
*" VALUE(E_WAERS) LIKE RSZGLOBV-WAERS
*" VALUE(E_WHFAC) LIKE RSZGLOBV-WHFAC
*" CHANGING
*" VALUE(C_S_CUSTOMER) TYPE
*" RRO04_S_CUSTOMER OPTIONAL
*"---------------------------------------

Listing 4.1 Schnittstelle des Funktionsbausteins EXIT_SAPLRSR0_001

Die einzelnen Parameter haben dabei folgende Bedeutung:

왘 I_VNAM
Dieser Parameter enthält in Step 0, 1 und 2 den Variablennamen, der
berechnet werden soll.
왘 I_VARTYP
Dieser Parameter gibt in Step 1 und 2 an, um welchen Variablentyp es sich
handelt, das heißt, ob als Rückgabe ein Merkmalswert, Text, Formelwert,
Hierarchieknoten oder eine Hierarchie erwartet wird.
왘 I_IOBJNM
Dieser Parameter gibt das InfoObjekt an, auf das sich die Variable bezieht.
왘 I_S_COB_PRO
Dieser Parameter enthält verschiedene Informationen über das InfoObjekt,
auf das sich die Variable bezieht. ATRNAVFL gibt beispielsweise an, ob es sich
bei der Variablen um ein Navigationsattribut handelt, oder ATRTIMFL, ob
das Navigationsattribut zeitabhängig ist. Des Weiteren gibt er ähnliche
Informationen, die nur in speziellen Situationen benötigt werden, weil sie
normalerweise zum Zeitpunkt der Programmierung feststehen und nicht
verändert werden. Dieser Parameter wird deshalb nur selten benötigt.
왘 I_S_RKB1D
Dieser Parameter enthält Informationen wie den Query-Namen, den Auf-
rufer etc. Er ist vor allem in Step 3 von Bedeutung, um zu bestimmen, wel-
che Validierungen durchgeführt werden sollen. Wichtige Felder dafür
sind INFOCUBE (der Name des InfoProviders, auf dem der Bericht ausge-
führt wird) und COMPID (der Query-Name, der gerade ausgeführt wird).

106
Variablen-Exit RSR00001 4.1

왘 I_PERIV
Dieser Parameter enthält die Geschäftsjahresvariante, sofern sie in der
Query eindeutig bestimmt werden kann. Dies ist immer dann wichtig,
wenn aus einem Datum eine Periode bestimmt, beispielsweise die aktuelle
Buchungsperiode als Vorschlagswert gezeigt werden soll. Da aber nur sel-
ten mehrere unterschiedliche Geschäftsjahresvarianten in einem System
vorhanden sind, wird der Parameter auch entsprechend selten benötigt.
왘 I_T_VAR_RANGE
Dieser Parameter enthält eine Tabelle, die sämtliche weiteren Variablen-
werte beinhaltet. Dies ist besonders in Step 2 und 3 sinnvoll.
왘 I_STEP
Der Schritt für die Variablenbestimmung wurde bereits ausführlich erläu-
tert.
왘 E_T_RANGE
In dieser Tabelle müssen die Rückgabewerte in Step 0, 1 und 2 zurückge-
geben werden. Sie ist im Prinzip wie eine Ranges-Tabelle aufgebaut, die
weiteren Felder können ignoriert werden. Abhängig von der Art der Vari-
ablen, müssen dabei folgende Beschränkungen berücksichtigt werden:
왘 Das Feld LOW enthält bei Merkmalswertvariablen den Wert oder die
Wertuntergrenze (bei Intervallen), bei Textvariablen den Text, bei Hie-
rarchievariablen die Hierarchie, bei Knotenvariablen den Knotennamen
und bei Formelvariablen den Rechenwert.
왘 Das Feld HIGH enthält bei Merkmalswertvariablen für Intervalle oder
Selektionsoptionen die Obergrenze des Intervalls. Bei Hierarchieknoten-
variablen beinhaltet dieses Feld das InfoObjekt des Hierarchieknotens.
Dieses kann entfallen, wenn es sich bei dem Knoten um ein Blatt der Hie-
rarchie handelt. Bei anderen Variablen ist es immer leer.
왘 Das Feld SIGN enthält in der Regel immer ein I (für include: einschlie-
ßen). Einzige Ausnahme können Selektionsoptionen sein, bei denen
auch ein E (für exclude: ausschließen) erlaubt ist. SAP NetWeaver Busi-
ness Warehouse erlaubt ein E auch bei Intervallen. Da dies aber nicht der
Logik von Intervallen entspricht, sollten Sie solche Variablen als Selek-
tionsoptionen implementieren.
왘 Das Feld OPT wird in der Regel mit EQ (für equal: gleich) gefüllt. Bei Inter-
vallen können Sie auch BT (für between: zwischen) oder NB (für not bet-
ween: nicht zwischen) verwenden. Bei Selektionsoptionen sind sämtli-
che in Ranges-Tabellen zulässigen Operatoren möglich, die Sie zum Bei-
spiel in der ABAP-Dokumentation zum Schlüsselwort IF finden können.

107
4 User-Exits und BAdIs im Reporting

왘 E_MEEHT, E_MEFAC, E_WAERS, E_WHFAC, C_S_CUSTOMER


Diese Parameter sind in der Schnittstelle zwar angegeben, werden jedoch
nicht abgefragt.

Aufgrund der unterschiedlichen Bedeutungen der Schritte können Sie auch


die Implementierung des Exits entsprechend vorgeben. Möchten Sie, wie
bereits zu Listing 4.2 beschrieben, eine generische Vorgabe machen, die
dann einzelne Funktionsbausteine aufruft, können Sie folgende Implemen-
tierung verwenden (siehe Listing 4.2):

DATA: l_d_fname(30) TYPE c.


CASE i_step.
WHEN 1.
CONCATENATE 'Z_VAR_PRE_POPUP_'
i_vnam INTO l_d_fname.
WHEN 2.
CONCATENATE 'Z_VAR_POST_POPUP_'
i_vnam INTO l_d_fname.
WHEN 0.
CONCATENATE 'Z_VAR_AUTHORITY_'
i_vnam INTO l_d_fname.
WHEN 3.
l_d_fname = 'Z_VAR_CHECK_VALIDITY'.
ENDCASE.
TRY.
CALL FUNCTION l_d_fname
EXPORTING
I_VNAM = i_vnam
I_VARTYP = i_vartyp
I_IOBJNM = i_iobjnm
I_S_COB_PRO = i_s_cob_pro
I_S_RKB1D = i_s_rkb1d
I_PERIV = i_periv
I_T_VAR_RANGE = i_t_var_range
I_STEP = i_step
IMPORTING
E_T_RANGE = e_t_range
E_MEEHT = e_meeht
E_MEFAC = e_mefac
E_WAERS = e_waers
E_WHFAC = e_whfac
CHANGING
C_S_CUSTOMER = c_s_customer
EXCEPTIONS
OTHERS = 1.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY

108
Variablen-Exit RSR00001 4.1

NUMBER SY-MSGNO
WITH
SY-MSGV1 SY-MSGV2
SY-MSGV3 SY-MSGV4
RAISING ERROR_IN_VARIABLE.
ENDIF.
CATCH CX_SY_DYN_CALL_ILLEGAL_FUNCTION.
* Nichts machen, weil kein Exit implementiert wurde,
* zum Beispiel in Step 1, wenn nur Step 2 implementiert wurde.
ENDTRY.

Listing 4.2 Beispielimplementierung für den Variablen-Exit ZXRSRU01

Wenn Sie sich die Funktionsbausteine RSVAREXIT_* anschauen, werden


Sie feststellen, dass Variablen mit einem SAP-Exit von der SAP-Entwicklung
fast genauso implementiert werden, nur dass die Entwicklung nicht nach
dem I_STEP unterscheidet. Sie sollten in diesem Schritt jedoch eine Unter-
scheidung vornehmen, da Sie auf diese Art und Weise bereits am Namen
des Funktionsbausteins erkennen, wozu er gedacht ist. Haben Sie bereits in
größeren BW-Systemen gearbeitet, werden Sie festgestellt haben, dass der
Exit ZXRSRU01 einer der größten im System ist. Alle Änderungen an die-
sem Exit sind kritisch, da gegebenenfalls sämtliche Berichte davon betrof-
fen sind. Nach Ihrem ersten Transport eines nicht syntaxfehlerfreien Exits
in ein Produktivsystem werden Sie wissen, wovon hier die Rede ist. Sie
sollten deshalb von Anfang an die Beispielimplementierung übernehmen,
um damit ein lästiges Problem zu vermeiden, das sich meist erst zeigt,
wenn mehrere Projekte in dem System bereits produktiv laufen: einen
inhaltlich getrennten Transport, um verschiedene Variablenimplementie-
rungen zu ermöglichen. Natürlich stellt sich dann noch die Frage, wer die
Verantwortung für den Funktionsbaustein Z_VAR_CHECK_VALIDITY über-
nimmt. Aber im Zweifelsfall können Sie in diesem Baustein aus jedem Pro-
jekt heraus einen zentralen Funktionsbaustein aufrufen und die Prüfergeb-
nisse sammeln.

4.1.2 Implementierung bei I_STEP = 1


Nun zur eigentlichen Implementierung der Variablenlogik. Da I_STEP = 1 die
Vorschlagswerte setzen soll, können Sie nur Algorithmen implementieren,
die keine Benutzereingaben erfordern. Daher gibt es hauptsächlich zwei
Arten von Algorithmen:

왘 eine datumsabhängige Vorschlagswertbestimmung


왘 eine tabellengesteuerte Vorschlagswertbestimmung

109
4 User-Exits und BAdIs im Reporting

Beispiel 1: Datumsabhängige Vorbelegung


Eine Variable WEEK6F soll für das InfoObjekt 0CALWEEK implementiert werden.
Diese Variable ist eine Merkmalswertvariable vom Typ Intervall und soll als
Vorschlagswert das Intervall von der aktuellen Woche bis in sechs Wochen
erhalten. Das Coding hierzu könnte wie in Listing 4.3 aussehen.

DATA: l_d_datum TYPE d,


l_d_woche TYPE /bi0/oicalweek.
DATA: l_s_range TYPE rsr_s_rangesid.
CASE i_vnam.
WHEN 'WEEK6F'.
IF i_step = 1. "Vor dem Pop-up
* Aktuelle Woche bestimmen
CALL FUNCTION 'DATE_GET_WEEK'
EXPORTING
date = sy-datum
IMPORTING
week = l_d_woche.
* Woche in Rückgabe aufnehmen
l_s_range-low = l_d_woche.
l_s_range-sign = 'I'.
l_s_range-option = 'EQ'.
* Jetzt sechs Wochen später bestimmen
l_d_datum = sy-datum + 42.
"42 Tage = 6 Wochen
CALL FUNCTION 'DATE_GET_WEEK'
EXPORTING
date = l_d_datum
IMPORTING
week = l_d_woche.
* Ende des Rückgabeintervalls füllen
l_s_range-high = l_d_woche.
APPEND l_s_range TO l_t_range.

Listing 4.3 Beispiel zur datumsabhängigen Variablenvorbelegung

Beispiel 2: Tabellenabhängige Vorbelegung


Im zweiten Beispiel soll eine Variable LASTCPER die letzte im Quellsystem
abgeschlossene Periode enthalten. Damit nicht bei jedem Query-Aufruf das
Quellsystem mittels Remote Function Call aufgerufen wird, wurde zu diesem
Zweck eine Tabelle Z_BEX_VAR angelegt, die manuell während des Monats-
abschlusses gepflegt wird und aus den Feldern KEY (CHAR 20) und VALUE
(CHAR 60) besteht. KEY ist dabei das einzige Schlüsselfeld der Tabelle, VALUE
das Datenfeld.

110
Variablen-Exit RSR00001 4.1

In dem Eintrag mit KEY = 'LASTCPER' wird dabei manuell die letzte abge-
schlossene Periode gepflegt. Das Coding zur Abfrage der Tabelle sieht wie in
Listing 4.4 aus.

DATA: l_s_bex_var TYPE z_bex_var,


l_s_range TYPE rsr_s_rangesid.
CASE i_vnam.
WHEN 'LASTCPER'.
IF i_step = 1. "Vor Variablen-Popup
* Tabelleneintrag lesen
SELECT SINGLE * FROM z_bex_var
INTO l_s_bex_var
WHERE key = 'LASTCPER'.
IF SY-SUBRC = 0.
* In Rückgabe übertragen
l_s_range-low = l_s_bex_var-value.
ELSE.
* Hier könnte man auch einen Fehler ausgeben
clear l_s_range-low.
ENDIF.
l_s_range-sign = 'I'.
l_s_range-opt = 'EQ'.
ENDIF.
ENDCASE.

Listing 4.4 Beispiel zur tabellenabhängigen Vorbelegung

Aus der gewünschten Art der Vorbelegung ergibt sich, welche Art der Imple-
mentierung Sie nutzen. Häufig wird die tabellenabhängige Vorbelegung auch
für eine Vorbelegung abhängig vom Benutzernamen oder gar von bestimm-
ten Benutzerberechtigungen verwendet. Da das Handling von Reporting-
Berechtigungen nicht ganz einfach ist, wird im Folgenden noch anhand eines
etwas komplexeren Beispiels gezeigt, wie Sie Reporting-Berechtigungen der
Klasse RSR oder die neuen Analyseberechtigungen lesen, ohne für jeden
Stammdateneintrag einen AUTHORITY-CHECK durchzuführen.

Beispiel 3: Vorbelegung aus Berechtigungen


Für einen Kunden, der über gesellschaftsübergreifende Geschäftsbereiche ver-
fügt, soll ein zweidimensionales Berechtigungsobjekt implementiert werden,
das die externe Unternehmensstruktur (InfoObjekt 0COMPANY) und die interne
Unternehmenssicht (InfoObjekt 0BUS_AREA) in einem Berechtigungsobjekt ver-
eint. Auf diese Weise soll die externe und die interne Sicht besser unterschie-
den werden. Je nach Bericht sollen die Verantwortlichen entweder alle Kosten
ihrer Gesellschaft oder alle Kosten in ihrem Geschäftsbereich sehen.

111
4 User-Exits und BAdIs im Reporting

Zweidimensionales Berechtigungsobjekt
Es ist sicherlich eher eine Ausnahme, dass zwei InfoObjekte in einer Reporting-
Berechtigung Verwendung finden, und vielen ist bestimmt nicht bewusst, dass dies
möglich ist. Aber sowohl Reporting als auch Planung laufen in dem System ein-
wandfrei und verproben die Berechtigungen korrekt.

Daher haben zahlreiche Mitarbeiter zwei Ausprägungen des Berechtigungs-


objektes, beispielsweise:

왘 0COMPANY = 100 und 0BUS_AREA = *


왘 0COMPANY = * und 0BUS_AREA = 1000

Dieses Konzept bereitet eine große Schwierigkeit: Ruft ein Mitarbeiter einen
Bericht in der externen Sicht auf, soll ihm automatisch seine Gesellschaft 100
als Vorschlagswert eingeblendet werden. Lassen Sie die Variable jedoch aus
der Berechtigung füllen, wird dem Benutzer immer die erweiterte Ausprä-
gung * vorgeschlagen; in diesem Fall eine leere Selektion.

Die Implementierung in Listing 4.5 liest die Berechtigungen und füllt den
Vorschlagswert entsprechend. Dabei werden im ersten Schritt die existie-
renden Berechtigungen zu dem InfoObjekt 0BUS_AREA gelesen. Anschlie-
ßend werden diese überprüft. Handelt es sich um eine allgemeine Berechti-
gung (*-Berechtigung), wird diese ignoriert. Handelt es sich um einen
konkreten Geschäftsbereich, wird dieser in die Vorbelegung der Variablen
zurückgegeben.

DATA: v_tsx_auth_values_user TYPE


rssb_tsx_auth_values_user,
w_sx_auth_values_user TYPE line of
rssb_tsx_auth_values_user,
w_sx_auth_values_auth TYPE
rssb_sx_auth_values_user_auth,
w_sx_auth_values_iobjnm TYPE
rssb_sx_auth_values_user_iobj,
w_sx_auth_values_range LIKE rrrange,
v_ts_authnode TYPE rssbr_ts_authnode,
w_s_authnode TYPE line of
rssbr_ts_authnode,
v_authhieruid TYPE rssauthhieruid.

CONSTANTS: c_zcomp_bus TYPE rssb_sx_auth_values_user-object


VALUE 'ZCOMP_BUS',
c_attrinm_company TYPE
rssb_sx_auth_values_user_iobj-iobjnm
VALUE '0COMPANY',

112
Variablen-Exit RSR00001 4.1

c_attrinm_busarea TYPE
rssb_sx_auth_values_user_iobj-iobjnm
VALUE '0BUS_AREA'.

IF i_step = 1.

* Lies alle Reporting-Berechtigungen für den Benutzer


* (nur InfoObjekt 0BUS_AREA)
CALL FUNCTION 'RSSB_AUTHORIZATIONS_OF_USER'
EXPORTING
I_IOBJNM = '0BUS_AREA'
I_INFOPROV = 'DEMOCUBE'
I_UNAME = sy-uname
I_HIENM = 'DEMOHIER'
I_DATETO = sy-datum
I_VERSION = '000'
IMPORTING
* E_T_RANGESID =
E_TSX_AUTH_VALUES_USER = v_tsx_auth_values_user
* E_NIOBJNM =
* E_NODE =
* E_TS_NODE =
* E_TS_AUTH_VALUES_HIERARCHY =
* E_T_MSG =
EXCEPTIONS
NOT_AUTHORIZED = 1
INTERNAL_ERROR = 2
USER_DOESNT_EXIST = 3
X_MESSAGE = 4
OTHERS = 5.
IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY
NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4
RAISING not_authorized.
ENDIF.

* LOOP über alle Reporting-Berechtigungen des Benutzers


LOOP AT v_tsx_auth_values_user
INTO w_sx_auth_values_user.
* Welches Berechtigungsobjekt?
CHECK w_sx_auth_values_user-object = c_zcomp_bus.
* Doppelberechtigungsobjekt LOOP über alle Ausprägungen
* zum Berechtigungsobjekt
LOOP AT w_sx_auth_values_user-auth
INTO w_sx_auth_values_auth.
* Company-Ausprägung lesen
READ TABLE w_sx_auth_values_auth-values_iobjnm

113
4 User-Exits und BAdIs im Reporting

INTO w_sx_auth_values_iobjnm
WITH KEY iobjnm = c_attrinm_company.
IF sy-subrc = 0.
* Gesellschaft gefunden
LOOP AT w_sx_auth_values_iobjnm-ranges
INTO w_sx_auth_values_range.
IF ( w_sx_auth_values_range-sign = 'I' )
AND ( w_sx_auth_values_range-opt = 'CP' )
AND ( w_sx_auth_values_range-low = '*' ).
* Existiert eine *-Berechtigung für 0COMPANY?
* Geschäftsbereich bestimmen.
READ TABLE w_sx_auth_values_auth-values_iobjnm
INTO w_sx_auth_values_iobjnm
WITH KEY iobjnm = c_attrinm_busarea.
IF sy-subrc = 0.
* Berechtigung zum Geschäftsbereich
LOOP AT w_sx_auth_values_iobjnm-ranges
INTO w_sx_auth_values_range.
MOVE-CORRESPONDING w_sx_auth_values_range
TO l_s_range.
APPEND l_s_range TO e_t_range.
ENDLOOP. "w_sx_auth_values_iobjnm_range
ENDIF. "sy-subrc = 0
ENDIF. "*-Berechtigung für 0COMPANY
ENDLOOP. " w_sx_auth_values_iobjnm-ranges
ENDIF. "sy-subrc = 0
ENDLOOP. "w_sx_auth_values_user-auth
ENDLOOP. "v_tsx_auth_values_user

Listing 4.5 Ableitung der Berechtigungen aus speziellen Berechtigungsobjekten

4.1.3 Implementierung bei I_STEP = 2


Im Prinzip unterscheidet sich die Implementierung von Schritt 2 nicht von
der Implementierung von Schritt 1. Es gibt jedoch eine bedeutende Abwei-
chung, die enorm wichtig ist: In Schritt 2 haben Sie die Möglichkeit, auf die
Werte zurückzugreifen, die im Pop-up eingegeben wurden. Dies ist oft nötig,
wenn der Benutzer einen Zeitpunkt eingibt und abhängig von dem Zeit-
punkt Ableitungen getroffen werden. Dies wird im folgenden Beispiel erläu-
tert.

Beispiel 4: Zeitabhängige Versionen


Der Benutzer soll in der Variablen REP_PER eine Berichtsperiode eingeben.
Die Variable REP_VERS soll dann abhängig von dem Zeitpunkt der Variablen
REP_PER die Werte in Tabelle 4.1 annehmen.

114
Variablen-Exit RSR00001 4.1

Zeitpunkt REP_PER Wert REP_VERS


Periode ist abgeschlossen. ACT (Ist-Version)
Periode ist im aktuellen Jahr, aber nicht abgeschlossen. PRE (Vorschau)
Periode ist in einem der Folgejahre. PLN (Planversion)

Tabelle 4.1 Versionsumsetzung

Die Implementierung dazu finden Sie in Listing 4.6. Dabei wird zuerst die
Berichtsperiode REP_PER gelesen. Anschließend wird der letzte Tag der
Berichtsperiode bestimmt. Nach den Vorgaben der Tabelle 4.1 wird dann
der Rückgabewert bestimmt.

DATA: l_s_range TYPE rsr_s_rangesid.


DATA: l_s_var_range LIKE rrrangeexit,
l_d_datum LIKE sy-datum,
l_d_year TYPE /bi0/oifiscyear,
l_d_per3 TYPE /bi0/oifiscper3.
CASE i_vnam.
WHEN 'CUMMONTH'.
CLEAR l_s_range.
IF i_step = 2. "Nach Pop-up
* Eingabe der Variablen REP_PER lesen
READ TABLE i_t_var_range INTO l_s_var_range
WITH KEY vnam = 'REP_PER'.
IF sy-subrc = 0.
l_d_year = l_s_var_range-low(4).
l_d_per3 = l_s_var_range-low+4(3).
CALL_FUNCTION 'LAST_DAY_IN_PERIOD_GET'
EXPORTING
I_GJAHR = l_d_year
I_PERIV = i_periv
I_POPER = l_d_per3
IMPORTING
E_DATUM = l_d_datum
EXCEPTIONS
OTHERS = 1.
IF SY-SUBRC <> 0.
* Nicht bestimmbar (fehlende
* Geschäftsjahresvariante?) => Default setzen
l_s_range-low = 'ACT'.
ELSE.
IF l_d_datum <= sy-datum.
* Periode abgeschlossen
l_s_range-low = 'ACT'.
ELSE.
CALL_FUNCTION 'FIRST_DAY_IN_YEAR_GET'

115
4 User-Exits und BAdIs im Reporting

EXPORTING
I_GJAHR = l_d_year
I_PERIV = i_periv
IMPORTING
E_DATUM = l_d_datum
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
* Nicht bestimmbar (aber Periode war
* bestimmbar?) => Default setzen
l_s_range-low = 'ACT'.
ELSE.
IF l_d_datum > sy-datum.
* Geschäftsjahr noch nicht begonnen
l_s_range-low = 'PLN'.
ELSE.
l_s_range-low = 'PRE'.
ENDIF.
ENDIF.
ENDIF.
ENDIF.
ELSE.
* Variable wurde irrtümlich verwendet, sinnvollen
* Default setzen (zum Beispiel ACT)
l_s_range-low = 'ACT'.
ENDIF.
l_s_range-sign = 'I'.
l_s_range-opt = 'EQ'.
APPEND l_s_range TO e_t_range.

Listing 4.6 Beispiel zur Variablenbestimmung abhängig von Eingabevariablen

Typische Beispiele für die Variablenbestimmung abhängig von Eingabevari-


ablen sind:

왘 Ableitung einer Formelvariablen aus einer eingegebenen Periode zur


Hochrechnung von Jahresprognosen oder Verteilung von Jahreswerten
왘 Ableitung einer Vergleichsgruppe (zum Beispiel einer Hierarchieknoten-
variablen) zu einem eingegebenen Merkmal, beispielsweise einem Profit-
Center
왘 Ableitung der Unter- oder Obergrenze eines Zeitintervalls, das nicht
durch eine feste Anzahl von Perioden, sondern durch andere Schranken
definiert ist, zum Beispiel Quartalsanfang oder -ende
왘 Bestimmung einer berechtigungsabhängigen Formelvariablen zur Anzeige
von noch nicht freigegebenen Perioden. Dabei wird abhängig von der ein-

116
Variablen-Exit RSR00001 4.1

gegebenen Periode geprüft, ob die Periode schon freigegeben ist. Wenn


nicht, wird eine Berechtigungsprüfung durchgeführt. Schlägt diese fehl,
wird 0 zurückgeliefert, sonst 1. Die Query multipliziert daraufhin den tat-
sächlichen Wert mit dem Ergebnis der Formelvariablen.
왘 Ableitung von Variablen für MultiProvider. So können Sie zum Beispiel
eine Variable für eine Kostenstelle abfragen und aus der Kostenstelle dann
das zugeordnete Profit-Center ableiten, da in einem der beteiligten Info-
Provider keine Kostenstelle, sondern nur das Profit-Center enthalten ist.

4.1.4 Implementierung bei I_STEP = 0


Step 0 ist unter anderem für die Ableitung von Variablen in Berechtigungen
vorgesehen. Sie können in einer Reporting-Berechtigung einfach eine Vari-
able verwenden, indem Sie einen Variablennamen eintragen, der mit einem
Dollarzeichen ($) beginnt. Diese Variable muss vorher im Query Designer
definiert worden sein. Bei der Ausführung eines Berichts wird der Exit auf-
gerufen, und Sie können die Bestimmung der Berechtigung in ABAP durch-
führen.

Bei der Bestimmung der Berechtigungen wird die Rückgabetabelle wie eine
Berechtigung aufgefasst, daher müssen auch hier die Einschränkungen wie
bei Berechtigungen berücksichtigt werden. Dementsprechend muss SIGN
immer den Wert I haben, OPT muss einen der Werte EQ oder BT annehmen.
Ausschließende Berechtigungen, zum Beispiel »alle Gehälter außer den Vor-
standsbezügen«, sind nicht erlaubt.

Mögliche und typische Anwendungen dafür sind Ableitungen von Berechti-


gungen aus Tabellen oder aus Stammdaten. Auf diese Art und Weise ist es
jedoch auch möglich, die Berechtigung abhängig vom aktuellen Datum zu
vergeben. Eine typische Anwendung dafür zeigt das folgende Beispiel.

Beispiel 5: Berechtigungen in der Quiet Period ändern


In diesem Beispiel soll für eine Regionalhierarchie eine Berechtigung zeitab-
hängig gesteuert werden. Dabei haben alle Mitarbeiter immer die Berechti-
gung auf alle Regionen, nur in der sogenannten Quiet Period vom 25. eines
Monats zum Quartalsende bis zum 15. des Folgemonats (im Januar bis zum
25. Januar) dürfen sie ausschließlich die Regionen sehen, die in einer Tabelle
abgelegt sind. Dazu ist in ihrer Berechtigung die Variable $QREGION hinter-
legt. Diese Variable wird in Listing 4.7 gefüllt. Dabei wird zuerst der aktuelle
Tag bestimmt. Anschließend wird überprüft, ob der Tag in den definierten

117
4 User-Exits und BAdIs im Reporting

Perioden liegt. Wenn ja, darf der Benutzer nur bestimmte Regionen sehen,
im Übrigen darf er alles sehen.

DATA: L_S_RANGE TYPE RSR_S_RANGESID.


CASE i_vnam.
WHEN 'QREGION'.
* Datum in der Quiet Period?
DATA: l_d_tag(4) TYPE n,
l_s_region TYPE z_user_region.
l_d_tag = sy-datum+4(4).
IF ( l_d_tag <= '0125' ) OR
( ( l_d_tag >= '0325' ) AND
( l_d_tag <= '0415' ) ) OR
( ( l_d_tag >= '0625' ) AND
( l_d_tag <= '0715' ) ) OR
( ( l_d_tag >= '0925' ) AND
( l_d_tag <= '1015' ) ) OR
( l_d_tag >= '1225' ).
l_s_range-sign = 'I'.
l_s_range-opt = 'EQ'.
SELECT * FROM z_user_region
INTO l_s_region
WHERE uname = sy-uname.
l_s_range-low =
l_s_region-region.
APPEND l_s_range TO e_t_range.
ENDSELECT.
ELSE.
l_s_range-sign = 'I'.
l_s_range-opt = 'CP'.
l_s_range-low = '*'.
APPEND l_s_range TO e_t_range.
ENDIF.

Listing 4.7 Implementierung einer Berechtigungsvariablen

Die IF-Abfrage in Listing 4.7 würde normalerweise nicht direkt in die Vari-
able geschrieben, sondern in eine separate Check-Funktion ausgelagert,
eventuell sogar in einer Customizing-Tabelle hinterlegt werden. In der Praxis
würden diese Zeilen sonst regelmäßig geändert.

4.1.5 Implementierung bei I_STEP = 3


Die Implementierung bei I_STEP = 3 ist anders und etwas komplizierter als
die Implementierung der anderen Schritte. Dies liegt vor allem an zwei Fak-
toren: Zum einen ist darauf zu achten, dass nicht in jeder Query dieselben

118