Upload-Tool für Hauptbuchbelege (SAPGUI)
Eine viel nachgefragte Funktion im FI ist die Möglichkeit, Belege in Excel aufzubereiten und unter SAP hochzuladen, z.B. für Sachkonten-Umbuchungen im Rahmen von Abschlusstätigkeiten. Unter S/4 (ab Rel. 1511) gibt es hierfür eine Fiori-App zum Upload von Hauptbuchbelegen via Excel-Template, ab Release 1809 gibt es diese auch für kreditorische Belege...
Bis dahin hilft meines Wissens tatsächlich nur eine selbstgebaute Upload-Funktion oder ggf. ein 3rd Party-Produkt.
Ein einfaches Programm inkl. Testlauf-/Prüffunktion findet sich in diesem Artikel. Hinweise zur Installation und zum Format der Quell-Datei finden sich am Ende des Codings...
*&---------------------------------------------------------------------* *& Report ZFI_UPLOAD_DOCUMENT *----------------------------------------------------------------------* * Funktion : Upload Belege aus Excel * *----------------------------------------------------------------------* * Beschreibung : Upload von Belegen und Verbuchung via Excel * * (Ausweichtool für Fiori-App) * *----------------------------------------------------------------------* REPORT zfi_upload_document. *********************************************************************** ******************** GLOBAL DATA ************************************** *********************************************************************** CONSTANTS: gc_delimiter(1) TYPE c VALUE '~'. SET EXTENDED CHECK OFF. INCLUDE: sbal_constants, <icon>. SET EXTENDED CHECK ON. DATA: g_s_log TYPE bal_s_log, g_log_handle TYPE balloghndl, g_t_log_handle TYPE bal_t_logh, g_s_display_profile TYPE bal_s_prof. DATA: g_dummy TYPE c. DATA: data_tab TYPE TABLE OF string. TYPES: BEGIN OF tax_item, mwskz TYPE mwskz, direct_tax TYPE abap_bool, basis TYPE fwbas, steuer TYPE fwste, END OF tax_item. DATA: git_taxitems TYPE TABLE OF tax_item, gs_taxitem TYPE tax_item. TYPES: BEGIN OF doc_header, bukrs TYPE bukrs, blart TYPE blart, bldat(10) TYPE c, budat(10) TYPE c, bumon TYPE bumon, bktxt TYPE bktxt, waers TYPE waers, ldgrp TYPE fagl_ldgrp, ukurs(12) TYPE c, umdat(10) TYPE c, xblnr TYPE xblnr, pargb TYPE pargb, END OF doc_header. TYPES: BEGIN OF doc_item, bukrs TYPE bukrs, hkont TYPE hkont, sgtxt TYPE sgtxt, wrsol(15) TYPE c, wrhab(15) TYPE c, dmbtr(15) TYPE c, dmbe2(15) TYPE c, mwskz TYPE mwskz, txjcd TYPE txjcd, kostl TYPE kostl, prctr TYPE prctr, aufnr TYPE aufnr, ps_posid TYPE ps_posid, valut(10) TYPE c, hbkid TYPE hbkid, hktid TYPE hktid, zuonr TYPE dzuonr, vbund TYPE vbund, END OF doc_item. DATA: gs_doc TYPE doc_header, gs_item TYPE doc_item, git_items TYPE TABLE OF doc_item. * Schnittstellendaten für Verbuchungs-BAPI DATA: * Returnparameter des BAPIs g_obj_type TYPE bapiache09-obj_type, "Objekttyp * Objejktschlüssel erhält vom BAPI die Belegidentifikation: * NNNNNNNNNNYYYYBBBB N = Belegnummer, Y = GJahr, B = Buchungskreis g_obj_key TYPE bapiache09-obj_key, "Objektschlüssel g_obj_sys TYPE bapiache09-obj_sys, "log. System * Belegkopf gs_documentheader TYPE bapiache09, * Sachkontenpositionen git_accountgl TYPE TABLE OF bapiacgl09, gs_accountgl TYPE bapiacgl09, * Steuerzeilen git_accounttax TYPE TABLE OF bapiactx09, gs_accounttax TYPE bapiactx09, * Betragsinformationen git_currencyamount TYPE TABLE OF bapiaccr09, gs_currencyamount TYPE bapiaccr09, * Meldungen des BAPI's git_return TYPE TABLE OF bapiret2, gs_return TYPE bapiret2. DATA: g_itemno TYPE posnr_acc. "Postionsnummer *&---------------------------------------------------------------------* *& SELECTION-SCREEN *&---------------------------------------------------------------------* SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE TEXT-b01. PARAMETERS: pa_fnam LIKE rlgrap-filename OBLIGATORY. SELECTION-SCREEN END OF BLOCK b01. SELECTION-SCREEN BEGIN OF BLOCK b02 WITH FRAME TITLE TEXT-b02. PARAMETERS: pa_test AS CHECKBOX DEFAULT 'X'. SELECTION-SCREEN END OF BLOCK b02. AT SELECTION-SCREEN ON VALUE-REQUEST FOR pa_fnam. PERFORM f4_filename. *----------------------------------------------------------------------- START-OF-SELECTION. *----------------------------------------------------------------------- PERFORM init. PERFORM upload_data. PERFORM map_data. IF pa_test IS INITIAL. PERFORM post_document. ELSE. PERFORM check_document. ENDIF. PERFORM add_msg_to_prot. PERFORM log_display. *&---------------------------------------------------------------------* *& Form F4_FILENAME *&---------------------------------------------------------------------* *& F4 Hilfe Excel-Datei *&---------------------------------------------------------------------* FORM f4_filename . CALL FUNCTION 'FAA_FILE_F4' EXPORTING i_default_extension = 'XLS' IMPORTING e_filename = pa_fnam EXCEPTIONS interface_error = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. PERFORM msg_add USING probclass_high. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form UPLOAD_DATA *&---------------------------------------------------------------------* *& Upload der Excel-Tabelle mit den Belegdaten *&---------------------------------------------------------------------* FORM upload_data . DATA: l_buf TYPE string, l_tabix TYPE sy-tabix, l_msg(200) TYPE c. CLEAR data_tab[]. CALL FUNCTION 'FAA_FILE_UPLOAD_EXCEL' EXPORTING i_filename = pa_fnam i_delimiter = gc_delimiter TABLES et_filecontent = data_tab EXCEPTIONS error_accessing_file = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE i600(fr) WITH 'Fehler' sy-subrc 'beim Upload'. ELSE. CONCATENATE TEXT-001 pa_fnam INTO l_msg SEPARATED BY space. PERFORM msg_add_free_text USING l_msg. ENDIF. LOOP AT data_tab INTO l_buf. IF sy-tabix = 5. SPLIT l_buf AT gc_delimiter INTO gs_doc-bukrs gs_doc-blart gs_doc-bldat gs_doc-budat gs_doc-bumon gs_doc-bktxt gs_doc-waers gs_doc-ldgrp gs_doc-ukurs gs_doc-umdat gs_doc-xblnr gs_doc-pargb. ENDIF. IF sy-tabix GE 9. SPLIT l_buf AT gc_delimiter INTO gs_item-bukrs gs_item-hkont gs_item-sgtxt gs_item-wrsol gs_item-wrhab gs_item-dmbtr gs_item-dmbe2 gs_item-mwskz gs_item-txjcd gs_item-kostl gs_item-prctr gs_item-aufnr gs_item-ps_posid gs_item-valut gs_item-hbkid gs_item-hktid gs_item-zuonr gs_item-vbund. APPEND gs_item TO git_items. ENDIF. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form INIT_PROTOCOL *&---------------------------------------------------------------------* *& Anwendungsprotokoll aufbauen *&---------------------------------------------------------------------* FORM init_protocol . * create a log g_s_log-extnumber = 'Beleg-Upload'(ext). CALL FUNCTION 'BAL_LOG_CREATE' EXPORTING i_s_log = g_s_log IMPORTING e_log_handle = g_log_handle EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDFORM. *-------------------------------------------------------------------- * FORM ADD_MSG_TO_PROT *-------------------------------------------------------------------- FORM add_msg_to_prot. DATA: l_s_msg TYPE bal_s_msg, l_context TYPE bal_s_ex01. DATA: l_s_return LIKE LINE OF git_return. LOOP AT git_return INTO l_s_return. * define data of message for Application Log l_s_msg-msgty = l_s_return-type. l_s_msg-msgid = l_s_return-id. l_s_msg-msgno = l_s_return-number. l_s_msg-msgv1 = l_s_return-message_v1. l_s_msg-msgv2 = l_s_return-message_v2. l_s_msg-msgv3 = l_s_return-message_v3. l_s_msg-msgv4 = l_s_return-message_v4. * add this message to log file CALL FUNCTION 'BAL_LOG_MSG_ADD' EXPORTING * I_LOG_HANDLE = i_s_msg = l_s_msg EXCEPTIONS log_not_found = 0 OTHERS = 1. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDLOOP. ENDFORM. FORM log_display. DATA: l_s_display_profile TYPE bal_s_prof, l_s_fcat TYPE bal_s_fcat. * get standard display profile CALL FUNCTION 'BAL_DSP_PROFILE_SINGLE_LOG_GET' IMPORTING e_s_display_profile = l_s_display_profile EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. * for display variants add report id l_s_display_profile-disvariant-report = sy-repid. * when you use also other ALV lists in your report, * please specify a handle to distinguish between the display * variants of these different lists, e.g: l_s_display_profile-disvariant-handle = 'LOG'. * show log file with modified output profile * - we specify the display profile since we created our own * - we do not specify any filter (like I_S_LOG_FILTER, ..., * I_T_MSG_HANDLE) since we want to display all messages available CALL FUNCTION 'BAL_DSP_LOG_DISPLAY' EXPORTING * I_S_LOG_FILTER = * I_T_LOG_CONTEXT_FILTER = * I_S_MSG_FILTER = * I_T_MSG_CONTEXT_FILTER = * I_T_LOG_HANDLE = * I_T_MSG_HANDLE = i_s_display_profile = l_s_display_profile EXCEPTIONS OTHERS = 1. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDFORM. *-------------------------------------------------------------------- * FORM MSG_ADD_FREE_TEXT *-------------------------------------------------------------------- FORM msg_add_free_text USING VALUE(i_text) TYPE c. * add this message to log file CALL FUNCTION 'BAL_LOG_MSG_ADD_FREE_TEXT' EXPORTING * I_LOG_HANDLE = i_msgty = 'S' i_text = i_text EXCEPTIONS log_not_found = 0 OTHERS = 1. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form INIT *&---------------------------------------------------------------------* *& Initialisierung *&---------------------------------------------------------------------* FORM init . CLEAR: git_accountgl[], git_accounttax[], git_currencyamount[], git_return[]. CLEAR g_itemno. PERFORM init_protocol. ENDFORM. *&---------------------------------------------------------------------* *& Form POST_DOCUMENT *&---------------------------------------------------------------------* *& Beleg buchen *&---------------------------------------------------------------------* FORM post_document . DATA: l_error TYPE abap_bool VALUE abap_false. *----------------------------------------------------------------------- * BAPI-Aufruf *----------------------------------------------------------------------- CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST' EXPORTING documentheader = gs_documentheader IMPORTING obj_type = g_obj_type obj_key = g_obj_key obj_sys = g_obj_sys TABLES accountgl = git_accountgl accounttax = git_accounttax currencyamount = git_currencyamount return = git_return. LOOP AT git_return TRANSPORTING NO FIELDS WHERE type = 'A' OR type = 'E'. l_error = abap_true. ENDLOOP. IF l_error = abap_false. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'. ELSE. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form CHECK_DOCUMENT *&---------------------------------------------------------------------* *& Beleg prüfen *&---------------------------------------------------------------------* FORM check_document . CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK' EXPORTING documentheader = gs_documentheader TABLES accountgl = git_accountgl accounttax = git_accounttax currencyamount = git_currencyamount return = git_return. ENDFORM. *&---------------------------------------------------------------------* *& Form MAP_DATA *&---------------------------------------------------------------------* *& Mapping der Excel-Daten auf BAPI-Strukturen *&---------------------------------------------------------------------* FORM map_data . DATA: l_netto TYPE wrbtr, l_brutto TYPE wrbtr, l_steuer TYPE fwste, l_basis TYPE fwbas. DATA: l_mwskz TYPE skb1-mwskz. *----------------------------------------------------------------------- * Belegkopf *----------------------------------------------------------------------- CLEAR gs_documentheader. gs_documentheader-bus_act = 'RFBU'. gs_documentheader-username = sy-uname. gs_documentheader-comp_code = gs_doc-bukrs. PERFORM _convert USING gs_doc-bldat gs_documentheader-doc_date 'BLDAT'. PERFORM _convert USING gs_doc-budat gs_documentheader-pstng_date 'BUDAT'. IF gs_doc-bumon IS NOT INITIAL AND gs_doc-bumon NE space. gs_documentheader-fis_period = gs_doc-bumon. ENDIF. gs_documentheader-ref_doc_no = gs_doc-xblnr. gs_documentheader-header_txt = gs_doc-bktxt. gs_documentheader-doc_type = gs_doc-blart. *----------------------------------------------------------------------- * Belegpositionen *----------------------------------------------------------------------- LOOP AT git_items INTO gs_item. ADD 1 TO g_itemno. CLEAR: gs_accountgl, gs_currencyamount. gs_accountgl-itemno_acc = g_itemno. PERFORM _convert USING gs_item-hkont gs_accountgl-gl_account 'HKONT'. gs_accountgl-item_text = gs_item-sgtxt. IF gs_item-kostl IS NOT INITIAL. PERFORM _convert USING gs_item-kostl gs_accountgl-costcenter 'KOSTL'. ENDIF. IF gs_item-prctr IS NOT INITIAL. PERFORM _convert USING gs_item-prctr gs_accountgl-profit_ctr 'PRCTR'. ENDIF. IF gs_item-aufnr IS NOT INITIAL. PERFORM _convert USING gs_item-aufnr gs_accountgl-orderid 'AUFNR'. ENDIF. IF gs_item-ps_posid IS NOT INITIAL. PERFORM _convert USING gs_item-ps_posid gs_accountgl-wbs_element 'PS_POSID'. ENDIF. gs_accountgl-alloc_nmbr = gs_item-zuonr. gs_accountgl-trade_id = gs_item-vbund. gs_accountgl-tax_code = gs_item-mwskz. IF gs_item-valut IS NOT INITIAL. PERFORM _convert USING gs_item-valut gs_accountgl-value_date 'VALUT'. ENDIF. IF gs_item-wrsol IS NOT INITIAL. PERFORM _convert USING gs_item-wrsol l_brutto 'WRBTR'. ENDIF. IF gs_item-wrhab IS NOT INITIAL. PERFORM _convert USING gs_item-wrhab l_brutto 'WRBTR'. MULTIPLY l_brutto BY -1. ENDIF. * Sachkonto mit Steuer zu bebuchen CLEAR l_mwskz. SELECT SINGLE mwskz FROM skb1 INTO l_mwskz WHERE saknr = gs_accountgl-gl_account AND bukrs = gs_documentheader-comp_code. IF sy-subrc = 0 AND l_mwskz IS INITIAL. "keine Steuer erlaubt --> St. KZ. löschen (Verhalten analog FIORI-App) CLEAR: gs_item-mwskz, gs_accountgl-tax_code. ENDIF. CLEAR: l_steuer, l_netto, l_basis. * Mit Steuer? IF gs_item-mwskz IS NOT INITIAL. IF l_mwskz = '>' OR l_mwskz = '<'. "Direct Tax CALL FUNCTION 'RE_CALCULATE_BASE_AMOUNT' EXPORTING i_taxam = l_brutto i_mwskz = gs_item-mwskz i_waers = gs_doc-waers i_bukrs = gs_documentheader-comp_code IMPORTING e_fwbas = l_basis. l_steuer = l_netto = l_brutto. ELSE. CALL FUNCTION 'CALCULATE_TAX_FROM_GROSSAMOUNT' EXPORTING i_bukrs = gs_documentheader-comp_code i_mwskz = gs_item-mwskz i_waers = gs_doc-waers i_wrbtr = l_brutto IMPORTING e_fwste = l_steuer EXCEPTIONS OTHERS = 16. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO g_dummy. PERFORM msg_add USING probclass_high. ENDIF. l_netto = l_brutto - l_steuer. l_basis = l_netto. ENDIF. *----------------------------------------------------------------------- * korrespondierende Steuerzeile sammeln *----------------------------------------------------------------------- CLEAR gs_taxitem. gs_taxitem-mwskz = gs_item-mwskz. gs_taxitem-steuer = l_steuer. gs_taxitem-basis = l_basis. IF l_mwskz = '>' OR l_mwskz = '<'. "Direct Tax gs_taxitem-direct_tax = abap_true. ELSE. gs_taxitem-direct_tax = abap_false. ENDIF. COLLECT gs_taxitem INTO git_taxitems. ELSE. l_netto = l_brutto. ENDIF. IF NOT ( l_mwskz = '>' OR l_mwskz = '<' ). "Direct Tax gs_currencyamount-itemno_acc = gs_accountgl-itemno_acc. gs_currencyamount-currency = gs_doc-waers. gs_currencyamount-amt_doccur = l_netto. APPEND: gs_accountgl TO git_accountgl, gs_currencyamount TO git_currencyamount. ENDIF. ENDLOOP. *----------------------------------------------------------------------- * gesammelte Steuerzeilen aufbereiten und anhängen *----------------------------------------------------------------------- LOOP AT git_taxitems INTO gs_taxitem. ADD 1 TO g_itemno. CLEAR: gs_accounttax, gs_currencyamount. gs_accounttax-itemno_acc = g_itemno. gs_accounttax-tax_code = gs_taxitem-mwskz. gs_accounttax-direct_tax = gs_taxitem-direct_tax. gs_currencyamount-itemno_acc = gs_accounttax-itemno_acc. gs_currencyamount-currency = gs_doc-waers. gs_currencyamount-amt_doccur = gs_taxitem-steuer. gs_currencyamount-amt_base = gs_taxitem-basis. APPEND: gs_accounttax TO git_accounttax, gs_currencyamount TO git_currencyamount. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form _CONVERT *&---------------------------------------------------------------------* *& Daten ins SAP-Format konvertieren *&---------------------------------------------------------------------* *& --> in/out Ein/Ausgabe *& --> Dtel Datenelement *&---------------------------------------------------------------------* FORM _convert USING in out VALUE(dtel). CALL FUNCTION 'RS_CONV_EX_2_IN_DTEL' EXPORTING input_external = in dtel = dtel IMPORTING output_internal = out. IF sy-subrc <> 0. MESSAGE a600(fr) WITH 'Fehler' sy-subrc 'bei der Konvertierung' dtel. ENDIF. ENDFORM. *-------------------------------------------------------------------- * FORM MSG_ADD *-------------------------------------------------------------------- FORM msg_add USING VALUE(i_probclass) TYPE bal_s_msg-probclass. DATA: l_s_msg TYPE bal_s_msg. * define data of message for Application Log l_s_msg-msgty = sy-msgty. l_s_msg-msgid = sy-msgid. l_s_msg-msgno = sy-msgno. l_s_msg-msgv1 = sy-msgv1. l_s_msg-msgv2 = sy-msgv2. l_s_msg-msgv3 = sy-msgv3. l_s_msg-msgv4 = sy-msgv4. l_s_msg-probclass = i_probclass. * add this message to log file CALL FUNCTION 'BAL_LOG_MSG_ADD' EXPORTING * I_LOG_HANDLE = i_s_msg = l_s_msg EXCEPTIONS log_not_found = 0 OTHERS = 1. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDFORM.
Hinweise zur Installation:
Textelemente:
001 Verarbeitung der Datei
B01 Excel-Datei auswählen
B02 Testlauf ohne Buchen
Selektionstexte:
PA_FNAM Name der Datei
PA_TEST Testlauf - nur prüfen
Link zur Excel-Vorlage, die mit dem oben stehenden Programm verarbeitet werden kann.
https://drive.google.com/open?id=13XQEsF9yEa1wv6DE6SPn5zPNm8D9p9n-
Hinweis: die Vorlage ist an das Template für die S/4-FIORI-App "Hauptbuchbelege hochladen" angepasst. Es versteht sich wohl von selbst, dass Anpassungen am Programm gemacht werden müssen, wenn das Template abgeändert wird.
/image%2F1473637%2F20170207%2Fob_adae32_profilbild.png)
