FEBAN, FEB_BADI und die Kontoauszugsnachbearbeitung in FIORI (App F1520)
Wer (wie ich) gerne und ausgiebig das BadI FEB_BADI verwendet, um den Buchungsstoff, der aus der Buchung der eingelesenen elektronischen Kontoauszüge und deren Nachbearbeitung entsteht, vor der finalen Verbuchung anzupassen (z.B. um Kontierungselemente anzureichern, Texte und Referenzen im Beleg zu verändern oder gar Buchungszeilen hinzuzufügen), der rieb sich verwundert die Augen, als die für die Nachbearbeitung neu konzipierte FIORI-App (F1520) auf den Plan trat. Bei dieser wird nämlich das BadI nicht gerufen... eigentlich logisch, wenn man bedenkt, wie das Absetzen von Buchungen aus FIORI-Apps heraus funktioniert, jedenfalls nicht mit einem CALL TRANSACTION wie in der guten alten GUI-Transaktion FEBAN. Dennoch fühlt man sich im ersten Moment ziemlich abgehängt und wichtige Prozesse im Rahmen der Auszugsnachbearbeitung funktionieren auf einmal nicht mehr.
Anscheinend war ich nicht der Einzige "abgehängte", jedenfalls sah sich SAP genötigt, mittlerweile einen Hinweis (3635131 - Reprocess Bank Statement Items - Enabling BS_ITM_REPROC_POST) bereitzustellen, der ein astreines Pendant zum FEB_BADI beinhaltet. Aber Achtung: der genannte HW ist leider erst ab S/4 Core Release 108 einspielbar.
Anders als beim FEB_BADI wird der BS_ITM_REPROC_POST nicht nur beim Drücken der Taste "Buchen", sondern bei fast jeder User-Interaktion gerufen. Ansonsten kann man mit dem Ding praktisch alles machen, was man mit dem FEB_BADI auch konnte.
Ach ja - wer nun denkt, das neue BadI sei womöglich abwärtskompatibel mit der GUI-Transaktion FEBAN, wird leider enttäuscht sein. D.h., sofern ihr eine parallele GUI und FIORI Nutzung in Eurer SAP-Landschaft erlaubt, müsst ihr dafür sorgen, dass bei etwaigen Anpassungen, an beide BadIs gedacht wird. Oder ihr lagert das prozessrelevante Coding in eine zentrale Klasse aus. Da aber leider die Schnittstellen nicht identisch sind, müsstet ihr dann noch einen Adapter bauen, na ja - was tut man nicht alles...
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.
FEB_BSPROC / FEBA_BANK_STATEMENT - Unterbringung eigener Informationen
In neueren Releases wird die Nachbearbeitung der elektronischen Kontoauszüge (zumindest bei den noch immer zahlreich vorhandenen Fans des SAP-GUI) gerne mithilfe der Transaktion FEB_BSPROC erledigt. Sie kann zugegebenermaßen nicht alles, was die korrespondierende FIORI-App drauf hat (z.B. die Definition eigener Buchungsregeln während der Bearbeitung), aber sie verrichtet nach wie vor zuverlässig ihren Dienst in vielen Bankbuchhaltungsabteilungen.
Ab und zu wurde ich in der Vergangenheit gefragt, ob kundeneigene Informationen in irgendeiner Form (modifikationsfrei!) in die beliebte GUI-Transaktion integriert bzw. in ihr dargestellt werden können. Daraufhin habe ich mich mal damit beschäftigt und zu meiner Überraschung tatsächlich nur einen BTE gefunden, der in diese Richtung zielt.
Es ist z.B. leider nicht möglich, die Arbeitsliste mit den Einzelsätzen im oberen Bereich der Transaktion um eigene, d.h. nicht in der Tabelle FEBEP vorhandene Felder zu erweitern.
Es ist jedoch möglich, im unteren Abschnitt der Transaktion einen eigenen Reiter mit entsprechendem Subscreen einzufügen, in dem kundeneigene Informationen ermittelt/berechnet und dargestellt werden können (hier als Beispiel "Saldo"):
Dies lässt sich mit dem Business Transaction Event 00002340 (P&S-Schnittstelle) bewerkstelligen.
Informationen zu Implementierung von BTEs finden sich u.a. hier.
Im konkreten Fall wird der Musterfunktionsbaustein zum o.g. BTE (SAMPLE_INTERFACE_00002340) in den Kundennamensraum kopiert und die Exportparameter mit folgenden Daten versorgt:
e_dynnr = '0100'. e_repid = 'SAPLZBTE'. e_appl_tab_title = 'Saldo'. gs_febep = i_febep.
| e_dynnr | Nummer des Subscreen-Dynpros |
| e_repid | Rahmenprogramm der Funktionsgruppe, in der die Z-Kopie des Muster-FuBas angelegt wurde. In ihr sollte der Einfachheit halber auch das genannte Dynpro entwicklelt werden. |
| e_appl_tab_title | Beschriftung des Tabs (s. Grafik oben) |
Sofern Daten aus der Anwendung zur Bereitstellung der gewünschten Informationen im Subscreen benötigt werden, können diese hier in das globale Gedächtnis der Funktionsgruppe kopiert werden, damit auf diese später im Dynpro zugegriffen werden kann (hier bspw. der Inhalt des aktuell bearbeiteten Einzelsatzes).
Der Ausgestaltung des Subscreens sind nun kaum noch Grenzen gesetzt und hängt natürlich von der konkreten Anforderung ab. Ich hatte mal eine Anfrage, bei der es dem Anwender ermöglicht werden sollte, das Hauptbuch während der Bearbeitung mit den bereits verbuchten Auszugspositionen abzustimmen. Hierzu sollte der Saldo des Bankkontos 'realtime' dem Saldo des Kontoauszugs gegenübergestellt werden. Letztendlich ist es hierbei nicht zu einer Umsetzung gekommen, deshalb ist das unten aufgeführte Beispiel noch im "Mock-Up"-Status...
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. …
ALE Verteilung von Anzahlungsanforderungen
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.
Bestellpositionsfelder in Nachrichtenfindung verwenden
Lt. Hinweis 2398371 - Verwendung von Feldern auf Positionsebene (z.B. Werk) für die Nachrichtenfindung, ist es zwar grundsätzlich möglich, Felder aus der Bestellposition in die Zugriffsfolgen der Nachrichtenfindung einzufügen, jedoch werden diese nicht befüllt und sind somit zur Findung von Nachrichtenkonditionen unbrauchbar.
Auszug aus HW 2398371:
Symptom
für die Nachrichtenfindung im MM-Einkaufsbereich möchten Sie Felder auf Positionsebene verwenden, z.B. Werk, Warengruppe usw. Sie fügen das entsprechende Feld zur Zugriffsfolge hinzu und pflegen dafür einen Konditionssatz, aber der Nachrichtensatz wird weiterhin nicht gefunden.
Bei der Nachrichtenfindung wird nicht auf die Daten der einzelnen Positionen des Einkaufsbelegs (z.B. Tabelle EKPO oder EKET) zugegriffen, da die Werte in den positionsbezogenen Tabellenfeldern (z.B. EKPO-WERKS) von Position zu Position unterschiedlich sein können. Daher füllt das System das Feld auf Positionsebene (z.B. Werk usw.) nicht, so dass es den darauf basierenden Konditionssatz nicht finden kann.
Auflösung
In der SAP-Standardsoftware gibt es keine direkt unterstützte Lösung.
Bei der Lösung handelt es sich um ein Beratungsthema. Die folgenden Informationen sollen Ihnen die Richtung geben, aber keine konkrete Beratungslösung bereitstellen und diese für Ihre eigene Verantwortung verwenden:
Folgen Sie z.B. einer ähnlichen Logik wie im SAP-Hinweis 39462 erwähnt und RVCOMFZZ FORM USEREXIT_KOMKBEA_FILL für benutzerdefiniertes ABAP-Coding, z.B. Speicherzuordnung ( '(SAPLMEPO)POT[]' ) oder ein direktes SQL-Lesen von EKPO-Daten aus der Datenbank.
Eine solche "Beraterlösung" soll im folgenden kurz vorgestellt werden. Folgendes Szenario sei gegeben:
Die Nachrichtenfindung soll in Abhängigkeit des Lieferwerkes erfolgen. Da dieses - wie richtig im o.g. Hinweis beschrieben - von Position zu Position unterschiedlich sein kann, soll es explizit aus der ersten Position der Bestellung gezogen werden.
Eine entsprechende Zugriffsfolge inkl. Nachrichten-Konditionstabelle sei bereits im Customizing angelegt worden und das Feld in der für die Bestellnachrichten relevanten Kommunikationsstruktur KOMKBEA heiße WERKS.
Das Customizing zur Nachrichtenfindung in der Bestellung findet sich im IMG unter Materialwirtschaft - Einkauf - Nachrichten - Ausgabesteuerung
Um nun das Feld WERKS in der Kommunikationsstruktur KOMKBEA im Rahmen der Nachrichtenfindung zu befüllen, muss es über einen Userexit versorgt werden. Hierzu sind gewisse Grundkenntnisse in der ABAP/4-Entwicklung vonnöten. Der entsprechende Userexit befindet sich im Programm RVCOMFZZ, Form USEREXIT_KOMKBEA_FILL.
Ein Mustercoding zur Bedienung der oben beschriebenen Anforderung könnte so aussehen:
*---------------------------------------------------------------------*
* FORM USEREXIT_KOMKBEA_FILL *
*---------------------------------------------------------------------*
* This userexit can be used to move additional fields into the *
* communication table which is used for application EA *
*---------------------------------------------------------------------*
FORM userexit_komkbea_fill.
* Werk aus der ersten Bestell-Position holen und in
* passendes Feld in Struktur KOMKBEA abfüllen
SELECT WERKS FROM EKPO INTO COM_KBEA-WERKS "Feldname aus Zugriffsfolge
WHERE EBELN = COM_EKKO-EBELN UP TO 1 ROWS
ORDER BY EBELP ASCENDING.
ENDSELECT.
* COM_KBEA-ZZFIELD1 = COM_EKKO-field.
ENDFORM.
Im Ergebnis wird das Feld WERKS im Zuge der Nachrichtenfindung befüllt und der Zugriff auf werksabhängige Nachrichtenkonditionen ist möglich.
Replikation von bereits gebuchten Belegen per ALE
Öfter habe ich in letzter Zeit in einschlägigen Foren Anfragen bezüglich einer Möglichkeit gelesen, bereits gebuchte Belege per ALE in ein anderes System zu replizieren. Ohne weiteres ist dies ja nur für neu gebuchte Belege nach der Einrichtung des entsprechenden ALE-Verteilungsszenarios möglich. SAP ruft hierzu im Standard-Ablauf den Funktionsbaustein FI_IDOC_CREATE_FIDCC2 auf.
Mithilfe eines kundeneigenen Programms kann dieser bei Bedarf auch verwendet werden, um Belege, die vor Einrichtung des ALE-Szenarios gebucht wurden, in das Ziel-System zu replizieren.
Tatsächlich ist eine 1:1-Verteilung vergleichsweise einfach zu programmieren, siehe nachfolgendes Coding-Beispiel...
*&---------------------------------------------------------------------*
*& Report Y_MIGRATE_OPS
*&---------------------------------------------------------------------*
*& REPLICATE FI DOCUMENTS VIA ALE DISTRIBUTION - SAMPLE PROGRAM
*&---------------------------------------------------------------------*
REPORT y_replicate_fidocs.
DATA: lt_bkpf TYPE TABLE OF bkpf,
lt_bseg TYPE TABLE OF bseg,
lt_bset TYPE TABLE OF bset.
DATA: lt_bkpf_sel TYPE TABLE OF bkpf.
DATA: lv_ownsys LIKE tbdls-logsys.
DATA: lv_buk_global TYPE t001-bukrs_glob.
DATA: ls_bkpf TYPE bkpf.
DATA: lv_prot_title TYPE lvc_title.
SELECT-OPTIONS: so_bukrs FOR ls_bkpf-bukrs,
so_belnr FOR ls_bkpf-belnr,
so_gjahr FOR ls_bkpf-gjahr.
PARAMETERS: pa_logsy LIKE tbd03-rcvsystem OBLIGATORY.
PARAMETERS: pa_xtest AS CHECKBOX DEFAULT 'X'.
START-OF-SELECTION.
CALL FUNCTION 'OWN_LOGICAL_SYSTEM_GET'
IMPORTING
own_logical_system = lv_ownsys.
SELECT * FROM bkpf INTO TABLE lt_bkpf_sel
WHERE bukrs IN so_bukrs
AND belnr IN so_belnr
AND gjahr IN so_gjahr.
LOOP AT lt_bkpf_sel INTO ls_bkpf.
CLEAR: lt_bkpf[].
APPEND ls_bkpf TO lt_bkpf.
CLEAR: lt_bseg[], lt_bset[].
SELECT * FROM bseg INTO TABLE lt_bseg
WHERE belnr = ls_bkpf-belnr
AND bukrs = ls_bkpf-bukrs
AND gjahr = ls_bkpf-gjahr.
SELECT * FROM bset INTO TABLE lt_bset
WHERE belnr = ls_bkpf-belnr
AND bukrs = ls_bkpf-bukrs
AND gjahr = ls_bkpf-gjahr.
SELECT SINGLE bukrs_glob FROM t001 INTO lv_buk_global
WHERE bukrs = ls_bkpf-bukrs.
IF pa_xtest IS INITIAL.
SET UPDATE TASK LOCAL.
CALL FUNCTION 'FI_IDOC_CREATE_FIDCC2'
EXPORTING
i_sendsys = lv_ownsys
i_recsys = pa_logsy
i_bukrs_glob = lv_buk_global
TABLES
t_bkpf = lt_bkpf
t_bseg = lt_bseg
t_bset = lt_bset
EXCEPTIONS
error = 1
OTHERS = 2.
COMMIT WORK AND WAIT.
ENDIF.
ENDLOOP.
IF pa_xtest = abap_true.
lv_prot_title = 'TEST RUN - List of documents to be replicated - NO IDOCS GENERATED!!!'.
ELSE.
lv_prot_title = 'PROD RUN - List of replicated documents - IDOCS WERE GENERATED!!!'.
ENDIF.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_structure_name = 'BKPF'
i_grid_title = lv_prot_title
TABLES
t_outtab = lt_bkpf_sel.
Sofern Mappings / Veränderungen einzelner Datenfelder erforderlich sind, müssten diese natürlich noch in das o.g. Coding integriert werden.
Anzeige von Kontierungsinformationen bei der Buchung
Ö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.
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).
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:
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
*"--------------------------------------------------------------------
DATA: lv_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.
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.
/image%2F1473637%2F20170207%2Fob_adae32_profilbild.png)
/image%2F1473637%2F20250507%2Fob_9027c9_screenshot-2025-05-07-111052.png)
/image%2F1473637%2F20201125%2Fob_ccddc9_screenshot-at-nov-25-13-34-21.png)
/image%2F1473637%2F20201125%2Fob_e2113c_screenshot-at-nov-25-13-42-29.png)
/image%2F1473637%2F20201125%2Fob_827856_screenshot-at-nov-25-14-07-45.png)
/image%2F1473637%2F20201125%2Fob_b54fbb_screenshot-at-nov-25-14-52-39.png)
/image%2F1473637%2F20201125%2Fob_4e2ee2_screenshot-at-nov-25-14-53-29.png)




