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 die Notwendigkeit einer 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.