Berechnung von Arbeitstagen zwischen zwei Datumsangaben in SAP HANA Experten Skript

Die Berechnung von Arbeitstagen zwischen zwei Datumsangaben wird im SAP BW sehr oft benötigt wie zum Beispiel für die Berechnung der Auftragsdurchlaufzeit in der Produktion, welche meist in Anzahl Werktagen zwischen Auftragserfassungsdatum und 1. plausiblem Wunschlieferdatum oder dem Lieferdatum angegeben wird. Auch wird auf Basis von verfügbarem Personal die Kapazität eines Werks in Stunden auf Basis von Anzahl Mitarbeiter, Anzahl Schichten, Anzahl an Werktagen und Schichtdauer berechnet. Es gibt etliche Beispiele bei denen man die Anzahl an Werktagen benötigt zur Berechnung von Kennzahlen im BI Umfeld.

Im SAP BW verwendet man dafür in der Regel den Fabrikkalender. Man kann die Kkalender über die Transaktion SCAL pflegen bzw. prüfen.
Zur Berechnung der Arbeitstage verwendet man meistens ABAP Funktionsbausteine wie z.B. DURATION_DETERMINE im folgenden Beipsiel wird die Anzahl der Arbeitstage für die nächsten 30 Kalendertage berechnet in Baden-Württemberg.


data: l_duration type i.
data: l_sdate type sy-datum.
data: l_edate type sy-datum.

* Set start/end dates
l_sdate = sy-datum.
l_edate = sy-datum + 30.

* Calculate working days
call function 'DURATION_DETERMINE'
exporting
factory_calendar = '01'
importing
duration = l_duration
changing
start_date = l_sdate
end_date = l_edate
exceptions
factory_calendar_not_found = 1
date_out_of_calendar_range = 2
date_not_valid = 3
unit_conversion_error = 4
si_unit_missing = 5
parameters_not_valid = 6
others = 7.

Diesen Code Schnipsel kann entsprechend in einer Transformation angepasst verwendet werden. Mit SAP BW on HANA möchte man möglichst die In-Memory Technologie ausnutzen und zeitintensive Berechnungen in die SAP HANA Datenbank verlagern. SAP BW 7.4 on HANA ist dahingehend optimiert, dass Berechnungen, wenn möglich in die HANA verlagert werden – dies gilt auch für Transformationen. Ob eine Transformation in SAP HANA verarbeitet werden kann, erkennt man an der Checkbox „SAP-HANA-Verarbeitung mögl.“ direkt in der Transformation.

HANA Skriptverarbeitung in SAP BW Transformation

HANA Skriptverarbeitung in SAP BW Transformation

Das eine Transformation in HANA verarbeitet werden kann, setzt einige Bedingungen voraus die erfüllt werden müssen. Die Bedingungen können aus der SAP Hilfe entnommen werden. Diese sind beim Schreiben dieses Blogbeitrags die folgenden:

  • Queries als InfoProvider werden nicht als Quelle unterstützt.
  • ABAP-Routinen werden nicht unterstützt (Regeltyp Routine, Merkmals-, Start-, End- und Expertenroutine).
  • Regelgruppen werden nicht unterstützt.
  • Für das Nachlesen aus DataStore-Objekten muss der volle Schlüssel angegeben werden.
  • Nearline-Anschluss wird nicht unterstützt.

Das Problem in Bezug auf die Berechnung der oben beschriebenen Kennzahlen bzw. die Anzahl der Arbeitstagen zwischen zwei Datumsangaben ist, dass der keine ABAP Routinen unterstützt werden. Dies ist logisch, da ansonsten die Berechnung im Applikationsserver und nicht mehr in der HANA Datenbank abläuft.

Die Berechnung der Arbeitstage muss also in der HANA Datenbank durchgeführt werden. Viele Wege führen bekanntlich nach Rom – so ist es auch in der Programmierung und insbesondere mit SAP HANA. Denkbar wäre hier die Quelltabellen der Fabrikkalender, Feiertagskalender und die BW Quelldaten in einem HANA View zusammenführen und darüber die Anzahl der Arbeitstage zu berechnen. Hier muss man sich zum Glück das Rad nicht neu erfinden und kann auch eine bestehende SAP Funktion zurückgreifen. Mit der SAP HANA Application Function Library (AFL) wird die Procedure ERPA_FACTORY_DAYS_BETWEEN_DATES im Schema _SYS_AFL ausgeliefert. Diese berechnet die Anzahl Arbeitstage zwischen zwei Datumsangaben für einen Fabrikkalender. Im folgenden werde ich dies anhand eines einfachen Szenarios detailiert erklären.

Im ersten Schritt wurde ein einfaches Advanced DSO (ADSO) mit einer Vorgangs ID und einem Start- und Endedatum angelegt, welches unsere Ausgangsdaten beinhaltet. Das Datenmodell ist natürlich stark vereinfacht so dass der Fokus auf dem Wesentlichen liegt.

ADSO als Datenqeulle

ADSO als Datenqeulle

Diese Datenquelle wurde mit einer generischen DataSource befüllt, die Zufallsdaten generiert. In diesem Beispiel wurden 10 Millionen Datensätze generiert.

ADSO Quelle mit 10 Millionen Datensätze

ADSO Quelle mit 10 Millionen Datensätze

Ein weiteres ADSO wurde als Datenziel angelegt mit der Kennzahl für die Anzahl Arbeitstage zwischen den beiden Datumsangaben.

ADSO als Datenziel

ADSO als Datenziel

Es wird eine Transformation zwischen den beiden ADSOs angelegt und diese als SAP HANA-Experten-Skript implementiert.

HANA Skriptverarbeitung in SAP BW Transformation

HANA Skriptverarbeitung in SAP BW Transformation

Es wird eine ABAP Managed Database Procedure (AMDP) angelegt. Die Implementierung erfolgt in der Methode PROCEDURE.

Zur Implementierung der Methode wird mit den aktuelleren Support Package Ständen des AS ABAP bzw. BW 7.4 eine Installation von ABAP in Eclipse (AiE) benötigt, während bei ersten Releases es noch möglich war, dies in der SAP GUI durchzuführen. Im Folgenden können Sie das Coding für die Implementierung entnehmen.


METHOD PROCEDURE BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY.
-- You need to implement a procedure.
-- If you do not do this, the transformation cannot be activated.

-- In follow you can see the fields of the input table inTab
-- and the field of the output table outTab.

-- inTab fields:
-- "VORGANG_ID"
-- "START_DATE"
-- "END_DATE"
-- "RECORDMODE"
-- "RECORD"
-- outTab fields:
-- "VORGANG_ID"
-- "UNIT"
-- "START_DATE"
-- "END_DATE"
-- "RECORDMODE"
-- "WORKING_DAYS"
DECLARE l_unit nvarchar(5);
DECLARE l_recordmode nvarchar(1);
DECLARE l_record nvarchar(56);
DECLARE l_FactoryCalendarID VARCHAR(2);
DECLARE l_duration int;

-- Einheit auf Tag setzen und record
-- und recordmode auf leer setzen
l_unit := 'TAG';
l_record := '';
l_recordmode := '';

-- Fabrikkalender 01 fuer Baden-Wuerttemberg
l_FactoryCalendarID := '01';

-- Input Parameter aus Quelldaten befuellen
-- Der Einfachheit wird als Fabrikkalender 01
-- fuer Baden-Wuerttemberg ausgewaehlt
lt_input = SELECT distinct
"START_DATE" as "StartDate",
"END_DATE" as "EndDate",
l_FactoryCalendarID as "FactoryCalendarId",
l_duration as "Duration"
FROM :inTab;

-- Anzahl Werktage zwischen den Datumsangaben berechen
CALL "_SYS_AFL"."ERPA_FACTORY_DAYS_BETWEEN_DATES_PROC"( 'F004', 'SAPSA1', :lt_input, :result );

-- Ausgabe des Ergebnis durch den Join der berechneten Werktagen
outTab = SELECT
i."VORGANG_ID",
:l_unit as "UNIT",
i."START_DATE",
i."END_DATE",
:l_recordmode as "RECORDMODE",
r."Duration" as "WORKING_DAYS",
:l_record as "RECORD"
FROM :inTab as i
INNER JOIN :result as r ON
i."START_DATE" = r."StartDate" AND
i."END_DATE" = r."EndDate";

ENDMETHOD.

Nach der Implementierung der Methode muss man diese aktivieren und anschließend wie gewohnt im SAP BW die Transformation aktivieren und einen DTP anlegen und aktivieren. Zum Laden der Daten wird der DTP ausgeführt und anschließend werden die Daten im ADSO aktiviert.
Das Ergebnis der Berechnung kann man sich wie gewohnt im BW durch Anzeigen der Daten im ADSO anzeigen lassen.

Daten im ADSO anzeigen zur Überprüfung der Berechnung

Daten im ADSO anzeigen zur Überprüfung der Berechnung

Stichprobenartig prüfe ich, ob die Berechnung der Arbeitstage über die HANA AFL Funktion stimmt durch ausführen des Funktionsbaustein in der SE37.

Funktionsbaustein zum Prüfen der Berechnung

Funktionsbaustein zum Prüfen der Berechnung

Und das Ergebnis ist…

... 250 und somit korrekt.

… 250 und somit korrekt.

Dieses Beispiel ist sehr stark vereinfacht und in der Praxis sind die Transformation eher komplexer. Aus diesem Grund ist es wie bereits bei den in ABAP implementierten Transformationen notwendig, dass man diese debuggen kann. Ein weitere Frage die in diesem Zusammenhang aufkommt, welchen Performancevorteil bringt die Implementierung als HANA Experten Skript. In meinem nächsten Blog gehe ich darauf ein.

Getagged mit: , , , , , , ,
3 Kommentar auf “Berechnung von Arbeitstagen zwischen zwei Datumsangaben in SAP HANA Experten Skript
  1. Hallo Herr Wirth,

    F004 steht für den Benutzernamen und wie Sie richtig vermutet hatten SAPSA1 ist das Datenbankschema des BW on HANA. Das Schema setzt sich zusammen aus SAP und der System ID in diesem Fall SA1.
    Die Parameter kann man einerseits den Prozeduren entnehmen über das SAP HANA Studio oder wenn Sie einen Flowgraph in der HANA anlegen, können Sie ebenfalls die Prozedur verwenden und erhalten darüber Informationen zu den Parametern.

    Wie ich in Ihrem SDN Weblog gesehen habe, haben Sie dies bereits im HANA Studio gefunden.

    Bzgl. Ihrer zweiten Frage der doppelten Schemavariablen muss ich Sie darauf hinweisen, dass das Schema nicht doppelt übergeben wird. In Ihrem Beispiel wird das Schema SAPSR3 übergeben und der Benutzer SAPSR3, d.h. das SAP System auf HANA verwendet den Benutzer SAPSR3 um auf das Schema SAPSR3 zu zugreifen. Sicherlich haben Sie beim Arbeiten mit SAP HANA festgestellt, dass wenn Sie einen Neuen Benutzer anlegen auch ein Schema mit dem gleichen Namen angelegt wird. Dies ist hier analog.

    Ich hoffe Ihre Fragen vollends geklärt zu haben und bedanke mich für das Feedback zum Blog.

    Beste Grüße
    Marcel Salein

  2. T. Wirth sagt:

    Hallo,

    der vorherige Kommentar hat sich zum Teil erledigt. Ich verstehe die doppelte Schemavariable am Beginn der Prozedur nach wie vor nicht ganz. Anbei ein anderes Beispiel, dass grundsätzlich auf dem obigen aufbaut und die Basis für eine Verteilungsfunktion Monat > Tag sein kann:

    create procedure SAPSR3.MMBZ_TEST ( ) language sqlscript reads sql data as
    begin
    DECLARE l_FactoryCalendarID VARCHAR(2);
    DECLARE l_duration int;

    — Fabrikkalender 01 fuer NRW
    l_FactoryCalendarID := ’01‘;

    — Die generierten Zeitdaten in HANA bilden die BASIS um die Arbeitstage zu ermitteln
    lt_tab = SELECT DISTINCT DATE_SAP AS DATE_SAP , DATE_SAP + 1 AS SAP_MORGEN
    FROM „_SYS_BIC“.“ottofuchs.test/TIME“;

    — Aufbereitung für die HANA Procedure
    lt_input = SELECT distinct
    „DATE_SAP“ as „StartDate“,
    „SAP_MORGEN“ as „EndDate“,
    l_FactoryCalendarID as „FactoryCalendarId“,
    l_duration as „Duration“
    FROM :lt_Tab;

    — Anzahl Werktage zwischen den Datumsangaben berechnen
    CALL „_SYS_AFL“.“ERPA_FACTORY_DAYS_BETWEEN_DATES_PROC“( ‚SAPSR3‘, ‚SAPSR3‘, :lt_input, :lt_result );

    — Anreichern um Jahr und Monat – das Enddatum entfällt
    lt_result2 = SELECT „StartDate“ , „YEAR“ , „MONTH“ , „Duration“ FROM :lt_result AS A JOIN „_SYS_BIC“.“ottofuchs.test/TIME“ as b ON
    a.“StartDate“ = b.“DATE_SAP“
    order by „StartDate“;

    — Arbeitstage pro Monat ermitteln
    lt_result3 = Select „YEAR“ , „MONTH“ , SUM(„Duration“) as „Days“ FROM :lt_result2 GROUP BY YEAR , MONTH;

    — Einzelnze Arbeitstage mit Arbeitstagen pro Monat anreichern
    select a.“StartDate“ , a.“YEAR“ , a.“MONTH“ , a.“Duration“ , b.“Days“ FROM :lt_result2 as a join :lt_result3 as b
    on a.“YEAR“ = b.“YEAR“ and
    a.“MONTH“ = b.“MONTH“;

    –Diese Daten können z.B. in Kombination mit einer Eingabetabelle Daten pro Monat (join auf Monat Jahr) für ein Planungsszenario
    –verteilt werden auf die Arbeitstage im jeweiligen Monat (Teile Monatswert / Gesamtarbeitstage * 1 oder 0 für den Arbeitstag

    end;

    Das ganze kann z.B. wie folgt aufgerufen werden:
    call „SAPSR3″.“MMBZ_TEST“

    Gruß

    T. Wirth

  3. T. Wirth sagt:

    Hallo,

    danke für das Beispiel.

    Ich habe mir eine Prozedur mit einem vergleichbaren Beispiel erstellt. Ich scheitere gerade an den ersten beiden Parametern von ERPA_FACTORY_DAYS_BETWEEN_DATES_PROC. Wofür steht F004? Ich vermute SAPSA1 ist das Schema in dem die Prozedur aufgerufen wird? Und wo findet man die Doku dieser Parameter? Die Input / Output Tabellen sind ja über die Typen dokumentiert.

    Gruß

    T. Wirth

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*

*