Overblog
Folge diesem Blog Administration + Create my blog
SAPManDoo - SAP Resource

Der vorliegende Blog enthält von mir im Laufe meiner beruflichen Tätigkeit als SAP-Berater zusammengetragene Informationen / Beispiel-Codings zum Themenkreis SAP, speziell FI/CO.

s4

GRWTAUTH - erweiterte Berechtigungsprüfung im Report-Writer-Umfeld

Veröffentlicht am 27. Juni 2022 von sapmandoo in S4, SAP Reports, CO

Über die SAP-Erweiterung GRWTAUTH lassen sich kundeneigene Berechtigungsprüfungen für Report-Writer-Berichte implementieren. In der genannten Erweiterung sind Prüfbausteine für Eingaben im Selektionsbild sowie auf Einzelsatzebene enthalten.

Um bspw. bei Berichten der Profitcenterrechnung unter S/4 eine Berechtigungsprüfung nach Buchungskreis zu verbauen, kann der Funktionsexit EXIT_SAPFGRWS_001: Kunden-Exit: Berechtigungsprüfung auf Einzelsatzebene in der Selektion verwendet werden.

Nachfolgend die Dokumentation zum Funktionsexit sowie ein Beispiel-Coding:

Kurztext

Kunden-Exit: Berechtigungsprüfung auf Einzelsatzebene in der Selektion

Funktionalität

Dieser Exit wird während der Datenselektion bei der Neuselektion von der Datenbank (I_DATA_SOURCE = 'S') und beim Lesen vom Archiv (I_DATA_SOURCE = 'A') für jeden einzelnen Datensatz aufgerufen. Der aktuelle Datensatz wird in dem untypisierten Parameter I_S_RECORD an den Exit übergeben, die zugehörige DDIC-Referenzstruktur in dem Parameter I_DB_TABLE.

Eine Standardprüfung wird nicht für alle Report-Writer-Tabellen durchgeführt. Die Standardprüfung, sofern die jeweilige Report-Writer-Tabelle eine solche unterstützt, erfolgt in dem Unterprogramm ( T804A-AUTHR) in dem der Report-Writer-Tabelle zugeordneten Formpool ( T804A-MPOOL).

Existiert eine Standardprüfung, so kann der Exit durch den Parameter E_SKIP_STANDARD_EXIT steuern, ob die Standardprüfung anschließend durchgeführt oder übersprungen werden soll. Wird die Standardprüfung anschließend durchgeführt, so entscheidet sie über die Berechtigung für den aktuellen Datensatz. Wenn der Exit die Ausnahme NO_AUTHORITY auslöst, sollte die Standardprüfung daher immer mit E_SKIP_STANDARD_EXIT = 'X' übersprungen werden.

Parameter

I_REPORTING_TABLE
I_REPORT_GROUP
I_DATA_SOURCE
I_DB_TABLE
I_S_RECORD
E_SKIP_STANDARD_EXIT

Exceptions

NO_AUTHORITY

Funktionsgruppe

XRWA


DATA: LS_ACDOCA TYPE ACDOCA.
IF I_DB_TABLE = ‘ACDOCA’.
  MOVE I_S_RECORD TO LS_ACDOCA.
* in LS_ACDOCA-RBUKRS steht nun der Buchungskreis des aktuell selektierten Datensatzes drin
* Berechtigungsprüfung Buchungskreis (über welches Berechtigungsobjekt das auch immer 
* gesteuert werden soll) z.B. Anzeige-Berechtigung Belege
   AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
           ID 'BUKRS' FIELD LS_ACDOCA-RBUKRS
           ID 'ACTVT' FIELD '03'.
 IF sy-subrc <> 0.  “Keine Berechtigung
   E_SKIP_STANDARD_EXIT = ‚X‘.
     RAISE NO_AUTHORITY.
   ENDIF. 
ENDIF.
Kommentare

ALE Verteilung von Anzahlungsanforderungen

Veröffentlicht am 12. Mai 2022 von sapmandoo in ALE, S4, FI, Basis-Entwicklung allg.

Generell ist die ALE-Schnittstelle für FI-Belege (FIDCC1/2) ziemlich restriktiv, was die Verteilung von Sonderhauptbuchbelegen angeht. Im SAP-Hinweis 114814, Punkt 14. wird darauf explizit eingegangen:

Auszug aus HW 114814:

14. Sonderhauptbuchvorgänge SHBV
-------------------------------

Sonderhauptbuchvorgänge sind:

  • Anzahlungen
  • Anzahlungsanforderungen
  • Wechsel
  • sonstige

Beim SAP-Verteilungsszenario für FI-Belege wird davon ausgegangen, daß es sich bei den dezentralen Sender-Systemen um z.B. Logistik-Systeme handelt. Das zentrale Empfänger-System ist das FI-Buchhaltungssystem, in dem alle operativen Prozesse, wie Zahlen, Mahnen usw., stattfinden.
Unter dieser Voraussetzung erscheint das Buchen von Belegen mit Sonderhauptbuchvorgängen (SHBV), ausgenommen Anzahlungsanforderungen, nur im zentralen System sinnvoll. Mit anderen Worten, es besteht keine Notwendigkeit, SHBV in den dezentralen Systemen zu buchen und per ALE zu versenden.

Deshalb wird im SAP-Standard das Versenden von SHBV aus einem dezentralen System heraus nicht unterstützt.
Ist der Nachrichtentyp FIDCC1 oder FIDCC2 aktiv, ist es zwar möglich, im dezentralen System Belege mit SHBV zu buchen und auch zu versenden (außer Anzahlungsanforderungen), aber es ist nicht gewährleistet, daß im Empfängersystem aus diesem IDoc erfolgreich ein FI-Beleg gebucht werden kann.
Versendet der Anwender trotzdem SHBV aus dem dezentralen System, liegt es in seiner Verantwortung und Kontrolle, daß der SHBV-Beleg im Empfängersystem auch erfolgreich, vollständig und richtig verbucht wird.


Ursachen für eventuell auftretende Fehler sind:

  • Der FI-Beleg und das daraus resultierende IDoc beinhalten u.U. nicht alle notwendigen Felder. Z.B. fehlt für den SHBV 'Wechsel' die Struktur BSED.
  • Die RW-Schnittstelle zum Buchen der IDOC-Belege kann nicht alle SHBV verarbeiten, weil die entsprechenden Felder in den Übergabestrukturen ACCIT usw. fehlen. 'Wechsel' werden beispielsweise im RWIN sofort abgewiesen mit der Fehlermeldung: F5 246 Sonderhauptbuchvorgänge der Klasse W werden nicht unterstützt.

(Technisch: In der RW-Schnittstelle werden SHBV-Belege mit BSEG-UMSKS='W' und BKPF-BSTAT='S' nicht verbucht.)

Allerdings kann man in der Regel bei einer reinen FI-Buchung davon ausgehen, daß beim erfolgreichen Einbuchen eines IDoc-Beleges im Empfängersystem, d.h. wenn keine Fehlermeldung auftritt, der SHBV-Beleg tatsächlich vollständig und richtig verbucht wurde.
So könnte es möglich sein, daß beispielsweise reine FI-Anzahlungen erfolgreich verarbeitet werden können. Anzahlungen mit Zusatzkontierungen, z.B. auf Bestellungen, Anlagen, Aufträge, werden nicht vollständig verbucht.
Bei Bestellungen wird die Bestellhistorie nicht fortgeschrieben. Die Bestellungen werden sofort ausgeglichen, es ist keine Verrechnung möglich.
Bei Anlagen werden keine zusätzlichen Verrechnungszeilen erzeugt.
Bei Aufträgen wird kein Anzahlungs-Obligo fortgeschrieben.
Sollte der Anwender trotzdem SHBV aus dem dezentralen System versenden wollen, sind entsprechende Tests des Anwenders unerläßlich!


Anzahlungsanforderungen können im SAP-Standard nicht per ALE versendet werden.
Es ist wegen der Vielzahl der Möglichkeiten, wie ein Anwender ALE FI verwendet, auch nicht geplant (,weil nicht möglich), dafür eine Standardlösung zu entwickeln.
Allerdings ist es im Rahmen einer Kunden-Projektlösung möglich und wurde auch bereits realisiert, entsprechend der speziellen Konstellation beim Anwender, ein Verteilen von Anzahlungsanforderungen zu ermöglichen (-> SAP Beratung).

 

Genau so eine "Kunden-Projektlösung" zu finden, wie im oben rot markierten Abschnitt erwähnt, war gerade meine Aufgabe in meinem aktuellen Kundenprojekt. Es ist hierbei ein zwei System-Szenario gegeben, d.h. ein bestehendes ECC Logistiksystem soll an ein neues S/4-FI/CO System angebunden werden. Wegen der hohen Lizenzkosten und der begrenzten Lebensdauer dieses Szenarios (das Logistiksystem soll im zweiten Schritt ebenfalls in das S/4-System einziehen) wurde der von der SAP favorisierte Central Finance (CFIN) Ansatz verworfen und stattdessen auf ALE-Verteilung gesetzt. Dabei wurden die bekannten Restriktionen, was u.a. SHB-Vorgänge angeht, evaluiert und in Kauf genommen.

Was jedoch (kreditorische) Anzahlungsanforderungen angeht, musste ein Workaround her, da diese Vorgänge zum Teil vom Rechnungsworkflow-System, welches wiederum an das ECC Logistiksystem angebunden ist, ausgelöst werden. D.h., wir mussten einen Weg finden, die Anzahlungsanforderungen am "Türsteher" vorbeizukriegen, damit diese Merkposten vom ECC ans S/4-System verteilt werden, weil dort logischerweise der Zahllauf stattfindet.

 Die Schwierigkeit bei einem komplexen System wie SAP ist, erstmal die Tür zu finden, um im Endeffekt den Türsteher zu lokalisieren. Damit Euch die Suche erspart bleibt, hier die (mir bekannten) Türsteher:

1. Funktionsbaustein FI_IDOC_UPDATE, Zl. 96ff.:

  IF NOT T_BKPF-BSTAT IS INITIAL.
      CHECK X_GLFLEX_ACTIVE = 'X' AND "NewGL ist aktiv
            T_BKPF-BSTAT    = 'L'.    "Buchung in nicht führendes Ledger
  ENDIF.

 

Bei Belegen mit Belegstatus ungleich leer, werden hier nur solche durchgelassen, die den Belegstatus L (Ledgerspezifische Buchung bei aktivem NewGL) tragen. D.h., Merkposten mit Belegstatus S, wozu ja auch die Anzahlungsanforderungen gehören, haben hier keine Chance. 

Um die Tür auch für Merkposten aufzumachen, muss diese Stelle geeignet modifiziert werden, z.B. so:  

IF NOT T_BKPF-BSTAT IS INITIAL.    
   if not ( t_bkpf-bstat = 'S' and line_exists( t_bseg[ umsks = 'A' ] ) ). "<<<<INSERT
   CHECK X_GLFLEX_ACTIVE = 'X' AND "NewGL ist aktiv
            T_BKPF-BSTAT    = 'L'.    "Buchung in nicht führendes Ledger
   ENDIF.     "<<<<INSERT                                                             
 ENDIF.

2. Funktionsbaustein FI_IDOC_PREPARE, Zl. 260ff.:

* Belegstatus prüfen (keine Muster-, Dauerbuchungsurbelege versenden)
    IF NOT t_bkpf-bstat IS INITIAL.
      IF x_send_c3 = 'X'.
        CHECK x_glflex_active = 'X' AND "NewGL ist aktiv
              ( t_bkpf-bstat    = 'L' OR t_bkpf-bstat    = 'S' ).    "Buchung in nicht führendes Ledger + Anzahlungsanf.
      ELSE.
        CHECK x_glflex_active = 'X' AND "NewGL ist aktiv
              t_bkpf-bstat    = 'L'.    "Buchung in nicht führendes Ledger
      ENDIF.
    ENDIF. 

 

Anzahlungsanforderungen (BKPF-BSTAT = 'S') werden hier nur durchgelassen, wenn NewGL aktiv ist und der NewGL-Nachrichtentyp FAGLDT01 verwendet wird. Um Merkposten auch bei nicht aktivem NewGL und Verwendung der Nachrichtentypen FIDCC1 bzw. FIDCC2 zu verteilen, muss der o.g. Abschnitt entsprechend modifiziert werden z.B. so:

* Belegstatus prüfen (keine Muster-, Dauerbuchungsurbelege versenden)
    IF NOT t_bkpf-bstat IS INITIAL.
    if not ( t_bkpf-bstat = 'S' and line_exists( t_bseg[ umsks = 'A' ] ) ). "<<<<INSERT
      IF x_send_c3 = 'X'.
        CHECK x_glflex_active = 'X' AND "NewGL ist aktiv
              ( t_bkpf-bstat    = 'L' OR t_bkpf-bstat    = 'S' ).    "Buchung in nicht führendes Ledger + Anzahlungsanf.
      ELSE.
        CHECK x_glflex_active = 'X' AND "NewGL ist aktiv
              t_bkpf-bstat    = 'L'.    "Buchung in nicht führendes Ledger
      ENDIF.
    endif.    "<<<<INSERT
    ENDIF. 

Wie im eingangs erwähnten SAP-Hinweis beschrieben, müssen solche Eingriffe in die Verteilungslogik natürlich umfänglich getestet werden. Ich habe allerdings zumindest bei der Verteilung von Anzahlungsanforderungen bisher keine unerwünschten Seiteneffekte feststellen können.

Kommentare

Anzeige von Kontierungsinformationen bei der Buchung

Veröffentlicht am 25. November 2020 von sapmandoo in FI, Basis-Entwicklung allg., S4

Öfters kam in Kundenprojekten die Anforderung hoch, Informationen aus dem Kontierungshandbuch dem Belegerfasser während des Buchungsvorganges zugänglich zu machen. Eins vorweg: eine 1A-Lösung, die unabhängig vom verwendeten User-Interface funktioniert, habe ich bisher noch nicht gefunden, aber immerhin eine, die modifikationsfrei eingebaut werden kann und zumindest mal bei den gängigen GUI-Transaktionen (FB01, FB50, FB60 etc.) funktioniert. Sie fusst auf dem Business Transaction Event-Framework (BTE) und setzt voraus, dass die Informationen zum Kontierungshandbuch in Form von Standardtexten am Sachkontenstamm vorliegen. Für die Implementierung sind zumindest Grundkenntnisse in der ABAP-Programmierung vonnöten.

Textablage

Im SAP-Standard ist für die Ablage der Kontierungsinformationen zu einem Konto, die Text-ID 0001 (Kontierungsinfo) des Textobjektes SKB1 (Sachkontentexte im Buchungskr.) vorgesehen. Der technische Name des jeweiligen Textbausteins setzt sich aus der 10-stelligen Kontonummer (ggf. mit führenden Nullen) und dem Schlüssel des Buchungskreises (4-stellig) zusammen (Beispiel: Konto 4711, Buchungskreis 0001: 00000047110001). Diese Texte können in der Buchungskreissicht des Sachkontos mithilfe der Sachkontenpflege FS00 hinterlegt werden.

Sachkontenstammpflege FS00 - Kontierungsinfo

Sachkontenstammpflege FS00 - Kontierungsinfo

Um sich die so gepflegten Kontierungsinformationen anzeigen zu lassen, kann der Standardreport "Kontierungshandbuch" ausgeführt werden. Der Bericht ist im Infosystem des Hauptbuchs, Bereich "Stammdaten" zu finden (Transaktion S_ALR_87012330 - Kontierungshandbuch).

Transaktion S_ALR_87012330 - Kontierungshandbuch

Transaktion S_ALR_87012330 - Kontierungshandbuch

Unter S/4 wurde diese Transaktion als obsolet gekennzeichnet und ist nicht mehr aufrufbar. Um dies bei Bedarf dennoch zu ermöglichen, bitte gemäß Hinweis 2393666 vorgehen.

Um die Pflege der Kontierungsinformationen zu vereinfachen, habe ich mal in einem Kundenprojekt ein kleines Uploadprogramm geschrieben, welches eine entsprechend aufbereitete Excel-Vorlage hochladen kann.

Excel-Vorlage:

Excel-Vorlage für Upload Kontierungshandbuch

Excel-Vorlage für Upload Kontierungshandbuch

Wenn in der Vorlage buchungskreisspezifische Texte hinterlegt werden sollen, ist der Buchungskreis in der entsprechenden Spalte anzugeben. Ist der Wert in der Spalte "Buchungskreis" leer, wird der Text in allen Buchungskreisen, in denen das Konto vorhanden ist und die den angegebenen Kontenplan verwenden, aktualisiert.

Die Felder Kontenplan, Konto, Sprache und Text sind obligatorisch. Führende Nullen bei der Angabe des Kontos können weggelassen werden. Das Programm füllt dies automatisch auf. Der Buchungskreis ist ggf. mit führenden Nullen einzugeben.

Bei der Ausführung des Upload-Programms ist lediglich die Excel-Datei auszuwählen (sie kann ohne vorherige Umformatierung direkt im XLSX-Format verwendet werden) und ggf. anzukreuzen, ob bereits manuell gepflegte Texte bei diesem Lauf überschrieben werden sollen. 

Coding:

REPORT ystxupl1.
*&---------------------------------------------------------------------*
*& Report YSTXUPL1
*&---------------------------------------------------------------------*
*& Upload SAPScript-Texts for accounting manual from Excel
*&---------------------------------------------------------------------*

DATA: data_tab TYPE TABLE OF string.

TYPES: BEGIN OF ty_txt,
         ktopl    TYPE t001-ktopl,
         bukrs    TYPE t001-bukrs,
         spras(2) TYPE c,
         saknr    TYPE skb1-saknr,
         txt      TYPE string,
       END OF ty_txt.

TYPES: tty_bukrs TYPE TABLE OF bukrs,
       tty_t001  TYPE TABLE OF t001.

DATA:  wa_txt TYPE ty_txt.
DATA:  it_txt TYPE TABLE OF ty_txt.

*&---------------------------------------------------------------------*
*& SELECTION-SCREEN
*&---------------------------------------------------------------------*
PARAMETERS: pa_fnam LIKE rlgrap-filename OBLIGATORY. "Excelfilename
PARAMETERS: pa_xovr AS CHECKBOX DEFAULT space.       "Overwrite y/n

*&---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_fnam.
*&---------------------------------------------------------------------*
  PERFORM f4_filename.

START-OF-SELECTION.
  PERFORM upload_data.
  PERFORM save_texts.

*&---------------------------------------------------------------------*
*& Form UPLOAD_DATA
*&---------------------------------------------------------------------*
*& upload accounting manual template (Excel)
*&---------------------------------------------------------------------*
FORM upload_data .

  DATA: l_buf   TYPE string,
        l_tabix TYPE sy-tabix.

  CLEAR data_tab[].

  CALL FUNCTION 'FAA_FILE_UPLOAD_EXCEL'
    EXPORTING
      i_filename           = pa_fnam
      i_delimiter          = '~'
    TABLES
      et_filecontent       = data_tab
    EXCEPTIONS
      error_accessing_file = 1
      OTHERS               = 2.

  IF sy-subrc <> 0.
    WRITE: / 'Fehler', sy-subrc, 'beim Upload der Datei', pa_fnam.
  ENDIF.

  LOOP AT data_tab INTO l_buf.
    CHECK sy-tabix > 1.  "Skip Header
    SPLIT l_buf AT '~' INTO
         wa_txt-ktopl
         wa_txt-bukrs
         wa_txt-spras
         wa_txt-saknr
         wa_txt-txt.

*   clean up multiple text lines.
    IF wa_txt-txt(1) = '"'.
      SHIFT wa_txt-txt BY 1 PLACES LEFT.
    ENDIF.
    DATA(l_lastchar) = strlen( wa_txt-txt ) - 1.
    IF wa_txt-txt+l_lastchar(1) = '"'.
      wa_txt-txt = wa_txt-txt(l_lastchar).
    ENDIF.

    APPEND wa_txt TO it_txt.
  ENDLOOP.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form F4_FILENAME
*&---------------------------------------------------------------------*
*& F4 help Excel-file
*&---------------------------------------------------------------------*
FORM f4_filename .

  CALL FUNCTION 'FAA_FILE_F4'
    EXPORTING
      i_default_extension = 'XLS'
    IMPORTING
      e_filename          = pa_fnam
    EXCEPTIONS
      interface_error     = 1
      OTHERS              = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form save_texts
*&---------------------------------------------------------------------*
*& Process accounting manual texts and save them
*&---------------------------------------------------------------------*
FORM save_texts .

  DATA: lt_lines TYPE TABLE OF tline,
        l_name   TYPE thead-tdname,
        l_saknr  TYPE skb1-saknr,
        lt_t001  TYPE tty_t001,
        l_spras  TYPE t001-spras,
        lt_bukrs TYPE tty_bukrs.

  LOOP AT it_txt INTO wa_txt.

*   convert external data into SAP format, if necessary
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
      EXPORTING
        input  = wa_txt-saknr
      IMPORTING
        output = wa_txt-saknr.
    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
      EXPORTING
        input  = wa_txt-spras
      IMPORTING
        output = l_spras.

*   select company codes assigned to chart of acc.
*   in case company code isn't specified in excel template
    IF lt_t001[] IS INITIAL.
      SELECT * FROM t001 INTO TABLE lt_t001 WHERE ktopl = wa_txt-ktopl.
    ENDIF.

    IF wa_txt-bukrs IS INITIAL.
      PERFORM find_company_codes USING    wa_txt-ktopl
                                          wa_txt-saknr
                                          lt_t001
                                 CHANGING lt_bukrs.
    ELSE.
      CLEAR lt_bukrs[].
      APPEND wa_txt-bukrs TO lt_bukrs.
    ENDIF.

    LOOP AT lt_bukrs INTO wa_txt-bukrs.

      CONCATENATE wa_txt-saknr wa_txt-bukrs INTO l_name.

      IF pa_xovr IS INITIAL.
        CALL FUNCTION 'READ_TEXT'
          EXPORTING
            id                      = '0001'
            language                = l_spras
            name                    = l_name
            object                  = 'SKB1'
          TABLES
            lines                   = lt_lines
          EXCEPTIONS
            id                      = 1
            language                = 2
            name                    = 3
            not_found               = 4
            object                  = 5
            reference_check         = 6
            wrong_access_to_archive = 7
            OTHERS                  = 8.
        IF sy-subrc <> 0.
          PERFORM store_text USING l_spras l_name wa_txt.
        ENDIF.
      ELSE.
        PERFORM store_text USING l_spras l_name wa_txt.
      ENDIF.

    ENDLOOP.

  ENDLOOP.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form find_company_codes
*&---------------------------------------------------------------------*
*& Select all company codes with given chart of accounts
*&---------------------------------------------------------------------*
*&      --> pi_KTOPL
*&      --> pi_SAKNR
*&      --> pt_t001
*&      <-- pt_BUKRS
*&---------------------------------------------------------------------*
FORM find_company_codes  USING    pi_ktopl TYPE t001-ktopl
                                  pi_saknr TYPE skb1-saknr
                                  pt_t001  TYPE tty_t001
                         CHANGING pt_bukrs TYPE tty_bukrs.

  CLEAR pt_bukrs[].
  LOOP AT pt_t001 ASSIGNING FIELD-SYMBOL(<lfs_t001>).
    SELECT SINGLE COUNT(*) FROM skb1
           WHERE saknr = pi_saknr
             AND bukrs = <lfs_t001>-bukrs.
    IF sy-subrc = 0.
      APPEND <lfs_t001>-bukrs TO pt_bukrs.
    ENDIF.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form store_text
*&---------------------------------------------------------------------*
*& Put SAPScript-Tests for accouting mmanual in DB
*&---------------------------------------------------------------------*
*&      --> pi_SPRAS  Language
*&      --> pi_NAME   Textname
*&      --> pi_TXT    Text
*&---------------------------------------------------------------------*
FORM store_text  USING    pi_spras TYPE t001-spras
                          pi_name  TYPE thead-tdname
                          pi_txt   LIKE wa_txt.

  DATA: lt_tline TYPE tline_t.
  DATA: ls_header TYPE thead.

  DATA(lt_strings) = VALUE string_table( ( pi_txt-txt ) ).

* Stringtabelle -> TLINE-Tabelle
* SAPscript: Konvertieung Textstream nach ITF f¸r TextEditControl
  CALL FUNCTION 'CONVERT_STREAM_TO_ITF_TEXT'
    EXPORTING
      stream_lines = lt_strings
      lf           = abap_true
    TABLES
      itf_text     = lt_tline.

  ls_header-tdobject = 'SKB1'.
  ls_header-tdname   = pi_name.
  ls_header-tdspras  = pi_spras.
  ls_header-tdid     = '0001'.
  CALL FUNCTION 'SAVE_TEXT'
    EXPORTING
      header          = ls_header
      savemode_direct = 'X'
    TABLES
      lines           = lt_tline.

ENDFORM.

Interaktive Anzeige der Kontierungsinformationen

Um nun die so gepflegten Texte während des Buchens zur Anzeige zu bringen, implementieren wir die Business Transaction Events (BTE) 00001070 bzw. 00001080 (P/S-Schnittstelle). Details zur Implementierung von BTEs finden sich u.a. hier.

Mustercoding zur Implementierung der BTE-Bausteine:

BTE 00001070

FUNCTION y_interface_00001070.
*"--------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     REFERENCE(I_BKPF) TYPE  BKPF
*"     REFERENCE(I_BSEG) TYPE  BSEG
*"     REFERENCE(I_AKTYP) TYPE  AKTYP
*"     REFERENCE(I_DYNCL) TYPE  DYNCL
*"  EXPORTING
*"     REFERENCE(E_XCHNG) LIKE  OFIWA-XCHNG
*"--------------------------------------------------------------------
  DATAlv_tdname   TYPE stxh-tdname,
       lv_tdobject TYPE stxh-tdobject VALUE 'SKB1',
       lv_tdid     TYPE stxh-tdid VALUE '0001'.

  CONCATENATE i_bseg-hkont i_bkpf-bukrs INTO lv_tdname.

  CALL FUNCTION 'RECA_GUI_TEXTEDIT_POPUP'
    EXPORTING
      id_tdobject lv_tdobject
      id_tdname   
lv_tdname
      id_tdid     
lv_tdid
      id_activity 
'03'
      id_title    TEXT-002.

ENDFUNCTION.

TEXT-002 enthält dabei die Überschrift der Dialogbox, in der die Kontierungsinformation angezeigt wird.

BTE 00001080

FUNCTION y_interface_00001080.
*"--------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     REFERENCE(I_SPRAS) LIKE  SY-LANGU
*"     REFERENCE(I_AKTYP) TYPE  AKTYP
*"     REFERENCE(I_DYNCL) TYPE  DYNCL
*"  EXPORTING
*"     VALUE(E_FTEXT) LIKE  FTEXTS-FTEXT
*"--------------------------------------------------------------------

  e_ftext TEXT-001.

ENDFUNCTION.

TEXT-001 enthält dabei die Aufschrift der Drucktaste, die in den Buchungstransaktionen zusätzlich eingeblendet wird, also z.B. "Kontierungshandbuch".

Im Ergebnis erscheint im Detailbild der Belegerfassung (z.B.in der FB01 oder bei der FB60, wenn ein Doppelklick auf die zu erfassende Belegzeile erfolgt) eine neue Drucktaste. Beim Betätigen der Drucktaste wird die zum aktuellen Konto/Buchungskreis hinterlegte Kontierungsinformation in einer Dialogbox angezeigt.

Neue Drucktaste bei der Erfassung einer Belegposition

Neue Drucktaste bei der Erfassung einer Belegposition

Dialogbox zur Anzeige der hinterlegten Kontierungsinformation

Dialogbox zur Anzeige der hinterlegten Kontierungsinformation

Kommentare

Finanzplandaten importieren in S/4 / Budgetierung auf Kostenstellen

Veröffentlicht am 15. Juli 2020 von sapmandoo in CO, S4

Über die FIORI-App "Finanzplandaten importieren" können Plandaten in die ACDOCP geladen werden. Zu den Plandaten gehören seit Release 1909 (on premise) auch Budgets auf Kostenstellen, eine Funktionalität, die seit Ewigkeiten von Kunden nachgefragt und nun endlich seitens SAP ausgeliefert wurde. Hiermit können also bereitgestellte Plandaten ins System geladen und z.B. über die App "Multidimensionale Bilanz" den Ist-Werten gegenüber gestellt werden. 

Für erweiterte Planungsfunktionalitäten ist eine dedizierte Planungslösung notwendig, also bspw. SAP Analytics Cloud (SAC) bzw. embedded BPC. Das o.g. Szenario eignet sich also insbesondere dann, wenn die Plandaten überwiegend aus externen Quellen stammen. Es kann ohne weitere Lizensierung (fast) out of the Box verwendet werden, lediglich etwas Customizing ist vonnöten...

IMG: Controlling - Controlling Allgemein – Planung - Kategorie für Planung pflegen

Hier werden die sog. Plankategorien ausgeprägt, welche in etwa den Planversionen in der klassischen SAP Planungswelt entsprechen. SAP liefert hier bereits eine gewisse Anzahl von Kategorien aus, die ggf. als Kopiervorlage dienen können. Für die Budgetierung auf Kostenstellen kann die Plankategorie BUDGET02 verwendet werden. Für gewöhnliche Planzahlen stellt SAP die Kategorie PLN bereit.

Definition Plankategorie...

Definition Plankategorie...

Um die Daten über die Finanzplanungs-App importieren und ggf. löschen zu können, müssen natürlich die entsprechenden Optionen ausgewählt werden. In der IMG-Doku zur o.g. Aktivität finden sich detaillierte Ausführungen zu den einzelnen Einstellungen.

Sollen lediglich reine Plandaten importiert werden, war's das schon. Die folgenden IMG-Aktivitäten sind nur für Budgets notwendig. Offenbar ist die Funktionalität "Budgetierung auf Kostenstellen" unter großem Zeitdruck entstanden, so dass nicht mal Zeit war, alle IMG Knoten zu benamsen...;-):

IMG: Controlling - Controlling Allgemein – Planung - Knotentext wurde nicht gefunden - Budgetprüfungen für Kategorien festlegen

Budgetprüfung konfiguieren...

Budgetprüfung konfiguieren...

Mit der vorgenannten IMG Aktivität kann bei Budget-Kategorien die Verfügbarkeits- sowie die Konsistenzprüfung aktiviert werden. Das weiteren ist das Profil für die Budgetverfügbarkeitskontrolle auszuprägen:

IMG: Controlling – Kostenstellenrechnung – Etatverwaltung - Profil für Budgetverfügbarkeitskontrolle für Kostenstellen pflegen...

Profil für Budgetverfügbarkeitskontrolle

Profil für Budgetverfügbarkeitskontrolle

In diesem Abschnitt können je Sachkontenhierarchie/Sachkontengruppe/Vorgangsgruppe Toleranzen und die entsprechende Systemreaktion (Fehler/Warnung) konfiguriert werden. Weitere Infos finden sich in der ausführlichen Dokumentation zur IMG-Aktivität.

Für die Budgetierung auf Kostenstellen muss nun das definierte Verfügbarkeitsprofil im Kostenstellenstammsatz hinterlegt werden.

ACHTUNG: dies ist im Dialog nur mit der FIORI-App zur Kostenstellenpflege möglich, nicht mit der klassischen GUI-Transaktion KS02. Aber: über die Massenänderungs- bzw. Sammelbearbeitungsfunktion KS12N können die budgetrelevanten Daten versorgt werden. Insofern besteht Hoffnung, das in einem der kommenden Feature-Packs bzw. Releases, die KS02 entsprechend ertüchtigt wird.

FIORI-App Kostenstellen verwalten

FIORI-App Kostenstellen verwalten

Im Reiter Steuerung im Bereich Budgetverfügbarkeitskontrolle sind die Eingabefelder für die Budgetierung zu finden:

  • Budgettragende Kostenstelle
  • Verfügbarkeitsprofil
  • Budgetverfügbarkeitskontrolle aktiv

Anschließend können die Plan- bzw. Budgetdaten importiert werden. Die App Finanzplandaten importieren ist praktisch selbsterklärend. Zunächst wird die Vorlage generiert, anschließend geeignet mit Daten befüllt und abschließend wieder hochgeladen. Die Daten werden in der ACDOCP gespeichert.

Finanzplandaten importieren

Finanzplandaten importieren

Als Trennzeichen für die CSV-Datei sollte ";" gewählt werden. Auf diese Weise kann die Vorlage ohne weiteres Zutun in Excel geöffnet werden und die einzelnen Felder sind dabei in getrennten Spalten angeordnet.

Je nach ausgewähltem Planungsgebiet werden automatisch die zu befüllenden Spalten inklusive Feldnamen und Überschrift konfiguriert.

Kommentare

Pivot-Browser - eigene Aktionen

Veröffentlicht am 16. August 2019 von sapmandoo in Basis-Entwicklung allg., FI, S4, SAP Reports, Accruals Management, ACE, ACAC

Der Pivot-Browser (PIVB) ist ein neues Ausgabe-Framework der SAP, welches die Anzeige beliebiger (strukturierter) Dateninhalte in Tabellenform ermöglicht. Die Art der Darstellung der Daten ist dabei an das bekannte ALV-Grid angelehnt. Im Unterschied zum ALV geht der Funktionsumfang des Pivot-Browsers jedoch über die reine Aufbereitung und Anzeige der Daten hinaus. Auch die Datenbeschaffung (HANA-optimiert) sowie die Behandlung von Benutzerinteraktionen ist in das Framework integriert. 

Details hierzu finden sich in den PDF-Anhängen zum Hinweis 2100879 - Pivot Browser: Dokumentation

Einige der im Standard ausgelieferten Funktionalitäten, die auf dem Pivot-Browser basieren, sind die Einzelpostenbrowser in der S/4 Finanzbuchhaltung:

Transaktion Funktion / Beschreibung
FAGLL03H Sachkonteneinzelposten-Browser (ledgerspezifisch)
FBL3H Sachkonteneinzelposten-Browser (einfach)
FBL1H Kreditoren-Einzelposten
FBL5H Debitoren-Einzelposten
Beispiel FAGLL03H

Beispiel FAGLL03H

Während der Anzeige-Bereich (links) weitestgehend identisch zum bekannten ALV funktioniert, ist der Interaktionsbereich (rechts) ein neu gestaltetes Element im Pivot-Browser. 

Im Bereich Spalten können die anzuzeigenden Felder ausgewählt werden. Bei den o.g. FI-Einzelpostenbrowsern stehen gegen Ende der Liste auch Stammdatenfelder und Bezeichnungen zur Verfügung. So kann bspw. zur Kostenstelle die entsprechende Kostenstellenbezeichnung in die Anzeige geholt werden, ohne wie bei den klassischen Einzelpostenlisten (FBLxN) den Feldvorrat erweitern und die Inhalte per BTE/BADI nachlesen zu müssen.

Der Bereich Layouts enthält alle verfügbaren Anzeigelayouts und ermöglicht deren Verwaltung wie unter ALV bekannt (entsprechende Berechtigung vorausgesetzt).

Interessant ist der Bereich Aktionen, in dem für den aktuellen Anzeigevorrat verfügbare Benutzeraktionen dargestellt sind. Diese können in einer (max. zweistufigen) Baumstruktur angeordnet werden, um so gewisse Interaktionen zu gruppieren. 

Bereich "Aktionen" in der FAGLL03H

Bereich "Aktionen" in der FAGLL03H

Sie ahnen es wahrscheinlich schon, dieser Bereich lässt sich modifikationsfrei beliebig erweitern und mit kundenspezifischen Aktionen spicken...

Weiter unten möchte ich ein Beispiel für eine solche kundeneigene Aktion zeigen, das die Erzeugung von Abgrenzungsobjekten der Accrual Engine bzw. des Accruals Management (ab S/4 1809) direkt aus den Einzelpostenbrowsern der Finanzbuchhaltung ermöglicht.

Die einzelnen Anwendungen des Pivot-Browsers werden als Erweiterungsimplementierung des Erweiterungsspots PIVB registriert. Für die EP-Browser im FI (s.o.) ist dies die Implementierung FAGL_LIB_PIVB. In ihr wiederum werden die Implementierungen zur BadI-Definition FAGL_LIB gerufen, zu der auch kundeneigene Implementierungen angelegt werden können.

Für die Aktionen sind die beiden Interface-Methoden SIDEBAR_ACTIONS_SET und SIDEBAR_ACTIONS_HANDLE relevant. In ersterer kann der "Aktionsbaum" um kundeneigene Aktionen erweitert werden, in der zweitgenannten Methode wird dann die eigentliche Aktion ausgestaltet.

Fügen wir also zunächst eine Aktion in einem kundeneigenen Ordner hinzu:

METHOD if_fagl_lib~sidebar_actions_set.

*   Kundeneigene Aktionen im Einzelpostenbrowser 

    TYPE-POOLS: icon.

*   Neuer Ordner am Ende anfügen
    APPEND INITIAL LINE TO c_menu-t_folder_level1 ASSIGNING FIELD-SYMBOL(<lf_folder>).
    <lf_folder>-folder_key = 'ZZACE'.
    <lf_folder>-folder_text = 'Abgrenzungsobjekt'.

*   Aktion in den neuen Ordner einfügen
    APPEND INITIAL LINE TO <lf_folder>-t_item_level2 ASSIGNING FIELD-SYMBOL(<lf_menuitem>).
    <lf_menuitem>-item_key = 'ZZACE_CREATE'.
    <lf_menuitem>-text = 'Abgrenzungsobjekt anlegen'.
    <lf_menuitem>-icon = icon_fencing.

  ENDMETHOD.
Kundeneigener Ordner mit Aktion im Pivot-Browser

Kundeneigener Ordner mit Aktion im Pivot-Browser

...und nun kann die Aktion, die mit der ID ZZACE_CREATE angelegt wurde, ausgestaltet werden.

  METHOD if_fagl_lib~sidebar_actions_handle.

*   Kundeneigene Aktionen im Einzelpostenbrowser 

    DATA: l_checker TYPE i.
    DATA: ls_bseg TYPE bseg.
    DATA: ls_bkpf TYPE bkpf.

    l_checker = 0.

    CASE i_navigate_item_key.
      WHEN 'ZZACE_CREATE'.   "Abgrenzungsobjekt anlegen
        IF it_outtab_selected_rows[] IS NOT INITIAL.                                            "Mind. eine Zeile selektiert?
          LOOP AT it_column ASSIGNING FIELD-SYMBOL(<lf_col>) WHERE fieldname = 'BUKRS' OR       "Felder Bukrs, Belnr, Gjahr und Buzei in Liste?
                                                                   fieldname = 'BELNR' OR
                                                                   fieldname = 'GJAHR' OR
                                                                   fieldname = 'BUZEI'.
            IF <lf_col>-is_invisible = abap_false.
              ADD 1 TO l_checker.
            ENDIF.
          ENDLOOP.
          IF l_checker < 4.
            MESSAGE 'Bitte mind. BUKRS BELNR GJAHR BUZEI in Anzeige holen' TYPE 'I'.
            EXIT.
          ELSE.
            "Belegdaten nachlesen
            READ TABLE it_outtab INDEX it_outtab_selected_rows[ 1 ]-row_id ASSIGNING FIELD-SYMBOL(<lf_row>).
            MOVE-CORRESPONDING <lf_row> TO ls_bseg.
            SELECT SINGLE * FROM bkpf INTO ls_bkpf
                    WHERE bukrs = ls_bseg-bukrs
                      AND belnr = ls_bseg-belnr
                      AND gjahr = ls_bseg-gjahr.
            SELECT SINGLE * FROM bseg INTO ls_bseg
                    WHERE bukrs = ls_bkpf-bukrs
                      AND belnr = ls_bkpf-belnr
                      AND gjahr = ls_bkpf-gjahr
                      AND buzei = ls_bseg-buzei.
            IF sy-subrc = 0.
              "Aufruf Generierungsprogramm f. Abgrenzungsobjekte
              ls_bseg-dmbtr = abs( ls_bseg-dmbtr ).         "Abgrenzungsbetrag muss positiv sein
              IF ls_bseg-koart NE 'S'.                      "Kontokorrente (FBL1H)
                SUBMIT zacac_d_trans_s4 AND RETURN VIA SELECTION-SCREEN
                       WITH p_check  = 'X'
                       WITH p_efdate = sy-datum
                       WITH p_powip = 'X'
                       WITH so_acmth = 'LINEAR'
                       WITH so_acpst = ls_bkpf-budat
                       WITH so_belnr = ls_bkpf-belnr
                       WITH so_bukrs = ls_bkpf-bukrs
                       WITH so_gjahr = ls_bkpf-gjahr
                       WITH p_amnt   = ls_bseg-dmbtr
                       WITH p_text   = ls_bseg-sgtxt.
              ELSE.                                          "FAGLL03H, FBL3H
                SUBMIT zacac_d_trans_s4 AND RETURN VIA SELECTION-SCREEN
                        WITH p_check  = 'X'
                        WITH p_efdate = sy-datum
                        WITH p_powoip = 'X'                  "Bei Sachkontenposten - OHNE Eröffnungbuchung als Default
                        WITH p_powip  = space
                        WITH so_acmth = 'LINEAR'
                        WITH so_acpst = ls_bkpf-budat
                        WITH so_belnr = ls_bkpf-belnr
                        WITH so_bukrs = ls_bkpf-bukrs
                        WITH so_buzei = ls_bseg-buzei
                        WITH so_gjahr = ls_bkpf-gjahr
                        WITH p_amnt   = ls_bseg-dmbtr
                        WITH p_text   = ls_bseg-sgtxt.
              ENDIF.
            ENDIF.
          ENDIF.
        ENDIF.
    ENDCASE.
  ENDMETHOD.

Da der Pivot-Browser HANA optimiert ist, werden nur die Spalten gelesen, die auch im aktuellen Layout benötigt werden. Dies ist ein wesentlicher Unterschied zu den klassischen EP-Listen, die immer alle Spalten eines Postens lesen, unabhängig von deren Verwendung in der Anzeige.

D.h., es muss zunächst geprüft werden, ob die für die weitere Verarbeitung benötigten Felder auch zur Verfügung stehen!

Im weiteren Verlauf dieses Beispiels wird eine angepasste Z-Kopie des Demo-Reports ACAC_D_TRANS_EXAMPLE_S4 gerufen, der aus einem vorgegebenen Belegvorrat Abgrenzungsobjekte im Accruals Management generiert. Für die "alte" Accrual Engine (vor S/4 1809) wäre dies der Report ACAC_DATA_TRANSFER_EXAMPLE.

 

Kommentare

CO Umlagen - der sog. "Vorbrenner"

Veröffentlicht am 25. Februar 2019 von sapmandoo in CO, Basis-Entwicklung allg., S4, SAP Reports

Umlagen im CO führen insbesondere im Bereich der Konzernumlage immer dann zu Problemen, wenn als Empfängerbezugsbasis die Gesamtkosten einer Kostenstelle herangezogen werden sollen und dazu ggfls. noch eine sehr differenzierte Funktionsbereichsdefinition mit vielen Empfängerkostenstellen vorliegt. Dies führt in Großkonzernen und Retail Gesellschaften mit vielen Filialen und damit einhergehend vielen Empfängerkostenstellen dazu, das bei Aufbau der Sender-/Empfängerbeziehungen eine interne Tabelle aufgebaut wird, die ggfls. die Speichergrenzen übersteigt und zu einem Short Dump führt.
Folgendes Programm sorgt dafür, dass die gebuchten Kostenarten (echte Buchung) auf eine statistische Kennzahl verdichtet werden. 

Der Effekt bei einem Kunden war bspw., dass eine nicht lauffähige Umlage nach 1300 Sekunden durchgebucht wurde.

In diesem Zusammenhang wurde auch eine Meldung bei SAP aufgemacht und es gab diesbezüglich einen regen Austausch mit dem SAP Development Support. Lt. SAP Entwicklung ist demnach die Nutzung solcher „Vorbrenner“ in diesen Konstellationen wohl nicht unüblich.
 

Das nachfolgende Programm stellt einen solchen "Vorbrenner" dar.

Das Programm startet mit folgendem Selektionsbildschirm:

Selection-Screen des Programms

Selection-Screen des Programms

  • Der Kostenrechnungskreis ist mit 1000 vorbelegt.
  • Im Feld Kostenstellengruppe kann eine Gruppe oder Selektionsvariante angegeben werden. Es werden nur die Kostenstellen für die Fortschreibung der kumulierten Kosten berücksichtigt, die in der Gruppe enthalten sind. Dies entspricht in der Umlage der Empfängerbezugsbasis.
  • Mittels der Kostenartengruppe (Gruppe/Selektionsvariante) kann auf bestimmte Kosten eingeschränkt werden, um z.B. um bereits ausgeführte Umlagen / Abrechnungen nicht als Empfängerbezugsbasis heranzuziehen. Sofern gewünscht kann das Feld leer gelassen werden und das Häkchen Gesamtkosten gesetzt werden. In diesem Fall werden alle Kosten der in der Kostenstellengruppe angegeben Kostenstellen berücksichtigt.
  • Geschäftsjahr und Periode müssen angegeben werden. Unter dieser Periode erfolgt die Selektion und Fortschreibung.
  • Die statistische Kennzahl ISTKOS ist die statistische Kennzahl, unter der die Kosten fortgeschrieben werden.
     

Coding:

*&---------------------------------------------------------------------*
*& Report ZCO_POST_COSTASSKF
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zco_post_costasskf.

* Datendeklaration
INCLUDE zco_post_costasskf_top.
* Selektionsbildschirm
INCLUDE zco_post_costasskf_sel.


START-OF-SELECTION.
  IF gs_selection-kstar IS INITIAL AND p_gesam IS INITIAL.
    "Fehlermeldung
  ENDIF.
*Übernahme der Selektionsparameter in Struktur
  gs_selection-kokrs p_kokrs.
  gs_selection-gjahr p_gjahr.
  gs_selection-perio p_perio.
  gs_selection-gesam p_gesam.
  gs_selection-verto p_verto.
  gs_selection-stagr p_stagr.
  LOOP AT s_verfr REFERENCE INTO DATA(ls_verfr).
    APPEND ls_verfr->TO gs_selection-verfr.
  ENDLOOP.
  IF gs_selection-koset IS INITIALgs_selection-koset '0101' && gs_selection-kokrs && p_1kosetENDIF.
  IF gs_selection-kstar IS NOT INITIAL AND p_gesam IS INITIALgs_selection-kstar '0102' && gs_selection-kokrs && p_1kstarENDIF.

* Start der Verarbeitung
  DATA(lo_instance) = zcl_co_cost2statfig=>get_instance( ).
  lo_instance->startgs_selection ).

 

 

*&---------------------------------------------------------------------*
*& Include          ZCO_POST_COSTASSKF_TOP
*&---------------------------------------------------------------------*

DATAgv_kosetname TYPE c LENGTH 10,
      gv_kstarname TYPE c LENGTH 10.

DATAgs_selection TYPE zcl_co_cost2statfig=>ts_selection.

TABLEScsks.

 

*&---------------------------------------------------------------------*
*& Include          ZCO_POST_COSTASSKF_SEL
*&---------------------------------------------------------------------*

SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE TEXT-t01.
PARAMETERSp_kokrs TYPE kokrs MATCHCODE OBJECT csh_tka01 OBLIGATORY DEFAULT 1000.
PARAMETERSp_1koset  LIKE rksb1-ksgru OBLIGATORY.
*PARAMETERS: p_2koset  LIKE rgsbs-setnr MODIF ID in5.
PARAMETERSp_1kstar  LIKE rksb1-kagru.
*PARAMETERS: p_2kstar  LIKE rgsbs-setnr MODIF ID in5.
PARAMETERSp_gesam AS CHECKBOX.
SELECTION-SCREEN SKIP 1.
PARAMETERSp_gjahr TYPE gjahr OBLIGATORY.
PARAMETERSp_perio TYPE periode OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b01.

SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME TITLE TEXT-t02.
PARAMETERSp_stagr TYPE ccss-stagr OBLIGATORY.
PARAMETERSp_verto TYPE csks-kosar.
SELECT-OPTIONSs_verfr FOR csks-kosar NO INTERVALS.
SELECTION-SCREEN END OF BLOCK b02.

INITIALIZATION.
* Defaultwert Datum
  SELECT SINGLE lmona FROM tka01
    
WHERE kokrs EQ @p_kokrs
    
INTO @DATA(gv_periv).
  CALL FUNCTION 'DATE_TO_PERIOD_CONVERT'
    EXPORTING
      i_date         sy-datum
*     I_MONMIT       = 00
      i_periv        gv_periv
    
IMPORTING
      e_buper        p_perio
      e_gjahr        
p_gjahr
    
EXCEPTIONS
      input_false    1
      t009_notfound  2
      t009b_notfound 3
      OTHERS         4.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

* Periodenberechnung
  p_perio p_perio 1.
  IF p_perio EQ 0p_perio 12ENDIF.
  IF p_perio EQ 12p_gjahr p_gjahr 1ENDIF.


AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_1koset.
  CALL FUNCTION 'K_GROUP_SELECT'
    EXPORTING
      class         '0101'
      field_name    'KOSTL                         '
      table         'CCSS                          '
    IMPORTING
      setid         gs_selection-koset
      set_name      
gv_kosetname
    
EXCEPTIONS
      no_set_picked 02.
  IF sy-subrc 0.
    p_1koset gv_kosetname.
  ENDIF.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_1kstar.
  CALL FUNCTION 'K_GROUP_SELECT'
    EXPORTING
      class         '0102'
      field_name    'KSTAR                         '
      table         'CCSS                          '
    IMPORTING
      setid         gs_selection-kstar
      set_name      
gv_kstarname
    
EXCEPTIONS
      no_set_picked 02.
  IF sy-subrc 0.
    p_1kstar gv_kstarname.
  ENDIF.

AT SELECTION-SCREEN.
  IF p_gesam EQ abap_true.
    CLEARp_1kstargs_selection-kstargv_kstarname.
  ENDIF.

AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    IF screen-name 'P_1KSTAR'.
      IF p_gesam EQ abap_true.
        CLEAR p_1kstar.
        screen-input '0'.
      ELSE.
        screen-input '1'.
      ENDIF.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.

 

CLASS zcl_co_cost2statfig DEFINITION
  PUBLIC
  FINAL
  
CREATE PUBLIC .

  PUBLIC SECTION.

 

    TYPES:
      tr_kosar TYPE RANGE OF csks-kosar .
    TYPES:
      BEGIN OF ts_selection.
    TYPES kokrs TYPE kokrs.
    TYPES koset TYPE rgsbs-setnr.
    TYPES kstar TYPE rgsbs-setnr.
    TYPES gesam TYPE checkbox.
    TYPES gjahr TYPE gjahr.
    TYPES perio TYPE periode.
    TYPES verto TYPE kosar.
    TYPES verfr TYPE tr_kosar.
    TYPES stagr TYPE stagr.
    TYPES END OF ts_selection .

    TYPES BEGIN OF ts_csks.
    TYPES kokrs TYPE kokrs.
    TYPES kostl TYPE kostl.
    TYPES datbi TYPE datbi.
    TYPES bukrs TYPE bukrs.
    TYPES prctr TYPE prctr.
    TYPES kosar TYPE kosar.
    TYPES END OF ts_csks.

    TYPES tt_csks TYPE STANDARD TABLE OF ts_csks WITH DEFAULT KEY
                                                 WITH UNIQUE HASHED KEY k1 COMPONENTS kokrs kostl datbi
                                                 
WITH NON-UNIQUE SORTED KEY k2 COMPONENTS kosar.

    TYPES tt_cskb TYPE STANDARD TABLE OF cskb WITH DEFAULT KEY.

    TYPES BEGIN OF ts_costs.
    TYPES kokrs TYPE kokrs.
    TYPES kostl TYPE kostl.
    TYPES bukrs TYPE bukrs.
    TYPES prctr TYPE prctr.
    TYPES kosar TYPE kosar.
    TYPES wrttp TYPE co_wrttp.
    TYPES sum   TYPE coep-wkgbtr.
    TYPES END OF ts_costs.

    TYPES tt_costs TYPE STANDARD TABLE OF ts_costs WITH DEFAULT KEY.

    CLASS-METHODS get_instance
      RETURNING
        
VALUE(ro_instanceTYPE REF TO zcl_co_cost2statfig .
    METHODS start
      
IMPORTING
        !is_selection TYPE ts_selection .
protected section.
private section.

  data CV_FAILURE type ABAP_BOOL .
  data GT_COSTS type TT_COSTS .
  data CV_VERTO type KOSAR .
  data GR_KSTAR type REP_EAPS_TAB_KSTAR_RANGE .
  data GT_VERTO type TT_CSKS .
  data RT_VERFR type TR_KOSAR .
  data CV_GESAM type CHECKBOX .
  data CV_DATAB type DATEFROM .
  data CV_DATBI type DATETO .
  data CV_GJAHR type GJAHR .
  data CV_KOKRS type KOKRS .
  data CV_PERIO type PERIODE .
  class-data GO_INSTANCE type ref to ZCL_CO_COST2STATFIG .
  data GT_CSKB type TT_CSKB .
  data GR_KOSTL type HRPP_SEL_KOSTL .
  data CV_STAGR type STAGR .
  data GT_RETURN type BAPIRET2_T .

  methods CALCULATE_COSTS .
  methods DBSEL_CSKB
    
importing
      !IT_KSTAR type REP_EAPS_TAB_KSTAR_RANGE
    returning
      
value(RT_CSKBtype TT_CSKB .
  methods DBSEL_CSKS
    
importing
      !IT_KOSTL type HRPP_SEL_KOSTL
    returning
      
value(RT_CSKStype TT_CSKS .
  methods POST_STATFIG .
  methods REVERSE_STATFIGPOST .
  methods SHOW_LOG .
  methods SET_DATA
    
importing
      !IS_SELECTION type TS_SELECTION .
  methods SET_KOSTENARTEN
    
importing
      !IS_SELECTION type TS_SELECTION .
  methods SET_KOSTENSTELLEN
    
importing
      !IS_SELECTION type TS_SELECTION .
  methods SET_SELMAIN
    
importing
      !IS_SELECTION type TS_SELECTION .
ENDCLASS.



CLASS ZCL_CO_COST2STATFIG IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->CALCULATE_COSTS
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD calculate_costs.

    DATAlv_tabix     TYPE sy-tabix,
          ls_costverto TYPE ts_costs,
          lt_costverto TYPE tt_costs.

*   Prüfen, ob bereits eine Fehlersituation vorliegt
    CHECK cv_failure IS INITIAL.
*   Select aus COEP, da hier die Daten mit Vorzeichen vorliegen
    SELECT
      a~kokrsa~kostlb~bukrsb~prctrb~kosar,
      a~wrttpSUMa~wkgbtr AS sum "Direkte Summierung möglich, da Werte positiv und negativ vorliegen
      FROM coep AS a
      INNER 
JOIN csks AS b
      
ON a~kokrs EQ b~kokrs AND a~kostl EQ b~kostl
      
WHERE a~kokrs EQ @cv_kokrs
      
AND   a~lednr EQ '00'
      AND   a~gjahr EQ @cv_gjahr
      
AND   a~perio EQ @cv_perio
      
AND   a~kstar IN @gr_kstar
      
AND   a~kostl IN @gr_kostl
      
GROUP BY a~kokrsb~bukrsb~prctra~kostlb~kosara~wrttp
      
INTO CORRESPONDING FIELDS OF TABLE @gt_costs.
*   Buchungskreis 1003 hat Filialkostenstellen, die irrelevant sind, Nullzeilen ignorieren!
    DELETE gt_costs WHERE bukrs '1003' AND kosar EQ cv_verto OR sum IS INITIAL.
    DELETE gt_costs WHERE wrttp NE '04'.
*   Verdichtung
    LOOP AT gt_verto REFERENCE INTO DATA(ls_verto).
      CLEAR ls_costverto.
      MOVE-CORRESPONDING ls_verto->TO ls_costverto.
      LOOP AT gt_costs REFERENCE INTO DATA(ls_costs)
        WHERE bukrs EQ ls_verto->bukrs
        
AND   prctr EQ ls_verto->prctr
        
AND   

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->DBSEL_CSKB
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_KSTAR                       TYPE        REP_EAPS_TAB_KSTAR_RANGE
* | [<-()] RT_CSKB                        TYPE        TT_CSKB
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD dbsel_cskb.

    IF cv_gesam IS INITIAL AND it_kstar IS NOT INITIAL.
      SELECT kokrskstarkatyp FROM cskb
        
WHERE kokrs EQ @cv_kokrs
        
AND   kstar IN @it_kstar
        
AND   datbi GE @cv_datbi
        
INTO CORRESPONDING FIELDS OF TABLE @rt_cskb.
    ELSE.
      SELECT kokrskstarkatyp FROM cskb
        
WHERE kokrs EQ @cv_kokrs
        
AND   datbi GE @cv_datbi
        
INTO CORRESPONDING FIELDS OF TABLE @rt_cskb.
    ENDIF.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->DBSEL_CSKS
* +-------------------------------------------------------------------------------------------------+
* | [--->] IT_KOSTL                       TYPE        HRPP_SEL_KOSTL
* | [<-()] RT_CSKS                        TYPE        TT_CSKS
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD dbsel_csks.

    SELECT kokrskostldatbibukrsprctrkosar
      
FROM csks
      
WHERE kokrs EQ @cv_kokrs
      
AND   kostl IN @it_kostl
      
AND   datbi GE @cv_datbi
      
AND   datab LE @cv_datab
      
and   kosar EQ @cv_verto
      
INTO CORRESPONDING FIELDS OF TABLE @rt_csks.


  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_CO_COST2STATFIG=>GET_INSTANCE
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RO_INSTANCE                    TYPE REF TO ZCL_CO_COST2STATFIG
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method GET_INSTANCE.

    IF go_instance IS INITIAL.
      CREATE OBJECT go_instance.
    ENDIF.

    ro_instance go_instance.


  endmethod.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->POST_STATFIG
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD post_statfig.

    DATAlt_item   TYPE STANDARD TABLE OF bapiskfitm WITH DEFAULT KEY,
          lt_return TYPE bapiret2_t,
          ls_return TYPE REF TO bapiret2,
          lv_count  TYPE i.

*   Bei Fehler keine weitere Verarbeitung
    CHECK cv_failure IS INITIAL.
*   Ohne Daten keine Competition
    CHECK gt_costs IS NOT INITIAL.
*   Kopfdaten füllen
    DATA(ls_header) = VALUE bapidochdrpco_area    cv_kokrs
                                         postgdate  
cv_datbi
                                         doc_hdr_tx 
'CUM_COSTS' && ' ' && cv_gjahr && '/' && cv_perio
                                         username   
sy-uname ).
*   Positionsdaten füllen
    LOOP AT gt_costs REFERENCE INTO DATA(ls_costs).
      lv_count lv_count + 1.
      APPEND VALUE bapiskfitmstatkeyfig cv_stagr
                               stat_qty   
CONV smexxxls_costs->sum )
                               seg_text   ' '
                               rec_cctr   ls_costs->kostl TO lt_item.
      IF lv_count 899.
*       Funktionsbaustein aufrufen
        CALL FUNCTION 'BAPI_ACC_STAT_KEY_FIG_POST'
          EXPORTING
            doc_header ls_header
*           IGNORE_WARNINGS       = ' '
*      IMPORTING
*           doc_no     = lv_belnr
          TABLES
            doc_items  lt_item
            
return     lt_return.
*       Rückgabetabelle auswerten
        LOOP AT lt_return REFERENCE INTO ls_return.
          IF ls_return->type CA 'AEX'.
            cv_failure abap_true.
          ENDIF.
          APPEND ls_return->TO gt_return.
        ENDLOOP.
*       Clear
        CLEARlv_countlt_itemlt_return.
      ENDIF.
    ENDLOOP.

*   Letzter Block
    IF lt_item IS NOT INITIAL.
*     Funktionsbaustein aufrufen
      CALL FUNCTION 'BAPI_ACC_STAT_KEY_FIG_POST'
        EXPORTING
          doc_header ls_header
*         IGNORE_WARNINGS       = ' '
*      IMPORTING
*         doc_no     = lv_belnr
        TABLES
          doc_items  lt_item
          
return     lt_return.
*     Rückgabetabelle auswerten
      LOOP AT lt_return REFERENCE INTO ls_return.
        IF ls_return->type CA 'AEX'.
          cv_failure abap_true.
        ENDIF.
        APPEND ls_return->TO gt_return.
      ENDLOOP.
*       Clear
      CLEARlv_countlt_itemlt_return.
    ENDIF.

*   Fehlerprüfung
    IF cv_failure NE abap_true.
*     Auf Datenbank schreiben
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          wait abap_true.
    ELSE.
*     Nicht auf DB schreiben
      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ENDIF.

  ENDMETHOD.

 

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->REVERSE_STATFIGPOST
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD reverse_statfigpost.

*   Erst mal kein Storno, sondern nur Fehlermeldung ausgeben
*   Selektion Kopf und Position
    SELECT
      a~kokrsa~belnr,
      SUMb~smebtr AS wert
      
FROM cobk AS a
      INNER 
JOIN coepr AS b
      
ON  a~kokrs EQ b~kokrs
      
AND a~belnr EQ b~belnr
      
WHERE a~kokrs EQ @cv_kokrs
      
AND   a~gjahr EQ @cv_gjahr
*      AND   a~versn EQ 0
      AND   a~vrgng EQ 'RKS'
      AND   a~perab EQ @cv_perio
      
AND   a~stflg NE @abap_true
      
AND   a~stokz NE @abap_true
      
AND   b~stagr EQ @cv_stagr
      
GROUP BY a~kokrsa~belnr
      
INTO TABLE @DATA(lt_cobk).

*   Daten gefunden? Dann Fehler und Returntabelle füllen
    LOOP AT lt_cobk REFERENCE INTO DATA(ls_cobk).
      cv_failure abap_true.
      APPEND VALUE bapiret2id         'ZCO'
                             number     5       "Bitte &1 / &2 in &3 mittels KB34N stornieren (Wert: &4).
                             type       'E'
                             message_v1 ls_cobk->kokrs
                             message_v2 
ls_cobk->belnr
                             message_v3 
cv_gjahr && '/' && cv_perio
                             message_v4 
CONV char13ls_cobk->wert ) ) TO gt_return.
    ENDLOOP.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SET_DATA
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION                   TYPE        TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD set_data.

*   Datum/Kostenrechnungskreis setzen
    set_selmainis_selection ).
*   Kostenstellen festlegen
    set_kostenstellenis_selection ).
*   Kostenarten festlegen
    set_kostenartenis_selection ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SET_KOSTENARTEN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION                   TYPE        TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD set_kostenarten.

    DATAlt_setvalues TYPE TABLE OF setvalues,
          lr_kstar     TYPE rep_eaps_tab_kstar_range.

    IF is_selection-kstar IS NOT INITIAL.
*     Werte importieren
      CALL FUNCTION 'G_SET_TREE_IMPORT'
        EXPORTING
          client          sy-mandt
          setid           
is_selection-kstar
*         tabname         = table
*         fieldname       = fieldname
          no_descriptions abap_true
          no_rw_info      
abap_true
          date_from       
cv_datab
          date_to         
cv_datbi
        
TABLES
*         set_hierarchy   =
          set_values      lt_setvalues
        
EXCEPTIONS
          set_not_found   1
          OTHERS          3.
*     Werte in Rangetabelle übernehmen
      LOOP AT lt_setvalues REFERENCE INTO DATA(ls_set).
        APPEND VALUE rep_eaps_str_kstar_rangesign    'I'
                                               option  'BT'
                                               low     ls_set->from
                                               high    ls_set->to TO gr_kstar.
      ENDLOOP.
    ENDIF.
*   Benötigte Daten selektieren und in Attributtabelle stellen
    gt_cskb dbsel_cskbgr_kstar ).

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SET_KOSTENSTELLEN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION                   TYPE        TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD set_kostenstellen.

    DATAlt_setvalues TYPE TABLE OF setvalues.

    CALL FUNCTION 'G_SET_TREE_IMPORT'
      EXPORTING
        client          sy-mandt
        setid           
is_selection-koset
*       tabname         = table
*       fieldname       = fieldname
        no_descriptions abap_true
        no_rw_info      
abap_true
        date_from       
cv_datab
        date_to         
cv_datbi
      
TABLES
*       set_hierarchy   =
        set_values      lt_setvalues
      
EXCEPTIONS
        set_not_found   1
        OTHERS          3.

    LOOP AT lt_setvalues REFERENCE INTO DATA(ls_set).
      APPEND VALUE hrpp_sel_st_kostlsign    'I'
                                      option  'BT'
                                      low     ls_set->from
                                      high    ls_set->to TO gr_kostl.
    ENDLOOP.

    gt_verto dbsel_csksgr_kostl ).


  ENDMETHOD.



 

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SET_SELMAIN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION                   TYPE        TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD set_selmain.

*   Übernahme in globale Attribute
    cv_gjahr is_selection-gjahr.
    cv_perio is_selection-perio.
    cv_kokrs is_selection-kokrs.
    cv_gesam is_selection-gesam.
    rt_verfr is_selection-verfr.
    cv_verto is_selection-verto.
    cv_stagr is_selection-stagr.
*   Datum ermitteln
    SELECT SINGLE lmona FROM tka01
      
WHERE kokrs EQ @cv_kokrs
      
INTO @DATA(lv_periv).
*   Anfangsdatum
    CALL FUNCTION 'FIRST_DAY_IN_PERIOD_GET'
      EXPORTING
        i_gjahr        cv_gjahr
*       I_MONMIT       = 00
        i_periv        lv_periv
        i_poper        
cv_perio
      
IMPORTING
        e_date         cv_datab
      
EXCEPTIONS
        input_false    1
        t009_notfound  2
        t009b_notfound 3
        OTHERS         4.
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.
*   Enddatum
    CALL FUNCTION 'LAST_DAY_OF_MONTHS'
      EXPORTING
        day_in            cv_datab
      
IMPORTING
        last_day_of_month cv_datbi
      
EXCEPTIONS
        day_in_no_date    1
        OTHERS            2.
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.



  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SHOW_LOG
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD show_log.

    CALL FUNCTION 'C14ALD_BAPIRET2_SHOW'
      TABLES
        i_bapiret2_tab gt_return.

  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_CO_COST2STATFIG->START
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION                   TYPE        TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD start.

*   Wesentliche Attribute füllen
    set_datais_selection ).
*   Ggfls. bisherige stat. Kennzahl stornieren
    reverse_statfigpost( ).
*   Kosten ermitteln und Verdichten
    calculate_costs( ).
*   Wert buchen
    post_statfig( ).
*   Protokoll ausgeben
    show_log( ).

  ENDMETHOD.
ENDCLASS.

Kommentare

Upload-Tool für Hauptbuchbelege (SAPGUI)

Veröffentlicht am 4. Februar 2019 von sapmandoo in S4, FI, SAP Reports

Eine viel nachgefragte Funktion im FI ist die Möglichkeit, Belege in Excel aufzubereiten und unter SAP hochzuladen, z.B. für Sachkonten-Umbuchungen im Rahmen von Abschlusstätigkeiten. Unter S/4 (ab Rel. 1511) gibt es hierfür eine Fiori-App zum Upload von Hauptbuchbelegen via Excel-Template, ab Release 1809 gibt es diese auch für kreditorische Belege... 

Bis dahin hilft meines Wissens tatsächlich nur eine selbstgebaute Upload-Funktion oder ggf. ein 3rd Party-Produkt.

Ein einfaches Programm inkl. Testlauf-/Prüffunktion findet sich in diesem Artikel. Hinweise zur Installation und zum Format der Quell-Datei finden sich am Ende des Codings...

*&---------------------------------------------------------------------*
*& Report ZFI_UPLOAD_DOCUMENT
*----------------------------------------------------------------------*
* Funktion       : Upload Belege aus Excel                             *
*----------------------------------------------------------------------*
* Beschreibung   : Upload von Belegen und Verbuchung via Excel         *
*                  (Ausweichtool für Fiori-App)                        *
*----------------------------------------------------------------------*
REPORT zfi_upload_document.

***********************************************************************
******************** GLOBAL DATA **************************************
***********************************************************************

CONSTANTS: gc_delimiter(1) TYPE c VALUE '~'.

SET EXTENDED CHECK OFF.
INCLUDE:
  sbal_constants,
  <icon>.
SET EXTENDED CHECK ON.

DATA:
  g_s_log             TYPE bal_s_log,
  g_log_handle        TYPE balloghndl,
  g_t_log_handle      TYPE bal_t_logh,
  g_s_display_profile TYPE bal_s_prof.

DATA: g_dummy         TYPE c.

DATA: data_tab TYPE TABLE OF string.

TYPES: BEGIN OF tax_item,
         mwskz      TYPE mwskz,
         direct_tax TYPE abap_bool,
         basis      TYPE fwbas,
         steuer     TYPE fwste,
       END OF tax_item.

DATA: git_taxitems TYPE TABLE OF tax_item,
      gs_taxitem   TYPE tax_item.

TYPES: BEGIN OF doc_header,
         bukrs     TYPE bukrs,
         blart     TYPE blart,
         bldat(10) TYPE c,
         budat(10) TYPE c,
         bumon     TYPE bumon,
         bktxt     TYPE bktxt,
         waers     TYPE waers,
         ldgrp     TYPE fagl_ldgrp,
         ukurs(12) TYPE c,
         umdat(10) TYPE c,
         xblnr     TYPE xblnr,
         pargb     TYPE pargb,
       END OF doc_header.

TYPES: BEGIN OF doc_item,
         bukrs     TYPE bukrs,
         hkont     TYPE hkont,
         sgtxt     TYPE sgtxt,
         wrsol(15) TYPE c,
         wrhab(15) TYPE c,
         dmbtr(15) TYPE c,
         dmbe2(15) TYPE c,
         mwskz     TYPE mwskz,
         txjcd     TYPE txjcd,
         kostl     TYPE kostl,
         prctr     TYPE prctr,
         aufnr     TYPE aufnr,
         ps_posid  TYPE ps_posid,
         valut(10) TYPE c,
         hbkid     TYPE hbkid,
         hktid     TYPE hktid,
         zuonr     TYPE dzuonr,
         vbund     TYPE vbund,
       END OF doc_item.

DATA: gs_doc    TYPE doc_header,
      gs_item   TYPE doc_item,
      git_items TYPE TABLE OF doc_item.


* Schnittstellendaten für Verbuchungs-BAPI
DATA:
* Returnparameter des BAPIs
  g_obj_type         TYPE bapiache09-obj_type,  "Objekttyp
* Objejktschlüssel erhält vom BAPI die Belegidentifikation:
* NNNNNNNNNNYYYYBBBB  N = Belegnummer, Y = GJahr, B = Buchungskreis
  g_obj_key          TYPE bapiache09-obj_key,   "Objektschlüssel
  g_obj_sys          TYPE bapiache09-obj_sys,   "log. System

* Belegkopf
  gs_documentheader  TYPE bapiache09,

* Sachkontenpositionen
  git_accountgl      TYPE TABLE OF bapiacgl09,
  gs_accountgl       TYPE bapiacgl09,

* Steuerzeilen
  git_accounttax     TYPE TABLE OF bapiactx09,
  gs_accounttax      TYPE bapiactx09,

* Betragsinformationen
  git_currencyamount TYPE TABLE OF bapiaccr09,
  gs_currencyamount  TYPE bapiaccr09,

* Meldungen des BAPI's
  git_return         TYPE TABLE OF bapiret2,
  gs_return          TYPE bapiret2.

DATA:
  g_itemno           TYPE posnr_acc.           "Postionsnummer 


*&---------------------------------------------------------------------*
*& SELECTION-SCREEN
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE TEXT-b01.
PARAMETERS: pa_fnam LIKE rlgrap-filename OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b01.

SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME TITLE TEXT-b02.
PARAMETERS: pa_test AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK b02.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_fnam.
  PERFORM f4_filename.

*-----------------------------------------------------------------------
START-OF-SELECTION.
*-----------------------------------------------------------------------

  PERFORM init.
  PERFORM upload_data.
  PERFORM map_data.
  IF pa_test IS INITIAL.
    PERFORM post_document.
  ELSE.
    PERFORM check_document.
  ENDIF.
  PERFORM add_msg_to_prot.
  PERFORM log_display.

*&---------------------------------------------------------------------*
*& Form F4_FILENAME
*&---------------------------------------------------------------------*
*& F4 Hilfe Excel-Datei
*&---------------------------------------------------------------------*
FORM f4_filename .

  CALL FUNCTION 'FAA_FILE_F4'
    EXPORTING
      i_default_extension = 'XLS'
    IMPORTING
      e_filename          = pa_fnam
    EXCEPTIONS
      interface_error     = 1
      OTHERS              = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    PERFORM msg_add USING probclass_high.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form UPLOAD_DATA
*&---------------------------------------------------------------------*
*& Upload der Excel-Tabelle mit den Belegdaten
*&---------------------------------------------------------------------*
FORM upload_data .

  DATA: l_buf      TYPE string,
        l_tabix    TYPE sy-tabix,
        l_msg(200) TYPE c.

  CLEAR data_tab[].

  CALL FUNCTION 'FAA_FILE_UPLOAD_EXCEL'
    EXPORTING
      i_filename           = pa_fnam
      i_delimiter          = gc_delimiter
    TABLES
      et_filecontent       = data_tab
    EXCEPTIONS
      error_accessing_file = 1
      OTHERS               = 2.

  IF sy-subrc <> 0.
    MESSAGE i600(fr) WITH 'Fehler' sy-subrc 'beim Upload'.
  ELSE.
    CONCATENATE TEXT-001 pa_fnam INTO l_msg SEPARATED BY space.
    PERFORM msg_add_free_text USING l_msg.
  ENDIF.

  LOOP AT data_tab INTO l_buf.
    IF sy-tabix = 5.
      SPLIT l_buf AT gc_delimiter INTO
            gs_doc-bukrs
            gs_doc-blart
            gs_doc-bldat
            gs_doc-budat
            gs_doc-bumon
            gs_doc-bktxt
            gs_doc-waers
            gs_doc-ldgrp
            gs_doc-ukurs
            gs_doc-umdat
            gs_doc-xblnr
            gs_doc-pargb.
    ENDIF.
    IF sy-tabix GE 9.
      SPLIT l_buf AT gc_delimiter INTO
            gs_item-bukrs
            gs_item-hkont
            gs_item-sgtxt
            gs_item-wrsol
            gs_item-wrhab
            gs_item-dmbtr
            gs_item-dmbe2
            gs_item-mwskz
            gs_item-txjcd
            gs_item-kostl
            gs_item-prctr
            gs_item-aufnr
            gs_item-ps_posid
            gs_item-valut
            gs_item-hbkid
            gs_item-hktid
            gs_item-zuonr
            gs_item-vbund.
      APPEND gs_item TO git_items.
    ENDIF.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form INIT_PROTOCOL
*&---------------------------------------------------------------------*
*& Anwendungsprotokoll aufbauen
*&---------------------------------------------------------------------*
FORM init_protocol .

* create a log
  g_s_log-extnumber = 'Beleg-Upload'(ext).
  CALL FUNCTION 'BAL_LOG_CREATE'
    EXPORTING
      i_s_log      = g_s_log
    IMPORTING
      e_log_handle = g_log_handle
    EXCEPTIONS
      OTHERS       = 1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.

*--------------------------------------------------------------------
* FORM ADD_MSG_TO_PROT
*--------------------------------------------------------------------
FORM add_msg_to_prot.

  DATA:
    l_s_msg   TYPE bal_s_msg,
    l_context TYPE bal_s_ex01.

  DATA:
    l_s_return  LIKE LINE OF git_return.

  LOOP AT git_return INTO l_s_return.

*   define data of message for Application Log
    l_s_msg-msgty           = l_s_return-type.
    l_s_msg-msgid           = l_s_return-id.
    l_s_msg-msgno           = l_s_return-number.
    l_s_msg-msgv1           = l_s_return-message_v1.
    l_s_msg-msgv2           = l_s_return-message_v2.
    l_s_msg-msgv3           = l_s_return-message_v3.
    l_s_msg-msgv4           = l_s_return-message_v4.

* add this message to log file
    CALL FUNCTION 'BAL_LOG_MSG_ADD'
      EXPORTING
*       I_LOG_HANDLE  =
        i_s_msg       = l_s_msg
      EXCEPTIONS
        log_not_found = 0
        OTHERS        = 1.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDLOOP.

ENDFORM.

FORM log_display.
  DATA:
    l_s_display_profile TYPE bal_s_prof,
    l_s_fcat            TYPE bal_s_fcat.

* get standard display profile
  CALL FUNCTION 'BAL_DSP_PROFILE_SINGLE_LOG_GET'
    IMPORTING
      e_s_display_profile = l_s_display_profile
    EXCEPTIONS
      OTHERS              = 1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

* for display variants add report id
  l_s_display_profile-disvariant-report = sy-repid.
* when you use also other ALV lists in your report,
* please specify a handle to distinguish between the display
* variants of these different lists, e.g:
  l_s_display_profile-disvariant-handle = 'LOG'.

* show log file with modified output profile
* - we specify the display profile since we created our own
* - we do not specify any filter (like I_S_LOG_FILTER, ...,
*   I_T_MSG_HANDLE) since we want to display all messages available
  CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
    EXPORTING
*     I_S_LOG_FILTER      =
*     I_T_LOG_CONTEXT_FILTER =
*     I_S_MSG_FILTER      =
*     I_T_MSG_CONTEXT_FILTER =
*     I_T_LOG_HANDLE      =
*     I_T_MSG_HANDLE      =
      i_s_display_profile = l_s_display_profile
    EXCEPTIONS
      OTHERS              = 1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.
*--------------------------------------------------------------------
* FORM MSG_ADD_FREE_TEXT
*--------------------------------------------------------------------
FORM msg_add_free_text USING VALUE(i_text) TYPE c.

* add this message to log file
  CALL FUNCTION 'BAL_LOG_MSG_ADD_FREE_TEXT'
    EXPORTING
*     I_LOG_HANDLE  =
      i_msgty       = 'S'
      i_text        = i_text
    EXCEPTIONS
      log_not_found = 0
      OTHERS        = 1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form INIT
*&---------------------------------------------------------------------*
*& Initialisierung
*&---------------------------------------------------------------------*
FORM init .
  CLEAR: git_accountgl[],
         git_accounttax[],
         git_currencyamount[],
         git_return[].
  CLEAR g_itemno.
  PERFORM init_protocol.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form POST_DOCUMENT
*&---------------------------------------------------------------------*
*& Beleg buchen
*&---------------------------------------------------------------------*
FORM post_document .

  DATA: l_error TYPE abap_bool VALUE abap_false.

*-----------------------------------------------------------------------
* BAPI-Aufruf
*-----------------------------------------------------------------------
  CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
    EXPORTING
      documentheader = gs_documentheader
    IMPORTING
      obj_type       = g_obj_type
      obj_key        = g_obj_key
      obj_sys        = g_obj_sys
    TABLES
      accountgl      = git_accountgl
      accounttax     = git_accounttax
      currencyamount = git_currencyamount
      return         = git_return.

  LOOP AT git_return TRANSPORTING NO FIELDS
          WHERE type = 'A' OR type = 'E'.
    l_error = abap_true.
  ENDLOOP.
  IF l_error = abap_false.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form CHECK_DOCUMENT
*&---------------------------------------------------------------------*
*& Beleg prüfen
*&---------------------------------------------------------------------*
FORM check_document .
  CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK'
    EXPORTING
      documentheader = gs_documentheader
    TABLES
      accountgl      = git_accountgl
      accounttax     = git_accounttax
      currencyamount = git_currencyamount
      return         = git_return.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form MAP_DATA
*&---------------------------------------------------------------------*
*& Mapping der Excel-Daten auf BAPI-Strukturen
*&---------------------------------------------------------------------*
FORM map_data .

  DATA: l_netto  TYPE wrbtr,
        l_brutto TYPE wrbtr,
        l_steuer TYPE fwste,
        l_basis  TYPE fwbas.

  DATA: l_mwskz  TYPE skb1-mwskz.
*-----------------------------------------------------------------------
* Belegkopf
*-----------------------------------------------------------------------
  CLEAR gs_documentheader.
  gs_documentheader-bus_act    = 'RFBU'.
  gs_documentheader-username   = sy-uname.
  gs_documentheader-comp_code  = gs_doc-bukrs.
  PERFORM _convert USING gs_doc-bldat gs_documentheader-doc_date   'BLDAT'.
  PERFORM _convert USING gs_doc-budat gs_documentheader-pstng_date 'BUDAT'.
  IF gs_doc-bumon IS NOT INITIAL AND gs_doc-bumon NE space.
    gs_documentheader-fis_period = gs_doc-bumon.
  ENDIF.
  gs_documentheader-ref_doc_no = gs_doc-xblnr.
  gs_documentheader-header_txt = gs_doc-bktxt.
  gs_documentheader-doc_type   = gs_doc-blart.

*-----------------------------------------------------------------------
* Belegpositionen
*-----------------------------------------------------------------------
  LOOP AT git_items INTO gs_item.

    ADD 1 TO g_itemno.
    CLEAR: gs_accountgl, gs_currencyamount.

    gs_accountgl-itemno_acc      = g_itemno.
    PERFORM _convert USING gs_item-hkont gs_accountgl-gl_account 'HKONT'.
    gs_accountgl-item_text       = gs_item-sgtxt.
    IF gs_item-kostl IS NOT INITIAL.
      PERFORM _convert USING gs_item-kostl gs_accountgl-costcenter 'KOSTL'.
    ENDIF.
    IF gs_item-prctr IS NOT INITIAL.
      PERFORM _convert USING gs_item-prctr gs_accountgl-profit_ctr 'PRCTR'.
    ENDIF.
    IF gs_item-aufnr IS NOT INITIAL.
      PERFORM _convert USING gs_item-aufnr gs_accountgl-orderid 'AUFNR'.
    ENDIF.
    IF gs_item-ps_posid IS NOT INITIAL.
      PERFORM _convert USING gs_item-ps_posid gs_accountgl-wbs_element 'PS_POSID'.
    ENDIF.
    gs_accountgl-alloc_nmbr      = gs_item-zuonr.
    gs_accountgl-trade_id        = gs_item-vbund.
    gs_accountgl-tax_code        = gs_item-mwskz.
    IF gs_item-valut IS NOT INITIAL.
      PERFORM _convert USING gs_item-valut gs_accountgl-value_date 'VALUT'.
    ENDIF.

    IF gs_item-wrsol IS NOT INITIAL.
      PERFORM _convert USING gs_item-wrsol l_brutto 'WRBTR'.
    ENDIF.
    IF gs_item-wrhab IS NOT INITIAL.
      PERFORM _convert USING gs_item-wrhab l_brutto 'WRBTR'.
      MULTIPLY l_brutto BY -1.
    ENDIF.

*   Sachkonto mit Steuer zu bebuchen
    CLEAR l_mwskz.
    SELECT SINGLE mwskz FROM skb1 INTO l_mwskz
            WHERE saknr = gs_accountgl-gl_account
              AND bukrs = gs_documentheader-comp_code.
    IF sy-subrc = 0 AND l_mwskz IS INITIAL.
      "keine Steuer erlaubt --> St. KZ. löschen (Verhalten analog FIORI-App)
      CLEAR: gs_item-mwskz, gs_accountgl-tax_code.
    ENDIF.

    CLEAR: l_steuer, l_netto, l_basis.
*   Mit Steuer?
    IF gs_item-mwskz IS NOT INITIAL.
      IF l_mwskz = '>' OR l_mwskz = '<'.  "Direct Tax
        CALL FUNCTION 'RE_CALCULATE_BASE_AMOUNT'
          EXPORTING
            i_taxam = l_brutto
            i_mwskz = gs_item-mwskz
            i_waers = gs_doc-waers
            i_bukrs = gs_documentheader-comp_code
          IMPORTING
            e_fwbas = l_basis.
        l_steuer = l_netto = l_brutto.
      ELSE.
        CALL FUNCTION 'CALCULATE_TAX_FROM_GROSSAMOUNT'
          EXPORTING
            i_bukrs = gs_documentheader-comp_code
            i_mwskz = gs_item-mwskz
            i_waers = gs_doc-waers
            i_wrbtr = l_brutto
          IMPORTING
            e_fwste = l_steuer
          EXCEPTIONS
            OTHERS  = 16.

        IF sy-subrc <> 0.
          MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO g_dummy.
          PERFORM msg_add USING probclass_high.
        ENDIF.
        l_netto = l_brutto - l_steuer.
        l_basis = l_netto.
      ENDIF.

*-----------------------------------------------------------------------
*     korrespondierende Steuerzeile sammeln
*-----------------------------------------------------------------------
      CLEAR gs_taxitem.
      gs_taxitem-mwskz  = gs_item-mwskz.
      gs_taxitem-steuer = l_steuer.
      gs_taxitem-basis  = l_basis.
      IF l_mwskz = '>' OR l_mwskz = '<'.  "Direct Tax
        gs_taxitem-direct_tax = abap_true.
      ELSE.
        gs_taxitem-direct_tax = abap_false.
      ENDIF.
      COLLECT gs_taxitem INTO git_taxitems.

    ELSE.
      l_netto = l_brutto.
    ENDIF.

    IF NOT ( l_mwskz = '>' OR l_mwskz = '<' ).  "Direct Tax
      gs_currencyamount-itemno_acc = gs_accountgl-itemno_acc.
      gs_currencyamount-currency   = gs_doc-waers.
      gs_currencyamount-amt_doccur = l_netto.

      APPEND: gs_accountgl      TO git_accountgl,
              gs_currencyamount TO git_currencyamount.
    ENDIF.

  ENDLOOP.

*-----------------------------------------------------------------------
*     gesammelte Steuerzeilen aufbereiten und anhängen
*-----------------------------------------------------------------------
  LOOP AT git_taxitems INTO gs_taxitem.
    ADD 1 TO g_itemno.
    CLEAR: gs_accounttax, gs_currencyamount.
    gs_accounttax-itemno_acc     = g_itemno.
    gs_accounttax-tax_code       = gs_taxitem-mwskz.
    gs_accounttax-direct_tax     = gs_taxitem-direct_tax.
    gs_currencyamount-itemno_acc = gs_accounttax-itemno_acc.
    gs_currencyamount-currency   = gs_doc-waers.
    gs_currencyamount-amt_doccur = gs_taxitem-steuer.
    gs_currencyamount-amt_base   = gs_taxitem-basis.

    APPEND: gs_accounttax     TO git_accounttax,
            gs_currencyamount TO git_currencyamount.
  ENDLOOP.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form _CONVERT
*&---------------------------------------------------------------------*
*& Daten ins SAP-Format konvertieren
*&---------------------------------------------------------------------*
*&      --> in/out Ein/Ausgabe
*&      --> Dtel   Datenelement
*&---------------------------------------------------------------------*
FORM _convert  USING    in out VALUE(dtel).

  CALL FUNCTION 'RS_CONV_EX_2_IN_DTEL'
    EXPORTING
      input_external  = in
      dtel            = dtel
    IMPORTING
      output_internal = out.

  IF sy-subrc <> 0.
    MESSAGE a600(fr) WITH 'Fehler' sy-subrc 'bei der Konvertierung' dtel.
  ENDIF.

ENDFORM.

*--------------------------------------------------------------------
* FORM MSG_ADD
*--------------------------------------------------------------------
FORM msg_add USING VALUE(i_probclass) TYPE bal_s_msg-probclass.
  DATA:
    l_s_msg TYPE bal_s_msg.

* define data of message for Application Log
  l_s_msg-msgty     = sy-msgty.
  l_s_msg-msgid     = sy-msgid.
  l_s_msg-msgno     = sy-msgno.
  l_s_msg-msgv1     = sy-msgv1.
  l_s_msg-msgv2     = sy-msgv2.
  l_s_msg-msgv3     = sy-msgv3.
  l_s_msg-msgv4     = sy-msgv4.
  l_s_msg-probclass = i_probclass.

* add this message to log file
  CALL FUNCTION 'BAL_LOG_MSG_ADD'
    EXPORTING
*     I_LOG_HANDLE  =
      i_s_msg       = l_s_msg
    EXCEPTIONS
      log_not_found = 0
      OTHERS        = 1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.

Hinweise zur Installation:

Textelemente:

001    Verarbeitung der Datei
B01    Excel-Datei auswählen
B02    Testlauf ohne Buchen

Selektionstexte:

PA_FNAM    Name der Datei
PA_TEST    Testlauf - nur prüfen

 

Link zur Excel-Vorlage, die mit dem oben stehenden Programm verarbeitet werden kann.

https://drive.google.com/open?id=13XQEsF9yEa1wv6DE6SPn5zPNm8D9p9n-

Hinweis: die Vorlage ist an das Template für die S/4-FIORI-App "Hauptbuchbelege hochladen" angepasst. Es versteht sich wohl von selbst, dass Anpassungen am Programm gemacht werden müssen, wenn das Template abgeändert wird.

Excel-Template

Excel-Template

Kommentare

Kontenfindung für buchungskreisübergreifende CO Umlagen

Veröffentlicht am 15. Januar 2019 von sapmandoo in CO, S4

Grundsätzlich ist ja möglich, CO Umlagen buchungskreisübergreifend zu definieren, wenn die beteiligten Buchungskreise einem Kostenrechnungskreis zugeordnet sind. Dabei werden ohne weiteres Zutun die im Rahmen der CO-FI Integration im Customizing der Finanzbuchhaltung hinterlegten Buchnungskreisverrechnungskonten (Vorgang BUV) angebucht. Dies ist nicht immer gewünscht, weil Umlagen im CO zumeist nur interne Werteflüsse abbilden und keine echten Intercompany-Geschäftsvorfälle darstellen. 

In den Hinweisen 2483347 bzw. 2457163 wird das Vorgehen beschrieben, wie für Umlagekostenarten eine dedizierte Kontenfindung abseits der 'normalen' Buchungskreisverrechnungskonten eingestellt werden kann.

Kommentare

S/4 HANA F4 Werthilfe u.a. für Debitoren und Kreditoren braucht ewig zum öffnen

Veröffentlicht am 18. September 2018 von sapmandoo in Basis-Entwicklung allg., FI, CO, MM, S4

Symptom:

Beim Öffnen der Werthilfe (z.B. für Kreditoren in der FB60) hängt das System und erst Minuten später wird einem der Werthilfe-Dialog angezeigt.

Abhilfe schafft hier der Hinweis 2571623 - S/4HANA - F4 Search Help is very slow

In diesem wird als eine Möglichkeit zur Behebung des Problems aufgeführt, die Enterprise Search auf die Initialkonfiguration zurückzusetzen. Hierzu dient die Aufgabenliste SAP_ESH_RESET, die mithilfe der Transaktion STC01 ausgeführt werden kann. Allerdings ist die Transaktion nicht gerade ein Ausbund an Benutzerfreundlichkeit, zumindest habe ich einen Moment gebraucht, um mit dem Ding zurechtzukommen.

STC01

STC01

Zunächst muss über das Icon (1.) der Parameter "Zurücksetzen des Mandanten bestätigen" gesetzt werden. Anschließend wird der so geänderte Parameter in eine Variante gespeichert (2.) und zum Schluss die Ausführung der Aufgabenliste als Job eingeplant (3.). Eine Ausführung im Dialog schließt das System aus.

Der Job läuft nicht lange und danach ist die Performance der Werthilfe wieder wie gewohnt.

 

 

 

Kommentare

Anlagen-Migration unter S/4 HANA mithilfe des BAPIs

Veröffentlicht am 26. Juni 2018 von sapmandoo in AA, Basis-Entwicklung allg., S4

Gerade erfolgreich unter S/4 1709 on premise getestet, deshalb hier druckfrisch meine gewonnen Erkenntnisse...

Es soll eine Excel-Datei mit Altanlagen und -werten in SAP-Anlagen migriert werden. Die Übernahme erfolgt zum Jahresende, d.h., es findet keine Übernahme von unterjährigen Bewegungen statt. Es werden zwei Bewertungsbereiche (HGB & IFRS) berücksichtigt.

Die Migrationsdatei hat folgenden Aufbau:

Excel-Datei mit den zu migrierenden Anlagen

Excel-Datei mit den zu migrierenden Anlagen

Die Excel-Datei kann unkonvertiert verwendet werden, d.h. ein vorheriges Abspeichern im TXT-Format oder ähnliches ist nicht erforderlich. Die Nummer der Altanlage ist in der Spalte "Inventarnummer" hinterlegt. Die SAP-Anlagennummern werden in diesem Fall neu intern vergeben.

Die Übernahme erfolgt mit eigenem Programm unter Zuhilfenahme des BAPIs BAPI_FIXEDASSET_OVRTAKE_CREATE. Der genannte BAPI erzeugt in einem Arbeitsgang sowohl den Stammsatz als auch die unter S/4 zwingend erforderliche Übernahmebuchung (ABLDT). Der gute alte Button "Übernahmewerte" in der AS91 und die anschließende Einbuchung der Salden (OASV) ist ja passé...

 

Vorbereitungen

Im Grunde sind die Einstellungen zur Anlagenmigration weitestgehend identisch mit denen unter ECC/ERP. Hinzu kommt die Angabe der Belegart (für die Übernahmebuchung) und in der Fixkontentabelle muss noch ein Übernahmekonto für die Anlagenmigration hinterlegt werden, gegen dass die jeweiligen AHKs und die kumulierte Abschreibung gebucht werden. Hier hat's mich im Q-System zerlegt, weil es ein Problem mit dem Transportanschluss für eben diese Kontenfindung gibt/gab. Hinweise 2376485 und 2289443 schaffen Abhilfe...

Zuvor muss zudem die neue Anlagenbuchhaltung aktiviert werden (IMG: Finanzwesen - Anlagenbuchhaltung - Produktionsvorbereitung - Produktivstart - neue Anlagenbuchhaltung aktivieren (Neukunden)).

Die Übernahmeparameter haben keinen Transportanschluß, d.h. sie müssen ggf. in jedem System/Mandanten eingetragen werden.

IMG-Pfad "Datenübernahme Anlagen"

IMG-Pfad "Datenübernahme Anlagen"

Eingabe von Übernahmestatus, -belegart und -datum pro Buchungskreis

Eingabe von Übernahmestatus, -belegart und -datum pro Buchungskreis

Die obenstehende Excel-Datei kann mit dem untenstehenden Programm eingelesen und verarbeitet werden. Das meiste Coding ging dabei für die Protokollausgabe drauf. Inhaltlich Interessant ist eigentlich nur die Routine "MAP_DATA".

Im ersten Versuch hatte ich die kum. Abschreibungen mit positivem Vorzeichen (also so wie sie in der Excel-Tabelle stehen) an das BAPI übergeben - sah nicht gut aus... Einmal mit -1 multiplizieren reduziert die blutroten Meldungen drastisch...

Zudem hatte ich zuerst den klassischen Anfängerfehler gemacht und das COMMIT nach dem BAPI-Aufruf vergessen.

*&---------------------------------------------------------------------*
*& Report ZFI_MIG_ANLAGEN
*&---------------------------------------------------------------------*
*& Anlagenstamm-Migration (Stammdaten & Werte)
*&---------------------------------------------------------------------*
REPORT zfi_mig_anlagen.
***********************************************************************
******************** GLOBAL DATA **************************************
***********************************************************************
TABLESt001.
SET EXTENDED CHECK OFF.
INCLUDE:
  sbal_constants,
  <icon>.
SET EXTENDED CHECK ON.

DATA:
  g_s_log             TYPE bal_s_log,
  g_log_handle        TYPE balloghndl,
  g_t_log_handle      TYPE bal_t_logh,
  g_s_display_profile TYPE bal_s_prof.

TYPESBEGIN OF ty_mig,  "Spaltenstruktur Excel Datei
         bukr                  LIKE anla-bukrs,
         anlagenklasse         LIKE anla-anlkl,
         anlage                LIKE anla-anln1,
         anlagenbezeichnung1   LIKE anla-txt50,
         anlagenbezeichnung2   LIKE anla-txa50,
         inventarnummer        LIKE anla-invnr,
         aktivdatum(10),
         kostenst              LIKE anlz-kostl,
         standort              LIKE anlz-stort,
         seriennummer          LIKE anla-sernr,
         filiale               LIKE anlz-werks,
         innenauftrag_kost2    LIKE anlz-caufn,
         hgb_afaschl(20),
         hgb_ntz               LIKE anlb-ndjar,
         hgb_per               LIKE anlb-ndper,
         hgb_nafabeg(10),
         hbg_kumanschwert(15),
         hgb_kumnormalafa(15),
         ifrs_afaschl(20),
         ifrs_ntz              LIKE anlb-ndjar,
         ifrs_per              LIKE anlb-ndper,
         ifrs_nafabeg(10),
         ifrs_kumanschwert(15),
         ifrs_kumnormalafa(15),
       END OF ty_mig.

DATAit_mig TYPE TABLE OF ty_mig,
      wa_mig TYPE ty_mig.

DATAkey                  TYPE  bapi1022_key,
      reference            LIKE  bapi1022_reference,
      createsubnumber      LIKE  bapi1022_misc-xsubno,
      creategroupasset     LIKE  bapi1022_misc-xanlgr,
      testrun              LIKE  bapi1022_misc-testrun,
      generaldata          LIKE  bapi1022_feglg001,
      generaldatax         LIKE  bapi1022_feglg001x,
      inventory            LIKE  bapi1022_feglg011,
      inventoryx           LIKE  bapi1022_feglg011x,
      postinginformation   LIKE  bapi1022_feglg002,
      postinginformationx  LIKE  bapi1022_feglg002x,
      timedependentdata    LIKE  bapi1022_feglg003,
      timedependentdatax   LIKE  bapi1022_feglg003x,
      allocations          LIKE  bapi1022_feglg004,
      allocationsx         LIKE  bapi1022_feglg004x,
      origin               LIKE  bapi1022_feglg009,
      originx              LIKE  bapi1022_feglg009x,
      investacctassignmnt  LIKE  bapi1022_feglg010,
      investacctassignmntx LIKE  bapi1022_feglg010x,
      networthvaluation    LIKE  bapi1022_feglg006,
      networthvaluationx   LIKE  bapi1022_feglg006x,
      realestate           LIKE  bapi1022_feglg007,
      realestatex          LIKE  bapi1022_feglg007x,
      insurance            LIKE  bapi1022_feglg008,
      insurancex           LIKE  bapi1022_feglg008x,
      leasing              LIKE  bapi1022_feglg005,
      leasingx             LIKE  bapi1022_feglg005x.

DATAcompanycode  LIKE  bapi1022_1-comp_code,
      asset        LIKE  bapi1022_1-assetmaino,
      subnumber    LIKE  bapi1022_1-assetsubno,
      assetcreated LIKE  bapi1022_reference.

DATAdepreciationareas  LIKE TABLE OF bapi1022_dep_areas WITH HEADER LINE,
      depreciationareasx LIKE TABLE OF bapi1022_dep_areasx WITH HEADER LINE,
      investment_support LIKE TABLE OF bapi1022_inv_support WITH HEADER LINE,
      extensionin        LIKE TABLE OF bapiparex WITH HEADER LINE,
      cumulatedvalues    LIKE TABLE OF bapi1022_cumval WITH HEADER LINE,
      postedvalues       LIKE TABLE OF bapi1022_postval WITH HEADER LINE,
      transactions       LIKE TABLE OF bapi1022_trtype WITH HEADER LINE,
      proportionalvalues LIKE TABLE OF bapi1022_propval WITH HEADER LINE,
      return             LIKE TABLE OF bapiret2 WITH HEADER LINE,
      postingheaders     LIKE TABLE OF bapi1022_postingheader WITH HEADER LINE.

DATAdata_tab TYPE TABLE OF string.



 

*&---------------------------------------------------------------------*
*& SELECTION-SCREEN
*&---------------------------------------------------------------------*
PARAMETERSpa_test AS CHECKBOX DEFAULT 'X'.
PARAMETERSpa_fnam LIKE rlgrap-filename OBLIGATORY.

*&---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_fnam.
*&---------------------------------------------------------------------*
  PERFORM f4_filename.

*&---------------------------------------------------------------------*
START-OF-SELECTION.
*&---------------------------------------------------------------------*

  PERFORM upload_data.
  IF it_mig[] IS NOT INITIAL.
    PERFORM init_protocol.
    LOOP AT it_mig INTO wa_mig.
      PERFORM map_data.
      PERFORM bapi_call.
    ENDLOOP.
    PERFORM protocol.
  ELSE.
    MESSAGE i600(frWITH 'Datei enthält keine' 'verarbeitbaren' 'Datensätze'.
  ENDIF.

*&---------------------------------------------------------------------*
*& Form BAPI_CALL
*&---------------------------------------------------------------------*
*& Anlagen-Migrations-BAPI rufen, Meldungen speichern und f...ing COMMIT
*&---------------------------------------------------------------------*
FORM bapi_call.

  DATAl_error TYPE abap_bool VALUE abap_false.

  CALL FUNCTION 'BAPI_FIXEDASSET_OVRTAKE_CREATE'
    EXPORTING
      key                 key
*     REFERENCE           =
*     CREATESUBNUMBER     =
*     CREATEGROUPASSET    =
      testrun             pa_test
      generaldata         generaldata
      generaldatax        generaldatax
      inventory           inventory
      inventoryx          inventoryx
      postinginformation  postinginformation
      postinginformationx postinginformationx
      timedependentdata   timedependentdata
      timedependentdatax  timedependentdatax
      allocations         allocations
      allocationsx        allocationsx
      origin              origin
      originx             originx
*     INVESTACCTASSIGNMNT =
*     INVESTACCTASSIGNMNTX       =
*     NETWORTHVALUATION   =
*     NETWORTHVALUATIONX  =
*     REALESTATE          =
*     REALESTATEX         =
*     INSURANCE           =
*     INSURANCEX          =
*     LEASING             =
*     LEASINGX            =
    IMPORTING
      companycode         companycode
      asset               asset
      subnumber           subnumber
      assetcreated        assetcreated
    TABLES
      depreciationareas   depreciationareas
      depreciationareasx  depreciationareasx
*     INVESTMENT_SUPPORT  =
*     EXTENSIONIN         =
      cumulatedvalues     cumulatedvalues
*     POSTEDVALUES        =
*     TRANSACTIONS        =
*     PROPORTIONALVALUES  =
      return              return
      postingheaders      postingheaders.

  LOOP AT return WHERE type 'A' OR type 'E'.
    l_error abap_true.
  ENDLOOP.

  IF l_error abap_false.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
  ELSE.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
  ENDIF.

  PERFORM add_msg_to_prot.

ENDFORM.

Wichtig: bitte beachten Sie, dass in Ihrem Migrationsprogramm auch im Testlauf ein Rollback gemacht wird, bspw. mithilfe des BAPI_TRANSACTION_ROLLBACK. Andernfalls bauen sich bei vielen zu migrierenden/testenden Anlagen Puffer- und Arbeitstabellen so auf, dass die Performance rapide in den Keller geht und die Laufzeit exponentiell ansteigt.

(Quelle: Hinweis 2554160 - SAP-S/4HANA-Migrationscockpit: Anlage: Schlechtere Performance beim Simulationslauf)

*&---------------------------------------------------------------------*
*& Form UPLOAD_DATA
*&---------------------------------------------------------------------*
*& Anlagendatei uploaden
*&---------------------------------------------------------------------*
FORM upload_data .

  DATAl_buf   TYPE string,
        l_tabix TYPE sy-tabix.

  CLEAR data_tab[].

  CALL FUNCTION 'FAA_FILE_UPLOAD_EXCEL'
    EXPORTING
      i_filename           pa_fnam
      i_delimiter          '~'
    TABLES
      et_filecontent       data_tab
    EXCEPTIONS
      error_accessing_file 1
      OTHERS               2.

  IF sy-subrc <> 0.
    WRITE'Fehler'sy-subrc'beim Upload der Datei'pa_fnam.
  ENDIF.

  LOOP AT data_tab INTO l_buf.
    SPLIT l_buf AT '~' INTO
         wa_mig-bukr
         wa_mig-anlagenklasse
         wa_mig-anlage
         wa_mig-anlagenbezeichnung1
         wa_mig-anlagenbezeichnung2
         wa_mig-inventarnummer
         wa_mig-aktivdatum
         wa_mig-kostenst
         wa_mig-standort
         wa_mig-seriennummer
         wa_mig-filiale
         wa_mig-innenauftrag_kost2
         wa_mig-hgb_afaschl
         wa_mig-hgb_ntz
         wa_mig-hgb_per
         wa_mig-hgb_nafabeg
         wa_mig-hbg_kumanschwert
         wa_mig-hgb_kumnormalafa
         wa_mig-ifrs_afaschl
         wa_mig-ifrs_ntz
         wa_mig-ifrs_per
         wa_mig-ifrs_nafabeg
         wa_mig-ifrs_kumanschwert
         wa_mig-ifrs_kumnormalafa.
    APPEND wa_mig TO it_mig.
  ENDLOOP.

* Irrelevante Zeilen (Überschriften etc.) ausfiltern
  LOOP AT it_mig INTO wa_mig.
    l_tabix sy-tabix.
    "ist die erste Spalte ein gültiger Buchungskreis?
    "dann gehen wir davon aus, dass es sich um eine Anlagenzeile handelt
    SELECT SINGLE COUNT(*FROM t001 WHERE bukrs wa_mig-bukr.
    IF sy-subrc NE 0.
      DELETE it_mig INDEX l_tabix.
    ENDIF.
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form MAP_DATA
*&---------------------------------------------------------------------*
*& Upload daten in SAP BAPI-Strukturen überführen
*&---------------------------------------------------------------------*
FORM map_data .

  PERFORM init.

  "Buchungskreisdaten lesen
  SELECT SINGLE FROM t001 WHERE bukrs wa_mig-bukr.

*&---------------------------------------------------------------------*
* Schlüssel (mit Altanlagennummer füllen)
*&---------------------------------------------------------------------*
  key-companycode wa_mig-bukr.
  key-asset wa_mig-inventarnummer.
  key-subnumber 0.

*&---------------------------------------------------------------------*
* Allg. Daten
*&---------------------------------------------------------------------*
  PERFORM _convert USING wa_mig-anlagenklasse generaldata-assetclass  'ANLKL'.
  generaldata-descript    wa_mig-anlagenbezeichnung1.
  generaldata-descript2   wa_mig-anlagenbezeichnung2.
  generaldata-serial_no   wa_mig-seriennummer.
  generaldata-invent_no   wa_mig-inventarnummer.
  generaldatax-assetclass abap_true.
  generaldatax-descript   abap_true.
  generaldatax-descript2  abap_true.
  generaldatax-serial_no  abap_true.
  generaldatax-invent_no  abap_true.

*&---------------------------------------------------------------------*
* Buchungsinfos
*&---------------------------------------------------------------------*
  PERFORM _convert USING wa_mig-aktivdatum postinginformation-cap_date  'AKTIVD'.
  postinginformationx-cap_date abap_true.

*&---------------------------------------------------------------------*
* Zeitabhängige Daten
*&---------------------------------------------------------------------*
  timedependentdata-location wa_mig-standort.
  timedependentdatax-location abap_true.
  PERFORM _convert USING wa_mig-kostenst timedependentdata-costcenter 'KOSTL'.
  timedependentdatax-costcenter abap_true.
  "INTERN_ORD
  "PLANT

*&---------------------------------------------------------------------*
* Bewertungsbereichsdaten
*&---------------------------------------------------------------------*
* 01 HGB / local GAAP
  IF generaldata-assetclass <> '00013000'.   "IFRS Leasingobjekte
    depreciationareasx-area depreciationareas-area '01'.
    TRANSLATE wa_mig-hgb_afaschl TO UPPER CASE.
    CASE wa_mig-hgb_afaschl.
      WHEN 'LINEAR'.  depreciationareas-dep_key 'LINI'.
      WHEN 'KEINE'.   depreciationareas-dep_key '0000'.
      WHEN 'MANUELL'depreciationareas-dep_key 'MANU'.
    ENDCASE.
    depreciationareas-ulife_yrs   wa_mig-hgb_ntz.
    depreciationareas-ulife_prds  wa_mig-hgb_per.
    PERFORM _convert USING wa_mig-hgb_nafabeg depreciationareas-odep_start_date 'BF_AFABG'.
    APPEND depreciationareas.
    depreciationareasx-dep_key         abap_true.
    depreciationareasx-ulife_yrs       abap_true.
    depreciationareasx-ulife_prds      abap_true.
    depreciationareasx-odep_start_date abap_true.
    APPEND depreciationareasx.
  ENDIF.

* 02 IFRS
  depreciationareasx-area depreciationareas-area '30'.
  TRANSLATE wa_mig-ifrs_afaschl TO UPPER CASE.
  CASE wa_mig-ifrs_afaschl.
    WHEN 'LINEAR'.  depreciationareas-dep_key 'LINI'.
    WHEN 'KEINE'.   depreciationareas-dep_key '0000'.
    WHEN 'MANUELL'depreciationareas-dep_key 'MANU'.
  ENDCASE.
  depreciationareas-ulife_yrs   wa_mig-ifrs_ntz.
  depreciationareas-ulife_prds  wa_mig-ifrs_per.
  PERFORM _convert USING wa_mig-ifrs_nafabeg depreciationareas-odep_start_date 'BF_AFABG'.
  APPEND depreciationareas.
  depreciationareasx-dep_key         abap_true.
  depreciationareasx-ulife_yrs       abap_true.
  depreciationareasx-ulife_prds      abap_true.
  depreciationareasx-odep_start_date abap_true.
  APPEND depreciationareasx.
*&---------------------------------------------------------------------*
* Kumulierte Anlagenwerte
*&---------------------------------------------------------------------*
* 01 HGB
  IF generaldata-assetclass <> '00013000'.  "IFRS Leasingobjekte
    cumulatedvalues-fisc_year '2018'.
    cumulatedvalues-area '01'.
    PERFORM _convert USING wa_mig-hbg_kumanschwert cumulatedvalues-acq_value 'BF_KANSW'.
    PERFORM _convert USING wa_mig-hgb_kumnormalafa cumulatedvalues-ord_dep 'BF_KNAFA'.
*   Achtung: kum.AfA muss negativ vorgegeben werden
    MULTIPLY cumulatedvalues-ord_dep BY -1.
    cumulatedvalues-currency t001-waers.
    APPEND cumulatedvalues.
  ENDIF.

* 02 IFRS
  cumulatedvalues-fisc_year '2018'.
  cumulatedvalues-area '30'.
  PERFORM _convert USING wa_mig-ifrs_kumanschwert cumulatedvalues-acq_value 'BF_KANSW'.
  PERFORM _convert USING wa_mig-ifrs_kumnormalafa cumulatedvalues-ord_dep 'BF_KNAFA'.
* Achtung: kum.AfA muss negativ vorgegeben werden
  MULTIPLY cumulatedvalues-ord_dep BY -1.
  cumulatedvalues-currency t001-waers.
  APPEND cumulatedvalues.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form PROTOCOL
*&---------------------------------------------------------------------*
*& Return-Tabelle ausgeben
*&---------------------------------------------------------------------*
FORM protocol .

* define how message should be displayed
  PERFORM create_display_profile
            CHANGING
               g_s_display_profile.

* display log
  INSERT g_log_handle INTO TABLE g_t_log_handle.
  CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
    EXPORTING
      i_s_display_profile g_s_display_profile
      i_t_log_handle      g_t_log_handle
    EXCEPTIONS
      OTHERS              1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form F4_FILENAME
*&---------------------------------------------------------------------*
*& F4 Hilfe Excel-Datei
*&---------------------------------------------------------------------*
FORM f4_filename .

  CALL FUNCTION 'FAA_FILE_F4'
    EXPORTING
      i_default_extension 'XLS'
    IMPORTING
      e_filename          pa_fnam
    EXCEPTIONS
      interface_error     1
      OTHERS              2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form INIT
*&---------------------------------------------------------------------*
*& BAPI-Strukturen und -tabellen initialisieren
*&---------------------------------------------------------------------*
FORM init .

  CLEARkey,
         reference,
         createsubnumber,
         creategroupasset,
         testrun,
         generaldata,
         generaldatax,
         inventory,
         inventoryx,
         postinginformation,
         postinginformationx,
         timedependentdata,
         timedependentdatax,
         allocations,
         allocationsx,
         origin,
         originx,
         investacctassignmnt,
         investacctassignmntx,
         networthvaluation,
         networthvaluationx,
         realestate,
         realestatex,
         insurance,
         insurancex ,
         leasing,
         leasingx,
         companycode,
         asset,
         subnumber,
         assetcreated,
         depreciationareas[],
         depreciationareasx[],
         investment_support[],
         extensionin[],
         cumulatedvalues[],
         postedvalues[],
         transactions[],
         proportionalvalues[],
         return[],
         postingheaders[].

  CLEARdepreciationareas,
         depreciationareasx,
         investment_support,
         extensionin,
         cumulatedvalues,
         postedvalues,
         transactions,
         proportionalvalues,
         return,
         postingheaders.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form _CONVERT
*&---------------------------------------------------------------------*
*& Daten ins SAP-Format konvertieren
*&---------------------------------------------------------------------*
*&      --> in/out Ein/Ausgabe
*&      --> Dtel   Datenelement
*&---------------------------------------------------------------------*
FORM _convert  USING    in out VALUE(dtel).

  CALL FUNCTION 'RS_CONV_EX_2_IN_DTEL'
    EXPORTING
      input_external  in
      dtel            dtel
    IMPORTING
      output_internal out.

  IF sy-subrc <> 0.
    WRITE'Fehler'sy-subrc'bei der Konvertierung von'in'Datenelement'dtel.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form INIT_PROTOCOL
*&---------------------------------------------------------------------*
*& Anwendungsprotokoll aufbauen
*&---------------------------------------------------------------------*
FORM init_protocol .

  DATA:
      l_s_message_defaults TYPE bal_s_mdef.

* create a log
  g_s_log-extnumber 'Anlagenmigration'(ext).
  CALL FUNCTION 'BAL_LOG_CREATE'
    EXPORTING
      i_s_log      g_s_log
    IMPORTING
      e_log_handle g_log_handle
    EXCEPTIONS
      OTHERS       1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

* set default log for all following messages
  l_s_message_defaults-log_handle      g_log_handle.
  CALL FUNCTION 'BAL_GLB_MSG_DEFAULTS_SET'
    EXPORTING
      i_s_msg_defaults l_s_message_defaults
    EXCEPTIONS
      OTHERS           0.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_DISPLAY_PROFILE
*&---------------------------------------------------------------------*
*& Protokollausgabe individualisieren
*&---------------------------------------------------------------------*
*&      <-- C_S_DISPLAY_PROFILE
*&---------------------------------------------------------------------*
FORM create_display_profile
       CHANGING
         c_s_display_profile     TYPE bal_s_prof.

  DATA:
    l_s_fcat TYPE bal_s_fcat,
    l_s_sort TYPE bal_s_sort.

* set title of dynpro
  c_s_display_profile-title     'Migrationsprotokoll Anlagen'(set).
* set header of tree
  c_s_display_profile-head_text 'Alte AnlagenNr'(raf).
  c_s_display_profile-head_size 35.
* set size of tree
  c_s_display_profile-tree_size 22.

* set report for display variants
  c_s_display_profile-disvariant-report sy-repid.
* when you use also other ALV lists in your report,
* please specify a handle to distinguish between the display
* variants of these different lists, e.g:
  c_s_display_profile-disvariant-handle 'LOG'.

* all messages should be displayed immediately
  c_s_display_profile-show_all 'X'.

************* define structure of message table
* message text
  CLEAR l_s_fcat.
  l_s_fcat-ref_table 'BAL_S_SHOW'.
  l_s_fcat-ref_field 'T_MSG'.
  l_s_fcat-outputlen 50.
  l_s_fcat-col_pos   1.
  APPEND l_s_fcat TO c_s_display_profile-mess_fcat.
* alte Anlagen Nummer
  CLEAR l_s_fcat.
  l_s_fcat-ref_table 'BAL_S_EX03'.
  l_s_fcat-ref_field 'INVOICE'.
  l_s_fcat-coltext   'ALTANLAGE'(c01).
  l_s_fcat-col_pos   2.
  APPEND l_s_fcat TO c_s_display_profile-mess_fcat.


************* define structure of level 1 in tree
* external number
  CLEAR l_s_fcat.
  l_s_fcat-ref_table 'BAL_S_SHOW'.
  l_s_fcat-ref_field 'EXTNUMBER'.
  l_s_fcat-outputlen  40.
  APPEND l_s_fcat TO c_s_display_profile-lev1_fcat.

************* define structure of level 2 in tree
  CLEAR l_s_fcat.
  l_s_fcat-ref_table 'BAL_S_EX04'.
  l_s_fcat-ref_field 'TXT_CARRID'.
  l_s_fcat-is_extern 'X'.
  l_s_fcat-col_pos   1.
  APPEND l_s_fcat TO c_s_display_profile-lev2_fcat.

* define callback routine which derives the external fields
  c_s_display_profile-clbk_read-userexitt     const_callback_form.
  c_s_display_profile-clbk_read-userexitp     sy-repid.
  c_s_display_profile-clbk_read-userexitf     'CALLBACK_READ'.

* define if grid is to be used for display
  c_s_display_profile-use_grid abap_true.

* define up to which level the tree should be expanded
  c_s_display_profile-exp_level 1.

ENDFORM.

*--------------------------------------------------------------------
* FORM callback_read
*--------------------------------------------------------------------
FORM callback_read                                          "#EC CALLED
       USING                                                "#EC CALLED
         i_s_info            TYPE bal_s_cbrd     "#EC CALLED #EC NEEDED
       CHANGING                                             "#EC CALLED
         c_display_data      TYPE bal_s_show                "#EC NEEDED
         c_context_header    TYPE bal_s_cont                "#EC NEEDED
         c_context_message   TYPE bal_s_cont                "#EC NEEDED
         c_field             TYPE any.                      "#EC NEEDED

  STATICS:
    l_s_context              TYPE bal_s_ex03.

  IF     i_s_info-ref_table 'BAL_S_EX04' AND
         i_s_info-ref_field 'TXT_CARRID'.
*   give back DATEV-Anlagennummer
    l_s_context c_context_message-value.
    c_field l_s_context-invoice.
  ENDIF.

ENDFORM.

*--------------------------------------------------------------------
* FORM ADD_MSG_TO_PROT
*--------------------------------------------------------------------
FORM add_msg_to_prot.
  DATA:
    l_s_msg     TYPE bal_s_msg,
    l_s_context TYPE bal_s_ex03.

  DATA:
    l_s_return  LIKE LINE OF return.

  LOOP AT return INTO l_s_return.

*   define data of message for Application Log
    l_s_msg-msgty           l_s_return-type.
    l_s_msg-msgid           l_s_return-id.
    l_s_msg-msgno           l_s_return-number.
    l_s_msg-msgv1           l_s_return-message_v1.
    l_s_msg-msgv2           l_s_return-message_v2.
    l_s_msg-msgv3           l_s_return-message_v3.
    l_s_msg-msgv4           l_s_return-message_v4.
    l_s_context-invoice     wa_mig-inventarnummer.  "DATEV-Nummer
    l_s_msg-context-tabname 'BAL_S_EX03'.
    l_s_msg-context-value   l_s_context.

* add this message to log file
* we do not specify I_LOG_HANDLE since we want to add this message
* to the default log. If it does not exist we do not care
* (EXCEPTIONS log_not_found = 0).
    CALL FUNCTION 'BAL_LOG_MSG_ADD'
      EXPORTING
*       I_LOG_HANDLE  =
        i_s_msg       l_s_msg
      EXCEPTIONS
        log_not_found 0
        OTHERS        1.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDLOOP.

ENDFORM.

Die Ergebnisse werden in einem Anwendungsprotokoll ausgegeben, wobei zur leichteren Fehlersuche die Meldungen unter der Nummer der Altanlage referenziert werden.

Über den Selektionsparameter "Testlauf" kann die Migration zunächst getestet werden, um vor der Übernahme etwaige Fehler zu eliminieren.

Migrationsprotokoll

Migrationsprotokoll

Folgendes ist bei der Übernahme noch zu beachten: 

  • Gegeben seien folgende Rahmenbedingungen:
    • Geschäftsjahr = Kalenderjahr
    • Die Übernahme erfolge zum 31.12.2017

 

  • Bei der Übernahme muss das Geschäftsjahr 2017 in der Anlagenbuchhaltung abgeschlossen sein (AJAB).
  • Die Übernahme muss zum letzten Buchungstag des letzten geschlossenen Geschäftsjahres erfolgen (31.12.17)
  • Das Übernahmejahr ist kurioserweise das Folgejahr (also 2018 im vorliegenden Fall).
  • Es muss bereits das Übernahmejahr (2018) per Saldovortrag in der AnBu geöffnet worden sein (FAGLGVTR). 
Kommentare
1 2 > >>