SAP Planung - Flexible Datenscheiben in SAP BPC mit ABAP und SQLScript

Chris Fidanidis

Geschrieben von: Chris Fidanidis - 14 September 2020
(Aktualisiert am: 20 Januar 2023)

Eine häufige Anforderung in der SAP Planung, sei es Planning and Consolidation (BPC) oder BW Integrierte Planung (BW IP), ist die Möglichkeit, flexible Datenscheiben zu nutzen. Dadurch soll dem Fachbereich ermöglicht werden, Daten zentral sperren und entsperren zu können. So soll die Konsistenz der Daten in den verschiedenen Planungsschritten gewährleistet werden. In diesem Beitrag lernen Sie, wie Sie dieses Szenario mithilfe eines Exits umsetzen können.

In unserem Beispiel wollen wir einen Buchungskreis für die Planung sperren. Dabei haben die Benutzer die Möglichkeit, über eine Query Daten im DSO einzutragen. So wird zum Beispiel für den Buchungskreis eine 1 oder 0 eingetragen.

Noch schneller geht die Erfassung der Daten mit NextTables.

Mehr Informationen über NextTables erhalten Sie hier.

 

Locked company code

Diese Information wird über den Exit ausgelesen. Wenn ein Buchungskreis mit dem Flag 1 vorhanden ist, wird dieser Buchungskreis als gesperrt behandelt. In unserem Beispiel gilt der Buchungskreis 1000 als gesperrt.

Customer Exit DataSlice

Grundlagen der SQL Script Umsetzung

Die Umsetzung des Customer Exits mit SQL Script erlaubt es, die Performancevorteile von HANA voll auszuschöpfen. Bei Disaggregationen oder Planungsfunktionen mit vielen Daten werden Kalkulationen in der SAP HANA Datenbank verarbeitet. Dabei profitieren Sie von den Performance Steigerungen, da die Daten nicht zuerst in die ABAP Umgebung übertragen werden müssen, sondern mittels SQL Script direkt auf der Datenbank verarbeitet werden können.

Allerdings muss neben der SQL Script Implementierung auch die entsprechende Implementierung in ABAP vorhanden sein. Wenn nämlich Eingabe-bereite Queries verwendet werden, nutzt das SAP System die ABAP Umgebung. Eine weitere Ausnahme stellt die Planungsfunktion vom Typ Prognose dar. In allen anderen Fällen wird die SQL Script Implementierung verwendet.

ABAP Klasse anlegen

Wie Sie bereits gelernt haben, muss das Exit in beiden Sprachen, ABAP und SQL Script, vorhanden sein. Daher legen wir zunächst die ABAP Klasse an.

Dabei können Sie die vorhandene Beispielklasse CL_RSPLS_DS_EXIT_BASE als Vorlage nutzen. Diese Klasse enthält die für die ABAP Implementierung notwendigen Schnittstellen und vordefinierte Methoden.

Beispielklasse CL_RSPLS_DS_EXIT_BASE

Die Beispielklasse befindet sich im Paket RSPLS. Um die Klasse leichter finden zu können, können Sie das Paket zu den Favoriten hinzufügen.

Paket zu Favoriten hinzufügen

Selektieren Sie die Klasse CL_RSPLS_DS_EXIT_BASE und führen einen Rechtsklick aus. Wählen Sie anschließend Duplicate aus dem Kontextmenü.

Klasse kopieren

Bestimmen Sie anschließend das Paket und den Namen der neuen Klasse.

Name der Klasse definieren

Wählen Sie in der neuen Klasse die Methode IS_PROTECTED aus. In dieser erfolgt die Prüfung, ob ein Datensatz gegen Änderungen geschützt ist.

Methode IS_PROTECTED definieren

In unserem Beispiel verwenden wir einen Buffer und eine zusätzliche Methode, um das DSO auszulesen. Wenn für einen Buchungskreis ein Eintrag mit dem Flag 1 gefunden wird, gilt dieser als gesperrt.

Code Snippets ABAP

Methode: IS_PROTECTED

Fügen Sie den folgenden Code ein:

METHOD IF_RSPLS_DS_METHODS~IS_PROTECTED.
*---------------------------------------------------------------------*
* --> i_s_data data record, the values for infoobjects from
* n_ts_fields are set, the rest is initial
* <-- e_t_mesg messages
* <-- e_noinput flag, records is protected or not
*---------------------------------------------------------------------*


FIELD-SYMBOLS:
<l_th_buf> TYPE HASHED TABLE,
<l_s_buf> TYPE any.

CLEAR e_t_mesg.

ASSIGN o_r_th_buf->* TO <l_th_buf>.
ASSIGN o_r_s_buf->* TO <l_s_buf>.
<l_s_buf> = i_s_data.
READ TABLE <l_th_buf> INTO <l_s_buf> FROM <l_s_buf>.
IF sy-subrc NE 0.
* This record is not checked before
* Now we check if the record is locked

CALL METHOD me->get_locked_entries
EXPORTING
i_s_data = i_s_data
IMPORTING
e_s_mesg = o_r_s_mesg->*
e_noinput = o_r_protected->*.

INSERT <l_s_buf> INTO TABLE <l_th_buf>.
ENDIF.
e_noinput = o_r_protected->*."fix pointer to <l_s_buf>-protected
IF e_noinput = rs_c_true AND e_t_mesg IS SUPPLIED.
* o_r_s_mesg is a pointer to '_S_MESG' in the buffer workarea
APPEND o_r_s_mesg->* TO e_t_mesg.
ENDIF.

ENDMETHOD.

Methode: Get Locked Entries

Zunächst müssen wir die Parameter im DEFINITION Teil bestimmen:

Parameter der Methode

METHODS get_locked_entries
IMPORTING
!i_s_data TYPE any
EXPORTING
!e_s_mesg TYPE if_rspls_cr_types=>tn_s_mesg
!e_noinput TYPE rs_bool .

Im IMPLEMENTATION Teil fügen wir die folgende Logik hinzu:

METHOD get_locked_entries.
DATA:
l_s_mesg TYPE if_rspls_cr_types=>tn_s_mesg,
lv_compcode TYPE /bi0/oicomp_code.

FIELD-SYMBOLS:
<fs_compcode> TYPE /bi0/oicomp_code.

ASSIGN COMPONENT:
'COMP_CODE' OF STRUCTURE i_s_data TO <fs_compcode>.


CHECK sy-subrc EQ 0.
CLEAR lv_compcode.
SELECT SINGLE comp_code FROM /bic/azd011lock7
INTO lv_compcode
WHERE comp_code = <fs_compcode>
AND /bic/zdflag = 1.

IF lv_compcode IS NOT INITIAL.
e_s_mesg-msgid = 'ZDR'.
e_s_mesg-msgno = '000'. "Company Code &1 is locked against changes.
e_s_mesg-msgty = 'W'.
e_s_mesg-msgv1 = <fs_compcode>.
e_noinput = rs_c_true.
ELSE.
e_noinput = rs_c_false.
ENDIF.

ENDMETHOD.

Bessere Performance mit externem Buffer

Wenn das Exit oft aufgerufen wird, erreichen Sie mit dem externen Buffer eine bessere Performance. Löschen Sie dazu in der CONSTRUCTOR Methode die vorhandene Buffer Logik und definieren Sie Folgendes:

*use external buffering
if_rspls_dataslice~n_use_external_buffer = abap_true.

External buffer attribut

Anlegen der Datenscheibe

Nachdem wir die Klasse angelegt haben, legen wir eine neue Datenscheibe vom Typ Exit an. Als Exit Klasse wählen Sie die vorhin definierte Klasse aus.

Datenscheibe definieren


Planungstools im Vergleich - SAP BW IP vs. BPC vs. SAC 

Neuer Call-to-Action



Implementierung in SQL Script

Für die Verwendung der Datenscheiben auf der Ebene der SAP HANA Datenbank wird die HANA spezifische Schnittstelle IF_RSPLS_DS_EXIT_HDB benötigt. Diese Schnittstelle enthält zwei Methoden GET_SQLSCRIPT_INFO und GET_SQLSCRIPT_PARAMETERS. Die erste Methode, GET_SQLSCRIPT_INFO, bestimmt die Namen der SQL Script Prozedur, die für die Verarbeitung des Exits benötigt werden. So wird dem System mitgeteilt, welche Methode es aufrufen muss, um in unserem Beispiel die gesperrten Buchungskreise zu bestimmen. Diese Methode wird in der vorhin angelegten Klasse als AMDP (ABAP Managed Database Procedure) implementiert.

Die Methode GET_SQLSCRIPT_INFO enthält folgende Parameter:

  • E_DB_SCHEMA_NAME - Name des Datenbankschemas, welches die auszuführenden SQL Script Prozeduren enthält. Wenn dieser Parameter nicht gefüllt wird, wird standardmäßig das Datenbankschema des SAP Systems übernommen.
  • E_PROCEDURE_NAME_PROTECTED - Name der SQL Script Prozedur, die die Implementierung der Sperrprüfung enthält. Wenn keine Prozedur übergeben wird, ruft das System die ABAP Implementierung als Fallback Lösung auf.
  • E_PARAMETER_NAME - Name der Struktur, die zusätzliche Parameter enthält, die zur Laufzeit an die jeweiligen SQL Script Prozeduren übergeben werden. Diese Struktur muss zuvor im ABAP Dictionary angelegt werden. Wenn dieser Parameter nicht gesetzt ist, werden vom Applikationsserver keine zusätzlichen Informationen gesendet.
  • E_HAS_SQL_MESG - boolescher Operator, ob die SQL Script Prozedur Nachrichten ausgibt.

Mit der Methode GET_SQLSCRIPT_PARAMETERS können Sie zusätzliche Parameter, wie z.B. das ABAP System-Datum oder Benutzername an die SQL Script Methode übergeben. In unserem Beispiel benötigen wir keine zusätzlichen Parameter, daher verwenden wir diese Methode nicht. Eine leere Implementierung genügt in dem Fall.

Das von SAP ausgelieferte Programm RSPLS_SQL_SCRIPT_TOOL bietet eine Hilfestellung bei der Implementierung von SQL Script Methoden. Rufen Sie in der SAP GUI die Transaktion SE38 auf und wählen Sie RSPLS_SQL_SCRIPT_TOOL als Programm aus. Starten Sie das Programm über den Button Ausführen oder über die F8 Taste.

Programm ausführen

Wechseln Sie anschließend auf die Registerkarte Beispiel-Merkmalsbeziehung/Datenscheibe. Wählen Sie danach den InfoProvider und die Nummer der relevanten Datenscheiben aus. Selektieren Sie auch die Option Mit Codinghinweisen.

Tool für SQL Script Exits

Wenn Sie anschließend auf Ausführen klicken, generiert das System einen Vorschlag. Sie können den generierten Quellcode direkt an den jeweiligen Stellen in Ihrer Klasse einsetzen. Die gelb markierten Felder dienen der Navigation. Diese ermöglichen es, direkt zu dem jeweiligen InfoProvider, der Klasse oder InfoObjekt zu springen.

2020-09-10_12_57_22-code-vorschlag

Folgen Sie den generierten Kommentaren und fügen Sie die Code Vorschläge in Ihre ABAP Klasse ein.

So fügen wir in den PUBLIC Bereich der Klasse den folgenden Code ein:

* the public section of your class ZDRCL_RSPLS_DS_EXIT_BASE has to contain the following lines:
INTERFACES if_amdp_marker_hdb.
INTERFACES if_rspls_ds_exit_hdb .

types:
begin of tn_s_data,
COMP_CODE type /BI0/OICOMP_CODE,
end of tn_s_data.
types
tn_t_data TYPE STANDARD TABLE OF tn_s_data
WITH DEFAULT KEY.

METHODS AMDP_GET_PROTECTED_RECORD
IMPORTING
VALUE(i_t_data) TYPE tn_t_data
EXPORTING
VALUE(e_t_data) TYPE tn_t_data.

Im IMPLEMENTATION Bereich legen wir die AMDP Methode fest, die ausgeführt werden soll.

METHOD if_rspls_ds_exit_hdb~get_sqlscript_info.
e_procedure_name_protected = 'ZDRCL_RSPLS_DS_EXIT_BASE=>AMDP_GET_PROTECTED_RECORD'.
ENDMETHOD.

In unserem Beispiel verwenden wir keine Parameter, daher muss nichts übergeben werden.

Anschließend definieren wir die Logik der AMDP Methode in SQL Script. Dabei lesen wir die geprüften Buchungskreise aus dem ADSO aus. Wenn ein Eintrag mit dem Flag 1 gefunden wird, gelten diese Buchungskreise als gesperrt.

METHOD amdp_get_protected_record BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING /bic/azd011lock7.

e_t_data = select it.COMP_CODE
from :i_t_data as it
LEFT JOIN "/BIC/AZD011LOCK7" as lookup
ON it.COMP_CODE = lookup.COMP_CODE
where lookup."/BIC/ZDFLAG" = 1;

ENDMETHOD.

Um Nachrichten aus Ihrer SQL Script Logik auszugeben, müssen Sie folgende Anpassungen vornehmen. In DEFINITION Teil definieren wir die Tabelle für die Nachrichten und erweitern die AMDP Methode:

TYPES:
BEGIN OF tn_s_mesg,
msgid TYPE syst-msgid,
msgno TYPE syst-msgno,
msgty TYPE syst-msgty,
msgv1 TYPE syst-msgv1,
msgv2 TYPE syst-msgv2,
msgv3 TYPE syst-msgv3,
msgv4 TYPE syst-msgv4,
END OF tn_s_mesg,
tn_t_mesg TYPE STANDARD TABLE OF tn_s_mesg
WITH NON-UNIQUE DEFAULT KEY.

METHODS amdp_get_protected_record
IMPORTING
VALUE(i_t_data) TYPE tn_t_data
EXPORTING
VALUE(e_t_data) TYPE tn_t_data
VALUE(e_t_mesg) TYPE tn_t_mesg.

Im IMPLEMENTATION Teil legen wir fest, dass die Methode Nachrichten ausgibt.

METHOD if_rspls_ds_exit_hdb~get_sqlscript_info.
e_procedure_name_protected = 'ZDRCL_RSPLS_DS_EXIT_BASE=>AMDP_GET_PROTECTED_RECORD'.
e_has_sql_mesg = abap_true. "Flag: SQLscript returns messages
ENDMETHOD.

In der ADMP Methode selbst füllen wir die Nachrichtentabelle. Bitte beachten Sie, dass alle vier Variablen übergeben werden müssen, auch wenn sie keine Werte tragen.

METHOD amdp_get_protected_record BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING /bic/azd011lock7.

e_t_data = select it.COMP_CODE
from :i_t_data as it
LEFT JOIN "/BIC/AZD011LOCK7" as lookup
ON it.COMP_CODE = lookup.COMP_CODE
where lookup."/BIC/ZDFLAG" = 1;

e_t_mesg = select
'ZDR' as MSGID,
'000' as MSGNO,
'W' as MSGTY,
COMP_CODE as MSGV1,
'' as MSGV2,
'' as MSGV3,
'' as MSGV4
from
:e_t_data;

* alle vier Variablen muessen uebergeben werden
ENDMETHOD.

Datenscheibe testen

Anschließend können wir unsere Implementierung testen. Am besten geht es mithilfe einer Planungssequenz, da bei der Query-Ausführung (außer der Disaggregation) die ABAP Umgebung verwendet wird. Dabei sollten Sie eine Planungsfunktion nutzen, die in der SAP HANA Umgebung ausgeführt werden kann, wie z.B. die Kopierfunktion.

Wenn Sie eine Planungssequenz verwenden, können Sie die ABAP und SQL Implementierungen separat testen. Wenn Sie die Planungsfunktion über den Button Schritt ausführen starten, wird die SQL Implementierung genutzt. Falls Sie hingegen den Button Schritt mit Trace ausführen nutzen, wird die ABAP Implementierung ausgeführt.

Planungssequenz anzeigen

Fazit

Nun wissen Sie, wie Sie mittels ABAP bzw. SQL Datenscheiben flexibel anlegen können. Dieses Vorgehen lässt sich durch die Programmierfreiheiten, die man in beiden Welten besitzt, beliebig erweitern. Somit könnten Sie einfach und schnell z. B. die Sperre nur an bestimmten Tagen aktivieren. Des Weiteren haben Sie Dank der Implementierung mit SQL Script das volle Potential der HANA Datenbank.

Benötigen Sie Hilfe bei der Definition Ihrer Planungsstrategie oder suchen Sie nach erfahrenen Entwicklern mit SQL Script Know How? Zögern Sie bitte nicht, uns zu kontaktieren.

Erfahren Sie mehr über SAP BPC

Themen: SAP HANA, SAP BW/4HANA, SAP Planning, SAP HANA SQL

Beitrag teilen

Sie haben eine Frage zum Blog?
Fragen Sie Chris Fidanidis