IDoc-Monitor WLF_IDOC um eigene Funktionen ergänzen
Der neue (na ja - so neu ist er auch nicht mehr) IDoc-Monitor bietet gegenüber der guten alten WE02 bzw. WE09 doch einige Vorteile, insbesondere in punkto Übersichtlichkeit und Folgebeleg-Absprünge. Was mich jedoch nervt ist, dass es z.B. keinen Absprung in den POS-Monitor (WPER) für POS-Nachrichtentypen gibt. Ok - ist sicherlich auch eine etwas extravagante Anforderung, aber gut dass es da BAdIs gibt (Details s. Hinweis 1897880 - BAdIs für WLF_IDOC).
Mithilfe des BAdIs WLF_REPORT_PROCESS_BD können eigene OK-Codes hinzugefügt und ausgewertet werden. Das BAdI beherbergt die Methoden...
ADJUST_STATUS
Hier kann ein eigener Oberflächenstatus gesetzt werden. Hierzu habe ich mithilfe der SE41 den Status STANDARD des Reports RWLFIDOC_NEW in einen (leeren) Z-Report kopiert und eine Drucktaste/Funktionscode (ZWPER) hinzugefügt.
In der BAdI-Implementierung setze ich lediglich über den CHANGING-Parameter CV_PROGRAM mein leeres Z-Programm, so dass der namensgleiche Status mit dem neuen FCODE gezogen wird.
method IF_WLF_REPORT_PROCESS_BD~ADJUST_STATUS.
cv_program = 'ZWLF_IDOC'.
endmethod. HANDLE_FCODE
Hier wird dann auf die (eigenen) Funktionscodes reagiert und (in diesem Fall) in die WPER abgesprungen. In der Struktur IS_DOC_LIST_OUT stehen die Daten des aktuell selektierten bzw. markierten IDocs zur Verfügung. Über den CHANGING-Parameter CV_FCODE_PROCESSED wird dem System mitgeteilt, dass der (eigene) Funktionscode prozessiert wurde.
METHOD if_wlf_report_process_bd~handle_fcode.
CASE iv_okcode.
WHEN 'ZWPER'.
cv_fcode_processed = abap_true.
CHECK is_idoc_list_out-docnum IS NOT INITIAL.
CHECK is_idoc_list_out-mestyp(3) = 'WPU'. "nur für WPUxxx-IDocs
SUBMIT sapmwper AND RETURN
WITH p_dat_b = is_idoc_list_out-credat
WITH p_dat_v = is_idoc_list_out-credat
WITH s_docnum = is_idoc_list_out-docnum.
ENDCASE.
ENDMETHOD. Dies ist natürlich nur ein Beispiel für eine sinnvolle Funktionserweiterung in Retail-Systemen. Euch fällt sicherlich auch noch was besseres ein...
Der o.g. BAdI ist übrigens nur ein Teil des Erweiterungsframeworks, welches in diesem Kontext zur Verfügung steht. Der Erweiterungsspot WLF_IDOC_PROCESSING umfasst weitere BAdIs, z.B. WLF_ENH_IDOC_DATA_BADI, mit dem der IDoc-Liste zusätzliche Felder hinzugefügt werden können.
Mahnliste RFMAHN21 erweitern
Im Hinweis 590421 ist eine Möglichkeit beschrieben, die Mahnliste RFMAHN21 um eigene Felder zu erweitern. Bei der im Hinweis genannten Lösung handelt es sich jedoch um eine Modifikation, die vermutlich nicht in jedem System verbaut werden kann/soll. Alternativ lässt sich das Ganze auch mit einem impliziten Enhancement bewerkstelligen, was dann im technischen Sinne eben keine Modifikation mehr darstellt...
Hierzu wird einfach an das Ende der Routine APPEND_MHND_EXT2 im RFMAHN21 ein implizites Enhancement eingefügt, welches dann den Beispielcode aus dem o.g. Hinweis beherbergt (in leicht abgewandelter Form).
Siehe auch hier
Bestelldatenvorschlag bei bestellbezogener Rechnungsprüfung
Bei bestellbezogener Rechnungsprüfung ist das Standardverhalten im Rahmen der logistischen Rechnungsprüfung im Dialog (Transaktionen MIRO bzw. MIR7) so, dass bei Eingabe der Bestellinformationen die Positionen zwar vorgeblendet werden, jedoch die Eingabefelder Menge und Wert leer bleiben.
D.h. ohne weiteres Zutun müssten die Werte und Mengen aus der Rechnung manuell in die Felder der Tabelle eingetragen werden. Vielfach sind jedoch zwischen Rechnung und Bestellung nur wenig Abweichungen, so dass es wünschenswert wäre, die Daten aus der Bestellung wenigstens als Vorschlagswerte einzufüllen, um so die Rechnungserfassung zu erleichtern.
Über den Erweiterungsspot MRM_PROPOSAL_DETERMINE kann auf das Systemverhalten Einfluss genommen werden.
Hierzu kann eine geeignete Implementierung zur Methode AMNT_QUANT_PROPOSAL_DETERMINE angelegt werden, die bspw. im Fall von bestellbezogener Rechnungsprüfung die Mengen und Werte aus den Bestellpositionen nachliest und als Vorschlagswerte ins Tableau einfüllt.
Beispielcoding:
METHOD if_ex_mrm_proposal_determine~amnt_quant_proposal_determine.
DATA: l_amount TYPE ekpo-netwr,
l_quantity type ekpo-menge,
l_webre type ekpo-webre.
SELECT SINGLE netwr menge webre FROM ekpo
INTO (l_amount, l_quantity, l_webre)
WHERE ebeln = i_drseg-ebeln
AND ebelp = i_drseg-ebelp.
CHECK sy-subrc = 0.
CHECK l_webre IS INITIAL. "nur bei bestellbezogener RePrü !!!!
e_propose_item-amount = l_amount.
e_propose_item-quantity = l_quantity.
e_xchange = abap_true.
ENDMETHOD. "IF_EX_MRM_PROPOSAL_DETERMINE~AMNT_QUANT_PROPOSAL_DETERMINE
Im Ergebnis werden im Rahmen der Rechnungserfassung die Informationen aus der Bestellposition als Vorschlagswerte eingefüllt. Dies erfolgt genau dann einmal, wenn die Bestellpositionen vom Anwender zugeordnet werden. Die Vorschlagswerte sind natürlich vom Rechnungsprüfer überschreibbar. Das BadI wird nur dann erneut durchlaufen, wenn eine neue Bestellzuordnung getroffen wurde.
IDoc ACC_DOCUMENT - Beispiele
Will man FI-Belege aus externen Quellen ins System buchen, bietet sich die Verwendung von IDocs des Typs ACC_DOCUMENT an. In den nachfolgenden Abschnitten wird die ordnungsgemäße Befüllung des IDoc-Inhalts beschrieben.
Eigenschaften der IDocs des Typ ACC_DOCUMENT
Nachrichtentyp: ACC_DOCUMENT
Basistyp: ACC_DOCUMENT04
Struktur
Die relevanten Segmente des IDocs sind:
- E1BPACHE09 : Kopfzeile
Status : Optional , min. Anzahl : 1 , max. Anzahl : 1
- E1BPACGL09 : Sachkontenzeile
Status : Optional , min. Anzahl : 1 , max. Anzahl : 999999999
- E1BPACAR09 : Debitorzeile
Status : Optional , min. Anzahl : 1 , max. Anzahl : 999999999
- E1BPACAP09 : Kreditorzeile
Status : Optional , min. Anzahl : 1 , max. Anzahl : 999999999
- E1BPACTX09 : Steuerzeile
Status : Optional , min. Anzahl : 1 , max. Anzahl : 999999999
- E1BPACCR09 : Währungspositionen
Status : Optional , min. Anzahl : 1 , max. Anzahl : 999999999
Der generelle Aufbau ist wie folgt: Ein valides IDoc besteht aus genau einem Kopfsegment E1BPACHE09 und mindestens 2 Positionen. Die Positionen setzen sich jeweils aus einem Segment der Typen E1BPACGL09, E1BPACAP09 oder E1BPACAR09 mit jeweils einem korrespondierenden Betragssegment E1BPACCR09 zusammen. Die Verknüpfung zwischen den Belegpositionen und den Betragssegmenten erfolgt über das Feld ITEMNO_ACC (Positionsnummer).
Minimal-Beleg:
Belegkopf E1BPACHE09 |
Position 000001 Sachkontenzeile E1BPACGL09 oder Kreditorenzeile E1BPACAP09 oder Debitorenzeile E1BPACAR09 |
Position 000002 Sachkontenzeile E1BPACGL09 oder Kreditorenzeile E1BPACAP09 oder Debitorenzeile E1BPACAR09 |
Position 000001 Betragssegment E1BPACCR09 |
Position 000002 Betragssegment E1BPACCR09 |
Die Positionsnummern können im Prinzip beliebig vergeben werden, es empfiehlt sich jedoch, eine aufsteigende nummerische Positionsnummernvergabe vorzusehen.
Befüllung
Der oben beschriebene Minimalbeleg benötigt mindestens folgende Feldversorgungen:
E1BPACHE09
BUS_ACT RFBU (Vorgang fix)
USERNAME USERXYZ
HEADER_TXT KOPFTEXT (Belegkopftext, optional, sofern Belegart keine Eingabe erfordert)
COMP_CODE 1000 (Buchungskreis)
DOC_DATE 20150227 (Belegdatum)
PSTNG_DATE 20150227 (Buchungsdatum)
DOC_TYPE SA (Belegart)
REF_DOC_NO REFERENZ-NR (Referenznummer, optional, sofern Belegart keine Eingabe erfordert)
E1BPACGL09 (1. Position, Sachkontenposition)
ITEMNO_ACC 000010 (Positionsnummer)
GL_ACCOUNT 0000160000 (Sachkonto)
ITEM_TEXT BUCHUNGSTEXT (optional)
ALLOC_NMBR ZUORDNUNG (optional, ansonsten wird Zuordnung systemseitig gemäß Einstellung im Sachkontenstamm befüllt)
E1BPACGL09 (2. Position, Sachkontenposition)
ITEMNO_ACC 000020 (Positionsnummer)
GL_ACCOUNT 0000151000 (Sachkonto)
ITEM_TEXT BUCHUNGSTEXT (optional)
ALLOC_NMBR ZUORDNUNG (optional, ansonsten wird Zuordnung systemseitig gemäß Einstellung im Sachkontenstamm befüllt)
E1BPACCR09 (zu Position 1)
ITEMNO_ACC 000010
CURRENCY EUR (Belegwährung)
AMT_DOCCUR 10.00 (Betrag in Belegwährung)
E1BPACCR09 (zu Position 2)
ITEMNO_ACC 000020
CURRENCY EUR
AMT_DOCCUR 10.00-
(Achtung: Soll und Haben wird durch positiven bzw. negatives Vorzeichen unterschieden, - = Haben, + = Soll)
Besonderheit bei Buchung mit Umsatzsteuer
Im Gegensatz zum Batch-Input-Verfahren ist es mit dem Nachrichtentyp ACC_DOCUMENT (bzw. im Endeffekt mit dem dahinterliegenden BAPI_ACC_DOCUMENT_POST) nicht möglich, den Steueranteil einer Buchung vom System generieren zu lassen. D.h., die Steuerinformationen müssen dem IDoc auf folgende Weise mitgegeben werden:
Bei der Position, die die Steuer beinhaltet (i.d.R. die Sachkontenposition) wird der Betrag netto mitgegeben. Zusätzlich wird eine Steuerzeile des Segmenttyps E1BPACTX09 nebst Betragssegment (E1BPACCR09) mit folgenden Informationen benötigt:
E1BPACTX09
ITEMNO_ACC 000030
TAX_CODE V1 (Steuerkennzeichen)
E1BPACCR09
ITEMNO_ACC 000030
CURRENCY EUR
AMT_DOCCUR 1.60 (Steuerbetrag)
AMT_BASE 8.40 (Steuerbasis)
Beispiel:
Kreditorische Buchung
per Stromkosten 632500 8,40,-- an Kreditor 100003 10,--
Vorsteuer (V1) 1,60,--
Belegkopf E1BPACHE09:
BUS_ACT: RFBU
USERNAME: USERXYZ
HEADER_TXT: KOPFTEXT
COMP_CODE: 1000
DOC_DATE: 20150227
PSTNG_DATE: 20150227
DOC_TYPE: KR
REF_DOC_NO: 378455676
Kreditorenposition E1BPACAP09:
ITEMNO_ACC 000010
VENDOR_NO 0000100003 (Kreditorennummer)
Betragsposition zur Kreditorenposition E1BPACCR09
ITEMNO_ACC 000010
CURRENCY EUR
AMT_DOCCUR 10-
Sachkontenposition E1BPACGL09
ITEMNO_ACC 000020
GL_ACCOUNT 0000632500
ITEM_TEXT TESTBUCHUNG MIT STEUER
TAX_CODE V1 (Steuerkennzeichen!)
COSTCENTER 0000001000 (Kostenstelle, Konto 632500 ist Kostenart!)
Betragsposition zur Sachkontenposition E1BPACCR09
ITEMNO_ACC 000020
CURRENCY EUR
AMT_DOCCUR 8.40 (netto!)
Steuerzeile E1BPACTX09
ITEMNO_ACC 000030
TAX_CODE V1
Betragsposition zur Steuerzeile E1BPACCR09
ITEMNO_ACC 000030
CURRENCY EUR
AMT_DOCCUR 1.60 (Steuerbetrag)
AMT_BASE 8.40 (Steuerbasis)
Gegenkonto - das unbekannte Wesen...
Relevante SAP-Hinweise:
- 112312 - Einzelposten: Anzeige von Gegenkontoinformationen
- 1034354 - FAGLL03: Anzeige von Gegenkontoinformationen
- 1504612 - Einzelposten: Gegenkontoinformationen(BADI FI_ITEMS_CH_DATA)
Grundlagen
Öfter werde ich von Kunden oder auch Kollegen gefragt, wie denn die Gegenkontoinformationen in den Einzelpostenlisten (FBLxN, FAGLL03 usw.) ermittelt werden und wie man dies ggf. nachvollziehen oder gar beeinflussen kann:
Sofern die Hinweise 112312 bzw. 1034354/1504612 eingebaut wurden, lassen sich in den einschlägigen Einzelpostenanzeigen Gegenkontoinformationen einblenden, bestehend aus Gegenkontoart (S = Sachkonto, K = Kreditor, D = Debitor) und der Nummer des Gegenkontos.
Bei zweizeiligen Belegen ist die Auswahl des Gegenkontos ja eindeutig, d.h. bei einer Buchung
Aufwand 100,-- an Kreditor 100,--
ist die Gegenbuchung natürlich die jeweils andere Belegposition.
Bei drei- und mehrzeiligen Belegen muss ggf. eine Auswahl des Gegenkontos (nach Signifikanz) erfolgen:
Aufwand1 100,--
Aufwand2 200,--
Aufwand3 300,--
Vorsteuer 60,-- an Kreditor 660,--
Für die Ermittlung des Gegenkontos steht in der SAP Standardauslieferung der Funktionsbaustein GET_GKONT zur Verfügung. In diesem sind drei verschiedene Verfahren zur Bestimmung des signifikanten Gegenkontos implementiert - die Auswahl des Verfahrens erfolgt durch den Import-Parameter GKNKZ.
GKNKZ | Beschreibung | Ermitteltes Gegenkonto im o.g. Beispielbeleg (aus Sicht des kreditorischen Postens) |
1 | Es wird nur dann ein Gegenkonto zurückgeliefert, wenn es eindeutig ermittelt werden kann. Automatisch erzeugte Belegzeilen (wie bspw. Steuerzeilen) werden dabei ignoriert. | ./. |
2 | Das betragsmäßig höchste Gegenkonto ohne Berücksichtigung automatisch generierter Belegzeilen wird zurückgeliefert. | Aufwand3 |
3 | Das betragsmäßig höchste Gegenkonto mit Berücksichtigung automatisch generierter Belegzeilen wird zurückgeliefert. | Aufwand3 |
Werden zur Gegenkontoermittlung die weiter oben genannten Hinweise ohne Abwandlung implementiert, greift das Verfahren 3.
Erweiterung der bestehenden Verfahren
In vielen Fällen reicht die oben genannte Logik zur Gegenkontoermittlung aus. Im Einzelfall kann jedoch die Anforderung bestehen, den oben beschrieben Verfahren eigene, ausgefeiltere Methoden hinzuzufügen. Hierzu kann dann der Funktionsbaustein GET_GKONT in den Kundennamensraum kopiert (z.B. als Z_GET_GKONT) und anstelle des Standard-Bausteins an den entsprechenden Coding-Stellen in den Hinweisen 112312 bzw. 1034354 und 1504612 gerufen werden. Hierzu sind natürlich gewisse ABAP-Kenntnisse nötig.
Eine mögliche Anforderung könnte z.B. sein, dass als Gegenkonto von Sachkontenpositionen Kontokorrentpositionen grundsätzlich Vorrang haben sollen, auch wenn sie betragsmäßig kleiner sind als andersartige Gegenpositionen.
Beispiel:
Aufwand1 100,--
Aufwand2 200,--
Aufwand3 300,-- an Kreditor 220,--
Vorsteuer 60,-- Kasse 440,--
Die Standard-Gegenkontoermittlung würde bei Abfrage des Gegenkontos aus Sicht eines der Aufwandskonten das Kassenkonto zurückliefern, weil es betragsmäßig signifikanter ist als die kreditorische Gegenposition. Genau hier soll aber ein „Override“ eingebaut werden, dass die Kontokorrentposition trotzdem Vorrang erhält. Das Verfahren erhält in unserem Beispiel die Kennzeichnung ‚4‘.
Hierzu passen wir die Form-Routine GKONT_ERMITTELN in unserer kundeneigenen Funktionsgruppe geeignet an:
…
*---- NEUES VERFAHREN 4 (wie 3, aber Vorfahrt für Kontokorrente)
WHEN '4'.
IF BSEG-SHKZG = 'S'.
* nur dann neu setzen, wenn Betrag höher ODER ein Kontokorrent daherkommt
* UND nicht schon bereits ein Kontokorrent als Gegenkonto gesetzt ist
IF BSEG-DMBTR > GKSUM_S OR BSEG-KOART CA 'DK' AND KOART_S CN 'DK'.
…
(Haben-Seite analog)
Das Beispielcoding aus den weiter oben genannten Hinweisen ist dann entsprechend anzupassen.
Beispiel-Coding aus Hinweis 1504612:
DATA: wa_items TYPE rfposxext.
LOOP AT ct_items INTO wa_items.
CALL FUNCTION 'Z_GET_GKONT'
EXPORTING
belnr = wa_items-belnr
bukrs = wa_items-bukrs
buzei = wa_items-buzei
gjahr = wa_items-gjahr
gknkz = '4'
IMPORTING
gkont = wa_items-gkont
koart = wa_items-gkart
EXCEPTIONS
belnr_not_found = 1
buzei_not_found = 2
gknkz_not_found = 3
OTHERS = 4.
IF sy-subrc = 0.
MODIFY ct_items FROM wa_items.
ENDIF.
ENDLOOP.Eine immer wiederkehrende Anforderung in dem Themenkreis „Gegenkonto“ ist, dass zusätzlich zur Art und Nummer des Gegenkontos auch die entsprechende Bezeichnung anzeigbar gemacht werden soll. Hierzu lässt sich der Feldvorrat der Einzelpostenlisten um das Feld „Bez. Gegenkonto“ erweitern. Details dazu siehe hier, Abschnitt "Hinzufügen eigener Felder".
Es ist nun ein leichtes, nach erfolgreicher Gegenkontoermittlung anhand der Kontoart und der Nummer aus den entsprechenden Stammsatztabellen die Bezeichnung zu lesen und bereitzustellen.
Das obenstehende Beispielcoding kann dazu bspw. wie folgt erweitert werden:
…
CALL FUNCTION 'Z_GET_GKONT'
EXPORTING
belnr = wa_items-belnr
bukrs = wa_items-bukrs
buzei = wa_items-buzei
gjahr = wa_items-gjahr
gknkz = '4'
IMPORTING
gkont = wa_items-gkont
koart = wa_items-gkart
EXCEPTIONS
belnr_not_found = 1
buzei_not_found = 2
gknkz_not_found = 3
OTHERS = 4.
CASE wa_items_gkart. "das neue Feld heisse zzgkbez.
WHEN ‚S‘.
SELECT SINGLE txt50 INTO wa_items-zzgkbez FROM SKAT
WHERE KTOPL = <Kontenplan>
AND SAKNR = wa_items-gkont
AND SPRAS = sy-langu.
WHEN ‘K’.
SELECT SINGLE name1 INTO wa_items-zzgkbez FROM LFA1
WHERE LIFNR = wa_items-gkont.
WHEN ‘D’.
SELECT SINGLE name1 INTO wa_items-zzgkbez FROM KNA1
WHERE KUNNR = wa_items-gkont.
ENDCASE.
…
Im S/4 werden die Gegenkontoinformationen automatisch im Zuge der Buchung in die entsprechenden Felder der ACDOCA abgefüllt, so dass eine Anreicherung der Gegenkontoinformationen wie oben beschrieben nicht nötig ist. Hierzu wird im Customizing unter Finanzwesen - Hauptbuchhaltung - Informationssystem - Gegenkontoermittlungsart definieren die gewünschte Gegenkontoermittlung aktiviert (1, 2 oder 3, s.o.)
In den neuen Einzelpostenbrowsern
| FBL1H | Kreditoreneinzelposten |
| FBL5H | Debitoreneinzelposten |
| FAGLL03H | Sachkonteneinzelposten |
sind im Feldvorrat zudem bereits zahlreiche Texte u.a. zu Stammdatenobjekten verfügbar, z.B. die Bezeichnung des Gegenkontos, Kostenstellentexte und so weiter.
ALE Verteilung von CO Innenaufträgen mit Z-Feldern
Die Verteilung von CO Innenaufträgen per ALE mithilfe des Nachrichtentyps INTERNAL_ORDER funktioniert im Prinzip problemlos und ist auch schnell konfiguriert. Komplizierter wird's da schon, wenn Kundenerweiterungen in Form von Z-Feldern im Spiel sind. Mein Kollege Markus Läller hat sich dieser Problematik im Rahmen eines Kundenprojektes annehmen müssen und hat seine Erkenntnisse dankenswerterweise in Form einer Schritt-für-Schritt-Anleitung aufgeschrieben. Das komplette Dokument findet ihr hier:
Nach dem Studium des o.g. Dokuments sagt sich der ein oder andere vielleicht: "hmm - möglicherweise doch keine gute Idee, Z-Felder in verteilten Systemen zu verwenden...".
Muss vielleicht auch nicht sein. Im Auftragsstammsatz (Tab. AUFK) gibt es diverse vordefinierte Userfelder verschiedener Datentypen, die kundenspezifische Informationen beherbergen können:
- USER0 CHAR 20
- USER1 CHAR 20
- USER2 CHAR 20
- USER3 CHAR 20
- USER4 CURR 11 (Betrag)
- USER5 DATS 8
- USER6 CHAR 15
- USER7 DATS 8
- USER8 DATS 8
- USER9 CHAR 1 (Ankreuzfeld)
Die Felder sind in der SAP-Auslieferung schon mit Bezeichnungen versehen (z,B. USER0 = 'Antragsteller'), die auf den ersten Blick den Eindruck erwecken, dass es sich um Standard-Felder mit fester interner Verwendung handelt, ist aber nicht so. Details hierzu finden sich im Customizing unter Controlling - Innenaufträge - Auftragsstammdaten - Bildschirmgestaltung - Individuelle Stammdatenfelder ändern.
Anders als in der o.g. Customizing-Doku beschrieben, würde ich in verteilten Systemen davon abraten, den User-Feldern eigene/abweichende Datenelemente zuzuordnen, da diese sonst von denen in den korrespondierenden IDoc-Strukturen abweichen. Natürlich könnte man auch die anpassen, aber ob das dann noch alles kompatibel ist...? Am Ende muss man sich dann womöglich doch durch die oben verlinkte Anleitung kämpfen.
Einfacher hat man es da natürlich, wenn man mit den oben aufgelisteten Feldern/Datentypen auskommen kann. Die Bezeichnungen lassen sich modifikationsfrei mithilfe der "globalen Erweiterungen" kundenspezifisch anpassen (Transaktion CMOD, Menü: Springen - Glob. Erweiterungen - Schlüsselworte - Ändern...)
Um bspw. die Bezeichnung zum Feld USER0 zu ändern, wählt man das zugehörige Datenelement AUFUSER0 aus und ändert mithilfe der vorgenannten Funktion die Bezeichnung "Antragsteller" auf einen eigenen Wert ab.
Diese Felder werden in der Standard-ALE-Verteilung mit INTERNAL_ORDER ohne weiteres Zutun bereits berücksichtigt.
Umrechnungsdatum beeinflussen
Danke an Marek aus dem FICO-Forum.de, für's Erinnern an diese (manchmal) nützliche Funktion.
Ohne weiteres Zutun wird das Umrechnungsdatum im FI-Beleg aus dem Buchungsdatum abgeleitet, d.h. es wird der zum Buchungsdatum gültige Umrechnungskurs aus der TCURR verwendet. Möchte man dies (fallweise) nicht, kann dieses Systemverhalten mithilfe des BadIs FI_TRANS_DATE_DERIVE beeinflusst werden.
Das BadI ist filterabhängig und zwar vom Land (des Buchungskreises). Als Import-Parameter der Methode DERIVE_WWERT steht neben Buchungs- und Belegdatum, die Belegart zur Verfügung. Die Rückgabe des gewünschten Umrechnungsdatums erfolgt im Export-Parameter E_WWERT.
Codingbeispiel BadI-Implementierung:
METHOD if_ex_fi_trans_date_derive~derive_wwert.
* Bei Belegart xy...
IF i_blart = 'XY'.
* Umrechnungsdatum auf Folgetag des Belegdatums setzen
e_wwert = i_bldat + 1.
ENDIF.
ENDMETHOD.
Weitere Details finden sich im SAP-Hinweis 1670697 - FBCJ: BADI für Wertstellungsdatum
Massenlöschung von Kostenstellen
Mithilfe der KS04 lassen sich Kostenstellen löschen. Blöd nur, dass dabei immer nur eine spezifiziert werden kann und man aber z.B. 100 fehlerhaft angelegt (noch nicht bebuchte!) KST löschen will.
Anbei ein kleines Programm, welches sich des BAPIs BAPI_COSTCENTER_DELETEMULTIPLE bedient. Der Baustein durchläuft dabei die gleichen Prüfungen, die auch beim Löschen im Dialog (KS04) ausgeführt werden. Entsprechend lange wird die Laufzeit sein.
REPORT Z_KS04_MEHR_ALS_EINE.
* Löschen von mehreren Kostenstellen
TABLES: CSKS.
DATA: LT_CLIST TYPE TABLE OF BAPI0012_CCDELLIST.
DATA: LT_RETURN TYPE BAPIRET2_TAB.
PARAMETERS: pa_kokrs like csks-kokrs obligatory.
SELECT-OPTIONS: so_kostl for csks-kostl.
* hier ggf. noch weitere Selektionskriterien einfügen...
START-OF-SELECTION.
SELECT * FROM CSKS INTO CORRESPONDING FIELDS OF TABLE LT_CLIST
WHERE kokrs = pa_kokrs
AND kostl in so_kostl.
CALL FUNCTION 'BAPI_COSTCENTER_DELETEMULTIPLE'
EXPORTING
controllingarea = pa_kokrs
testrun = 'X' "TESTLAUF-Kz. raus, wenn's ernst wird
TABLES
COSTCENTERLIST = lt_clist
return = lt_return
EXCEPTIONS
error_message = 1.
IF SY-SUBRC <> 0.
MESSAGE 'Mind. eine KST muckt auf, Details s. Protokoll'.
ENDIF.
* Ausgabe Meldungen
CALL FUNCTION 'C14ALD_BAPIRET2_SHOW'
TABLES
i_bapiret2_tab = lt_return.
CO-Kontierungen im SD Auftragskopf
Bestimmte CO-Objekte (wie z.B. Innenaufträge) lassen sich im SD Auftrag im SAP Standard nur auf Positionsebene kontieren, was natürlich nervt, wenn bei allen Positionen das gleiche CO-Objekt eingetragen werden soll.
Kann man aber mithilfe der einschlägigen Userexits im Include MV45AFZB was machen:
1. Schritt:
Gewünschtes CO-Objekt "aufmachen" (Im Standard ist nur PSP-Element im Auftragskopf kontierbar).
z.B. Innenauftrag:
FORM USEREXIT_COBL_SEND_HEADER. * This example shows how to select fields that are shown in the * account assignment block * INT_COBLF-FDNAM = zzfield1. "hier: 'AUFNR' * INT_COBLF-OUTPUT = '1'. * IF T180-TRTYP NE CHARA AND * VBAP-KZVBR NE KZVBR_P. * INT_COBLF-INPUT = '1'. * INT_COBLF-REQUIRED = '1'. "nur wenn Mussfeld!!!! * ENDIF. * INT_COBLF-ACTIVE = '1'. * APPEND INT_COBLF. ENDFORM.
2. Schritt:
Auftragsnummer in Auftragskopf (VBAK) speichern:
FORM USEREXIT_COBL_RECEIVE_VBAK. * VBAK-zzfield = COBL-zzfield2. "hier: vbak-aufnr = cobl-aufnr. ENDFORM.
3. Schritt
Objekt in die Auftragspositionen "vererben":
FORM USEREXIT_MOVE_FIELD_TO_COBL USING US_VBAK STRUCTURE VBAK US_VBAP STRUCTURE VBAP CHANGING CH_COBL STRUCTURE COBL. * Examples * CH_COBL-zzfield = US_VBAK-zzfield2. * CH_COBL-zzfield = US_VBAP-zzfield2. "hier: ch_cobl-aufnr = us_vbak-aufnr. ENDFORM.
Sofern die Anforderung besteht, zusätzliche CO-Objekte in den Auftragspositionen aufzumachen, ist das Vorgehen ähnlich.
Im Include MV45AFZB, Routine USEREXIT_COBL_SEND_ITEM wird das gewünschte Objekt in den Kontierungsblock aufgenommen.
FORM USEREXIT_COBL_SEND_ITEM.
* This example shows how to select fields that are shown in the
* account assignment block
* INT_COBLF-FDNAM = zzfield1. "z.B. Kostenstelle 'KOSTL'
* INT_COBLF-OUTPUT = '1'.
* IF T180-TRTYP NE CHARA AND
* VBAP-KZVBR NE KZVBR_P.
* INT_COBLF-INPUT = '1'.
* INT_COBLF-REQUIRED = '1'. "nur bei Mussfeld
* ENDIF.
* INT_COBLF-ACTIVE = '1'.
* APPEND INT_COBLF.
ENDFORM.
In der Routine USEREXIT_COBL_RECEIVE_VBAP wird die CO-Kontierung in das entsprechende Feld in der Auftragsposition übernommen.
FORM USEREXIT_COBL_RECEIVE_VBAP.
* VBAP-zzfield = COBL-zzfield2.
"z.B. VBAP-KOSTL = COBL-KOSTL.
ENDFORM.
Ein etwaig bereits in der Auftragsposition vorhandenes CO-Objekt soll natürlich in den Kontierungsblock übernommen werden (Routine USEREXIT_MOVE_FIELD_TO_COBL)
FORM USEREXIT_MOVE_FIELD_TO_COBL USING US_VBAK STRUCTURE VBAK
US_VBAP STRUCTURE VBAP
CHANGING CH_COBL STRUCTURE COBL.
* Examples
* z.B. CH_COBL-KOSTL = US_VBAP-KOSTL. "Bsp. Kostenstelle
* CH_COBL-zzfield = US_VBAK-zzfield2.
* CH_COBL-zzfield = US_VBAP-zzfield2.
ENDFORM.
Beleg- / Referenznummernsuche im elektronischen Kontoauszug
Immer wieder taucht die (berechtigte) Frage auf, wie die Eingangsverarbeitung des elektronischen Kontoauzugs den Verwendungszweck analysiert, die zu suchenden Beleg- und/oder Referenznummern extrahiert und wo die relevanten Stellen im Coding sind. Ich will hier versuchen, auf die wichtigsten Stellen einzugehen und die Arbeitsweise (ggf. mit Beispielen im Coding) zu erläutern.
Als Beispiel nehmen wir den Klassiker "Zahlungseingang" (MT940-GVC 051 bzw. SEPA 166) und gehen davon aus, dass die Buchungsregel hierfür sowohl eine Buchung im Hauptbuch (Buchungsbereich 1) erzeugen als auch im Nebenbuch (Buchungsbereich 2) den debitorischen OP anhand der Referenzinformationen ausziffern soll. Die Suche im Verwendungszweck erfolgt anhand des Interprationsalgotithmus 001 (Standardalgorithmus, Details s. http://help.sap.com/saphelp_erp60_sp/helpdata/de/43/0bd56743de11d1896f0000e8322d00/content.htm )
Das Einlesen und Verbuchen erfolge kombiniert, d.h. wir verwenden die Transaktion FF_5 (Report RFEBKA00).
Zunächst wird der Einlesevorgang in Abhängigkeit des verwendeten Kontoauszugsformats gestartet. Je nach Format werden die entsprechenden Einlese-Reports gerufen, z.B.
Report RFEBKA00, Zl.410 ff.:
*---------------------------------------------------------------*
* Einlesen im richtigen Format *
*---------------------------------------------------------------*
IF einlesen = 'X'.
CASE format.
WHEN 'M'.
* Format: MultiCash (AUSZUG.TXT und UMSAT.TXT)
PERFORM multicash(rfeka200).
WHEN 'S'.
* Format: SWIFT MT940 (mit Strukturiertem Feld 86)
PERFORM swift_mt940(rfeka400).
...Anschließend wird die Verbuchung aufgerufen:
Report RFEBKA00, Formroutine automatic_processing
... PERFORM einzelposten_auswerten(rfebbu10) USING 'X'.
...
Report RFEBBU10, Formroutine einzelposten_auswerten
Hier werden zunächst die für die aktuelle Auszugsposition anwendbaren Suchmuster ermittelt (FuBa BSPS_PATTERN_SETUP) und angewandt (FuBa BSPS_PATTERN_SEARCH).
Die Standardinterpretation erfolgt mit dem Aufruf der Routine:
... PERFORM interpret_n2p TABLES _t_bapiret2. ...
Report RFEEBU10, Form-Routine interpret_n2p
In Abhängigkeit des Interpretationsalgorithmus wird hier die Routine analyse_verwendungzweck unter Angabe des relevanten Suchfeldes gerufen:
...
CASE febep-intag.
WHEN '000'.
* do nothing
WHEN '001'.
* Standardalgo: Führt Suche nach BELNR bzw. XBLNR aus,
* wenn BELNR bzw. XBLNR Range nicht initial ist.
IF NOT filter IS INITIAL.
PERFORM analyse_verwendungszweck USING 'BELNR'.
ENDIF.
IF NOT tfilter IS INITIAL.
PERFORM analyse_verwendungszweck USING 'XBLNR'.
ENDIF.
WHEN '011'.
...Im Rahmen dieser CASE-Anweisung erfolgt auch der Aufruf der kundeneigenen Interpretationsalgorithmen:
...
WHEN OTHERS.
* user algorithm according to naming convention "hw597428
CONCATENATE 'Z_FIEB_' febep-intag '_ALGORITHM'
INTO l_funct.
...
CALL FUNCTION l_funct
EXPORTING
i_note_to_payee = l_note_to_payee
...Ein Hinweis zur Simulationsfunktion im Suchmuster-Customizing. Hier wird nur eine Teilmenge der zur Verfügung stehenden Interpretationsalgorithmen unterstützt und kundeneigene Algorithmen gar nicht! Details s. hier: http://fico-forum.de/fico_forum/thread.php?board=2&thread=1500#3
In der Routine ANALYSE_VERWENDUNGSZWECK (RFEBBU10) erfolgt nun in Abhängigkeit des zu suchenden Feldes...
CASE sfnam.
...zunächst die Analyse des Verwendungszwecks (Details s. Kommentare im Coding)
WHEN 'XBLNR'.
PERFORM search_xblnr.Report RFEBBU10, Routine SEARCH_XBLNR:
" in 'puffer' stehen die zusammengesetzten " Zeilen des Verwendungszwecks als ein " langer String drin... ... " hier schmeisst er alle Sonderzeichen raus bzw. ersetzt sie durch Leerzeichen, " somit wird aus XY123-456 --> XY123 456 " als Sonderzeichen werden betrachtet:. , < > & " % ! ( ) = ? : - # * + / " TRANSLATE puffer USING convert2. " jetzt wirft er alle mehrfachen Leerzeichen raus " somit wird aus 'Kalle ist doof' --> 'Kalle ist doof' CONDENSE puffer. puffer2 = puffer. " jetzt werden alle übrigen Leerzeichen durch ; ersetzt --> XY123;456 TRANSLATE puffer USING convert3. REFRESH treffer. ... " hier zerlegt er den Verw.zweck anhand ';' in Teilstrings " und guckt, ob die Teilstrings in dem vom Benutzer angegeben " Vorgabeintervall für XBLNR liegen (hier: 'XY123' und '456') " Falls ja - als potenzielle Treffer merken PERFORM is_puffer_in_tfilter. " jetzt die zweite Runde, diesmal gehts den Buchstaben " an den Kragen, ansonsten analog wie oben puffer = puffer2. TRANSLATE puffer USING convert1. ... " jetzt bleibt '123' und '456' über... ... " doppelte raus (also '456' bleibt nur einmal stehen) PERFORM delete_double_treffer.nbsp;# _ ;
Insbesondere sind Sonderzeichen im Referenzfeld wie '-' oder '/' also ein Problem, weil diese von der Suche ausgeschlossen werden. In diesen Fällen muss schlimmstenfalls eine eigene Referenznummernsuche mithilfe der einschlägigen Erweiterungsmöglichkeiten implementiert werden.
Eine Auflistung aller Erweiterungsmöglichkeiten im Rahmen des elektronischen Kontoauszuges findet sich im Beratungs-Hinweis 494777.
In der int. Tabelle 'treffer' stehen nun alle potenziellen Treffer drin, d.h. alle die Zeichenfolgen, die aus dem Verwendungszweck extrahiert werden konnten und in die Intervallvorgabe, die vom Benutzer beim Einstieg in die FF_5 mitgegeben wurde, passen. Mit diesen potenziellen Treffern wird nun ein 'Probelesen' veranstaltet, d.h. das System versucht mit diesen Referenzen passende Belege von der Datenbank zu lesen.
Report RFEBBU10, Routine ANALYSE_VERWENDUNGSZWECK
... PERFORM x-treffer_probelesen.
Report RFEBBU10, Routine x-treffer_probelesen
...
LOOP AT treffer.
SELECT * FROM bkpf WHERE bukrs = febko-bukrs
AND bstat = ' '
AND xblnr = treffer-nummer. ...Etwaige Treffer werden dann im Anschluss in die Tabelle FEBCL geschrieben und der Buchungsschnittstelle übergeben.
/image%2F1473637%2F20170207%2Fob_adae32_profilbild.png)







