Extractor Report
Report ZFI_BILENDO_EXPORT_V2 zur Datenextraktion aus SAP nach Bilendo.
Übersicht
| Eigenschaft | Wert |
|---|---|
| Report | ZFI_BILENDO_EXPORT_V2 |
| SAP-Modul | FI-AR |
| Version | 2.1 |
| Funktion | Extrahiert Kundenstamm, Offene Posten und Ausgeglichene Posten aus SAP und schreibt TXT-Dateien auf den Applikationsserver |
| Includes | ZFI_BILENDO_EXPORT_V2_D01 (Datendeklaration), ZFI_BILENDO_EXPORT_V2_F01 (Verarbeitungslogik) |
| Abhängigkeit | ZCL_FI_BILENDO_ASSIST_V2 (→ 03 - Assist-Klasse) |
Selektionsbild
Der Report bietet folgende Selektionsparameter:
Block 1: Kundenstammdaten
| Parameter | Feld | Typ | Default | Beschreibung |
|---|---|---|---|---|
| P_KNA1 | – | Checkbox | X | Kundenstammdaten extrahieren |
| S_CUSDT | BKPF-CPUDT | Select-Option | – | Erfassungsdatum Kundenstamm |
Block 2: Bewegungsdaten
| Parameter | Feld | Typ | Default | Beschreibung |
|---|---|---|---|---|
| P_BSEG | – | Checkbox | – | Alle Posten (BSEG komplett) |
| P_BSID | – | Checkbox | X | Offene Posten |
| P_BSAD | – | Checkbox | X | Ausgeglichene Posten |
| S_BUDAT | BKPF-BUDAT | Select-Option | – | Buchungsdatum |
| S_AUGDT | BSEG-AUGDT | Select-Option | – | Ausgleichsdatum |
| S_CPUDT | BKPF-CPUDT | Select-Option | – | Erfassungsdatum |
| S_CPUTM | BKPF-CPUTM | Select-Option | – | Erfassungsuhrzeit |
Block 3: Lademodus
| Parameter | Typ | Default | Beschreibung |
|---|---|---|---|
| P_ALL | Radiobutton | – | Vollladen (Initial) – alle Daten ohne Zeiteinschränkung |
| P_DELTA | Radiobutton | X | Deltaladen – nur Daten im Selektionszeitraum |
Weitere
| Parameter | Feld | Typ | Beschreibung |
|---|---|---|---|
| S_BUKRS | BKPF-BUKRS | Select-Option | Buchungskreis (Einschränkung) |
| S_AUGBL | BSEG-AUGBL | Select-Option | Ausgleichsbeleg (für ausgeglichene Posten über Beleg) |
| P_F_KNA1 | – | Text255 | Dateiname Kundenstamm (automatisch befüllt) |
| P_F_BSEG | – | Text255 | Dateiname alle Posten (automatisch befüllt) |
| P_F_BSID | – | Text255 | Dateiname offene Posten (automatisch befüllt) |
| P_F_BSAD | – | Text255 | Dateiname ausgeglichene Posten (automatisch befüllt) |
Quellcode
Hauptreport – ZFI_BILENDO_EXPORT_V2
*&---------------------------------------------------------------------*
*& Report ZFI_BILENDO_EXPORT_V2
*& Owner : Bilendo GmbH
*& Module : SAP A/R Module
*& Description : Report to extract Customer Master, Open Item,
*& Cleared Items and create .txt files & place it in
*& application server
*& Version : 2.1
*&---------------------------------------------------------------------*
REPORT ZFI_BILENDO_EXPORT_V2.
INCLUDE ZFI_BILENDO_EXPORT_V2_D01.
INCLUDE ZFI_BILENDO_EXPORT_V2_F01.
INITIALIZATION.
PERFORM sub_initial.
AT SELECTION-SCREEN OUTPUT.
START-OF-SELECTION.
PERFORM get_filenames USING 'Customers' CHANGING p_f_kna1.
PERFORM get_filenames USING 'all' CHANGING p_f_bseg.
PERFORM get_filenames USING 'open' CHANGING p_f_bsid.
PERFORM get_filenames USING 'cleared' CHANGING p_f_bsad.
PERFORM sub_getscreendata.
PERFORM sub_processing.
END-OF-SELECTION.Include D01 – Datendeklaration und Selektionsbild
⚠️ Anpassung erforderlich: Die Konstanten
gc_dir_hed,gc_dir_heq,gc_dir_hepund dieWHEN-Zweige inget_filenames(F01) müssen an die jeweilige Systemlandschaft angepasst werden.
*&---------------------------------------------------------------------*
*& Include ZFI_BILENDO_EXPORT_V2_D01
*&---------------------------------------------------------------------*
TABLES: bkpf, bseg.
DATA: gt_seltab TYPE TABLE OF rsparams,
gt_seltab_255 TYPE TABLE OF rsparamsl_255,
gf_file TYPE string,
gf_file_kna1 TYPE string,
gf_file_bseg TYPE string,
gf_file_bsid TYPE string,
gf_file_bsad TYPE string,
go_bilendo TYPE REF TO zcl_fi_bilendo_assist_v2,
gf_msg TYPE string,
gt_t001 TYPE TABLE OF t001,
gs_t001 TYPE t001.
CONSTANTS: gc_dir_hed TYPE string VALUE '/.....', " ← DEV-Pfad anpassen
gc_dir_heq TYPE string VALUE '/.....', " ← QA-Pfad anpassen
gc_dir_hep TYPE string VALUE '/.....'. " ← PRD-Pfad anpassen
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-006 .
PARAMETERS: p_kna1 TYPE xfeld AS CHECKBOX DEFAULT 'X'.
SELECT-OPTIONS: s_cusdt FOR bkpf-cpudt.
SELECTION-SCREEN END OF BLOCK b1 .
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE text-007 .
PARAMETERS: p_bseg TYPE xfeld AS CHECKBOX,
p_bsid TYPE xfeld AS CHECKBOX DEFAULT 'X',
p_bsad TYPE xfeld AS CHECKBOX DEFAULT 'X'.
SELECT-OPTIONS: s_budat FOR bkpf-budat,
s_augdt FOR bseg-augdt.
SELECT-OPTIONS: s_cpudt FOR bkpf-cpudt,
s_cputm FOR bkpf-cputm.
SELECTION-SCREEN END OF BLOCK b2 .
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-008 .
PARAMETERS: p_all TYPE char1 RADIOBUTTON GROUP 01,
p_delta TYPE char1 RADIOBUTTON GROUP 01 DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK b3 .
SELECTION-SCREEN ULINE.
SELECT-OPTIONS: s_bukrs FOR bkpf-bukrs,
s_augbl FOR bseg-augbl.
SELECTION-SCREEN ULINE.
SELECTION-SCREEN COMMENT /1(83) text-005.
PARAMETERS: p_f_kna1 TYPE text255,
p_f_bseg TYPE text255,
p_f_bsid TYPE text255,
p_f_bsad TYPE text255.Include F01 – Verarbeitungslogik
*&---------------------------------------------------------------------*
*& Include ZFI_BILENDO_EXPORT_V2_F01
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
* FORM sub_initial
* Initialisierung: Variablen und interne Tabellen zurücksetzen
*----------------------------------------------------------------------*
FORM sub_initial.
CLEAR: gf_file.
REFRESH: gt_seltab, gt_seltab_255.
ENDFORM.
*----------------------------------------------------------------------*
* FORM get_filenames
* Baut den Dateinamen inkl. Pfad basierend auf Datentyp, Datum und
* System-ID zusammen.
* Schema: <Pfad>/CC_<Typ>_<TT-MM-JJJJ>_[INITIAL_]V2.txt
*----------------------------------------------------------------------*
FORM get_filenames USING pf_table TYPE tabname
CHANGING pf_file TYPE text255.
IF pf_file IS NOT INITIAL.
EXIT.
ENDIF.
CONCATENATE sy-datum+6(2) sy-datum+4(2) sy-datum(4)
INTO gf_file SEPARATED BY '-'.
CONCATENATE pf_table gf_file INTO pf_file SEPARATED BY '_'.
CONCATENATE 'CC' pf_file INTO pf_file SEPARATED BY '_'.
IF p_all = 'X'.
CONCATENATE pf_file 'INITIAL' INTO pf_file SEPARATED BY '_'.
ENDIF.
CONCATENATE pf_file 'V2' INTO pf_file SEPARATED BY '_'.
CONCATENATE pf_file '.txt' INTO pf_file.
CONDENSE pf_file.
CASE sy-sysid.
WHEN 'C01'. " ← System-ID DEV anpassen
CONCATENATE gc_dir_hed pf_file INTO pf_file.
WHEN 'Q01'. " ← System-ID QA anpassen
CONCATENATE gc_dir_heq pf_file INTO pf_file.
WHEN 'P01'. " ← System-ID PRD anpassen
CONCATENATE gc_dir_hep pf_file INTO pf_file.
WHEN OTHERS.
ENDCASE.
ENDFORM.
*----------------------------------------------------------------------*
* FORM sub_getscreendata
* Liest die aktuellen Selektionsparameter und instanziiert die
* Assist-Klasse.
*----------------------------------------------------------------------*
FORM sub_getscreendata.
CALL FUNCTION 'RS_REFRESH_FROM_SELECTOPTIONS'
EXPORTING
curr_report = sy-repid
TABLES
selection_table = gt_seltab
selection_table_255 = gt_seltab_255.
CREATE OBJECT go_bilendo
EXPORTING
it_seltab = gt_seltab_255.
ENDFORM.
*----------------------------------------------------------------------*
* FORM sub_processing
* Hauptverarbeitung: Iteriert über alle Buchungskreise und ruft
* je nach Selektion die Extraktion + Dateiexport auf.
*----------------------------------------------------------------------*
FORM sub_processing.
SELECT bukrs FROM t001 INTO CORRESPONDING FIELDS OF TABLE gt_t001
WHERE bukrs IN s_bukrs
AND rcomp <> ''.
LOOP AT gt_t001 INTO gs_t001.
go_bilendo->clear( ).
go_bilendo->set_bukrs( gs_t001-bukrs ).
" === Kundenstammdaten ===
IF p_kna1 = 'X'.
go_bilendo->get_kna1( ).
IF go_bilendo->at_kna1 IS INITIAL.
gf_msg = text-001.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ELSE.
WRITE:/ gf_msg.
go_bilendo->kna1_file_to_server(
IMPORTING ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR gf_msg.
CLEAR go_bilendo->at_kna1.
ENDIF.
ENDIF.
" === Alle Posten (BSEG komplett) ===
IF p_bseg = 'X'.
go_bilendo->get_bseg( ).
go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bseg ).
IF go_bilendo->at_bseg IS INITIAL.
gf_msg = text-002.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ELSE.
go_bilendo->bseg_file_to_server(
EXPORTING
it_bseg = go_bilendo->at_bseg
if_dataset = go_bilendo->af_dataset_bseg
IMPORTING
ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR gf_msg.
CLEAR go_bilendo->at_bseg.
ENDIF.
ENDIF.
" === Offene Posten (BSID) ===
IF p_bsid = 'X'.
go_bilendo->get_bsid( ).
go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsid ).
IF go_bilendo->at_bsid IS INITIAL.
gf_msg = text-003.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ELSE.
go_bilendo->bseg_file_to_server(
EXPORTING
it_bseg = go_bilendo->at_bsid
if_dataset = go_bilendo->af_dataset_bsid
IMPORTING
ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR gf_msg.
CLEAR go_bilendo->at_bsid.
ENDIF.
ENDIF.
" === Ausgeglichene Posten (BSAD) ===
IF p_bsad = 'X'.
go_bilendo->get_bsad( ).
go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsad ).
IF go_bilendo->at_bsad IS INITIAL.
gf_msg = text-004.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ELSE.
go_bilendo->bseg_file_to_server(
EXPORTING
it_bseg = go_bilendo->at_bsad
if_dataset = go_bilendo->af_dataset_bsad
IMPORTING
ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR gf_msg.
CLEAR go_bilendo->at_bsid. " Hinweis: im Original at_bsid statt at_bsad
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM.Textelemente
Der Report verwendet Textelemente für Meldungen und Blocktitel. Diese müssen im Report (SE38 → Textelemente) gepflegt werden:
| Text-ID | Verwendung | Vorschlag |
|---|---|---|
| text-001 | Meldung: keine Stammdaten für BUKRS | Keine Kundenstammdaten für Buchungskreis &1 |
| text-002 | Meldung: keine Belege (BSEG) für BUKRS | Keine Belege für Buchungskreis &1 |
| text-003 | Meldung: keine offenen Posten für BUKRS | Keine offenen Posten für Buchungskreis &1 |
| text-004 | Meldung: keine ausgeglichenen Posten für BUKRS | Keine ausgeglichenen Posten für Buchungskreis &1 |
| text-005 | Kommentar unter Selektionsbild | Bilendo SAP Extractor v2.1 – Dateien werden automatisch benannt |
| text-006 | Blocktitel: Kundenstamm | Kundenstammdaten |
| text-007 | Blocktitel: Bewegungsdaten | Bewegungsdaten |
| text-008 | Blocktitel: Lademodus | Lademodus |
Dateinamen-Generierung
Die Methode get_filenames baut den Dateinamen nach folgendem Schema:
<Pfad>/<Präfix>_<Typ>_<TT-MM-JJJJ>_[INITIAL_]V2.txt| Bestandteil | Wert | Quelle |
|---|---|---|
| Pfad | /usr/sap/P01/Bilendo_OUT/ | gc_dir_hep (je System) |
| Präfix | CC | Fest codiert |
| Typ | Customers, all, open, cleared | Parameter in PERFORM get_filenames |
| Datum | 01-04-2026 | sy-datum (Tagesdatum, Format TT-MM-JJJJ) |
| INITIAL | nur bei p_all = 'X' | Vollladen-Modus |
| Version | V2 | Fest codiert |
Beispiele:
CC_Customers_09-04-2026_V2.txt ← Stammdaten (Delta)
CC_open_09-04-2026_V2.txt ← Offene Posten (Delta)
CC_cleared_09-04-2026_V2.txt ← Ausgeglichene Posten (Delta)
CC_all_09-04-2026_INITIAL_V2.txt ← Alle Posten (Initial/Voll)Bekannte Hinweise
Bug im Original: In
sub_processing, Block ausgeglichene Posten, wird am Endego_bilendo->at_bsidstattgo_bilendo->at_bsadgeleert. Dies hat keine funktionale Auswirkung weil at_bsid an diesem Punkt bereits verarbeitet wurde, sollte aber bei einem Refactoring korrigiert werden.T001-Selektion: Die Bedingung
rcomp <> ''filtert auf Buchungskreise die einem Konzernunternehmen zugeordnet sind. Falls ein Buchungskreis kein RCOMP hat, wird er ignoriert – dies ist gewollt aber nicht immer offensichtlich.OPAMT: Das Feld OPAMT (offener Betrag für Innensaldoausgleich) ist in v2.1 nicht implementiert. Für eine Erweiterung → siehe 02 - DDIC Strukturen (Strukturerweiterung) und 03 - Assist-Klasse (Methodenerweiterung get_bsid/get_bsad).
Verbesserte Delta-Logik: Zwei-Stufen-Selektion
Problem der einfachen Delta-Selektion
Die in v2.1 implementierte Delta-Logik selektiert offene und ausgeglichene Posten primär über das Erfassungsdatum (CPUDT) oder Buchungsdatum (BUDAT) aus der BKPF. Bei einem typischen 7-Tage-Fenster entsteht folgendes Problem:
Tag 1: Beleg 100000001 wird gebucht (CPUDT = Tag 1)
→ Beleg steht in BSID (offen)
→ Delta-Selektion: CPUDT IN [Tag 1 - 7 ... Tag 1] → Treffer ✓
Tag 8: Beleg 100000001 wird ausgeglichen (AUGDT = Tag 8)
→ Beleg wandert von BSID nach BSAD
→ Delta-Selektion BSID: CPUDT IN [Tag 2 ... Tag 8] → kein Treffer ✗
(CPUDT = Tag 1, liegt außerhalb des Fensters)
→ Delta-Selektion BSAD mit CPUDT: ebenfalls kein Treffer ✗
→ Bilendo erfährt nicht, dass der Beleg ausgeglichen wurdeDas Ergebnis: Posten, deren Erfassungsdatum außerhalb des Delta-Fensters liegt und die danach ausgeglichen werden, werden von Bilendo nie als „ausgeglichen" erkannt. Die bestehende AUGDT-basierte Selektion in get_bsad adressiert dies teilweise, erfordert aber eine korrekte Variantenkonfiguration und deckt nicht alle Szenarien ab.
Lösungsansatz: Zwei-Stufen-Delta
Die verbesserte Delta-Logik trennt die Selektion in zwei Stufen:
Stufe 1 – Ausgleichsereignisse identifizieren (BSAD → AUGDT)
Selektiere aus BSAD alle Posten, deren Ausgleichsdatum (AUGDT) innerhalb des Delta-Fensters liegt. Dies liefert die Ausgleichsbelegnummern (AUGBL/AUGGJ), unabhängig vom ursprünglichen Erfassungsdatum.
Stufe 2 – Vollständige Beleggruppen nachladen (BSAD → AUGBL) Selektiere aus BSAD alle Posten, die zu den in Stufe 1 identifizierten Ausgleichsvorgängen gehören. Dies stellt sicher, dass Bilendo alle Belegpositionen eines Ausgleichsvorgangs erhält, nicht nur die kürzlich ausgeglichenen.
Ergänzend: BSID über BKPF Für offene Posten wird über BKPF ermittelt, welche Belege im Delta-Fenster erstellt oder geändert wurden. Anschließend werden die zugehörigen offenen Posten aus BSID selektiert.
flowchart LR
subgraph "Stufe 1"
BSAD1["BSAD\nAUGDT >= gestern"]
BSAD1 -->|"DISTINCT AUGBL, AUGGJ"| AUGBL["Ausgleichsbelege"]
end
subgraph "Stufe 2"
AUGBL -->|"FOR ALL ENTRIES"| BSAD2["BSAD\nAUGBL = Treffer"]
BSAD2 --> RESULT["at_bsad\n(vollständig)"]
end
subgraph "Ergänzend: BSID"
BKPF["BKPF\nCPUDT >= letzte 6h\nODER AEDAT >= letzte 6h"]
BKPF -->|"FOR ALL ENTRIES"| BSID["BSID\nBELNR = Treffer"]
BSID --> RESULT2["at_bsid\n(aktuell offen)"]
endVorteile gegenüber der einfachen Delta-Selektion
| Kriterium | Einfache Delta-Selektion (v2.1) | Zwei-Stufen-Selektion |
|---|---|---|
| Ausgleiche alter Belege | Werden übersehen wenn CPUDT außerhalb des Fensters | Werden über AUGDT zuverlässig erkannt |
| Selektionskriterium BSAD | CPUDT oder AUGDT (variantenabhängig) | Immer AUGDT → robust gegen Fehlkonfiguration |
| Vollständigkeit | Abhängig von korrekter Variantenpflege | Systemisch sichergestellt |
| Performance | BKPF JOIN auf großem Zeitfenster | Gezielte AUGDT-Selektion → kleinere Ergebnismenge |
| Empfohlene Frequenz | Täglich (mit 7-Tage-Overlap) | Alle 6 Stunden (mit 24h-Overlap) |
ABAP-Code: Methode GET_CLEARED_DELTA
Diese Methode ersetzt die BSAD-Selektion im Delta-Modus. Sie wird in die Klasse ZCL_FI_BILENDO_ASSIST_V2 aufgenommen.
Klassendefinition – Ergänzung:
"! Zwei-Stufen-Delta für ausgeglichene Posten
"! Stufe 1: AUGDT-basierte Selektion der Ausgleichsvorgänge
"! Stufe 2: FOR ALL ENTRIES für vollständige Beleggruppen
METHODS get_cleared_delta
IMPORTING
iv_hours TYPE i DEFAULT 24. " Delta-Fenster in StundenImplementierung:
METHOD get_cleared_delta.
*----------------------------------------------------------------------*
* Zwei-Stufen-Delta-Selektion für ausgeglichene Posten
*
* Hintergrund:
* Die einfache Delta-Selektion über CPUDT/BUDAT verpasst
* Ausgleichsereignisse an Belegen, deren Erfassungsdatum
* außerhalb des Selektionsfensters liegt.
*
* Stufe 1: Ermittle alle Ausgleichsvorgänge der letzten N Stunden
* über das Ausgleichsdatum (AUGDT) in BSAD.
* → Ergebnis: Liste von AUGBL/AUGGJ (Ausgleichsbelege)
*
* Stufe 2: Selektiere alle BSAD-Positionen, die zu diesen
* Ausgleichsvorgängen gehören (über AUGBL/AUGGJ).
* Ergänzend: Auch die Ausgleichsbelege selbst (über
* BELNR/GJAHR), falls diese als Originalbeleg in BSAD
* stehen (z. B. Zahlungsbelege).
*
* Parameter:
* IV_HOURS Größe des Delta-Fensters in Stunden (Default: 24)
* Bei 6-stündlichem Lauf: iv_hours = 24 für 4x Overlap
*----------------------------------------------------------------------*
TYPES: BEGIN OF ty_augbl,
bukrs TYPE bukrs,
augbl TYPE augbl,
auggj TYPE gjahr,
END OF ty_augbl.
DATA: lt_augbl TYPE TABLE OF ty_augbl,
lv_augdt_low TYPE sy-datum,
lv_days TYPE i.
" Delta-Fenster berechnen: Stunden → Tage (aufgerundet)
lv_days = ( iv_hours + 23 ) / 24. " ceil(hours/24)
lv_augdt_low = sy-datum - lv_days.
" === STUFE 1 ===
" Alle Ausgleichsvorgänge im Delta-Fenster identifizieren.
" AUGDT ist das SAP-Ausgleichsdatum – es wird beim Ausgleich gesetzt,
" unabhängig davon, wann der Originalbeleg gebucht wurde.
SELECT DISTINCT bukrs augbl auggj
FROM bsad
INTO TABLE lt_augbl
WHERE bukrs = af_bukrs
AND augdt >= lv_augdt_low
AND augbl <> space
AND umskz IN ('B', 'E', 'L', 'G', 'W', '5', '').
IF lt_augbl IS INITIAL.
" Keine Ausgleiche im Zeitfenster → at_bsad bleibt leer
RETURN.
ENDIF.
" === STUFE 2a ===
" Alle Positionen selektieren, die durch die identifizierten
" Ausgleichsbelege ausgeglichen wurden.
" Bedingung: AUGBL + AUGGJ matchen auf die Stufe-1-Treffer
SELECT bukrs kunnr umskz augdt augbl zuonr gjahr belnr buzei xblnr
blart auggj sgtxt budat bldat dmbtr waers wrbtr shkzg zterm
zfbdt cpudt gsber xref1 xref2 rstgr mansp manst madat zbd1t
zbd2t zbd3t zlsch maber kkber vbeln aufnr bschl hkont AS akont
FROM bsad
INTO CORRESPONDING FIELDS OF TABLE at_bsad
FOR ALL ENTRIES IN lt_augbl
WHERE bukrs = af_bukrs
AND auggj = lt_augbl-auggj
AND augbl = lt_augbl-augbl
AND umskz IN ('B', 'E', 'L', 'G', 'W', '5', '')
AND xcpdd = ''.
" === STUFE 2b ===
" Auch die Ausgleichsbelege selbst selektieren.
" Grund: Der Ausgleichsbeleg (z. B. ein Zahlungseingang) steht
" als eigenständiger Posten in BSAD. Seine BELNR entspricht
" dem AUGBL der ausgeglichenen Posten.
SELECT bukrs kunnr umskz augdt augbl zuonr gjahr belnr buzei xblnr
blart auggj sgtxt budat bldat dmbtr waers wrbtr shkzg zterm
zfbdt cpudt gsber xref1 xref2 rstgr mansp manst madat zbd1t
zbd2t zbd3t zlsch maber kkber vbeln aufnr bschl hkont AS akont
FROM bsad
APPENDING CORRESPONDING FIELDS OF TABLE at_bsad
FOR ALL ENTRIES IN lt_augbl
WHERE bukrs = af_bukrs
AND gjahr = lt_augbl-auggj
AND belnr = lt_augbl-augbl
AND umskz IN ('B', 'E', 'L', 'G', 'W', '5', '')
AND xcpdd = ''.
" Duplikate entfernen (Stufe 2a und 2b können überlappen)
SORT at_bsad.
DELETE ADJACENT DUPLICATES FROM at_bsad COMPARING ALL FIELDS.
ENDMETHOD.ABAP-Code: Methode GET_OPEN_DELTA
Ergänzende Methode für offene Posten. Selektiert über BKPF (Erfassungs-/Änderungsdatum) und zieht dann die zugehörigen offenen Posten aus BSID.
Klassendefinition – Ergänzung:
"! Zwei-Stufen-Delta für offene Posten
"! Stufe 1: BKPF-basierte Ermittlung neuer/geänderter Belege
"! Stufe 2: FOR ALL ENTRIES gegen BSID
METHODS get_open_delta
IMPORTING
iv_hours TYPE i DEFAULT 6. " Delta-Fenster in StundenImplementierung:
METHOD get_open_delta.
*----------------------------------------------------------------------*
* Zwei-Stufen-Delta-Selektion für offene Posten
*
* Hintergrund:
* BSID enthält nur aktuell offene Posten. Neue Buchungen oder
* Änderungen an bestehenden offenen Posten werden über BKPF
* (CPUDT/CPUTM/AEDAT) identifiziert.
*
* Stufe 1: Ermittle aus BKPF alle Belege, die im Delta-Fenster
* erstellt (CPUDT/CPUTM) oder geändert (AEDAT) wurden.
*
* Stufe 2: Selektiere aus BSID alle offenen Posten zu diesen
* Belegnummern. Nur Posten die noch in BSID stehen
* (also noch offen sind) werden zurückgegeben.
*
* Parameter:
* IV_HOURS Größe des Delta-Fensters in Stunden (Default: 6)
*----------------------------------------------------------------------*
DATA: lt_bkpf TYPE TABLE OF ty_bkpf,
lv_cpudt_low TYPE sy-datum,
lv_cputm_low TYPE sy-uzeit,
lv_seconds TYPE i.
" Delta-Fenster berechnen
lv_seconds = iv_hours * 3600.
lv_cputm_low = sy-uzeit - lv_seconds.
lv_cpudt_low = sy-datum.
" Unterlauf prüfen: wenn berechnete Uhrzeit > aktuelle Uhrzeit,
" hat ein Tageswechsel stattgefunden
IF lv_cputm_low > sy-uzeit.
lv_cpudt_low = sy-datum - 1.
ENDIF.
" === STUFE 1 ===
" BKPF: Alle Belegköpfe im Delta-Fenster
" Kriterien:
" - CPUDT/CPUTM: Erfassungszeitpunkt des Belegs
" - AEDAT: Änderungsdatum (fängt nachträgliche Änderungen)
SELECT bukrs belnr gjahr cpudt cputm aedat
FROM bkpf
INTO TABLE lt_bkpf
WHERE bukrs = af_bukrs
AND ( ( cpudt = lv_cpudt_low AND cputm >= lv_cputm_low )
OR ( cpudt > lv_cpudt_low )
OR ( aedat >= lv_cpudt_low ) ).
IF lt_bkpf IS INITIAL.
RETURN.
ENDIF.
" === STUFE 2 ===
" BSID: Offene Posten zu den identifizierten Belegen.
" Nur Posten die noch in BSID stehen werden selektiert –
" bereits ausgeglichene Posten sind in BSAD und werden
" von GET_CLEARED_DELTA abgedeckt.
SELECT i~bukrs
i~kkber
i~kunnr
i~gjahr
i~belnr
i~buzei
i~xblnr
i~zuonr
i~blart
i~sgtxt
i~budat
i~bldat
i~dmbtr
i~wrbtr
i~waers
i~shkzg
i~zfbdt
i~cpudt
i~gsber
i~xref1
i~xref2
i~rstgr
i~aufnr
i~mansp
i~manst
i~maber
i~madat
i~zterm
i~augbl
i~auggj
i~augdt
i~zbd1t
i~zbd2t
i~zbd3t
i~zlsch
i~vbeln
i~umskz
i~bschl
i~hkont AS akont
FROM bsid AS i
INTO CORRESPONDING FIELDS OF TABLE at_bsid
FOR ALL ENTRIES IN lt_bkpf
WHERE i~bukrs = af_bukrs
AND i~gjahr = lt_bkpf-gjahr
AND i~belnr = lt_bkpf-belnr
AND i~umskz IN ('B', 'E', 'L', 'G', 'W', '5', '')
AND i~xcpdd = ''.
SORT at_bsid BY bukrs kunnr umskz augdt augbl zuonr gjahr belnr buzei.
DELETE ADJACENT DUPLICATES FROM at_bsid COMPARING ALL FIELDS.
ENDMETHOD.Anpassung am Extractor Report (sub_processing)
Um die Zwei-Stufen-Methoden im Report zu nutzen, wird sub_processing wie folgt ergänzt. Der bestehende Code bleibt für den Vollladen-Modus (p_all = 'X') erhalten; im Delta-Modus werden die neuen Methoden aufgerufen:
*----------------------------------------------------------------------*
* FORM sub_processing (erweitert für Zwei-Stufen-Delta)
*----------------------------------------------------------------------*
FORM sub_processing.
SELECT bukrs FROM t001 INTO CORRESPONDING FIELDS OF TABLE gt_t001
WHERE bukrs IN s_bukrs
AND rcomp <> ''.
LOOP AT gt_t001 INTO gs_t001.
go_bilendo->clear( ).
go_bilendo->set_bukrs( gs_t001-bukrs ).
" === Kundenstammdaten ===
IF p_kna1 = 'X'.
go_bilendo->get_kna1( ).
IF go_bilendo->at_kna1 IS NOT INITIAL.
go_bilendo->kna1_file_to_server(
IMPORTING ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR: gf_msg, go_bilendo->at_kna1.
ELSE.
gf_msg = text-001.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ENDIF.
ENDIF.
" === Offene Posten (BSID) ===
IF p_bsid = 'X'.
IF p_delta = 'X'.
" Zwei-Stufen-Delta: über BKPF → BSID
go_bilendo->get_open_delta( iv_hours = 6 ).
ELSE.
" Vollladen: alle offenen Posten
go_bilendo->get_bsid( ).
ENDIF.
go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsid ).
IF go_bilendo->at_bsid IS NOT INITIAL.
go_bilendo->bseg_file_to_server(
EXPORTING
it_bseg = go_bilendo->at_bsid
if_dataset = go_bilendo->af_dataset_bsid
IMPORTING
ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR: gf_msg, go_bilendo->at_bsid.
ELSE.
gf_msg = text-003.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ENDIF.
ENDIF.
" === Ausgeglichene Posten (BSAD) ===
IF p_bsad = 'X'.
IF p_delta = 'X'.
" Zwei-Stufen-Delta: AUGDT → AUGBL → vollständige Beleggruppen
go_bilendo->get_cleared_delta( iv_hours = 24 ).
ELSE.
" Vollladen: alle ausgeglichenen Posten
go_bilendo->get_bsad( ).
ENDIF.
go_bilendo->get_additional( CHANGING ct_bseg = go_bilendo->at_bsad ).
IF go_bilendo->at_bsad IS NOT INITIAL.
go_bilendo->bseg_file_to_server(
EXPORTING
it_bseg = go_bilendo->at_bsad
if_dataset = go_bilendo->af_dataset_bsad
IMPORTING
ef_msg = gf_msg ).
WRITE:/ gf_msg.
CLEAR: gf_msg, go_bilendo->at_bsad.
ELSE.
gf_msg = text-004.
REPLACE '&1' IN gf_msg WITH gs_t001-bukrs.
WRITE:/ gf_msg.
CLEAR gf_msg.
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM.Job-Planung für Zwei-Stufen-Delta
Bei Verwendung der Zwei-Stufen-Selektion wird der Export-Job alle 6 Stunden statt täglich eingeplant. Die Selektionsvariante benötigt keine dynamischen Datumsfelder mehr – die Delta-Fenster werden programmatisch in den Methoden berechnet.
Variante: BILENDO_DELTA_6H
| Parameter | Wert | Anmerkung |
|---|---|---|
| P_KNA1 | X | Kundenstamm (einmal täglich reicht, optional) |
| P_BSID | X | Offene Posten |
| P_BSAD | X | Ausgeglichene Posten |
| P_DELTA | X | Delta-Modus (aktiviert Zwei-Stufen-Methoden) |
| S_BUKRS | Alle relevanten BUKRS | Wie gehabt |
| S_CPUDT | leer | Wird von get_open_delta intern berechnet |
| S_AUGDT | leer | Wird von get_cleared_delta intern berechnet |
SM36-Job:
Job: BILENDO_EXPORT_6H
Step 1: ZFI_BILENDO_EXPORT_V2 / Variante: BILENDO_DELTA_6H
Startbedingung: Periodisch, alle 6 Stunden
→ Startzeit: 00:00, 06:00, 12:00, 18:00important: > Die Zwei-Stufen-Methoden (
get_cleared_delta,get_open_delta) verwenden ihre eigenen Zeitfenster-Berechnungen. Die SelektionsvariablenS_CPUDTundS_AUGDTwerden im Delta-Modus ignoriert, wenn die neuen Methoden verwendet werden. Die alten Methoden (get_bsid,get_bsad) bleiben für den Vollladen-Modus und für Rückwärtskompatibilität erhalten.
Für Details zur Job-Einplanung → 07 - Varianten & Job-Planung.