co
Migration von Dauerbuchungs-Urbelegen
Mir wäre nicht bekannt, dass es im SAP Standard - egal mit welchem Migrationstool - ein Werkzeug gäbe, mit dem Dauerbuchungs-Urbelege von einem SAP-System in ein anderes migriert werden können. In meinen letzten Kundenprojekten waren jeweils eine stattliche Anzahl von aktiven Dauerbuchungs-Urbelegen im Altsystem vorhanden, so dass eine etwaige manuelle Übernahme, eine veritable Meuterei des Fachbereichs ausgelöst hätte.
Insofern war es meine Aufgabe, ein entsprechendes Übernahmeprogramm zu schreiben. Eins vorweg: perfekt (oder gar modern) ist es mit Sicherheit nicht. Ich verwende dabei zur Übernahme eine Batch-Input-Mappe, die aus der Liste der Dauerbuchungs-Urbelege aus dem Altsystem (Transaktion F.15) gespeist wird.
D.h. die erste Aufgabe ist, die relevanten, d.h. die zu migrierenden Dauerbuchungs-Urbelege mithilfe der Transaktion F.15 aus dem Altsystem zu extrahieren. Um tatsächlich nur die relevanten Belege zu erwischen, kann bspw. unter Berücksichtigung des Löschkennzeichens bzw. des Beginn/Ende-Datums selektiert werden. Die dann angezeigte Liste kann mithilfe der Menüfunktion "Liste --> Exportieren --> lokale Datei... / Text mit Tabulatoren" heruntergeladen und anschließend wieder in Excel importiert und von dort in eine "uploadbare" Form umgewandelt werden.
In der nachfolgenden Abbildung ist die Struktur der Excel-Datei zu sehen, auf dem das weiter unten stehende Upload-Programm ZFBD1 operiert.
Für einen besseren Überblick über die einzelnen Felder sind nachfolgend die Elemente des Belegkopfes und der Belegpositionen im Detail aufgeführt (sorry für den Deutsch/Englisch Misch-Masch):
Datenstruktur Header:
| Header | ||
| Fieldlist | Description | Remarks |
| BuKr | Buchungskreis | Mandatory |
| Belegnr | Dauerbuchungs-UrBeleg-Nr | Mandatory |
| Art | Belegart | Mandatory |
| Buch.dat. | Buchungsdatum | not relevant for migration |
| Erste Ausf. | Erste Ausführung | Mandatory, should be set to first due date after Go-Live |
| N.Ausführ. | Nächste Ausführung | not relevant for migration |
| L.Ausführ. | Letzte Ausführung | Mandatory |
| Abst. | Abstand | Mandatory |
| Tag | Tag der Ausführung | Mandatory |
| Apl. | Ausführungsplan | not relevant for migration |
| Anzahl | Anzahl der bisherigen Ausführungen | not relevant for migration |
| LKz | LöschKZ | |
| aSr | Steuer rechnen | |
| Referenz | Referenznummer | |
| Belegkopftext | ||
| Benutzername | not relevant for migration | |
| Erfasst am | not relevant for migration | |
Datenstruktur Position
| Item | ||
| Fieldlist | Description | Remarks |
| Pos | Positionsnummer | Mandatory |
| BS | Buchungsschlüssel | Mandatory |
| SK | Sonderhauptbuchkennzeichen | |
| Uw | Umsatzwirksam | not relevant for migration |
| Koart | Kontoart (Sachkonto, Kreditor, Debitor) | Mandatory |
| Konto | Sachkonto bzw. Debitor/Kreditor | Mandatory |
| not relevant for migration | ||
| St | Steuerkennzeichen | Mandatory |
| Steuer Hauswährung | Steuer in Hauswährung | only when 'calcluate tax' is not activated |
| Soll-/Haben-Betrag | Soll-/Habenbetrag | Mandatory |
| HWähr | Hauswährung | Mandatory |
| Betrag in Fremdwährung | Betrag in Fremdwährung | only if relevant |
| Buchungstext | ||
| Währg | Fremdwährung | only if relevant |
| Kostenstelle | only if applicable | |
| PSP-Element | only if applicable | |
Sobald die Vorbereitungen abgeschlossen sind und die Excel-Datei zum Import geeignet aufbereitet ist, kann diese ins Zielsystem geladen werden. Spielen Sie dazu im Zielsystem das untenstehende Programm ein und führen Sie es aus:
- Geben Sie Excel-Datei als Quelldatei an. Sie können die Datei im Excel-Format verwenden, eine vorherige Konvertierung nach CSV o.ä. ist nicht erforderlich.
- Geben Sie die entsprechenden Mappenparameter vor und führen Sie den Report aus.
- Spielen Sie die vom Programm erzeugte Batch-Input-Mappe ab.
*&---------------------------------------------------------------------*
*& Report ZFBD1
*&---------------------------------------------------------------------*
*& Migrationstool Dauerbuchungsurbelege
*&---------------------------------------------------------------------*
REPORT zfbd1
NO STANDARD PAGE HEADING LINE-SIZE 255.
DATA: data_tab TYPE TABLE OF string.
DATA: BEGIN OF header,
index TYPE i,
bukrs LIKE t001-bukrs,
fill1,
belnr LIKE bkpf-belnr,
fill2,
fill3,
fill4,
blart LIKE bkpf-blart,
fill5,
budat(10),
fill6,
dbbdt(10),
fill7,
dbndt(10),
dbedt(10),
dbmon(2),
dbtag(2),
dbakz LIKE bkdf-dbakz,
dbanz(5),
dblkz(1),
xtx(1),
xblnr LIKE bkpf-xblnr,
fill8,
fill9,
bktxt LIKE bkpf-bktxt,
fill10,
usnam LIKE sy-uname,
erdat LIKE bkpf-cpudt,
END OF header.
DATA: BEGIN OF item,
index TYPE i,
buzei LIKE bseg-buzei,
bschl LIKE bseg-bschl,
fill1,
umskz LIKE bseg-umskz,
umsws(1),
koart LIKE bseg-koart,
fill2,
konto LIKE bseg-hkont,
fill3,
mwskz LIKE bseg-mwskz,
fill4,
mwsbt(16),
fill5,
fill6,
dmbtr(16),
fill7,
fill8,
fill9,
fill10,
fill11,
fill12,
hwaer(5),
wrbtr(16),
sgtxt LIKE bseg-sgtxt,
fwaer(5),
kostl LIKE bseg-kostl,
pspnr LIKE bseg-projn,
END OF item.
DATA: db_headers LIKE header OCCURS 0.
DATA: db_items LIKE item OCCURS 0.
DATA: cnt_items_high TYPE i,
cnt_items TYPE i.
INCLUDE bdcrecx1_s.
PARAMETERS: pa_fnam LIKE rlgrap-filename OBLIGATORY.
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_fnam.
*&---------------------------------------------------------------------*
PERFORM f4_filename.
*&---------------------------------------------------------------------*
START-OF-SELECTION.
*&---------------------------------------------------------------------*
PERFORM upload_data.
IF db_headers[] IS INITIAL.
MESSAGE i600(fr) WITH 'Keine Dauerbuch.belege' 'zur Migration gefunden'.
LEAVE PROGRAM.
ENDIF.
PERFORM open_group.
LOOP AT db_headers INTO header.
PERFORM fbd1_header.
CLEAR cnt_items_high.
LOOP AT db_items INTO item WHERE index = header-index.
ADD 1 TO cnt_items_high.
ENDLOOP.
CLEAR cnt_items.
LOOP AT db_items INTO item WHERE index = header-index.
ADD 1 TO cnt_items.
IF item-koart = 'K'.
IF cnt_items = cnt_items_high.
PERFORM dynpro_0302_with_posting.
ELSE.
PERFORM dynpro_0302.
ENDIF.
ELSEIF item-koart = 'D'.
IF cnt_items = cnt_items_high.
PERFORM dynpro_0301_with_posting.
ELSE.
PERFORM dynpro_0301.
ENDIF.
ELSE.
IF cnt_items = cnt_items_high.
PERFORM dynpro_0300_with_posting.
ELSE.
PERFORM dynpro_0300.
ENDIF.
ENDIF.
ENDLOOP.
PERFORM bdc_transaction USING 'FBD1'.
ENDLOOP.
PERFORM close_group.
*&---------------------------------------------------------------------*
*& 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 UPLOAD_DATA
*&---------------------------------------------------------------------*
*& Anlagendatei uploaden
*&---------------------------------------------------------------------*
FORM upload_data .
DATA: l_buf TYPE string,
l_tabix TYPE sy-tabix,
l_bukrs TYPE t001-bukrs,
l_header TYPE abap_bool.
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 > 2. "Skip headers
l_bukrs = l_buf(4).
SELECT SINGLE COUNT(*) FROM t001 WHERE bukrs = l_bukrs.
IF sy-subrc = 0.
l_header = abap_true.
ELSE.
l_header = abap_false.
ENDIF.
CASE l_header.
WHEN abap_true.
ADD 1 TO l_tabix.
CLEAR header.
header-index = l_tabix.
SPLIT l_buf AT '~' INTO
header-bukrs
header-fill1
header-belnr
header-fill2
header-fill3
header-fill4
header-blart
header-fill5
header-budat
header-fill6
header-dbbdt
header-fill7
header-dbndt
header-dbedt
header-dbmon
header-dbtag
header-dbakz
header-dbanz
header-dblkz
header-xtx
header-xblnr
header-fill8
header-fill9
header-bktxt
header-fill10
header-usnam
header-erdat.
APPEND header TO db_headers.
WHEN OTHERS.
CLEAR item.
item-index = l_tabix.
SPLIT l_buf AT '~' INTO
item-buzei
item-bschl
item-fill1
item-umskz
item-umsws
item-koart
item-fill2
item-konto
item-fill3
item-mwskz
item-fill4
item-mwsbt
item-fill5
item-fill6
item-dmbtr
item-fill7
item-fill8
item-fill9
item-fill10
item-fill11
item-fill12
item-hwaer
item-wrbtr
item-sgtxt
item-fwaer
item-kostl
item-pspnr.
TRANSLATE item-mwsbt USING '- '.
CONDENSE item-mwsbt NO-GAPS.
TRANSLATE item-dmbtr USING '- '.
CONDENSE item-dmbtr NO-GAPS.
TRANSLATE item-wrbtr USING '- '.
CONDENSE item-wrbtr NO-GAPS.
APPEND item TO db_items.
ENDCASE.
ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form fbd1_header
*&---------------------------------------------------------------------*
*& Dauerbuchungen Kopfdaten
*&---------------------------------------------------------------------*
FORM fbd1_header .
REFRESH bdcdata.
PERFORM bdc_dynpro USING 'SAPMF05A' '0106'.
PERFORM bdc_field USING 'BDC_CURSOR'
'RF05A-NEWKO'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'BKPF-BUKRS'
header-bukrs.
PERFORM bdc_field USING 'BKDF-DBBDT'
header-dbbdt.
PERFORM bdc_field USING 'BKDF-DBEDT'
header-dbedt.
PERFORM bdc_field USING 'BKDF-DBMON'
header-dbmon.
PERFORM bdc_field USING 'BKDF-DBTAG'
header-dbtag.
PERFORM bdc_field USING 'BKPF-BLART'
header-blart.
READ TABLE db_items WITH KEY index = header-index INTO item.
PERFORM bdc_field USING 'BKPF-WAERS'
item-fwaer.
PERFORM bdc_field USING 'BKPF-XBLNR'
header-xblnr.
PERFORM bdc_field USING 'BKPF-BKTXT'
header-bktxt.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form dynpro_0302
*&---------------------------------------------------------------------*
*& Fill Dynpro 0302
*&---------------------------------------------------------------------*
FORM dynpro_0302 .
PERFORM bdc_field USING 'RF05A-NEWBS'
item-bschl.
PERFORM bdc_field USING 'RF05A-NEWKO'
item-konto.
PERFORM bdc_dynpro USING 'SAPMF05A' '0302'.
PERFORM bdc_field USING 'BDC_CURSOR'
'RF05A-NEWKO'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF header-xtx NE 'X'.
PERFORM bdc_field USING 'BSEG-WMWST'
item-mwsbt.
ENDIF.
PERFORM bdc_field USING 'BKPF-XMWST'
header-xtx.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form dynpro_0300
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM dynpro_0300 .
PERFORM bdc_field USING 'RF05A-NEWBS'
item-bschl.
PERFORM bdc_field USING 'RF05A-NEWKO'
item-konto.
PERFORM bdc_dynpro USING 'SAPMF05A' '0300'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
IF item-kostl IS NOT INITIAL OR item-pspnr IS NOT INITIAL.
PERFORM bdc_field USING 'BDC_CURSOR'
'DKACB-FMORE'.
PERFORM bdc_field USING 'DKACB-FMORE'
'X'.
PERFORM bdc_dynpro USING 'SAPLKACB' '0002'.
PERFORM bdc_field USING 'BDC_CURSOR'
'COBL-KOSTL'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=ENTE'.
IF item-kostl IS NOT INITIAL.
PERFORM bdc_field USING 'COBL-KOSTL'
item-kostl.
ELSE.
PERFORM bdc_field USING 'COBL-PS_POSID'
item-pspnr.
ENDIF.
PERFORM bdc_dynpro USING 'SAPMF05A' '0300'.
PERFORM bdc_field USING 'BDC_CURSOR'
'BSEG-SGTXT'.
PERFORM bdc_field USING 'DKACB-FMORE'
' '.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
ELSE.
PERFORM bdc_field USING 'BDC_CURSOR'
'DKACB-FMORE'.
PERFORM bdc_field USING 'DKACB-FMORE'
' '.
ENDIF.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form dynpro_0302_with_posting
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM dynpro_0302_with_posting .
PERFORM bdc_field USING 'RF05A-NEWBS'
item-bschl.
PERFORM bdc_field USING 'RF05A-NEWKO'
item-konto.
PERFORM bdc_dynpro USING 'SAPMF05A' '0302'.
PERFORM bdc_field USING 'BDC_CURSOR'
'RF05A-NEWKO'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BU'.
PERFORM bdc_field USING 'BKPF-XMWST'
header-xtx.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF header-xtx NE 'X'.
PERFORM bdc_field USING 'BSEG-WMWST'
item-mwsbt.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form dynpro_0300_with_posting
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM dynpro_0300_with_posting .
PERFORM bdc_field USING 'RF05A-NEWBS'
item-bschl.
PERFORM bdc_field USING 'RF05A-NEWKO'
item-konto.
PERFORM bdc_dynpro USING 'SAPMF05A' '0300'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BU'.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
IF item-kostl IS NOT INITIAL OR item-pspnr IS NOT INITIAL.
PERFORM bdc_field USING 'BDC_CURSOR'
'DKACB-FMORE'.
PERFORM bdc_field USING 'DKACB-FMORE'
'X'.
PERFORM bdc_dynpro USING 'SAPLKACB' '0002'.
PERFORM bdc_field USING 'BDC_CURSOR'
'COBL-KOSTL'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=ENTE'.
IF item-kostl IS NOT INITIAL.
PERFORM bdc_field USING 'COBL-KOSTL'
item-kostl.
ELSE.
PERFORM bdc_field USING 'COBL-PS_POSID'
item-pspnr.
ENDIF.
PERFORM bdc_dynpro USING 'SAPMF05A' '0300'.
PERFORM bdc_field USING 'BDC_CURSOR'
'BSEG-SGTXT'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BU'.
PERFORM bdc_field USING 'DKACB-FMORE'
' '.
ELSE.
PERFORM bdc_field USING 'BDC_CURSOR'
'DKACB-FMORE'.
PERFORM bdc_field USING 'DKACB-FMORE'
' '.
ENDIF.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BU'.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form dynpro_0301
*&---------------------------------------------------------------------*
*& Fill Dynpro 0301
*&---------------------------------------------------------------------*
FORM dynpro_0301.
PERFORM bdc_field USING 'RF05A-NEWBS'
item-bschl.
PERFORM bdc_field USING 'RF05A-NEWKO'
item-konto.
PERFORM bdc_dynpro USING 'SAPMF05A' '0301'.
PERFORM bdc_field USING 'BDC_CURSOR'
'RF05A-NEWKO'.
PERFORM bdc_field USING 'BDC_OKCODE'
'/00'.
PERFORM bdc_field USING 'BKPF-XMWST'
header-xtx.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF header-xtx NE 'X'.
PERFORM bdc_field USING 'BSEG-WMWST'
item-mwsbt.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form dynpro_0301_with_posting
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM dynpro_0301_with_posting .
PERFORM bdc_field USING 'RF05A-NEWBS'
item-bschl.
PERFORM bdc_field USING 'RF05A-NEWKO'
item-konto.
PERFORM bdc_dynpro USING 'SAPMF05A' '0301'.
PERFORM bdc_field USING 'BDC_CURSOR'
'RF05A-NEWKO'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=BU'.
* PERFORM bdc_field USING 'BDC_OKCODE'
* '/00'.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF header-xtx NE 'X'.
PERFORM bdc_field USING 'BSEG-WMWST'
item-mwsbt.
ENDIF.
PERFORM bdc_field USING 'BSEG-SGTXT'
item-sgtxt.
PERFORM bdc_field USING 'BSEG-WRBTR'
item-wrbtr.
IF item-mwskz IS NOT INITIAL.
PERFORM bdc_field USING 'BSEG-MWSKZ'
item-mwskz.
ENDIF.
" PERFORM bdc_field USING 'BDC_OKCODE'
" '=BU'.
PERFORM bdc_field USING 'BKPF-XMWST'
header-xtx.
ENDFORM.
Verfügbarkeitskontrolle - Mail an Verantwortlichen
Wer schon mal im Customizing der Budgetierung, speziell im Bereich der Verfügbarkeitskontrolle unterwegs war (z.B. im Kontext Projektcontrolling oder Investitionsmanagement), wird beim Einstellen der Toleranzen festgestellt haben, dass man bei Überschreitung einer gewissen Budget-Ausschöpfung die Auswahl zwischen drei System-Aktionen hat:
- Warnung
- Fehlermeldung
- Warnung mit Mail an den Verantwortlichen
Beim Punkt "Warnung mit Mail an Verantwortlichen" kamen (zumindest bei mir) etliche Fragen auf, z.B.:
- Wer ist dieser Verantwortliche in diesem Zusammenhang?
- Wohin wird die Mail eigentlich geschickt?
- Was steht da genau drin?
- Kann man das irgendwie beeinflussen?
- Warum habe ich nix anständiges gelernt...?
Der für das jeweilige PSP-Element bzw. für den Innenauftrag Verantwortliche wird in den Stammdaten zugeordnet. Während bei den Innenaufträgen direkt der entsprechende SAP-User im Feld "Verantwortlicher Benutzer" eingetragen wird...
... wird beim PSP-Element der Verantwortliche mit Schlüssel und Klarnamen im Customizing definiert und dort der korrespondierende SAP-User zugeordnet.
Im Stammsatz des PSP-Elementes selbst, wird dann der Schlüssel hinterlegt:
Für den Fall, dass man im Customizing der Toleranzen die Aktion "Warnung mit Mail an Verantwortlichen" ausgewählt hat aber zu einem Objekt KEIN Verantwortlicher gepflegt ist, wird aus der Warnung eine Fehlermeldung (natürlich ohne Mail, an wen auch...?).
Ohne weiteres Zutun wird die "Mail" als interne SAP-Office-Nachricht an den Business Workplace des jeweiligen verantwortlichen SAP-User gesendet.
Die Nachricht ist dabei wie folgt aufgebaut:
Das funktioniert soweit gut, d.h. wem das genügt, braucht hier nichts weiter einzustellen. Vermutlich wird man sich jedoch einigen weitergehenden Anforderungen gegenüber sehen, z.B. den Inhalt oder Betreff der Mail zu beeinflussen oder die Nachricht als "richtige" Mail an ein externes Mail-System zu senden.
Per Customizing geht hier leider nix. Aber es gibt eine SAP-Erweiterung, mit der man z.B. die Mail-Adressaten überschreiben und die interne Nachricht in eine externe Mail "umwandeln" kann.
Zudem gibt es einen Userexit, mit dem gewisse Eigenschaften der Mail verändert werden können. So kann z.B. ein Verfallsdatum hinzugefügt oder der Betreff angepasst werden. Der Inhalt, d.h. der Text der Mail ist leider ohne Modifikation nicht beeinflussbar, dazu aber später mehr.
SAP-Erweiterung zur Bestimmung des/der Mailempfänger/s
|
SMOD-Erweiterung |
Funktionsexit |
Beschreibung |
|
SAPLBPFC |
EXIT_SAPLBPFC_001 |
User-Exit: Mailempfänger bestimmen (Details s. Funktionsbaustein-Dokumentation |
Beispiel-Coding:
*&---------------------------------------------------------------------*
*& Include ZXBPFCU01
*&---------------------------------------------------------------------*
* in standard, the message will be sent to the business workplace of
* the SAP user, that is assigned as responsible for the PSP
* element or internal order. We want to send the warning mail
* to the responsible user's regular mail account (e.g. Outlook)
DATA: lt_return TYPE TABLE OF bapiret2,
lt_addsmtp TYPE TABLE OF bapiadsmtp.
* In case, responsible in the master data of the PSP element or
* int. order is not maintained, this table is empty and an error
* message will be thrown in the calling application.
CHECK t_mail_receivers[] IS NOT INITIAL.
* As only one responsible can be assigned, we take the first entry
READ TABLE t_mail_receivers INDEX 1 ASSIGNING FIELD-SYMBOL(<ls_mail_receiver>).
CHECK sy-subrc = 0 AND <ls_mail_receiver> IS ASSIGNED.
* Now we replace the SAP-User with the external EMail address. We retrieve
* that from their user data.
* Switch recipient adress type to external email address:
<ls_mail_receiver>-recesc = 'U'.
* Retrieve & set Email-Adress
CALL FUNCTION 'BAPI_USER_GET_DETAIL'
EXPORTING
username = <ls_mail_receiver>-recnam
TABLES
return = lt_return
addsmtp = lt_addsmtp.
CHECK lt_addsmtp[] IS NOT INITIAL.
READ TABLE lt_addsmtp INDEX 1 ASSIGNING FIELD-SYMBOL(<ls_addsmtp>).
IF sy-subrc = 0 AND <ls_addsmtp> IS ASSIGNED.
<ls_mail_receiver>-recextnam = <ls_addsmtp>-e_mail.
ENDIF.
Die Tabelle T_MAIL_RECEIVERS darf dabei auch mehrere Empfänger enthalten. Um bspw. CC oder BCC-Empfänger hinzuzufügen, sind die Tabellenfelder SNDBC (BCC) bzw. SNDCP (CC) des entsprechenden Eintrags mit 'X' zu belegen.
Userexit
Im Hinweis 879732 wird ein Userexit beschrieben, mit dem gewisse Mail-Attribute beeinflusst werden können. Nachfolgend einige Coding-Beispiele für typische Anwendungsfälle.
*&---------------------------------------------------------------------*
*& Subroutinenpool ZMAILHDR
*&---------------------------------------------------------------------*
*& Change mail properties for mails created by availability control
*& See SAP-Note 879732 for details
*&---------------------------------------------------------------------*
PROGRAM zmailhdr.
FORM mail_header_adjust
CHANGING c_sood1 LIKE sood1.
* Adjust header of mails sent along with warnings
* of availability control.
** Example: Determine an expiry date.
** Option 1 - Expiry date = end of this year.
* C_SOOD1-DLDAT+0(4) = SY-DATLO(4).
* C_SOOD1-DLDAT+4(4) = '1231'.
** Option 2 - Expiry date = current date + 4 weeks.
* C_SOOD1-DLDAT = SY-DATLO + 28.
** Example: Change Mail subject
* c_sood1-OBJDES = 'My subject'.
ENDFORM.
Mail-Inhalt
Der Inhalt der Mail ist leider nicht ohne Modifikation veränderbar. Es wird hierbei der Langtext der entsprechenden Warnmeldung, die bei der Belegerfassung geworfen wird, verwendet und noch um gewisse hart codierte Bestandteile ergänzt.
Falls es doch jemand anpassen will/muss: Der Zusammenbau des Textes findet im Funktionsbaustein BP_CREATE_MAIL, Zeilen 94ff statt.
GRWTAUTH - erweiterte Berechtigungsprüfung im Report-Writer-Umfeld
Ü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:
Kunden-Exit: Berechtigungsprüfung auf Einzelsatzebene in der Selektion
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.
I_REPORTING_TABLE
I_REPORT_GROUP
I_DATA_SOURCE
I_DB_TABLE
I_S_RECORD
E_SKIP_STANDARD_EXIT
NO_AUTHORITY
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. …
Finanzplandaten importieren in S/4 / Budgetierung auf Kostenstellen
Ü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.
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
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...
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.
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.
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.
Pimp my Batchman
Was sich anhört wie der Titel meines gefloppten Rap-Albums, ist in Wahrheit ein Upgrade des beliebten CO-Superhelden BATCHMAN, mit dem CO-Belege aus externen Dateien ins System geladen werden können. Mein Kollege Markus Läller hat hierzu den von SAP ausgelieferten schwachbrüstigen Schummeldiesel rausgerissen und durch ein bärenstarkes 5.0-Liter V8-Aggregat ersetzt.
Im Vergleich zur Standardauslieferung hat der aufgepumpte Batchman folgendes zu bieten:
- Natives Excel-Format kann ohne vorherige Konvertierung ins CSV-Format verwendet werden
- Vorlagen auf das Wesentliche reduziert und übersichtlich
- Keine führenden Nullen in der Uploaddatei für Stammdaten benötigt
- Zahlenformate mit Dezimalpunkt oder -komma unterstützt
- Kostenrechnungskreis wird auf Defaultwert gesetzt, sofern nicht gefüllt
- User wird automatisch gesetzt (SY-UNAME)
- Automatischer Belegsplit, wenn maximal zulässige Zeilenanzahl überschritten wird
Der Download-Link zu den im folgenden beschriebenen, vereinfachten Excel-Vorlagen findet sich weiter hinten in diesem Artikel.
Wer den BATCHMAN noch gar nicht kennt, kann sich hier mit der Standardauslieferung vertraut machen.
Unterstützte Datenübernahmen
Manuelle Kostenverrechnung
Mit Hilfe der manuellen Kostenverrechnung können Kosten umgebucht werden. Dabei wird ein Senderobjekt (z.B. eine Kostenstelle) entlastet und ein Empfängerobjekt (z.B. eine andere Kostenstelle/ein Auftrag) belastet. Dies ist als Ergänzung der maschinellen Verfahren für die Kostenverrechnung (Umlage, Verteilung) zu verstehen, bei denen nicht mit festen Regeln gearbeitet werden kann.
Im SAP Standard wird die manuelle Kostenverrechnung mit der Transaktion KB15N durchgeführt. Mittels der Transaktion BATCHMAN können Massendaten unter Zuhilfenahme folgender Vorlage gebucht werden:
Die Vorlage besitzt folgenden Aufbau:
Allgemein
Die Spalte A darf nicht verändert werden. Hier stehen die Strukturdaten, die dynamisch die Zeileninformationen aufbauen. Neben den Strukturen stehen die Felder, die in den Strukturen enthalten sind .
Die Daten werden ab Zeile 4 übernommen, d.h. die Zeile 3 (leer) darf nicht gelöscht werden.
Es dürfen maximal 9999 Zeilen angegeben werden (inklusive Leerzeilen).
Belegkopf
Das Feld DOC_NO stellt die Verbindung zwischen Belegkopf und Belegposition her. Somit es möglich, 1 bis n Belege zu erzeugen.
Im Feld DOC_HDR_TX kann ein Belegkopftext angegeben werden.
In den Feldern Belegdatum und Buchungsdatum können Angaben gemacht werden. Bleiben die Felder leer, wird das Systemdatum (=Tagesdatum) übernommen.
Im Feld TRANS_CURR muss die Transaktionswährung angegeben werden.
Belegposition
Das Feld DOC_NO stellt die Verbindung zwischen Belegkopf und Belegposition her. Somit es es möglich, 1 bis n Belege zu erzeugen.
Im Feld COST_ELEM ist die umzubuchende Kostenart anzugeben. Die Kostenart darf ohne führende Nullen angegeben werden.
Im Feld VALUE_TCUR muss der Wert der Buchung angegeben werden. Dezimalstellen können mit Punkt oder Komma angegeben werden.
Im Feld SEND_CCTR ist die abgebende SAP Kostenstelle anzugeben. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Im Feld REC_CCTR ist die empfangende SAP Kostenstelle anzugeben, sofern kein echter Auftrag kontiert werden soll. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Sofern ein Auftrag kontiert werden soll, ist das Feld REC_ORDER mit der SAP Auftragsnummer zu füllen. Die Auftragsnummer darf ohne führende Nullen angegeben werden.
Im Feld SEG_TEXT kann ein Positionstext angegeben werden.
Manuelle Umbuchung Kosten
Mittels der Funktion manuelle Umbuchung Kosten können Primärkosten umgebucht werden. Die Originalkostenart bleibt immer erhalten. Die Funktion wurde vorwiegend konzipiert, um Fehlbuchungen zu korrigieren. Es ist im Einzelfall zu entscheiden, ob wirklich im CO umgebucht werden sollte oder doch lieber die Buchung im Finanzwesen zu korrigieren ist.
Wichtig: Anders als bei der manuellen Kostenverrechnung wird das abgebende Objekt (z.B. die Kostenstelle) nicht mit Entlastungskennzeichen gebucht, sondern mit negativem Belastungskennzeichen.
Im SAP Standard wird die manuelle Umbuchung der Kosten mit der Transaktion KB11N durchgeführt.
Die Vorlage besitzt folgenden Aufbau:
Allgemein
Die Spalte A darf nicht verändert werden. Hier stehen die Strukturdaten, die dynamisch die Zeileninformationen aufbauen. Neben den Strukturen stehen die Felder, die in den Strukturen enthalten sind .
Die Daten werden ab Zeile 4 übernommen, d.h. die Zeile 3 (leer) darf nicht gelöscht werden.
Es dürfen maximal 9999 Zeilen angegeben werden (inklusive Leerzeilen).
Belegkopf
Das Feld DOC_NO stellt die Verbindung zwischen Belegkopf und Belegposition her. Somit es möglich, 1 bis n Belege zu erzeugen.
Im Feld DOC_HDR_TX kann ein Belegkopftext angegeben werden.
In den Feldern Belegdatum und Buchungsdatum können Angaben gemacht werden. Bleiben die Felder leer, wird das Systemdatum (=Tagesdatum) übernommen.
Im Feld TRANS_CURR muss die Transaktionswährung angegeben werden.
Belegposition
Das Feld DOC_NO stellt die Verbindung zwischen Belegkopf und Belegposition her. Somit es es möglich, 1 bis n Belege zu erzeugen.
Im Feld COST_ELEM ist die umzubuchende Kostenart anzugeben. Die Kostenart darf ohne führende Nullen angegeben werden.
Im Feld VALUE_TCUR muss der Wert der Buchung angegeben werden. Dezimalstellen können mit Punkt oder Komma angegeben werden.
Im Feld SEND_CCTR ist die abgebende SAP Kostenstelle anzugeben. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Im Feld REC_CCTR ist die empfangende SAP Kostenstelle anzugeben, sofern kein echter Auftrag kontiert werden soll. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Sofern ein Auftrag kontiert werden soll, ist das Feld REC_ORDER mit der SAP Auftragsnummer zu füllen. Die Auftragsnummer darf ohne führende Nullen angegeben werden.
Im Feld SEG_TEXT kann ein Positionstext angegeben werden.
Interne Leistungsverrechnung
Bei der direkten Leistungsverrechnung wird die erbrachte betriebliche Leistung gemessen, erfasst und verrechnet. Hierfür müssen im System die entsprechenden (messbaren) Bezugsgrößen (= Maßgrößen für die Kostenverursachung) angelegt sein. In der Kostenstellenrechnung werden sie als Leistungsarten bezeichnet. Eine Leistungsverrechnung erfolgt beispielsweise durch das Rückmelden von Arbeitsvorgängen bzw. durch Kontieren der Leistung. Hierbei wird die erbrachte Leistung mit dem Tarif der Leistungsart multipliziert.
Dies erfordert auf den entsprechenden Kostenstellen eine Planung der Leistungsarten mit manuell zu setzendem Tarif.
Im SAP Standard wird die Leistungsverrechnung mit der Transaktion KB21N durchgeführt. Mittels der Transaktion BATCHMAN können Massendaten unter zur Hilfenahme folgender Vorlage gebucht werden:
Allgemein
Die Spalte A darf nicht verändert werden. Hier stehen die Strukturdaten, die dynamisch die Zeileninformationen aufbauen. Neben den Strukturen stehen die Felder, die in den Strukturen enthalten sind .
Die Daten werden ab Zeile 4 übernommen, d.h. die Zeile 3 (leer) darf nicht gelöscht werden.
Es dürfen maximal 9999 Zeilen angegeben werden (inklusive Leerzeilen).
Belegkopf
Im Feld DOC_HDR_TX kann ein Belegkopftext angegeben werden.
In den Feldern Belegdatum und Buchungsdatum können Angaben gemacht werden. Bleiben die Felder leer, wird das Systemdatum (=Tagesdatum) übernommen.
Belegposition
Im Feld ACTTYPE ist Leistungsart anzugeben. Die Leistungsart darf ohne führende Nullen angegeben werden.
Im Feld ACTVTY_QTY muss die geleistete Menge angegeben werden. Die Leistungseinheit wird aus dem Leistungsartenstammsatz ermittelt und nicht eingebbar.
Im Feld SEND_CCTR ist die abgebende SAP Kostenstelle anzugeben. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Im Feld REC_CCTR ist die empfangende SAP Kostenstelle anzugeben, sofern kein echter Auftrag kontiert werden soll. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Sofern ein Auftrag kontiert werden soll, ist das Feld REC_ORDER mit der SAP Auftragsnummer zu füllen. Die Auftragsnummer darf ohne führende Nullen angegeben werden.
Im Feld SEG_TEXT kann ein Positionstext angegeben werden.
Statistische Kennzahl
Statistische Kennzahlen können für Kennzahlenbildungen im Berichtswesen sowie als Bezugsbasis für periodenbezogene Verrechnungen erfasst werden. Dies erfolgt ebenfalls im Rahmen einer vorgangsbezogenen Verrechnung im Controlling.
Im SAP Standard werden statistische Kennzahlen mit der Transaktion KB31N gebucht. Mittels der Transaktion BATCHMAN können Massendaten unter zur Hilfenahme folgender Vorlage gebucht werden:
Allgemein
Die Spalte A darf nicht verändert werden. Hier stehen die Strukturdaten, die dynamisch die Zeileninformationen aufbauen. Neben den Strukturen stehen die Felder, die in den Strukturen enthalten sind .
Die Daten werden ab Zeile 4 übernommen, d.h. die Zeile 3 (leer) darf nicht gelöscht werden.
Es dürfen maximal 9999 Zeilen angegeben werden (inklusive Leerzeilen).
Belegkopf
Im Feld DOC_HDR_TX kann ein Belegkopftext angegeben werden.
In den Feldern Buchungsdatum können Angaben gemacht werden. Sofern das Feld leer ist wird das Tagesdatum übernommen.
Belegposition
Im Feld STATKEYFIG ist die statistische Kennzahl anzugeben. Die Kennzahl darf ohne führende Nullen angegeben werden.
Im Feld STAT_QTY muss der Wert/die Menge angegeben werden. Dezimalstellen können mit Komma und Punkt abgetrennt werden.
Im Feld REC_CCTR ist die empfangende SAP Kostenstelle anzugeben, sofern kein echter Auftrag kontiert werden soll. Die Kostenstelle darf ohne führende Nullen angegeben werden.
Sofern ein Auftrag kontiert werden soll, ist das Feld REC_ORDER mit der SAP Auftragsnummer zu füllen. Die Auftragsnummer darf ohne führende Nullen angegeben werden.
Im Feld SEG_TEXT kann ein Positionstext angegeben werden.
Vorlagen
Nachfolgend der Download-Link zu den oben beschriebenen Excel-Templates:
https://drive.google.com/open?id=1PD1TyrMrV0ncoCvSyceVbgiOrvRi_cDD
Es handelt sich im um ein RAR-Archiv, in dem folgende Excel-Vorlagen enthalten sind:
Installation
Legen Sie in der SE24 die Klasse ZCL_IM_BATCHMAN an und betätigen Sie die Drucktaste "Quelltext-basiert".
Laden Sie anschließend das Coding der Klasse hier herunter und kopieren Sie es in den Editor ein. Aktivieren Sie die Klasse und verankern Sie diese im Customizing unter
Controlling - Kostenstellenrechnung - Istbuchungen - Datenübernahme aus Fremdsystemen - BAdI: Übernahme von externen CO-Istdaten implementieren...
Legen Sie eine BADI-Implementierung an und geben Sie als implementierende Klasse ZCL_IM_BATCHMAN vor.
Anschließend ist die Funktionalität aktiv.
Ausführung / Handhabung
In der Transaktion BATCHMAN stehen folgende Funktionen zur Verfügung:
- Ausführen der Datenübernahme
- Nachbearbeiten der Datenübernahme
- Stornieren der Datenübernahme
- Protokoll zur Datenübernahme anzeigen.
- Testen/Buchen : Die Datenübernahme kann im Testmodus und im Echtlauf ( Buchen ) gestartet werden. Im Testlauf werden alle erforderlichen Prüfungen durchgeführt, jedoch noch keine Buchungen vorgenommen.
- Warnungen ignorieren : Ist dieses Kennzeichen gesetzt, werden Belege auch dann gebucht, wenn bei der Belegprüfung Warnmeldungen auftreten. Ist das Kennzeichen nicht gesetzt, verhindert das Auftreten von Warnungen bei der Belegprüfung die Buchung des betreffenden Belegs.
- Das Feld Externe Nummernvergabe bitte nicht nutzen.
- Datenübernahme-Text : Den Datenübernahmen kann ein Text zugeordnet werden, um die Identifikation von Daten zu unterstützen.
Dateiname Buchungsdaten : Alle bei den Belegprüfungen auftretenden Nachrichten werden protokolliert. Im Echtlauf wird das Protokoll unter der Datenübernahme-Kennung gespeichert. Es kann später mit dieser Kennung gefunden und angezeigt werden (s.a. Protokoll zur Datenübernahme ). Daten, die nicht erfolgreich übernommen werden konnten, werden in einen Nachbearbeitungsvorrat gestellt. Dieser wird ebenfalls über die Kennung der Datenübernahme identifiziert. Dadurch wird gewährleistet, dass sich die Daten zwischen Einlesen und Nachbearbeitung nicht ändern.
Die externe Datenquelle kann mehrfach für die Datenübernahme verwendet werden kann. Die Reaktion der Anwendung auf die mehrfache Übernahme der gleichen Datenquelle kann über die Nachrichtensteuerung der Nachricht 001 des Arbeitsgebietes K41C eingestellt werden. Vorab eingestellt ist, dass der Hinweis auf eine bereits mit der gleichen Datenquelle durchgeführte Datenübernahme als Info-Meldung gezeigt wird, die übergangen werden kann.
Wurde die Datenübernahme im Testlauf durchgeführt, wird folgendes Protokoll ausgegeben:
Mittels Buchen kann die Buchung ausgeführt werden:
Das Ergebnis sind entsprechende Buchungsbelege, die wie folgt angezeigt werden können:
|
|
Anzeigen |
Storno |
|
Manuelle Kostenverrechnung |
KB16N |
KB17N |
|
Manuelle Umbuchung Kosten |
KB13N |
KB14N |
|
Interne Leistungsverrechnung |
KB23N |
KB24N |
|
Statistische Kennzahl |
KB33N |
KB34N |
Nachbearbeiten der Datenübernahme
Testen/Buchen: Die Nachbearbeitung kann im Testmodus oder im Echtlauf (Buchen) erfolgen.
Möglichkeiten:
· Manuelle Verarbeitung
· Halbautomatische Verarbeitung
· Automatische Verarbeitung
Welche der Optionen am besten für die Nachbearbeitung geeignet ist, hängt von der Art der aufgetretenen Fehler ab.
War zum Beispiel zum Zeitpunkt der Datenübernahme für den gewünschten Vorgang die Buchungsperiode gesperrt, sind in der Regel keine Änderungen an den zu buchenden Daten erforderlich. Der Datenübernahme kann automatisch wiederholt werden, nachdem die Periodensperre aufgehoben wurde.
Ist ein Fehler aufgetreten, der nur durch Korrigieren der übernommenen Daten behoben werden kann, kann dies halbautomatisch oder manuell geschehen. Die halbautomatische Nachbearbeitung ist geeignet, wenn Fehler auf der Ebene des Belegkopfes zu beheben sind (z.B. falsches Buchungsdatum oder falsche Referenz ). Sind einzelne Buchungszeilen falsch, wird es nötig sein, diese einzeln manuell zu korrigieren.
Warnungen Ignorieren: Ist dieses Kennzeichen gesetzt, werden Belege auch dann gebucht, wenn bei der Belegprüfung Warnmeldungen auftreten. Ist das Kennzeichen nicht gesetzt, verhindert das Auftreten von Warnungen bei der Belegprüfung die Buchung des betreffenden Belegs.
Externe Nummernvergabe: Dieses Kennzeichen bitte nicht verwenden.
Datenübernahme-ID: Dieser Parameter bestimmt, welche Datenübernahme nachbearbeitet wird.
Zunächst können die zu bearbeitenden Belege aus dem gesamten Nachbearbeitungsvorrat ausgewählt werden. Es können einzelne Belege, Beleggruppen oder alle Belege zur Nachbearbeitung ausgewählt werden.
Im halbautomatischen Modus können Informationen zum Belegkopf wie Kostenrechnungskreis, Version, Buchungsdatum, usw. korrigiert und die so berichtigten Belege automatisch gebucht werden.
Enthält eine Datenübernahme nur Belege eines Typs, werden nur die dafür relevanten Felder zur Korrektur eingeblendet. Wenn eine Datenübernahme Belege zu verschiedenen Vorgängen enthält (z.B. Leistungsverrechnung und Umbuchung von Primärkosten), werden alle Felder angezeigt, die für mindestens einen der Vorgänge geändert werden dürfen. Die korrigierten Werte werden nur dann in die Belege übernommen, wenn sie für den Vorgang des betreffenden Belegs gültige Eingaben sind. Wird zum Beispiel die Version geändert, wird der Wert nicht in Belege zur Umbuchung von Primärkosten übernommen.
Stornieren der Datenübernahme
Die Anwendung erlaubt es, Datenübernahme-Läufe komplett zu stornieren. Wurden einzelne Belege aus dem Lauf bereits manuell storniert, wird eine entsprechende Fehlermeldung ausgegeben, und es werden nur die noch nicht stornierten Belege zum Übernahmelauf storniert.
Testen/Stornieren : Die Stornierung kann im Testmodus oder im Echtlauf (Stornieren) erfolgen.
Warnungen ignorieren : Ist dieses Kennzeichen gesetzt, werden Belege auch dann gebucht, wenn bei der Belegprüfung Warnmeldungen auftreten. Ist das Kennzeichen nicht gesetzt, verhindert das Auftreten von Warnungen bei der Belegprüfung die Buchung des betreffenden Belegs.
Nachbearbeitungsvorrat löschen : Ist das Kennzeichen gesetzt, werden alle zum Datenübernahme-Lauf gehörenden Einträge im Nachbearbeitungsvorrat gelöscht.
Buchungsdatum für Storno : Der Storno kann mit einem Buchungsdatum versehen werden.
Zu stornierende Datenübernahme : Es werden einzelne Datenübernahmen storniert. Sie wählen hier die Datenübernahme-ID aus.
Protokoll zur Datenübernahme anzeigen.
Zu einer Datenübernahme wird das Protokoll angezeigt. In der Regel ist dies das Protokoll aus den Belegprüfungen bei der Datenübernahme. Falls die Datenübernahme nachbearbeitet worden ist, ist das Protokoll erweitert um die Nachrichten aus der Nachbearbeitung. Eine Stornierung der Datenübernahme wird ebenfalls protokolliert.
CO Umlagen - der sog. "Vorbrenner"
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:
- 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 INITIAL. gs_selection-koset = '0101' && gs_selection-kokrs && p_1koset. ENDIF.
IF gs_selection-kstar IS NOT INITIAL AND p_gesam IS INITIAL. gs_selection-kstar = '0102' && gs_selection-kokrs && p_1kstar. ENDIF.
* Start der Verarbeitung
DATA(lo_instance) = zcl_co_cost2statfig=>get_instance( ).
lo_instance->start( gs_selection ).
*&---------------------------------------------------------------------*
*& Include ZCO_POST_COSTASSKF_TOP
*&---------------------------------------------------------------------*
DATA: gv_kosetname TYPE c LENGTH 10,
gv_kstarname TYPE c LENGTH 10.
DATA: gs_selection TYPE zcl_co_cost2statfig=>ts_selection.
TABLES: csks.
*&---------------------------------------------------------------------*
*& Include ZCO_POST_COSTASSKF_SEL
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE TEXT-t01.
PARAMETERS: p_kokrs TYPE kokrs MATCHCODE OBJECT csh_tka01 OBLIGATORY DEFAULT 1000.
PARAMETERS: p_1koset LIKE rksb1-ksgru OBLIGATORY.
*PARAMETERS: p_2koset LIKE rgsbs-setnr MODIF ID in5.
PARAMETERS: p_1kstar LIKE rksb1-kagru.
*PARAMETERS: p_2kstar LIKE rgsbs-setnr MODIF ID in5.
PARAMETERS: p_gesam AS CHECKBOX.
SELECTION-SCREEN SKIP 1.
PARAMETERS: p_gjahr TYPE gjahr OBLIGATORY.
PARAMETERS: p_perio TYPE periode OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b01.
SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME TITLE TEXT-t02.
PARAMETERS: p_stagr TYPE ccss-stagr OBLIGATORY.
PARAMETERS: p_verto TYPE csks-kosar.
SELECT-OPTIONS: s_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 0. p_perio = 12. ENDIF.
IF p_perio EQ 12. p_gjahr = p_gjahr - 1. ENDIF.
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.
CLEAR: p_1kstar, gs_selection-kstar, gv_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: * <SIGNATURE>---------------------------------------------------------------------------------------+ * <SIGNATURE>---------------------------------------------------------------------------------------+ * <SIGNATURE>---------------------------------------------------------------------------------------+
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_instance) TYPE 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_CSKB) type TT_CSKB .
methods DBSEL_CSKS
importing
!IT_KOSTL type HRPP_SEL_KOSTL
returning
value(RT_CSKS) type 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.
DATA: lv_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~kokrs, a~kostl, b~bukrs, b~prctr, b~kosar,
a~wrttp, SUM( a~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~kokrs, b~bukrs, b~prctr, a~kostl, b~kosar, a~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
* | 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 kokrs, kstar, katyp 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 kokrs, kstar, katyp 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 kokrs, kostl, datbi, bukrs, prctr, kosar
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.
DATA: lt_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 bapidochdrp( co_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 bapiskfitm( statkeyfig = cv_stagr
stat_qty = CONV smexxx( ls_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
CLEAR: lv_count, lt_item, lt_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
CLEAR: lv_count, lt_item, lt_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.
* | 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~kokrs, a~belnr,
SUM( b~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~kokrs, a~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 bapiret2( id = '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 char13( ls_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_selmain( is_selection ).
* Kostenstellen festlegen
set_kostenstellen( is_selection ).
* Kostenarten festlegen
set_kostenarten( is_selection ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SET_KOSTENARTEN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION TYPE TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD set_kostenarten.
DATA: lt_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_range( sign = '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_cskb( gr_kstar ).
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_CO_COST2STATFIG->SET_KOSTENSTELLEN
* +-------------------------------------------------------------------------------------------------+
* | [--->] IS_SELECTION TYPE TS_SELECTION
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD set_kostenstellen.
DATA: lt_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_kostl( sign = 'I'
option = 'BT'
low = ls_set->from
high = ls_set->to ) TO gr_kostl.
ENDLOOP.
gt_verto = dbsel_csks( gr_kostl ).
ENDMETHOD.
* | 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_data( is_selection ).
* Ggfls. bisherige stat. Kennzahl stornieren
reverse_statfigpost( ).
* Kosten ermitteln und Verdichten
calculate_costs( ).
* Wert buchen
post_statfig( ).
* Protokoll ausgeben
show_log( ).
ENDMETHOD.
ENDCLASS.
Kontenfindung für buchungskreisübergreifende CO Umlagen
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.
Tarifierung mit BAPI analog zur KP26
Die Planung von Leistungserbringungen und Tarifen erfolgt im Dialog mithilfe der KP26. In einigen Planungsszenarien stellt sich die Aufgabe, externe Daten ins SAP-System zu laden. Hierfür können verschiedene Importszenarien verwendet werden, u.a. der Upload via BAPI BAPI_COSTACTPLN_POSTACTOUTPUT.
Die Schnittstelle des BAPIs ist dabei nicht gerade ein Ausbund an selbsterklärender Offenherzigkeit, deshalb nachfolgend ein Mustercoding sowohl für periodische als auch Gesamt-Planung.
Das nachfolgende Coding habe ich auf einem S/4 HANA on premise (1709) getestet, es sollte aber auch auf älteren Releases lauffähig sein.
*&---------------------------------------------------------------------*
*& Report ZTEST_KP26
*&---------------------------------------------------------------------*
*& KP26 tariff planning
*&---------------------------------------------------------------------*
REPORT ztest_kp26.
DATA: it_actout_index LIKE bapiacpstru OCCURS 0 WITH HEADER LINE.
DATA: it_actout_pervalue LIKE bapiacpval OCCURS 0 WITH HEADER LINE.
DATA: it_actout_totvalue LIKE bapiacptot OCCURS 0 WITH HEADER LINE.
DATA: it_actout_object LIKE bapiacpobj OCCURS 0 WITH HEADER LINE.
DATA: it_return LIKE bapiret2 OCCURS 0 WITH HEADER LINE.
DATA: rec_headerinfo LIKE bapiplnhdr.
DATA: fp_error(1) TYPE c.
" Object index / value index:
" You can post several objects/values at once (with one BAPI call).
" Please make sure, that object and value key correspond in object
" and value tables...
DATA: gw_objcnt(6) TYPE n,
gw_valcnt(6) TYPE n.
PARAMETERS: p_tariff LIKE bapiacpval-price_var_per01 OBLIGATORY,
p_kokrs LIKE rec_headerinfo-co_area OBLIGATORY,
p_kostl LIKE it_actout_object-costcenter OBLIGATORY,
p_lstar LIKE it_actout_object-acttype OBLIGATORY,
p_year LIKE rec_headerinfo-fisc_year OBLIGATORY,
p_from LIKE rec_headerinfo-period_from OBLIGATORY,
p_to LIKE rec_headerinfo-period_to OBLIGATORY,
p_versn LIKE rec_headerinfo-version OBLIGATORY.
PARAMETERS: p_tot RADIOBUTTON GROUP r1 DEFAULT 'X', "totals planning
p_per RADIOBUTTON GROUP r1. "periodic planning
START-OF-SELECTION.
IF p_per = 'X'.
PERFORM make_bapi_data_for_actout_per.
ELSE.
PERFORM make_bapi_data_for_actout_tot.
ENDIF.
*&---------------------------------------------------------------------*
* TOTALS
*&---------------------------------------------------------------------*
FORM make_bapi_data_for_actout_tot.
* init. variables
CLEAR: gw_objcnt, gw_valcnt.
* header data
CLEAR: rec_headerinfo.
rec_headerinfo-co_area = p_kokrs. "Controlling area
rec_headerinfo-fisc_year = p_year. "Fiscal year
rec_headerinfo-period_from = p_from. "From period
rec_headerinfo-period_to = p_to. "To period
rec_headerinfo-version = p_versn. "Version
rec_headerinfo-plan_currtype = 'C'. "Planning Currency
ADD 1 TO gw_objcnt.
* object list (cost center/activity type or business process)
CLEAR: it_actout_object.
it_actout_object-costcenter = p_kostl. "Costcenter
it_actout_object-acttype = p_lstar. "act. type
it_actout_object-object_index = gw_objcnt. "Object Index
APPEND it_actout_object.
ADD 1 TO gw_valcnt.
* plan values totals
CLEAR: it_actout_totvalue.
* check structure of table for other values such as quantities, capacities...
it_actout_totvalue-value_index = gw_valcnt. "Value Index
it_actout_totvalue-price_unit = 1. "price unit
it_actout_totvalue-price_var = p_tariff. "var. tariff
it_actout_totvalue-currency = 'EUR'.
it_actout_totvalue-dist_key_price_var = '2'. "distr.key
APPEND it_actout_totvalue.
* assignment of objects, values and control data
"the items given in the object and value tables are linked by the index value
"this is important, if you want to plan multiple objects with one BAPI call
CLEAR: it_actout_index.
it_actout_index-object_index = gw_objcnt. "Object Index
it_actout_index-value_index = gw_valcnt. "Value Index
APPEND it_actout_index.
CALL FUNCTION 'BAPI_COSTACTPLN_POSTACTOUTPUT'
EXPORTING
headerinfo = rec_headerinfo
TABLES
indexstructure = it_actout_index
coobject = it_actout_object
totvalue = it_actout_totvalue
return = it_return.
IF it_return[] IS INITIAL.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ELSE.
fp_error = 'X'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.
ENDFORM. " MAKE_BAPI_DATA_FOR_ACTOUT
*&---------------------------------------------------------------------*
* PERIODIC VALUES
*&---------------------------------------------------------------------*
FORM make_bapi_data_for_actout_per .
* init. variables
CLEAR: gw_objcnt, gw_valcnt,
it_actout_index[], it_actout_object[],
it_actout_pervalue[].
* header data
CLEAR: rec_headerinfo.
rec_headerinfo-co_area = p_kokrs. "Controlling area
rec_headerinfo-fisc_year = p_year. "Fiscal year
rec_headerinfo-period_from = p_from. "From period
rec_headerinfo-period_to = p_to. "To period
rec_headerinfo-version = p_versn. "Version
rec_headerinfo-plan_currtype = 'C'. "Planning Currency
ADD 1 TO gw_objcnt.
* object list (cost center/activity type or business process)
CLEAR: it_actout_object.
it_actout_object-costcenter = p_kostl. "Costcenter
it_actout_object-acttype = p_lstar. "act. type
it_actout_object-object_index = gw_objcnt. "Object Index
APPEND it_actout_object.
ADD 1 TO gw_valcnt.
* plan values per period
CLEAR: it_actout_pervalue.
* check structure of table for other values such as quantities, capacities...
it_actout_pervalue-value_index = gw_valcnt. "Value Index
it_actout_pervalue-price_unit_per01 = 1. "price unit per.
it_actout_pervalue-price_unit_per02 = 1.
it_actout_pervalue-price_unit_per03 = 1.
it_actout_pervalue-price_unit_per04 = 1.
it_actout_pervalue-price_unit_per05 = 1.
it_actout_pervalue-price_unit_per06 = 1.
it_actout_pervalue-price_unit_per07 = 1.
it_actout_pervalue-price_unit_per08 = 1.
it_actout_pervalue-price_unit_per09 = 1.
it_actout_pervalue-price_unit_per10 = 1.
it_actout_pervalue-price_unit_per11 = 1.
it_actout_pervalue-price_unit_per12 = 1.
it_actout_pervalue-price_var_per01 = p_tariff. "var. tariff per.
it_actout_pervalue-price_var_per02 = p_tariff.
it_actout_pervalue-price_var_per03 = p_tariff.
it_actout_pervalue-price_var_per04 = p_tariff.
it_actout_pervalue-price_var_per05 = p_tariff.
it_actout_pervalue-price_var_per06 = p_tariff.
it_actout_pervalue-price_var_per07 = p_tariff.
it_actout_pervalue-price_var_per08 = p_tariff.
it_actout_pervalue-price_var_per09 = p_tariff.
it_actout_pervalue-price_var_per10 = p_tariff.
it_actout_pervalue-price_var_per11 = p_tariff.
it_actout_pervalue-price_var_per12 = p_tariff.
it_actout_pervalue-currency = 'EUR'.
APPEND it_actout_pervalue.
* assignment of objects, values and control data
CLEAR: it_actout_index.
it_actout_index-object_index = gw_objcnt. "Object Index
it_actout_index-value_index = gw_valcnt. "Value Index
APPEND it_actout_index.
CALL FUNCTION 'BAPI_COSTACTPLN_POSTACTOUTPUT'
EXPORTING
headerinfo = rec_headerinfo
TABLES
indexstructure = it_actout_index
coobject = it_actout_object
pervalue = it_actout_pervalue
return = it_return.
IF it_return[] IS INITIAL.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ELSE.
fp_error = 'X'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ENDIF.
ENDFORM. " MAKE_BAPI_DATA_FOR_ACTOUT
S/4 HANA F4 Werthilfe u.a. für Debitoren und Kreditoren braucht ewig zum öffnen
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.
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.
Kostenartentexte und Sachkontentexte in andere Sprache kopieren
Das hat vermutlich jeder schon mal erlebt: man meldet sich in einer Sprache <> DE im System an und bei der Anzeige von Sachkonten und/oder Kostenarten fehlen die Texte, weil bei der Anlage von neuen Konten das Übersetzen vergessen bzw. unterlassen wurde.
Anbei zwei Reports, die Kostenarten- und Sachkontentexte von einer Quellsprache in eine Zielsprache kopieren. Ein Anwendungsfall könnte bspw. sein, dass die englischen Texte in andere (Fremd-) Sprachen kopiert werden sollen, damit die ausländischen Kollegen in ihren Reports wenigstens die englischen Kontenbezeichnungen sehen...
Kopieren von Sachkontentexten
REPORT z_copy_sako_texts
NO STANDARD PAGE HEADING LINE-SIZE 255.
*******************************************************************
* Rohde 01/2010
*******************************************************************
* Kopieren(!) von Sachkonten-Texten (Kurz und Langtext) von einer
* Sprache in eine andere. So lassen sich z.B. die englischen
* Sachkontenbezeichnungen auch in andere Sprachen kopieren, damit
* man bspw. bei Anmeldung in Spanisch keine leeren Sachkontentexte
* vorfindet. Die Betonung liegt auf KOPIEREN, nicht übersetzen,
* so schlau ist das Programm leider noch nicht!!!!
* Die Änderungen werden per Batch-Input durchgeführt. Bestehende
* Texte in der Zielsprache werden NICHT überschrieben.
*******************************************************************
TABLES: skat, ska1, t001.
INCLUDE bdcrecx1.
SELECTION-SCREEN ULINE.
SELECT-OPTIONS: so_saknr FOR skat-saknr. "Sachkonten
* Achtung: die Angabe Buchungskreis wird nur zur Ermitlung des
* Kontenplans benötigt. Das Programm muss nicht pro Buchungskreis
* laufen, da die Texte buchungskreisunabhängig sind!!!!
PARAMETERS: pa_bukrs LIKE t001-bukrs OBLIGATORY. "Buchungskreis
PARAMETERS: pa_qlang LIKE sy-langu OBLIGATORY. "Quell-Sprache
PARAMETERS: pa_zlang LIKE sy-langu OBLIGATORY. "Ziel-Sprache
PARAMETERS: pa_test AS CHECKBOX DEFAULT 'X'. "Testlauf
DATA: i_skat TYPE TABLE OF skat.
DATA: wa_skat TYPE skat.
START-OF-SELECTION.
IF pa_test IS INITIAL.
PERFORM open_group.
ENDIF.
* Buchungskreisdaten inkl. Kontenplan holen
SELECT SINGLE * FROM t001 WHERE bukrs = pa_bukrs.
CHECK sy-subrc = 0.
SELECT * FROM skat INTO TABLE i_skat
WHERE spras = pa_qlang
AND ktopl = t001-ktopl
AND saknr IN so_saknr.
LOOP AT i_skat INTO wa_skat.
SELECT SINGLE COUNT(*) FROM skat
WHERE spras = pa_zlang
AND ktopl = wa_skat-ktopl
AND saknr = wa_skat-saknr.
IF sy-subrc = 0.
WRITE: / 'Konto', wa_skat-saknr,
'Text in Sprache', pa_zlang, 'schon vorhanden'.
ELSE.
PERFORM protokoll.
IF pa_test IS INITIAL.
PERFORM fs00.
ENDIF.
ENDIF.
ENDLOOP.
IF pa_test IS INITIAL.
PERFORM close_group.
ENDIF.
*&---------------------------------------------------------------------*
*& Form fs00
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM fs00.
PERFORM bdc_dynpro USING 'SAPLGL_ACCOUNT_MASTER_MAINTAIN' '2001'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=TAB04'.
PERFORM bdc_field USING 'BDC_CURSOR'
'GLACCOUNT_SCREEN_KEY-SAKNR'.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_KEY-SAKNR'
wa_skat-saknr.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_KEY-BUKRS'
pa_bukrs.
PERFORM bdc_dynpro USING 'SAPLGL_ACCOUNT_MASTER_MAINTAIN' '2001'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=ACC_MOD'.
PERFORM bdc_field USING 'BDC_CURSOR'
'GLACCOUNT_SCREEN_KEY-SAKNR'.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_KEY-SAKNR'
wa_skat-saknr.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_KEY-BUKRS'
pa_bukrs.
PERFORM bdc_dynpro USING 'SAPLGL_ACCOUNT_MASTER_MAINTAIN' '2001'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=2105_P++'.
PERFORM bdc_field USING 'BDC_CURSOR'
'GLACCOUNT_SCREEN_COA-LANGU_KW(01)'.
PERFORM bdc_dynpro USING 'SAPLGL_ACCOUNT_MASTER_MAINTAIN' '2001'.
PERFORM bdc_field USING 'BDC_OKCODE'
'=SAVE'.
PERFORM bdc_field USING 'BDC_CURSOR'
'GLACCOUNT_SCREEN_COA-TXT50_TX(01)'.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_COA-LANGU_TX(01)'
pa_zlang.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_COA-TXT20_TX(01)'
wa_skat-txt20.
PERFORM bdc_field USING 'GLACCOUNT_SCREEN_COA-TXT50_TX(01)'
wa_skat-txt50.
PERFORM bdc_transaction USING 'FS00'.
ENDFORM. "fs00
*&---------------------------------------------------------------------*
*& Form PROTOKOLL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM protokoll .
WRITE: / wa_skat-saknr,
pa_zlang,
wa_skat-txt20,
wa_skat-txt50.
ENDFORM. " PROTOKOLL
Kopieren von Kostenartentexten
REPORT z_copy_kstar_texts. ******************************************************************* * Rohde 01/2010 ******************************************************************* * Kopieren(!) von Kostenarten-Texten (Kurz und Langtext) von einer * Sprache in eine andere. So lassen sich z.B. die englischen * Kostenartenbezeichnungen auch in andere Sprachen kopieren, damit * man bspw. bei Anmeldung in Spanisch keine leeren Kostenartentexte * vorfindet. Die Betonung liegt auf KOPIEREN, nicht übersetzen, * so schlau ist das Programm leider noch nicht!!!! * Die Änderungen werden per BAPI durchgeführt. Bestehende * Texte in der Zielsprache werden NICHT überschrieben. ******************************************************************* TABLES: csku, tka01. DATA: git_csku TYPE TABLE OF csku, gs_csku TYPE csku. DATA: git_textmdco TYPE TABLE OF textmdco, gs_textmdco TYPE textmdco. ******************************************************************* PARAMETERS: pa_kokrs LIKE tka01-kokrs OBLIGATORY. "Kostenrech.kreis SELECT-OPTIONS: so_kstar FOR csku-kstar. "Kostenart PARAMETERS: pa_qlang LIKE csku-spras OBLIGATORY, "Quell-Sprache pa_zlang LIKE csku-spras OBLIGATORY. "Ziel-Sprache PARAMETERS: pa_test AS CHECKBOX DEFAULT 'X'. "Testlauf ******************************************************************* ******************************************************************* START-OF-SELECTION. ******************************************************************* SELECT SINGLE * FROM tka01 WHERE kokrs = pa_kokrs. IF sy-subrc NE 0. MESSAGE e600(fr) WITH 'Kostenrechungskreis' pa_kokrs 'ungültig'. ENDIF. SELECT * FROM csku INTO TABLE git_csku WHERE spras = pa_qlang AND ktopl = tka01-ktopl AND kstar IN so_kstar. LOOP AT git_csku INTO gs_csku. SELECT SINGLE * FROM csku WHERE spras = pa_zlang AND ktopl = gs_csku-ktopl AND kstar = gs_csku-kstar. IF sy-subrc = 0. SUMMARY. WRITE: / 'Text zu Kostenart', gs_csku-kstar, 'in Sprache', pa_zlang, 'schon vorhanden'. ELSE. REFRESH git_textmdco. CLEAR gs_textmdco. gs_textmdco-spras = pa_zlang. gs_textmdco-ktext = gs_csku-ktext. gs_textmdco-ltext = gs_csku-ltext. APPEND gs_textmdco TO git_textmdco. IF pa_test = space. PERFORM update_kstar_texts. ELSE. DETAIL. WRITE: / gs_csku-ktopl, gs_csku-kstar, gs_textmdco-spras, gs_textmdco-ktext, gs_textmdco-ltext. ENDIF. ENDIF. ENDLOOP. *&---------------------------------------------------------------------* *& Form update_kstar_texts *&---------------------------------------------------------------------* * BAPI-Aufruf Ändern Kostenartentext *----------------------------------------------------------------------* FORM update_kstar_texts. CALL FUNCTION 'K_COSTELEMENT_CHANGE_TEXT' EXPORTING ktopl = gs_csku-ktopl kstar = gs_csku-kstar TABLES texttable = git_textmdco EXCEPTIONS not_found = 1 foreign_lock = 2 OTHERS = 3. IF sy-subrc <> 0. SUMMARY. WRITE: 'Fehler', sy-subrc, 'beim Update Kostenart', gs_csku-kstar. ELSE. DETAIL. WRITE: 'Kostenart', gs_csku-kstar, 'aktualisiert'. ENDIF. ENDFORM. "update_kstar_texts
/image%2F1473637%2F20170207%2Fob_adae32_profilbild.png)
/image%2F1473637%2F20250507%2Fob_9027c9_screenshot-2025-05-07-111052.png)

















