形成的原因:
sap在创建billing单据时,系统会给对应的出库单据添加锁。使用锁机制保证同一个出库单据在同时间只能被一个程序出路,这样也就保证同一个出库单据不会被创建多个发票。sap系统在处理完成会释放锁,出库单据状态也被改变,系统也就会通过单据的状态阻止再次创建发票。
SAP在单据更新出现错误时,出库单据的锁被释放,但是出库单据状态没有设置,这样统一出库单据就可能再次被创建一个新的发票(这种错误一般发生在后台批处理的情况下)。
解决的方法:
1.使用附带的ZVINVOIC程序检查重复的发票;
2.使用附带的ZZVBFA02程序检查和修复单据流(VBFA);
3.删除重复的发票
4.使用 SDVBUK00 修正单据状态
对应的程序ZVINVOIC:
*&---------------------------------------------------------------------*
*& Report ZVINVOIC
*&
*&---------------------------------------------------------------------*
*& Report to determine double billing documents
*&
*&---------------------------------------------------------------------*
REPORT ZVINVOIC.
INCLUDE RVVBTYP. "Belegtype
TABLES: VBFA. "Flusstabelle
DATA: BEGIN OF XVBFA OCCURS 1000. "gefundene Auftr鋑e
INCLUDE STRUCTURE VBFA. "und Lieferungen
DATA: END OF XVBFA.
DATA: BEGIN OF YVBFA OCCURS 1000. "Belege mit mehrfacher
INCLUDE STRUCTURE VBFA. "Fakturierung
DATA: END OF YVBFA.
DATA: NUMBER_OF_INVOICES_PLUS LIKE SY-TABIX. "Anzahl Umsatz+
DATA: NUMBER_OF_INVOICES_MINUS LIKE SY-TABIX. "Anzahl Umsatz-
DATA: NUMBER_OF_INVOICES_CROSP LIKE SY-TABIX. "Anzahl int. Verr.+
DATA: NUMBER_OF_INVOICES_CROSM LIKE SY-TABIX. "Anzahl int. Verr.-
DATA: START_VBTYP LIKE VBFA-VBTYP_N. "Erster Fakturatyp
DATA: VBTYPS(50). "Hilfsfeld
SELECT-OPTIONS: S_VBELV FOR VBFA-VBELV, "Documents
S_ERDAT FOR VBFA-ERDAT.
PARAMETERS: P_ORDER DEFAULT 'X', "Only Orders
P_DELIV DEFAULT 'X'. "Only Deliveries
*
RANGES: VBTYP_V FOR VBFA-VBTYP_V,
VBTYP_N FOR VBFA-VBTYP_N.
* * Sales Documents
IF NOT P_ORDER IS INITIAL.
CONCATENATE VBTYP_AUFT VBTYP_ANFO INTO VBTYPS.
DO.
IF VBTYPS CO ' '.
EXIT.
ENDIF.
VBTYP_V-LOW = VBTYPS(1).
VBTYP_V-SIGN = 'I'.
VBTYP_V-OPTION = 'EQ'.
APPEND VBTYP_V.
SHIFT VBTYPS.
ENDDO.
ENDIF.
* Deliveries
IF NOT P_DELIV IS INITIAL.
VBTYPS = VBTYP_LIEF.
DO.
IF VBTYPS CO ' '.
EXIT.
ENDIF.
VBTYP_V-LOW = VBTYPS(1).
VBTYP_V-SIGN = 'I'.
VBTYP_V-OPTION = 'EQ'.
APPEND VBTYP_V.
SHIFT VBTYPS.
ENDDO.
ENDIF.
* Subsequent document (billing documents)
VBTYPS = VBTYP_FAKT.
DO.
IF VBTYPS CO ' '.
EXIT.
ENDIF.
IF VBTYPS(1) NE 'U'. "Proforma Invoice"
VBTYP_N-LOW = VBTYPS(1).
VBTYP_N-SIGN = 'I'.
VBTYP_N-OPTION = 'EQ'.
APPEND VBTYP_N.
ENDIF.
SHIFT VBTYPS.
ENDDO.
* Fuellen interne Tabellen der gefundenen Fakturen
SELECT * INTO TABLE XVBFA FROM VBFA
WHERE VBELV IN S_VBELV
AND ERDAT IN S_ERDAT
AND VBTYP_V IN VBTYP_V
AND VBTYP_N IN VBTYP_N
AND STUFE = '00'
AND PLMIN NE '0'.
* Sort by document and item number and creation time
SORT XVBFA BY VBELV POSNV ERDAT ERZET.
LOOP AT XVBFA.
* Document or item has changed.
ON CHANGE OF XVBFA-VBELV OR
XVBFA-POSNV.
* Merken erster Belegtyp und loeschen Rechenfelder.
START_VBTYP = XVBFA-VBTYP_N.
CLEAR NUMBER_OF_INVOICES_PLUS.
CLEAR NUMBER_OF_INVOICES_MINUS.
CLEAR NUMBER_OF_INVOICES_CROSP.
CLEAR NUMBER_OF_INVOICES_CROSM.
ENDON.
* Erhoehen Positivbelege
IF XVBFA-VBTYP_N CA 'MPS'.
ADD 1 TO NUMBER_OF_INVOICES_PLUS.
ENDIF.
* Erhoehen Negativbelege
IF XVBFA-VBTYP_N CA 'NO'.
ADD 1 TO NUMBER_OF_INVOICES_MINUS.
ENDIF.
* Erhoehen interne Verrechnung +
IF XVBFA-VBTYP_N CA '5'.
ADD 1 TO NUMBER_OF_INVOICES_CROSP.
ENDIF.
IF XVBFA-VBTYP_N CA '6'.
ADD 1 TO NUMBER_OF_INVOICES_CROSM.
ENDIF.
VBFA = XVBFA.
VBFA = XVBFA.
* Last entry
AT END OF POSNV.
* Erster Typ war Positiv.
IF START_VBTYP CA 'MPS5'.
IF NUMBER_OF_INVOICES_MINUS > NUMBER_OF_INVOICES_PLUS OR
NUMBER_OF_INVOICES_CROSM > NUMBER_OF_INVOICES_CROSP.
YVBFA = VBFA.
APPEND YVBFA.
ELSE.
SUBTRACT NUMBER_OF_INVOICES_MINUS FROM
NUMBER_OF_INVOICES_PLUS.
SUBTRACT NUMBER_OF_INVOICES_CROSM FROM
NUMBER_OF_INVOICES_CROSP.
IF NUMBER_OF_INVOICES_PLUS > 1 OR
NUMBER_OF_INVOICES_CROSP > 1.
YVBFA = VBFA.
APPEND YVBFA.
ENDIF.
ENDIF.
ENDIF.
* Erster Typ war negativ.
IF START_VBTYP CA 'NO6'.
IF NUMBER_OF_INVOICES_PLUS > NUMBER_OF_INVOICES_MINUS OR
NUMBER_OF_INVOICES_CROSP > NUMBER_OF_INVOICES_CROSM.
YVBFA = VBFA.
APPEND YVBFA.
ELSE.
SUBTRACT NUMBER_OF_INVOICES_PLUS FROM
NUMBER_OF_INVOICES_MINUS.
SUBTRACT NUMBER_OF_INVOICES_CROSP FROM
NUMBER_OF_INVOICES_CROSM.
IF NUMBER_OF_INVOICES_MINUS > 1 OR
NUMBER_OF_INVOICES_CROSM > 1.
YVBFA = VBFA.
APPEND YVBFA.
ENDIF.
ENDIF.
ENDIF.
ENDAT.
ENDLOOP.
CLEAR YVBFA.
LOOP AT YVBFA.
IF YVBFA-VBTYP_V CA VBTYP_AUFT
OR YVBFA-VBTYP_V CA VBTYP_ANFO.
WRITE: / 'Sales Document:', YVBFA-VBELV, YVBFA-POSNV.
ENDIF.
IF YVBFA-VBTYP_V CA VBTYP_LIEF.
WRITE: / 'Delivery :', YVBFA-VBELV, YVBFA-POSNV.
ENDIF.
ENDLOOP.
对应ZZVBFA02代码
REPORT ZZVBFA02.
* Auftr鋑e *
***********************************************************************
*
* Bei der Erstellung Belegflu� k鰊nen Unterbrechnungen im Flu�
* auftreten. Diese Unterbrechnungen treten auf, wenn zwei Programme
* auf einen Cluster-Bereich gleichzeitig einen Update durchf黨ren
* wollen oder bei Nachverbuchungen nicht korrekt gearbeitet wird.
*
* Im ersten Schritt sollen die Fakturen durchsucht werden, und fehlende
* Verbindungen zu Auftr鋑en in die VBFA erstellt werden.
*
***********************************************************************
*
TABLES : VBRK, " Fakturakopf
VBRP, " Fakturapositionen
VBFA. " Vertriebsbelegflu�
*
TABLES : TVKO. " W鋒rungsinfo der VKORG
*
DATA : BEGIN OF LOC_VBFA.
INCLUDE STRUCTURE VBFA.
DATA : END OF LOC_VBFA.
*
DATA : BEGIN OF TAB_VBFA OCCURS 0.
INCLUDE STRUCTURE VBFA.
DATA : END OF TAB_VBFA.
*
DATA : BEGIN OF TAB_VBRK OCCURS 0.
INCLUDE STRUCTURE VBRK.
DATA : END OF TAB_VBRK.
*
DATA : BEGIN OF TAB_VBRP OCCURS 0.
INCLUDE STRUCTURE VBRP.
DATA : END OF TAB_VBRP.
*
DATA : BEGIN OF XVBRP OCCURS 0.
INCLUDE STRUCTURE VBRP.
DATA : END OF XVBRP.
*
DATA : GV_VBTYP_FAKTURA LIKE VBRP-VGTYP VALUE 'M', " Faktura
GV_VBTYP_ORDER LIKE VBRP-VGTYP VALUE 'CKL'. " Auftrag
DATA : GV_VBFA_GEFUNDEN(1),
CON_ANGEKREUZT(1) VALUE 'X',
KURSTYP LIKE VBRK-KURST,
GV_READ_VBRP TYPE P,
GV_MISS_VBRP TYPE P,
GV_CHECK_VBRP TYPE P.
SELECT-OPTIONS: S_BELEG FOR VBRK-VBELN.
PARAMETER: P_TEST LIKE RVSEL-UEBLI DEFAULT 'X'.
*
INCLUDE RVVBTYP.
*
PERFORM INVOICE_TO_ORDER_CHECK.
*---------------------------------
*
TOP-OF-PAGE.
*
WRITE: /20 TEXT-001.
WRITE: /.
WRITE: / TEXT-002, GV_READ_VBRP,
TEXT-007, GV_CHECK_VBRP,
TEXT-003, GV_MISS_VBRP.
WRITE: /.
WRITE: SY-ULINE.
WRITE: /.
*eject
*---------------------------------------------------------------------*
* FORM INVOICE_TO_ORDER_CHECK *
*---------------------------------------------------------------------*
* ........ *
*---------------------------------------------------------------------*
FORM INVOICE_TO_ORDER_CHECK.
SELECT * FROM VBRP INTO TABLE XVBRP
WHERE VBELN IN S_BELEG.
LOOP AT XVBRP.
GV_READ_VBRP = GV_READ_VBRP + 1.
IF XVBRP-VGTYP CA VBTYP_VERK.
GV_CHECK_VBRP = GV_CHECK_VBRP + 1.
SELECT SINGLE * FROM VBRK
WHERE VBELN EQ XVBRP-VBELN.
* ------------------------------------------------
SELECT SINGLE * FROM VBFA
WHERE VBELV EQ XVBRP-VGBEL
AND POSNV EQ XVBRP-VGPOS
AND VBELN EQ XVBRP-VBELN
AND POSNN EQ XVBRP-POSNR.
* ------------------------------------------------
IF SY-SUBRC EQ 0.
GV_VBFA_GEFUNDEN = CON_ANGEKREUZT.
ELSE.
CLEAR: GV_VBFA_GEFUNDEN.
ENDIF. " sy-subrc eq 0.
*
IF GV_VBFA_GEFUNDEN NE CON_ANGEKREUZT.
GV_MISS_VBRP = GV_MISS_VBRP + 1.
PERFORM MISSING_DOC_FLOW_INSERT.
* --------------------------------
ENDIF. " gv_vbfa_gefunden ne con_angekreuzt.
ENDIF. " vbrp-vgtyp eq gv_vbtyp_verk.
ENDLOOP. " at xvbrp.
*
PERFORM PROTOCOL_WRITE.
* -----------------------
COMMIT WORK.
*
ENDFORM. " invoice_to_delivery_check.
*eject
*---------------------------------------------------------------------*
* FORM MISSING_DOC_FLOW_INSERT *
*---------------------------------------------------------------------*
* ........ *
*---------------------------------------------------------------------*
FORM MISSING_DOC_FLOW_INSERT.
*
SELECT SINGLE * FROM TVKO
WHERE VKORG EQ VBRK-VKORG.
* --------------------------------------------
IF SY-SUBRC EQ 0.
PERFORM VBFA_FUELLEN.
* ---------------------
IF P_TEST NE 'X'.
INSERT VBFA.
ENDIF.
* ------------
CLEAR : TAB_VBRK, TAB_VBRP, TAB_VBFA.
*
TAB_VBFA = VBFA.
APPEND TAB_VBFA.
* --------------------
TAB_VBRK = VBRK.
APPEND TAB_VBRK.
* --------------------
TAB_VBRP = XVBRP.
APPEND TAB_VBRP.
* --------------------
ENDIF. " sy-subrc eq 0.
*
ENDFORM. " missing_doc_flow_insert.
*eject
*---------------------------------------------------------------------*
* FORM VBFA_FUELLEN *
*---------------------------------------------------------------------*
* ........ *
*---------------------------------------------------------------------*
FORM VBFA_FUELLEN. " using sst_vbeln sst_posnr sst_vbtyp.
CLEAR VBFA.
VBFA-MANDT = SY-MANDT.
VBFA-VBELV = XVBRP-VGBEL. " ts_vbeln
VBFA-POSNV = XVBRP-VGPOS. " ts_posnr
VBFA-VBELN = XVBRP-VBELN. " beleg
VBFA-POSNN = XVBRP-POSNR.
* Bei Anlegen einer Position durch Kopieren ist TVCPY f黵 die Position
* gelesen
IF XVBRP-ERDAT IS INITIAL.
VBFA-ERDAT = SY-DATUM. " xvbrk-erdat.
ELSE.
VBFA-ERDAT = XVBRP-ERDAT.
VBFA-ERZET = XVBRP-ERZET.
ENDIF.
VBFA-FKTYP = VBRK-FKTYP. " xvbrk-fktyp. "only 3.0
* Change FKTYP from L (delivery) to A (sales document) if necessary
* Compare determination of XVBAPF-FAKLMENG/-FAKLMENGV in LV45P011
IF VBRK-FKTYP EQ 'L'.
VBFA-FKTYP = 'A'.
ENDIF.
VBFA-PLMIN = '+'. " tvcpf-plmin.
VBFA-VBTYP_V = XVBRP-VGTYP. " ts_vbtyp
VBFA-VBTYP_N = VBRK-VBTYP. " xvbrk-vbtyp
VBFA-RFMNG = XVBRP-FKLMG.
VBFA-RFMNG_FLT = XVBRP-FKIMG * XVBRP-UMVKZ / XVBRP-UMVKN. "only 3.0
IF XVBRP-SHKZG CA 'AB'.
MULTIPLY VBFA-RFMNG BY -1.
MULTIPLY VBFA-RFMNG_FLT BY -1. "only 3.0
ENDIF.
VBFA-MEINS = XVBRP-MEINS.
VBFA-RFWRT = XVBRP-NETWR.
* Fakturierungsplan "only 3.0
IF NOT XVBRP-FPLNR IS INITIAL. "only 3.0
VBFA-FPLNR = XVBRP-FPLNR. "only 3.0
VBFA-FPLTR = XVBRP-FPLTR. "only 3.0
ENDIF. "only 3.0
VBFA-WAERS = TVKO-WAERS.
* " if xvbrk-waerk ne tvko-waers.
IF VBRK-WAERK NE TVKO-WAERS.
KURSTYP = VBRK-KURST. " xvbrk-kurst.
IF KURSTYP IS INITIAL.
KURSTYP = 'M'.
ENDIF.
CALL FUNCTION 'CONVERT_TO_LOCAL_CURRENCY'
EXPORTING
FOREIGN_AMOUNT = XVBRP-NETWR
FOREIGN_CURRENCY = VBRK-WAERK " xvbrk-waerk
LOCAL_CURRENCY = TVKO-WAERS
RATE = XVBRP-KURSK
TYPE_OF_RATE = KURSTYP
DATE = XVBRP-PRSDT
IMPORTING
LOCAL_AMOUNT = VBFA-RFWRT
EXCEPTIONS
NO_RATE_FOUND = 1
OVERFLOW = 2.
ENDIF.
*
ENDFORM.
*eject
*---------------------------------------------------------------------*
* FORM PROTOCOL_WRITE *
*---------------------------------------------------------------------*
* ........ *
*---------------------------------------------------------------------*
FORM PROTOCOL_WRITE.
*
DATA : LOC_TABIX LIKE SY-TABIX,
LOC_TABMAX LIKE SY-TABIX.
*
DESCRIBE TABLE TAB_VBRK LINES LOC_TABMAX.
*
IF LOC_TABMAX GT 0.
LOOP AT TAB_VBRK.
LOC_TABIX = SY-TABIX.
READ TABLE TAB_VBRP INDEX LOC_TABIX.
READ TABLE TAB_VBFA INDEX LOC_TABIX.
WRITE: /1(08) LOC_TABIX, TEXT-004, TAB_VBRK-VBELN,
TAB_VBRK-FKART, TAB_VBRK-FKTYP, TAB_VBRK-VBTYP,
TAB_VBRK-VKORG, TAB_VBRK-VTWEG, TAB_VBRK-BELNR.
WRITE: /10 TEXT-005, TAB_VBRP-VBELN, TAB_VBRP-POSNR,
TAB_VBRP-VBELV, TAB_VBRP-POSNV,
TAB_VBRP-VGBEL, TAB_VBRP-VGPOS, TAB_VBRP-VGTYP.
WRITE: /10 TEXT-006, TAB_VBFA-VBELV, TAB_VBFA-POSNV,
TAB_VBFA-VBELN, TAB_VBFA-POSNN, TAB_VBFA-VBTYP_N,
TAB_VBFA-RFMNG, TAB_VBFA-MEINS.
WRITE: /15 TAB_VBFA-RFWRT, TAB_VBFA-WAERS, TAB_VBFA-VBTYP_N,
TAB_VBFA-PLMIN, TAB_VBFA-TAQUI, TAB_VBFA-ERDAT,
TAB_VBFA-ERZET, TAB_VBFA-MATNR.
WRITE: /15 TAB_VBFA-BWART, TAB_VBFA-BDART, TAB_VBFA-PLART,
TAB_VBFA-STUFE, TAB_VBFA-LGNUM, TAB_VBFA-AEDAT,
* folgende 4 Zeilen " only 3.0
TAB_VBFA-FKTYP, TAB_VBFA-BRGEW, TAB_VBFA-GEWEI,
TAB_VBFA-VOLUM, TAB_VBFA-VOLEH.
WRITE: /15 TAB_VBFA-FPLNR, TAB_VBFA-FPLTR, TAB_VBFA-RFMNG_FLO,
TAB_VBFA-RFMNG_FLT.
* davorliegenden 4 Zeilen " only 3.0
* In einem 2.1 oder 2.2 Release ist das Komma nach "tab_vbfa-aedat"
* durch einen Punkt zu ersetzen
WRITE: / SY-ULINE.
ENDLOOP. " at tab_vbrk.
ELSE. " loc_tabmax eq 0.
WRITE: / 'Keine Fehler im Belegflu� Faktura / Auftrag gefunden'.
ENDIF. " loc_tabmax gt 0.
*
ENDFORM. " protocol_write.
相关的Notes:
Note 12934 - Two billing documents exist for one delivery note
Note 152051 - Error in the doc flow display of sales orders and bill docs