How To BI – Data Source über BAdI erweitern

Möglicherweise kennen Sie bereits die Erweiterung der Extraktoren über den User-Exit RSAP0001. Die Erweiterung über ein BAdI bietet die Möglichkeit, die Erweiterungen sauberer zu trennen. Jede Erweiterung wird dabei in einer getrennten Methode implementiert.
In diesem Artikel werde ich die DataSource für Debitoren 0FI_AR_4 um die Felder Division, Verkaufsorganisation und Vertriebsweg aus der Tabelle VBRK (Faktura: Kopfdaten) erweitern.

Durch einen Erfahrungsaustausch lässt sich viel voneinander lernen. Tauschen Sie sich deshalb jetzt mit Experten auf Ihrem Gebiet aus und erweitern Sie Ihr Netzwerk! Treten Sie jetzt der exklusiven Gruppe von SAP Experten bei.

Dazu fügen wir der Extraktstruktur der DataSource einen Append ein. Es wäre äußerst riskant, in eine Standardtabelle kundeneigene Felder einzubauen. Mit einer neuen Version könnte im Standard ein Feld eingebaut sein, das zufällig den gleichen Namen wie das kundeneigene Feld hat. Die Folgen wären nicht abzuschätzen.
Wählen Sie zunächst über die Transaktion RSA6 die DataSource 0FI_AR_4 aus. Doppelklicken Sie auf die Extraktstruktur.

DataSource 0FI_AR_4

Extraktstruktur auswählen

Fügen Sie nun eine neue Append-Struktur ein. Gehen Sie dazu auf den Button Append-Struktur (F5).

Append-Struktur

Append Struktur

Legen Sie nun einen Append an.

Append anlegen

Append anlegen

Vergeben Sie einen Namen, z.B. ZAEXTR_STR_0FIAR4.

Appendname

Appendname

Pflegen Sie nun die Beschreibung und tragen Sie die Komponenten ein. Bei der Vergabe des Komponententyps orientieren Sie sich an der Ursprungs-Tabelle VBRK. Die Komponenten sollten immer mit ZZ anfangen. Da es in Standardtabellen bereits Felder geben kann, die mit Z anfangen, könnten Konflikte auftreten, wenn die kundenspezifischen Felder der Append-Struktur nicht von den Feldern der Standardtabelle unterschieden werden könnten.

Append Struktur pflegen

Append Struktur pflegen

Aktivieren Sie anschließend die Append-Struktur (STRG+F3).
Wechseln Sie nun wieder in die Extraktstruktur der DataSource 0FI_AR_4. Klicken Sie dazu auf den Button Zurück.
Wählen Sie die neu angelegte Struktur aus und fügen Sie diese ein.

Append Struktur auswählen

Append Struktur auswählen

Unsere Append-Struktur wurde nun der Extraktorstruktur hinzugefügt. Die Felder Division, Verkaufsorganisation und Vertriebsweg sind nun sichtbar.

Append Struktur wurde hinzugefügt

Neue Felder sind sichtbar

Exkurs: alternativ könnten wir auch eine Include-Struktur zur Erweiterung der Standardtabelle nutzen. Im Gegensatz zur Append-Struktur, die immer zu genau einer Tabelle gehört, ist die Include-Struktur mehrfach verwendbar und kann in andere Tabellen, Strukturen, ABAP-Programme etc. eingebunden werden. Um einen Include einzufügen wählen Sie über BearbeitenInclude Einfügen aus.

Nun implementieren wir einen BAdI, um bei der Extraktion diese neuen Felder mit Inhalt zu füllen.
Rufen Sie dazu die Transaktion S19 auf. Wählen Sie „klassisches BAdI“ aus und geben Sie den Namen RSU5_SAPI_BADI ein. Klicken Sie auf Impl. anlegen.

BAdI Implementierung anlegen

SE19 – BAdI Implementierung anlegen

Vergeben Sie anschließend den Implementierungsnamen, zum Beispiel ZC_RSU5_SAPI_BADI.

Implementierungsname

Implementierungsname

Eine Implementierung ZC_RSU5_SAPI_BADI wird mit den Definitionen des Standard-BAdIs RSU5_SAPI_BADI angelegt.
Geben Sie als Nächstes die Beschreibung ein und aktivieren Sie die Implementierung.

Beschreibung der Implementierung

Kurztext zur Implementierung

Bei der Aktivierung wird eine Klasse angelegt. Diese ist nach der folgenden Namenskonvention aufgebaut: ZCL_IM_(Name der Implementierung ohne "Z"). In unserem Beispiel ZCL_IM_C_RSU5_SAPI_BADI.
Um sich die Klasse und ihre Methoden anzuschauen, doppelklicken Sie auf den Namen der Klasse.

Class Builder anzeigen

Methoden anzeigen

Sie befinden sich nun im Class Builder und sehen die zugehörigen Methoden.

Methoden der Klasse

Methoden der Klasse

Das BAdI beinhaltet zwei Methoden. Eine Methode DATA_TRANSFORM für alle Bewegungsdaten,- Attributs- und Text-Datasources und eine Methode HIER_TRANSFORM für alle Hierarchie-DataSources. In diesem Beispiel gehe ich auf die DATA_TRANSFORM Methode ein. Diese ermöglicht es Ihnen, eigene Felder zu füllen, die Sie als Append-Struktur an die Extraktstruktur von Bewegungs- und Stammdaten angehängt haben. Die Methode DATA_TRANSFORM besitzt die folgende Schnittstelle:
I_DATASOURCE – Name der DataSource für Bewegungs- und Stammdaten
I_UPDMODE – Übertragungsmodus (Full, Delta)
I_T_SELECT – Angeforderte Selektionskriterien
I_T_FIELDS – Angeforderte Felder
C_T_DATA – Tabelle der extrahierten Daten
C_T_MESSAGES – Fehlerprotokoll

Doppelklicken Sie die Methode DATA_TRANSFORM. Hier geben Sie den Quellcode ein, der die Methode für die einzelnen DataSources aufruft. Dieser Code ist allgemeingültig für alle Erweiterungen. Sie müssen nur den Namen der Klasse (hier: ZCL_IM_C_RSU5_SAPI_BADI) beim Lesen aus der Tabelle SEOCOMPO (Klassen-/Interface-Komponente) anpassen.

METHOD if_ex_rsu5_sapi_badi~data_transform.
 *Variable für die DataSource Erweiterung Methode deklarieren
   DATA : l_method TYPE seocmpname.
 *Einen Buchstaben als Präfix einfügen. Methode kann nicht mit einer Nummer anfangen.
   CONCATENATE 'M_' i_datasource INTO l_method.
 *Prüfe die Tabelle der extrahierten Daten (Rumpf), wenn keine Daten vorhanden, exit.
   CHECK c_t_data[] IS NOT INITIAL.
 *Lies den Komponentennamen (Methode) aus der Tabelle SEOCOMP
 *Wenn in unserer Klasse eine Methode für die jeweilige DataSource angelegt wird,
 *erscheint in der Tabelle ein Eintrag.
 *Diese Methode enthält die Logik für das Füllen der neuen Felder und soll aufgerufen werden.
   SELECT SINGLE cmpname FROM seocompo INTO l_method WHERE
                 clsname = 'ZCL_IM_C_RSU5_SAPI_BADI'
                 AND cmpname = l_method.
 *Prüfe sy-subrc, wenn ungleich 0, exit.
   CHECK sy-subrc EQ 0.
 *Wenn die Methode in der Tabelle SEOCOMP gefunden wurde, soll diese aufgerufen werden.
 *Die Logik in dieser Methode ändert die Tabelle der extrahierten Daten C_T_DATA.
   CALL METHOD (l_method)
     EXPORTING
       i_updmode    = i_updmode
       i_t_select   = i_t_select
       i_t_fields   = i_t_fields
     CHANGING
       c_t_data     = c_t_data
       c_t_messages = c_t_messages.
 ENDMETHOD.

Aktivieren Sie die Methode DATA_TRANSFORM und gehen Sie zurück in den Class Builder.
Fügen Sie nun eine neue Methode mit dem folgenden Namen ein „M_DataSource“, in unserem Beispiel M_0FI_AR_4. Wie bereits erwähnt, kann eine Methode nicht mit einer Nummer anfangen.
Geben Sie als Art „Static“ und Sichtbarkeit „Private“ an. Eine statische Methode ist instanzunabhängig und private Methoden sind nur innerhalb der definierenden Klasse sichtbar und verwendbar.
Aktivieren Sie die Klasse. Nun erscheint in der Tabelle SEOCOMPO ein Eintrag.

Tabelle SEOCOMPO

Zuordnung Klasse – Methode

Über diesen Eintrag rufen wir die zu der DataSource zugehörige Methode auf.
Nun befassen wir uns mit der eigentlichen Methode. Bevor wir jedoch die Logik zum Füllen der Felder schreiben, müssen wir die Parameter deklarieren. Doppelklicken Sie Ihre Methode M_0FI_AR_4 und wählen Sie Private Section aus.

Private Section

Deklaration von Parametern

Fügen Sie den folgenden Code an. Sie müssen nur den Namen der Methode anpassen.

PRIVATE SECTION.

  TYPE-POOLS sbiwa.

  CLASS-METHODS m_0fi_ar_4
  IMPORTING
    value(i_updmode) TYPE sbiwa_s_interface-updmode
    value(i_t_select) TYPE sbiwa_t_select
    value(i_t_fields) TYPE sbiwa_t_fields
    CHANGING
      !c_t_data TYPE ANY TABLE
      !c_t_messages TYPE rsu5_t_messages OPTIONAL.

Aktivieren Sie diese Sektion und gehen Sie zurück in den Quellcode der Methode.
Hier schreiben Sie Ihre Logik für das Füllen der neuen Felder. Betrachten Sie den folgenden Code als ein Beispiel. Passen Sie es an Ihre Anforderungen an.
Wir definieren Feldsymbole mit dem Typ der Extraktstruktur der DataSource 0FI_AR_4. Sie sehen die Extraktstruktur wenn Sie die DataSource über die Transaktion RSA6 aufrufen. Weitere Schritte sind in den Kommentaren beschrieben.

Extraktstruktur

Extraktstruktur

METHOD m_0fi_ar_4.
 * Eine Struktur mit den zu füllenden Feldern deklarieren
   TYPES: BEGIN OF tyt_vbrk,
     tyt_vbeln TYPE vbeln_vf,
     tyt_vkorg TYPE vkorg,
     tyt_vtweg TYPE vtweg,
     tyt_spart TYPE spart,
     END OF tyt_vbrk.

 * Eine interne Tabelle und Work Area deklarieren
   DATA: lt_vbrk TYPE HASHED TABLE OF tyt_vbrk WITH UNIQUE KEY tyt_vbeln, "Eindeutig, daher hashed
         lt_data TYPE STANDARD TABLE OF dtfiar_3. "Interne Tabelle wie C_T_DATA

 * Feldsymbole mit dem Typ der Extraktstruktur der DataSource 0FI_AR_4 deklarieren
   FIELD-SYMBOLS: <ls_data> TYPE dtfiar_3,
                  <ls_vbrk> TYPE tyt_vbrk.

 * Übernimm die extrahierten Daten in die interne Tabelle
   lt_data[] = c_t_data[].

   IF NOT lt_data IS INITIAL.
 * Lies die Felder aus der Tabelle VBRK für alle Einträge in lt_data und schreibe diese in lt_vbrk
     SELECT vbeln vkorg vtweg spart
       FROM vbrk INTO TABLE lt_vbrk
       FOR ALL ENTRIES IN lt_data
       WHERE vbeln = lt_data-belnr.
   ENDIF.

   LOOP AT c_t_data ASSIGNING <ls_data>.
 *Suche nach der jeweiligen Belegnummer
     READ TABLE lt_vbrk ASSIGNING <ls_vbrk> WITH TABLE KEY tyt_vbeln = <ls_data>-belnr.
     IF sy-subrc = 0.
 *Wenn Treffer, fülle die Felder
       <ls_data>-zzvkorg = <ls_vbrk>-tyt_vkorg.
       <ls_data>-zzvtweg = <ls_vbrk>-tyt_vtweg.
       <ls_data>-zzspart = <ls_vbrk>-tyt_spart.
     ENDIF.
   ENDLOOP.

   FREE: lt_data, lt_vbrk.

 ENDMETHOD.

Aktivieren Sie die Methode. Wenn Sie nun Daten extrahieren, wird der Parameter I_DATASOURCE (Name der DataSource) an unsere Klasse weitergegeben. Dann wird aus der Methode DATA_TRANSFORM das jeweilige Coding aufgerufen.
Gehen Sie nun in die Transaktion RSA3 und testen Sie Ihren Extraktor. Die neuen Felder werden gefüllt.

DataSource Erweiterung erfolgreich

Neue Felder werden gefüllt

Bedenken Sie, dass bei einer großen Datenmenge die interne Tabelle sehr groß wird, sodass es zu Performance– und Stabilitätsproblemen führen kann. Die Lösungsansätze sind von dem jeweiligen Kontext abhängig, werfen Sie einen Blick auf meinen Artikel zum Thema Interne Tabellen. Oft kommen Sie wohl nicht drum herum innerhalb des Loops über C_T_DATA mit SELECT auf die Datenbanktabelle zuzugreifen.

Diese ABAP Tricks machen Ihr Leben leichter!

  • In meinem Newsletter gebe ich eine Menge Tipps und Kniffe rund um ABAP.
  • Die Mini-Tutorials unterstützen Sie dabei, Software in ABAP effizienter zu entwickeln.
  • Praktische Anleitungen ermöglichen Ihnen schnelle Erfolge bei der Optimierung Ihrer Arbeit.
  • Bei der Anmeldung zu meinem Newsletter erhalten Sie das Buch „ABAP Tipps und Tricks“ als Willkommensgeschenk.
ABAP Tipps und Tricks

Jetzt anfordern!

* Pflichtfeld
 
Kein SPAM. Ich hasse Spam genau so wie du.

Quellen:
Karl-Heinz Kühnhauser, Thorsten Franz (2011): Discover ABAP, 3. Auflage, Bonn
Dirk Herzog (2012): ABAP-Programmierung für SAP NetWeaver BW – Kundeneigene Erweiterungen, 3. Auflage, Bonn
Suneel Kumar Reddy Sannala – How to Implement BAdI for Enhancing the Datasource in ECC
SAP Note 691154 – SAPI mit BADI: User-Exits im SAPI mit BADI-Schnittstellen

Falls Ihnen dieser Beitrag weitergeholfen hat, wäre es eine sehr nette Anerkennung meiner Arbeit wenn Sie z.B. Ihre Bücher über Amazon bestellen würden. Wenn Sie ein Produkt kaufen, erhalte ich dafür eine Provision. Für Sie ändert sich am Preis des Produktes gar nichts. Ich möchte mich an dieser Stelle jetzt schon für Ihre Unterstützung bedanken.

0 Kommentare

Hinterlasse einen Kommentar

An der Diskussion beteiligen?
Hinterlasse uns deinen Kommentar!

Schreibe einen Kommentar

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

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.