domenica 10 febbraio 2019

Link Fattura SD - Documento FI.

Nella tabella di testata della fattura SD (VBRK) ci sono 2 specifici campi che, almeno a prima vista, dovrebbero riportare il numero di documento FI prodotto dalla fattura.

In pratica però, ho controllato su tutta la tabella, questi campi sono sempre vuoti.





Il collegamento con il documento successivo non c'è nemmeno nella tabella del "Flusso docum. commerciale" (VBFA), probabilmente il confine è "segnato" dall'appartenza a 2 moduli differenti:

SD nel caso di fattura commerciale.
FI nel caso di documento contabile.

Dovendo preparare un report per la Fatturazione Elettronica, che parte dalle fatture SD ma volevo riportare anche il numero di documento FI, ho provato a cercare su Internet qualche info ed ho trovato questa indicazione:

Match VBRK-VBELN = BKPF-XBLNR and get the BELNR from BKPF.

In effetti la tabella BKPF riporta, nel campo XBLNR, il corretto riferimento al numero di fattura SD, il problema era che, letto su un solo record la risposta è veloce, lanciando un report con qualche centinaio di righe rallentava in modo impressionante. Ho anche provato a cambiare riferimento usando il campo AWKEY, verificato che conteneva sempre il riferimento al documento commerciale, ma la velocità restava praticamente uguale.

Ho quindi cercato delle info per velocizzare la lettura della BKPF da riferimenti SD, trovando indicazioni di passare attraverso le tabelle BSID e BSAD (Contabilità: indice secondario per clienti, la seconda per doc. pareggiati).

In effetti l'accesso risulta decisamente più veloce ma, poichè non si trovano proprio tutti i documenti e si deve tornare a leggere la BKP, non proprio rapido.

Alla fine ho trovato la corretta indicazione

Use vbrk-vbeln to find bkfp.

bkpf-awtyp = 'VBRK'
bkpf-awkey = vbrk-vbeln

Verificata anche effettuando il debug sul flusso documenti di una fattura SD:


questo il punto nel debug dove si trova il documento contabile


In effetti, nella BKPF, esiste una chiave secondaria così composta:


Per avere un accesso veloce è importante che la lettura venga eseguita con i campi chiave iniziali correttamente compilati.

Ho anche preparato un piccolo report per vedere i differenti tempi di accesso tra i vari metodi (vengono cercati i collegamenti tra 303 fatture (le ho selezionate per periodo) provando in un loop di 10 volte), questi i risultati:

Numero fatture =         303
Numero loop    =  10
Inizio accesso BSID/BSAD
                12,9380000
                12,9530000
                12,8600000
                52,8590000
                12,9380000
                13,0930000
                13,0160000
                52,8910000
                13,1090000
                12,7970000
BSID/BSAD non trovate:         47
Inizio accesso chiave incompleta.
               122,3610000
               162,1420000
               122,6940000
               121,7960000
               162,3600000
               122,0010000
               122,4860000
               162,8140000
               122,3600000
             4.162,7200000
Inizio accessi chiave completa.
                 0,0470000
                 0,0310000
                 0,0480000
                 0,0310000
                 0,0360000
                 0,0310000
                 0,0320000
                 0,0470000
                 0,0320000
                 0,0320000

Nei risultati vedo delle stranezze nel senso che mi aspetterei dei numeri abbastanza vicini tra gli stessi metodi, invece alcune volte si vedono dei valori molto più grandi della media, non saprei proprio da cosa dipenda. Forse la scelta della chiave di accesso viene effettuata random e, a volte, il DB sceglie la chiave sbagliata.

Codice del report:

*&---------------------------------------------------------------------*
*& Report  Z_51
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  Z_51.

tables: vbrk.
*----------------------------------------------------------------------*
* Parametri di selezione
*----------------------------------------------------------------------*

SELECT-OPTIONS: s_VBELN FOR vbrk-VBELN.                 "
SELECT-OPTIONS: s_VKORG FOR vbrk-VKORG.
SELECT-OPTIONS: s_ERDAT FOR vbrk-ERDAT.
PARAMETERS: i_num(2) TYPE n.

*----------------------------------------------------------------------*
* Variabili globali
*----------------------------------------------------------------------*

* Tabella di output.
Data: BEGIN OF tb_out occurs 0,
  BUKRS LIKE vbrk-BUKRS,
  BELNR LIKE vbrk-BELNR,
  GJAHR LIKE vbrk-GJAHR,
      END OF tb_out.

data: tb_vbrk LIKE vbrk OCCURS 0 WITH HEADER LINE.

*----------------------------------------------------------------------*
* Inizio programma
*----------------------------------------------------------------------*
start-of-selection.

  data: wa_vbrk LIKE vbrk.

  DATA: l_st1 TYPE timestampl,
        l_st2 TYPE timestampl,
        l_st3 TYPE timestampl,
        n_rec TYPE i,
        n_no  TYPE i.

  REFRESH tb_vbrk.

  SELECT * FROM vbrk INTO TABLE tb_vbrk
          WHERE vbeln IN s_vbeln
            AND vkorg IN s_vkorg
            AND erdat IN s_erdat.

  DESCRIBE TABLE tb_vbrk LINES n_rec.

  write: / 'Numero fatture = ', n_rec.
  write: / 'Numero loop    = ', i_num.

  write: / 'Inizio accesso BSID/BSAD'.

  DO i_num TIMES.

    GET TIME STAMP FIELD l_st1.

    n_no = 0.

    LOOP AT tb_vbrk.

* cerco prima in BSID che ha risposta più rapida
      SELECT SINGLE BELNR GJAHR FROM bsid INTO (tb_out-BELNR, tb_out-GJAHR)
                     WHERE BUKRS = tb_vbrk-BUKRS
                       AND KUNNR = tb_vbrk-KUNRG
                       AND XBLNR = tb_vbrk-vbeln.
      IF sy-subrc <> 0.
* poi in BSAD
        SELECT SINGLE BELNR GJAHR FROM bsad INTO (tb_out-BELNR, tb_out-GJAHR)
                                 WHERE BUKRS = tb_vbrk-BUKRS
                                   AND KUNNR = tb_vbrk-KUNRG
                                   AND XBLNR = tb_vbrk-vbeln.
        IF sy-subrc <> 0.

* altrimenti in BKPF + lento.
          add 1 to n_no.
          SELECT SINGLE BELNR GJAHR FROM bkpf INTO (tb_out-BELNR,
                                                    tb_out-GJAHR)
                         WHERE  AWKEY = tb_vbrk-vbeln.
        ENDIF.
      ENDIF.

    ENDLOOP.

    GET TIME STAMP FIELD l_st2.
    l_st3 = l_st2 - l_st1.

    write / l_st3.

  ENDDO.

  write: / 'BSID/BSAD non trovate:', n_no.
  write: / 'Inizio accesso chiave incompleta.'.

  DO i_num TIMES.

    GET TIME STAMP FIELD l_st1.

    LOOP AT tb_vbrk.

      SELECT SINGLE BELNR GJAHR FROM bkpf INTO (tb_out-BELNR,
                                                tb_out-GJAHR)
                     WHERE AWKEY = tb_vbrk-vbeln.
    ENDLOOP.

    GET TIME STAMP FIELD l_st2.
    l_st3 = l_st2 - l_st1.

    write / l_st3.

  ENDDO.

  write: / 'Inizio accessi chiave completa.'.

  DO i_num TIMES.

    GET TIME STAMP FIELD l_st1.

    LOOP AT tb_vbrk.

      SELECT SINGLE BELNR GJAHR FROM bkpf INTO (tb_out-BELNR,
                                                tb_out-GJAHR)
                     WHERE AWTYP = 'VBRK'
                       AND AWKEY = tb_vbrk-vbeln.

    ENDLOOP.

    GET TIME STAMP FIELD l_st2.
    l_st3 = l_st2 - l_st1.

    write / l_st3.

  ENDDO.

Nessun commento:

Posta un commento