Cerca nel blog

giovedì 28 novembre 2019

Modulo MM: (Processo di acquisto) Parte 5

Modulo MM (Processo di acquisto) Parte5

1.6            Rilascio (Approvazione)

La strategia di rilascio definisce il processo di approvazione per richieste di acquisto o documenti di acquisto esterni. La strategia specifica i codici di rilascio necessari e la sequenza in cui devono essere effettuati i rilasci. È possibile definire un massimo di otto codici di rilascio.

1.6.1       Procedura di Rilascio

Per visualizzare o modificare una caratteristica richiamare la transazione CT04.

Supponiamo di voler creare una caratteristica GRP_ACQ_ODA, quindi richiamiamo la transazione CT04, inseriamo nel nome Caratteristica il valore “GRP_ACQ_ODA” e premiamo Invio.


OPZIONALE
E’ possibile inserire un Gruppo Caratteristiche, nel campo Gruppo Caratteristiche, creato con la transazione O042 ( Il gruppo caratteristiche  può essere usato per raggruppare le caratteristiche simili)



Il Gruppo Caratteristiche creato, lo si può inserisce nel tab “Dati Base” nel campo “Gruppo Caratteristiche”.

Inserire nel Tab “Valori”, i valori ammessi, in questo caso i valori presenti nella tabella standard


Inserire nel Tab “Dati suppl.”, il riferimento al campo della tabella CEKKO- EKGRP



In questo tab “Dati suppl.” come nome tabella usare le seguenti strutture:
- CEBAN per le richieste
- CEKKO per i documenti di acquisto
- CESSR per service entry sheets (Modulo acquisizioni Prestazioni)
     Nomi dei campi delle tabelle di riferimento


OPZIONALE
E’ possibile valorizzare anche il tab “Delimitazioni” (Restrizioni), per inserire una limitazione per la caratteristica elaborata, ad uno specifico tipo di class, ad es. 032 ("strategie di rilascio")

 

Classe
Per creare/modificare/visualizzare una classe usare le transazioni CL01, CL02, CL03.

Supponiamo di voler creare la classe ZCL_RILASCIO_ODA, da usare per il rilascio degli ordini di acquisto, richiamiamo la transazione CL01,  inseriamo il nome della classe e il tipo classe “032” è premere invio. Poi inseriamo una descrizione nel campo “Denominazione”.

 

OPZIONALE
E’ possibile inserire un Gruppo Classe, nel campo Gruppo, che può essere creato con la transazione O043 ( Il gruppo Classe può essere usato per raggruppare le classi simili).

Il Gruppo Classe creato, lo si può inserisce nel tab “Dati Base” nel campo “Gruppo”.

 
Nel Tab “Caratteristiche”, inserire  le caratteristiche associate a questa classe, in questo caso la caratteristica che abbiamo creato in precedenza “GRP_ACQ_ODA GRP_ACQ_ODA

Se la caratteristica inserita in questa classe, viene modificata con la transazione CT02, le modifiche si rifletteranno in questa classe.



Tabelle usate per le procedure di rilascio sono:

TABELLA
DESCRIZIONE
T16FG
Gruppi di rilascio
T16FC
Codici di rilascio
T16FB
Indicatore di rilascio: documenti di acquisto
T161S
Indicatore di rilascio, richiesta di acquisto
T16FE
Descrizione degli indicatori di rilascio: documenti di acquisto
T16FS
Strategie di rilascio
T16FV
Prerequisiti di rilascio
T16FK
Stati di rilascio
 

Settaggio della procedura di rilascio

Per le OdA, richiamare la transazione SPRO, e selezionare Gestione materiale-> Acquisti -> Ordine d’acquisto -> Procedura di rilascio per ordini d’acquisto-> Definire Procedura di rilascio per ordini d’acquisto.

 
Per i service entry sheets (Modulo acquisizioni Prestazioni) il percorso è il seguente
richiamare la transazione SPRO, e selezionare Gestione materiale-> Prest. di servizio -> Definire Procedura di rilascio per il modulo di acquisizione prestazioni.

Per le RdA, richiamare la transazione SPRO, e selezionare Gestione materiale-> Acquisti -> richiesta d’acquisto -> Procedura di rilascio -> Procedura con classificazione -> Impostare proc. Con classificazione.

NOTA: Gli ordini di acquisto, i contratti, gli Scheduling agreements (accordi di pianificazione), le RFQ (richieste di offerta) e  le Quotation (preventivi) USANO TUTTI LA STESSA STRATEGIA DI RILASCIO.

Normalmente, le richieste di acquisto vengono rilasciate a livello ITEM. Dalla versione 4.0, il documento può anche essere rilasciato a livello di HEADER. Per questo, il flag di riferimento deve essere impostato in:

IMG> Gestione materiale-> Acquisti -> richiesta d’acquisto -> Procedura di rilascio -> Procedura con classificazione -> Impostare proc. Con classificazione. -> Gruppi di rilascio> Contrassegna "Rilascio complessivo della richiesta di acquisto"

Tutti gli altri documenti di acquisto vengono sempre rilasciati a livello di intestazione.
 
Per impostare correttamente una procedura di rilascio coerente, i seguenti ITEM devono essere elaborati nell'ordine appropriato:


  • Gruppo di Rilascio:
    • Inserire un Gruppo di Rilascio: il codice a 2 cifre che combinato con un codice di strategia a 2 cifre costituisce la strategia di rilascio finale
    • Inserire un Oggetto di Rilascio: può assumere i seguenti valori (1: RdA; 2: OdA o altri documenti di acquisto; 3: Service Entry Sheets). Non è un campo editabile ma il valore se lo deriva dalla classe che inseriamo.
    • Inserire un Classe: inseriamo la classe creata in precedenza
      E' possibile usare solo una classe di rilascio per un determinato oggetto di rilascio.
 


  • Codice di Rilascio:
Il codice di rilascio è un ID di due caratteri che consente a un determinato utente di rilasciare (o approvare) un elemento di richiesta o un documento di acquisto esterno.
I codici di rilascio sono sempre assegnati a un gruppo di rilascio
I workflows possono anche essere assegnati a un gruppo di rilascio o ad un codice di rilascio.


  • Indicatore di Rilascio:
Per richieste di acquisto:
Fornisce informazioni se il documento / item di riferimento può essere modificato, ad es. Da cicli di acquisto o di pianificazione del materiale e controlla dopo l'avvio della procedura di rilascio, se una richiesta di offerta o un ordine di acquisto può essere creato con riferimento alla RdA, se una nuova strategia viene determinata o se le versioni già esistenti devono essere revocate quando vengono apportate determinate modifiche al documento.
Per altri documenti di acquisto:
Fornisce informazioni se il documento può essere modificato acquistando funzionalità dopo l'avvio della procedura di rilascio, se viene determinata una nuova strategia o se le versioni esistenti devono essere annullate in caso di modifiche.


  • Strategia di rilascio:
La strategia completa è la combinazione del gruppo di rilascio e del codice di rilascio stesso, ciascuno costituito da un codice di 2 cifre. Esempio: XX YY, qui XX indica il gruppo di rilascio mentre YY indica il codice di rilascio.
Nella schermata dei dettagli, è possibile inserire i codici di rilascio assegnati a questa strategia. Inoltre, è necessario impostare i prerequisiti di rilascio nonché gli stati di rilascio e i valori per le caratteristiche della classe di rilascio assegnata.

Per impostare il dettaglio di questa strategia di rilascio, fare doppio click, sul gruppo acquisto, in questo caso “03”.
 


Qui, si settano i prerequisiti di rilascio. In questo esempio abbiamo riportato un esempio di una procedura di rilascio di 4 codici (supponiamo 01,02,03,04).
Premendo il pulsante “Premesse rilascio” si può impostare i prerequisiti per i rilasci dei vari codici, ad esempio, lo 01 è il prerequisito dello 02, lo 01 e 02 è il prerequisito dello 03 e così via dicendo.

Esempio di schermata



I prerequisiti di rilascio indicano la sequenza in cui una richiesta di acquisto (item) o un documento di acquisto deve essere approvato tramite codici di rilascio diversi.
Nell’esempio della figura precedente, abbiamo che il codice 03 può essere rilasciato solo se è stato rilasciato il codice 02, mentre il codice 04 può essere rilasciato solo se sono stati rilasciati i codici 02 e 03.

Lo stato di rilascio di un documento (premere il pulsante “Stati Rilasci”) è ulteriormente specificato dall'indicatore di rilascio. Questo indicatore può specificare se un documento è, ad esempio, bloccato, riparato rispetto alle esecuzioni MRP o se possono essere creati documenti successivi. Questo è illustrato da un altro esempio per la procedura di rilascio in tre passaggi:
 


Premendo sul pulsante Classificazione, settiamo le condizioni che si devono verificare, per determinare la strategia di rilascio.
Sulla base delle caratteristiche che sono state assegnate a una determinata classe di rilascio, l'utente può inserire i valori di campo specifici che desidera prendere in considerazione quando deve essere trovata una determinata strategia di rilascio per un documento di acquisto.
In questo caso, la strategia 03 20, scatta se si verificano le seguenti condizioni:
  • Tp ordine di acquisto= valore XXXX
  • Organizzazione acquisti= valore XXXX
  • Gruppo acquisti= valore XXXX
  • Divisione= valori XXXX, ZZZZ etc


Premendo sul pulsante Simulazione rilascio, per simulare se la sequenza di rilasci funziona.
Ogni strategia di rilascio può essere testata simulando l'approvazione di ciascuno dei codici di rilascio definiti.

  • Workflow:
Usando questa opzione, i ruoli potrebbero essere assegnati a una qualsiasi delle combinazioni del gruppo di rilascio / codice


Suggerimenti da ricordare

Una strategia di rilascio non può essere utilizzata contemporaneamente SENZA classificazione e CON classificazione. Se è presente una voce nella tabella Gruppo di rilasci (T16FG-FRGOT), è possibile utilizzare solo i rilasci CON classificazione.
Non usare trattini per i nomi delle classi, invece, è meglio usare un trattino basso.
Quando si impostano gli indicatori di rilascio nella schermata "stato", la sequenza dovrebbe iniziare con uno stato BLOCCATO e terminare con "RILASCIATO PER ORDINE". Se non è presente "RILASCIATO PER ORDINE" come ultimo stato, all'utente verrà visualizzato il messaggio di avviso ME167: "Verificare gli stati di rilascio".
I centri di costo (CEBAN-KOSTL) e i fornitori (CEBAN-LIFNR) in una strategia di rilascio devono essere inseriti con zero iniziali, anche se sono definiti come campi CHAR. Questo vale anche per le strutture CEKKO e CESSR. (vedi nota 52225)
Nel caso dei contratti, il valore obiettivo viene utilizzato per la determinazione della strategia di rilascio anziché il valore netto del contratto. Con la nota 116685, questa logica è stata notevolmente migliorata: se si mantiene un valore target nell'intestazione del contratto, questo valore viene impostato nel campo CEKKO-GNETW per determinare una possibile strategia di rilascio. Se non esiste alcun valore target a livello di intestazione, viene invece eseguita un'aggregazione dei valori target degli articoli.
Poiché la maggior parte dei documenti di acquisto (ad eccezione delle richieste) viene valutata a livello di intestazione, la strategia di rilascio non viene assegnata fino al salvataggio del documento. C'è una funzione di controllo che può essere utilizzata per determinare la strategia prima di salvare il documento.
Dopo che è stata determinata una strategia di rilascio per l'acquisto di documenti (diversi dalle richieste) senza alcuna approvazione, eventuali condizioni di output assegnate al documento non verranno visualizzate nella schermata del messaggio fino all'approvazione del rilascio. Ciò è dovuto al fatto che questi documenti sono bloccati per la stampa intenzionalmente.
Se il messaggio di errore ME179 viene visualizzato dal sistema ("errore nella classe di classificazione XXXXX tipo di classe 032"), la strategia è già assegnata a un'altra classe. L'utente deve quindi rimuovere questa strategia dalla vecchia classe prima che possa essere assegnata a un'altra classe.
Per i documenti di acquisto diversi dalle richieste, i campi a livello di articolo come lo stabilimento e il gruppo di materiali utilizzati per la determinazione della strategia, verranno aggregati al livello di intestazione. Ad esempio, per un determinato scenario di rilascio, l'utente desidera utilizzare l'impianto come una delle caratteristiche. Se tutti gli articoli NON appartengono allo stesso impianto, è necessario avere un valore vuoto come uno dei valori consentiti per selezionare una strategia. Inoltre, se tutti gli item appartengono all'impianto SAME, questo impianto si aggregherà all'intestazione, se non sono identici, un valore vuoto verrà passato all'intestazione (per ulteriori informazioni, vedere la nota 47089).
Se sono usate le user-exit EXIT_SAPLEBND_001 o EXIT_SAPLEBND_004, vengono utilizzate almeno le seguenti istruzioni nel codice: E_CEBAN = I_CEBAN. Allo stesso modo, per la user-exit EXIT_SAPLEBND_002, è necessario aggiungere la dichiarazione E_CEKKO = I_CEKKO.
Se sono usati intervalli di valori,  per determinate caratteristiche, il flag "valore multiplo" deve essere impostato di conseguenza.
Per quanto riguarda i rilasci, esistono differenze tra la transazione ME54N e ME55: ME54N è pensato per essere usato per i rilasci interattivi o per la modifica di una richiesta all'interno dello stesso ambiente di transazione a schermo singolo come per ME51N / ME52N / ME53N, mentre ME55 è pensato solo i rilasci. Se si desidera visualizzare solo le richieste soggette ad un rilascio specifico, usare ME55.


Controlla la strategia di rilascio rilevante per il documento di acquisto

Richiamare transazione CL30N

Inserire i valori delle caratteristiche. Il risultato dovrebbe restituire solo una strategia di release univoca. Le strategie di rilascio sovrapposte non sono consentite.

DEBUG

Per le RdA, il FM  ME_REL_STRATEGY_REQUISITION, verifica se è stata adottata un strategia sul item della Rda (al suo interno richiama il FM ME_REL_STRATEGIE_EBAN) o a livello di testata della Rda ( al suo interno richiama il FM ME_REL_GENERAL_STRATEGY_EBAN).

Questo Programma: LEBNDF01 – è usato per le richieste, e richiama il FM CLSC_SELECT_OBJECTS

Per gli OdA, nell’include MM06EF0S_STRATEGIE_CEKKO (se installata la nota 329898), debuggare:

  IF sy-subrc EQ AND NOT l_active IS INITIAL.
    
CALL FUNCTION 'EXIT_SAPLEBND_002'
      
EXPORTING
        i_cekko  
cekko
        it_bekpo 
pot[]
        it_beket 
ett[]
        it_ekknu 
knt[]
      
IMPORTING
        e_cekko  
cekko.
  
ENDIF.

Per gli OdA, se NON E’ installata la nota 329898, debuggare il FM ME_REL_STRATEGIE_EKKO
 

mercoledì 30 ottobre 2019

ABAP: Creare file Excel su Application Server

Creare file Excel su Application Server

Di seguito riporto un semplice programma ABAP, che legge i dati di un OdA, e li scrive in un file excel che salviamo sul server:

In fondo c'è un alternativa al primo programma

In input il programma richiede il percorso del file sul server:

In ouput, sul server, verrà scritto un file excel che può essere scaricato con la transazione CG3Y in formato binario. L'output è il seguente:


Ecco il programma che può essere copiato ed eseguito:

REPORT z_excel_server2.

TYPES: BEGIN OF ty_dati,
         ebeln TYPE ekko-ebeln,
         bsart TYPE ekko-bsart,
         aedat TYPE ekko-aedat,
         ernam TYPE ekko-ernam,
       END OF ty_dati,
       tt_dati TYPE STANDARD TABLE OF ty_dati.

DATA : g_xstring   TYPE xstring,
       gt_bintab   TYPE solix_tab,
       gt_dati     TYPE tt_dati,
       gt_fieldcat TYPE lvc_t_fcat.

SELECTION-SCREEN: BEGIN OF BLOCK block1 WITH FRAME TITLE text1.
PARAMETERS: p_filese TYPE dxlpath LOWER CASE.
SELECTION-SCREEN: END OF BLOCK block1.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_filese.
*Search file in server directory
  PERFORM search_server.


START-OF-SELECTION.

  FREE: gt_bintab, gt_dati, gt_fieldcat.
  CLEAR: g_xstring.

  PERFORM estrai_dati TABLES gt_dati.

  IF NOT gt_dati[] IS INITIAL.
    PERFORM crea_excel USING gt_dati gt_fieldcat
                       CHANGING g_xstring.

    PERFORM write_excel USING g_xstring.

  ELSE.
    MESSAGE e000(db) WITH 'Non esistono dati da estrarre'.
  ENDIF.

  FREE: gt_dati.

END-OF-SELECTION.

*&---------------------------------------------------------------------*
*&      Form  SEARCH_SERVER
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM search_server .
  CLEAR: p_filese.
  CALL FUNCTION '/SAPDMC/LSM_F4_SERVER_FILE'
    IMPORTING
      serverfile       = p_filese
    EXCEPTIONS
      canceled_by_user = 1
      OTHERS           = 2.
ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  ESTRAI_DATI
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM estrai_dati TABLES pt_dati TYPE tt_dati.

* Estraggo dati da esportare
  SELECT ebeln bsart aedat ernam
     INTO TABLE pt_dati
     FROM ekko
     UP TO 10 ROWS
     ORDER BY PRIMARY KEY.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  CREA_EXCEL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM crea_excel USING pt_dati     TYPE tt_dati
                      pt_fieldcat TYPE lvc_t_fcat
             CHANGING p_xstring.

  DATA: is_layout     TYPE lvc_s_layo,
        it_sort       TYPE lvc_t_sort,
        it_filt       TYPE lvc_t_filt,
        it_hyperlinks TYPE lvc_t_hype.

  DATA(lt_data) = REF #( pt_dati ).



** PER VERSIONI PRECEDENTI DI SAP, INVECE DI USARE L'ISTRUZIONE PRECEDENTE
** USARE QUESTE ISTRUZIONI COMMENTATE, E COMMENTATE QUELLA PRECEDENTE
**  DATA: lt_data2 TYPE REF TO data.
**  FIELD-SYMBOLS: <ltfs_data2> TYPE STANDARD TABLE.
**  CREATE DATA lt_data2 type STANDARD TABLE OF ty_dati.
**  aSSIGN lt_data2->* TO <ltfs_data2>.
**  <ltfs_data2>[] = pt_dati[].
** PER VERSIONI PRECEDENTI

  CLEAR: is_layout.
  FREE: it_sort, it_filt, it_hyperlinks.

  IF pt_fieldcat IS INITIAL.
    FIELD-SYMBOLS: <tab> TYPE STANDARD TABLE.
    ASSIGN lt_data->* TO <tab>.
** PER VERSIONI PRECEDENTI DI SAP, INVECE DI USARE L'ISTRUZIONE PRECEDENTE
** USARE QUESTA ISTRUZIONE COMMENTATA, E COMMENTATE QUELLA PRECEDENTE
*    ASSIGN lt_data2->* TO <tab>.
    TRY.
        cl_salv_table=>factory(
        EXPORTING
          list_display = abap_false
        IMPORTING
          r_salv_table = DATA(salv_table)
        CHANGING
          t_table      = <tab> ).

        DATA(lt_fcat) = cl_salv_controller_metadata=>get_lvc_fieldcatalog(
                                 r_columns      = salv_table->get_columns( )
                                 r_aggregations = salv_table->get_aggregations( ) ).
      CATCH cx_salv_msg.
        RETURN.
    ENDTRY.

  ELSE.
    lt_fcat = pt_fieldcat.
  ENDIF.

  cl_salv_bs_lex=>export_from_result_data_table(
    EXPORTING
      is_format            = if_salv_bs_lex_format=>mc_format_xlsx
      ir_result_data_table =  cl_salv_ex_util=>factory_result_data_table(
                                              r_data                      = lt_data
                                              s_layout                    = is_layout
                                              t_fieldcatalog              = lt_fcat
                                              t_sort                      = it_sort
                                              t_filter                    = it_filt
                                              t_hyperlinks                = it_hyperlinks )
    IMPORTING
      er_result_file       = p_xstring ).

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  WRITE_EXCEL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_G_XSTRING  text
*----------------------------------------------------------------------*
FORM write_excel  USING p_xstring.

  DATA: lt_rawdata      TYPE solix_tab,
        lv_bytecount    TYPE i,
        lv_bytes_remain TYPE i.

  FIELD-SYMBOLS: <rawdata> LIKE LINE OF lt_rawdata.

  CLEAR: lv_bytecount, lv_bytes_remain.
  FREE: lt_rawdata.

  lt_rawdata = cl_bcs_convert=>xstring_to_solix( iv_xstring  = p_xstring ).
  lv_bytecount = xstrlen( p_xstring ).

  OPEN DATASET p_filese FOR OUTPUT IN BINARY MODE.
  CHECK sy-subrc = 0.

  lv_bytes_remain = lv_bytecount.

  UNASSIGN <rawdata>.
  LOOP AT lt_rawdata ASSIGNING <rawdata>.

    AT LAST.
      CHECK lv_bytes_remain >= 0.
      TRANSFER <rawdata> TO p_filese LENGTH lv_bytes_remain.
      EXIT.
    ENDAT.

    TRANSFER <rawdata> TO p_filese.
    SUBTRACT 255 FROM lv_bytes_remain.  " Solix has length 255
  ENDLOOP.

  CLOSE DATASET p_filese.

  IF sy-repid <> sy-cprog AND sy-cprog IS NOT INITIAL.  " no need to display anything if download was selected and report was called for demo purposes
    LEAVE PROGRAM.
  ELSE.
    MESSAGE 'File Creato' TYPE 'S'.
  ENDIF.

ENDFORM.


2o PROGRAMMA (SOLO SE NEL VOSTRO SISTEMA E' INSTALLATO il pacchetto ZABAP2XLSX) che deve essere scaricato


Questo programma fa la stessa cosa di quello precedente, ma l'output del file excel creato sul server è il seguente:



Ecco il 2o programma che può essere copiato ed eseguito:


REPORT z_excel_server.

* Definizione Classe
CLASS lcl_output DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      output         IMPORTING cl_excel            TYPE REF TO zcl_excel
                               iv_writerclass_name TYPE clike OPTIONAL.

  PRIVATE SECTION.
    METHODS:
      download_backend.

    DATA: xdata     TYPE xstring,             " Will be used for sending as email
          t_rawdata TYPE solix_tab,           " Will be used for downloading or open directly
          bytecount TYPE i.                   " Will be used for downloading or open directly
ENDCLASS.                    "lcl_output DEFINITION

* Dichiarazione variabili
TYPES: BEGIN OF ty_dati,
         ebeln TYPE ekko-ebeln,
         bsart TYPE ekko-bsart,
         aedat TYPE ekko-aedat,
         ernam TYPE ekko-ernam,
       END OF ty_dati,
       tt_dati TYPE STANDARD TABLE OF ty_dati.

DATA: lo_excel         TYPE REF TO zcl_excel,
      lo_worksheet     TYPE REF TO zcl_excel_worksheet,
      column_dimension TYPE REF TO zcl_excel_worksheet_columndime,
      gt_dati          type tt_dati.

SELECTION-SCREEN: BEGIN OF BLOCK block1 WITH FRAME TITLE text1.
PARAMETERS: p_filese TYPE dxlpath LOWER CASE.
SELECTION-SCREEN: END OF BLOCK block1.

* Implementazione Classe
CLASS lcl_output IMPLEMENTATION.
  METHOD output.

    DATA: cl_output TYPE REF TO lcl_output,
          cl_writer TYPE REF TO zif_excel_writer.

    IF iv_writerclass_name IS INITIAL.
      CREATE OBJECT cl_output.
      CREATE OBJECT cl_writer TYPE zcl_excel_writer_2007.
    ELSE.
      CREATE OBJECT cl_output.
      CREATE OBJECT cl_writer TYPE (iv_writerclass_name).
    ENDIF.
    cl_output->xdata = cl_writer->write_file( cl_excel ).

* After 6.40 via cl_bcs_convert
    cl_output->t_rawdata = cl_bcs_convert=>xstring_to_solix( iv_xstring  = cl_output->xdata ).
    cl_output->bytecount = xstrlen( cl_output->xdata ).

    cl_output->download_backend( ).

  ENDMETHOD.                    "output


  METHOD download_backend.
    DATA: bytes_remain TYPE i.
    FIELD-SYMBOLS: <rawdata> LIKE LINE OF t_rawdata.

    OPEN DATASET p_filese FOR OUTPUT IN BINARY MODE.
    CHECK sy-subrc = 0.

    bytes_remain = bytecount.

    LOOP AT t_rawdata ASSIGNING <rawdata>.

      AT LAST.
        CHECK bytes_remain >= 0.
        TRANSFER <rawdata> TO p_filese LENGTH bytes_remain.
        EXIT.
      ENDAT.

      TRANSFER <rawdata> TO p_filese.
      SUBTRACT 255 FROM bytes_remain.  " Solix has length 255

    ENDLOOP.

    CLOSE DATASET p_filese.

    IF sy-repid <> sy-cprog AND sy-cprog IS NOT INITIAL.  " no need to display anything if download was selected and report was called for demo purposes
      LEAVE PROGRAM.
    ELSE.
      MESSAGE 'File Creato' TYPE 'S'.
    ENDIF.
  ENDMETHOD.                    "download_backend

ENDCLASS.                    "lcl_output IMPLEMENTATION

* Scegliere percorso dove scriver ei lfile sul server
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_filese.
  PERFORM search_server.

* Main
START-OF-SELECTION.
  free: gt_dati.
  PERFORM estrai_dati TABLES gt_dati.

  IF NOT gt_dati[] IS INITIAL.
    PERFORM crea_excel USING gt_dati.
  ELSE.
    MESSAGE e000(db) WITH 'Non esistono dati da estrarre'.
  ENDIF.

END-OF-SELECTION.

*&---------------------------------------------------------------------*
*&      Form  SEARCH_SERVER
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM search_server .
  CLEAR: p_filese.
  CALL FUNCTION '/SAPDMC/LSM_F4_SERVER_FILE'
    IMPORTING
      serverfile       = p_filese
    EXCEPTIONS
      canceled_by_user = 1
      OTHERS           = 2.
ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  ESTRAI_DATI
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM estrai_dati TABLES pt_dati TYPE tt_dati.

* Estraggo dati da esportare
  SELECT ebeln bsart aedat ernam
     INTO TABLE pt_dati
     FROM ekko
     UP TO 10 ROWS
     ORDER BY PRIMARY KEY.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  CREA_EXCEL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM crea_excel USING pt_dati TYPE tt_dati.
  DATA: ls_table_settings       TYPE zexcel_s_table_settings.

  CHECK NOT pt_dati[] IS INITIAL.

  CLEAR: ls_table_settings.

  " Creates active sheet
  CREATE OBJECT lo_excel.

  " Get active sheet
  lo_worksheet = lo_excel->get_active_worksheet( ).
  lo_worksheet->set_title( ip_title = 'Dati EKKO').

  ls_table_settings-table_style       = zcl_excel_table=>builtinstyle_medium2.
  ls_table_settings-show_row_stripes  = abap_true.
  ls_table_settings-nofilters         = abap_true.

  lo_worksheet->bind_table( ip_table          = pt_dati
                            is_table_settings = ls_table_settings ).

  lo_worksheet->freeze_panes( ip_num_rows = 3 ). "freeze column headers when scrolling
  column_dimension = lo_worksheet->get_column_dimension( ip_column = 'E' ). "make date field a bit wider
  column_dimension->set_width( ip_width = 11 ).

*** Create output
  lcl_output=>output( lo_excel ).
ENDFORM.