Creación de fuentes de extracción utilizando módulos de función (BW)

0
La creación de fuentes desde SAP a BW puede ser variada, desde una simple vista replicada a BW, un infoset, una tabla, donde los datos pueden ser datos maestros, textos o bien transaccionales, es decir que conforman datos del día a día en una empresa ( Pedidos, facturas, ordenes compra, etc.), en este artículo intentare explicar el uso de uno de los más elaborados por no decir complejo, el de los creados a partir de un módulo de función, donde principalmente se utiliza ABAP como herramienta de desarrollo, esto se realiza del lado del emisor de datos en este caso SAP ECC.

Primero, necesitamos crear una estructura que será la base de la tabla que recibirá la información. Creamos la estructura por la SE11 y colocamos los campos que se  van a obtener en la extracción.



Para crear la función que genera la extracción nos dirigimos primero a la SE80 y colocamos el módulo de funcion RSAX ahí, encontraremos dos módulos de funciones que podemos usar para generar una copia de la misma y migren las variables de dicha función, con el fin que se copien todos sus parámetros y no te genere error al momento de probar tu extractor.

Ubicamos la función  RSAX_BIW_GET_DATA_SIMPLE presionamos el botón derecho del mouse y escogemos COPIAR

En la ventana que nos aparece completamos lo siguiente:

De: Es el nombre de la función que vamos a copiar
A: Colocamos el nombre de nuestra función 
Grupo funciones: Colocamos el grupo de función donde lo vas a crear.


Nos dirigimos a nuestro módulo de función y verificamos en la pestaña IMPORT, TABLAS y COD FTE se haya generado sus respectivas variables.


En La pestaña TABLAS ubicamos E_T_DATA que es la tabla de salida y le cambiamos su tipo de referencia por la estructura que creamos que va tener nuestra tabla de salida. Para este caso ZMM_MOV_MER_BW


En la pestaña COD FTE  ya está generado la lógica del extractor, es por ello que yo te recomiendo hacer la copia de la función de ejemplo, puesto que la base de lectura ya estaría desarrollada y solo quedaría plantear la lógica de obtención para la tabla de respuesta. Copia el siguiente código, ahí indico en un comentario donde deberías insertar tu programación.
FUNCTION ZMF_MM_MOV_MER_BW.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(I_REQUNR) TYPE  SRSC_S_IF_SIMPLE-REQUNR
*"     VALUE(I_DSOURCE) TYPE  SRSC_S_IF_SIMPLE-DSOURCE OPTIONAL
*"     VALUE(I_MAXSIZE) TYPE  SRSC_S_IF_SIMPLE-MAXSIZE OPTIONAL
*"     VALUE(I_INITFLAG) TYPE  SRSC_S_IF_SIMPLE-INITFLAG OPTIONAL
*"     VALUE(I_READ_ONLY) TYPE  SRSC_S_IF_SIMPLE-READONLY OPTIONAL
*"     VALUE(I_REMOTE_CALL) TYPE  SBIWA_FLAG DEFAULT SBIWA_C_FLAG_OFF
*"  TABLES
*"      I_T_SELECT TYPE  SRSC_S_IF_SIMPLE-T_SELECT OPTIONAL
*"      I_T_FIELDS TYPE  SRSC_S_IF_SIMPLE-T_FIELDS OPTIONAL
*"      E_T_DATA STRUCTURE  SFLIGHT OPTIONAL
*"  EXCEPTIONS
*"      NO_MORE_DATA
*"      ERROR_PASSED_TO_MESS_HANDLER
*"----------------------------------------------------------------------

* Example: DataSource for table SFLIGHT
  TABLES: SFLIGHT.

* Auxiliary Selection criteria structure
  DATA: L_S_SELECT TYPE SRSC_S_SELECT.

* Maximum number of lines for DB table
  STATICS: S_S_IF TYPE SRSC_S_IF_SIMPLE,

* counter
          S_COUNTER_DATAPAKID LIKE SY-TABIX,

* cursor
          S_CURSOR TYPE CURSOR.
* Select ranges
  RANGES: L_R_CARRID  FOR SFLIGHT-CARRID,
          L_R_CONNID  FOR SFLIGHT-CONNID.

* Initialization mode (first call by SAPI) or data transfer mode
* (following calls) ?
  IF I_INITFLAG = SBIWA_C_FLAG_ON.

************************************************************************
* Initialization: check input parameters
*                 buffer input parameters
*                 prepare data selection
************************************************************************

*************************************************************
* NOTA 1
“ZBW_EXTRACTOR cámbialo por el nombre de tu fuente de datos
*************************************************************

* Check DataSource validity
    CASE I_DSOURCE.
      WHEN 'ZBW_EXTRACTOR'. 
      WHEN OTHERS.
        IF 1 = 2. MESSAGE E009(R3). ENDIF.
* this is a typical log call. Please write every error message like this
        LOG_WRITE 'E'                  "message type
                  'R3'                 "message class
                  '009'                "message number
                  I_DSOURCE   "message variable 1
                  ' '.                 "message variable 2
        RAISE ERROR_PASSED_TO_MESS_HANDLER.
    ENDCASE.

    APPEND LINES OF I_T_SELECT TO S_S_IF-T_SELECT.

* Fill parameter buffer for data extraction calls
    S_S_IF-REQUNR    = I_REQUNR.
    S_S_IF-DSOURCE = I_DSOURCE.
    S_S_IF-MAXSIZE   = I_MAXSIZE.

* Fill field list table for an optimized select statement
* (in case that there is no 1:1 relation between InfoSource fields
* and database table fields this may be far from beeing trivial)
    APPEND LINES OF I_T_FIELDS TO S_S_IF-T_FIELDS.

  ELSE.                 "Initialization mode or data extraction ?

************************************************************************
* Data transfer: First Call      OPEN CURSOR + FETCH
*                Following Calls FETCH only
************************************************************************

* First data package -> OPEN CURSOR
    IF S_COUNTER_DATAPAKID = 0.

*************************************************************
NOTA 2 
ES ACA  DONDE DEBES INGRESAR TU LOGICA, Y COMO EN ESTE EJEMPLO GENERAR TUS RANGOS QUE SERIAN LOS VALORES DE ENTRADA

* Fill range tables BW will only pass down simple selection criteria
* of the type SIGN = 'I' and OPTION = 'EQ' or OPTION = 'BT'.

      LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'CARRID'.
        MOVE-CORRESPONDING L_S_SELECT TO L_R_CARRID.
        APPEND L_R_CARRID.
      ENDLOOP.

      LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'CONNID'.
        MOVE-CORRESPONDING L_S_SELECT TO L_R_CONNID.
        APPEND L_R_CONNID.
      ENDLOOP.

* Determine number of database records to be read per FETCH statement
* from input parameter I_MAXSIZE. If there is a one to one relation
* between DataSource table lines and database entries, this is trivial.
* In other cases, it may be impossible and some estimated value has to
* be determined.
      OPEN CURSOR WITH HOLD S_CURSOR FOR
      SELECT (S_S_IF-T_FIELDS) FROM SFLIGHT
                               WHERE CARRID  IN L_R_CARRID AND
                                     CONNID  IN L_R_CONNID.
    ENDIF.                             "First data package ?

*************************************************************


* Fetch records into interface table.
*   named E_T_'Name of extract structure'.
    FETCH NEXT CURSOR S_CURSOR
               APPENDING CORRESPONDING FIELDS
               OF TABLE E_T_DATA
               PACKAGE SIZE S_S_IF-MAXSIZE.

    IF SY-SUBRC <> 0.
      CLOSE CURSOR S_CURSOR.
      RAISE NO_MORE_DATA.
    ENDIF.

    S_COUNTER_DATAPAKID = S_COUNTER_DATAPAKID + 1.

  ENDIF.              "Initialization mode or data extraction ?

ENDFUNCTION.




Adicionalmente, se debe crear un include para el método LOG_WRITE para que muestre un log cuando se conecte o no el cursor. Solo genera el include bajo el nombre ZLOGEXTRACTOR y copia esta lógica.
*&  Include           ZLOGEXTRACTOR
*&---------------------------------------------------------------------*
DATA: RSAL_SAVE_SUBRC LIKE SY-SUBRC,
      RSAL_S_LOGPARMS LIKE RSLOGPARMS.

* --------------------------------------------------------------------
*  Open application log
* --------------------------------------------------------------------
DEFINE LOG_OPEN.
  RSAL_S_LOGPARMS-FUNCTION   = &1.
  RSAL_S_LOGPARMS-LOGSYS     = &2.
  RSAL_S_LOGPARMS-INFOSOURCE = &3.
  RSAL_S_LOGPARMS-TYPE       = &4.
  CALL FUNCTION 'RSAL_LOG_OPEN'
       EXPORTING
            I_FUNCTION      = RSAL_S_LOGPARMS-FUNCTION
            I_LOGSYS        = RSAL_S_LOGPARMS-LOGSYS
            I_INFOSOURCE    = RSAL_S_LOGPARMS-INFOSOURCE
            I_TYPE          = RSAL_S_LOGPARMS-TYPE.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Set logical system to log
* --------------------------------------------------------------------
DEFINE LOG_SET_LOGSYS.
  RSAL_S_LOGPARMS-LOGSYS     = &1.
  CALL FUNCTION 'RSAL_LOG_SET_LOGSYS'
       EXPORTING
            I_LOGSYS        = RSAL_S_LOGPARMS-LOGSYS.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Reset logical system to log
* --------------------------------------------------------------------
DEFINE LOG_RESET_LOGSYS.
  CALL FUNCTION 'RSAL_LOG_RESET_LOGSYS'.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Set InfoSource to log
* --------------------------------------------------------------------
DEFINE LOG_SET_ISOURCE.
  RSAL_S_LOGPARMS-INFOSOURCE = &1.
  RSAL_S_LOGPARMS-TYPE       = &2.
  CALL FUNCTION 'RSAL_LOG_SET_ISOURCE'
       EXPORTING
            I_OBJECT = RSAL_S_LOGPARMS-INFOSOURCE
            I_TYPE   = RSAL_S_LOGPARMS-TYPE.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Reset InfoSource to log
* --------------------------------------------------------------------
DEFINE LOG_RESET_ISOURCE.
  CALL FUNCTION 'RSAL_LOG_RESET_ISOURCE'.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Write log using specified message (using only first two message
*  values)
* --------------------------------------------------------------------
DEFINE LOG_WRITE.
  RSAL_SAVE_SUBRC = SY-SUBRC.
  RSAL_S_LOGPARMS-MSGTY = &1.
  RSAL_S_LOGPARMS-MSGID = &2.
  RSAL_S_LOGPARMS-MSGNO = &3.
  RSAL_S_LOGPARMS-MSGV1 = &4.
  RSAL_S_LOGPARMS-MSGV2 = &5.
  CALL FUNCTION 'RSAL_LOG_WRITE'
       EXPORTING
            I_MSGTY      = RSAL_S_LOGPARMS-MSGTY
            I_MSGID      = RSAL_S_LOGPARMS-MSGID
            I_MSGNO      = RSAL_S_LOGPARMS-MSGNO
            I_MSGV1      = RSAL_S_LOGPARMS-MSGV1
            I_MSGV2      = RSAL_S_LOGPARMS-MSGV2.
  SY-SUBRC = RSAL_SAVE_SUBRC.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Write message with all message parameters
* --------------------------------------------------------------------
DEFINE LOG_WRITE_FULL.
  RSAL_SAVE_SUBRC = SY-SUBRC.
  RSAL_S_LOGPARMS-MSGTY = &1.
  RSAL_S_LOGPARMS-MSGID = &2.
  RSAL_S_LOGPARMS-MSGNO = &3.
  RSAL_S_LOGPARMS-MSGV1 = &4.
  RSAL_S_LOGPARMS-MSGV2 = &5.
  RSAL_S_LOGPARMS-MSGV3 = &6.
  RSAL_S_LOGPARMS-MSGV4 = &7.
  CALL FUNCTION 'RSAL_LOG_WRITE'
       EXPORTING
            I_MSGTY      = RSAL_S_LOGPARMS-MSGTY
            I_MSGID      = RSAL_S_LOGPARMS-MSGID
            I_MSGNO      = RSAL_S_LOGPARMS-MSGNO
            I_MSGV1      = RSAL_S_LOGPARMS-MSGV1
            I_MSGV2      = RSAL_S_LOGPARMS-MSGV2
            I_MSGV3      = RSAL_S_LOGPARMS-MSGV3
            I_MSGV4      = RSAL_S_LOGPARMS-MSGV4.
  SY-SUBRC = RSAL_SAVE_SUBRC.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Write log using last error message from 'sy' variables
*  without closing log
* --------------------------------------------------------------------
DEFINE LOG_WRITE_ERROR.
  RSAL_SAVE_SUBRC = SY-SUBRC.
  CALL FUNCTION 'RSAL_LOG_WRITE'.
  SY-SUBRC = RSAL_SAVE_SUBRC.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Write log using last error message from 'sy' variables
*  and close log
* --------------------------------------------------------------------
DEFINE LOG_WRITE_ERROR_AND_CLOSE.
  RSAL_SAVE_SUBRC = SY-SUBRC.
  CALL FUNCTION 'RSAL_LOG_WRITE'
       EXPORTING
            I_CLOSE_LOG  = 'X'.
  SY-SUBRC = RSAL_SAVE_SUBRC.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Write log using last error message from 'sy' variables,
*  close log and send message
* --------------------------------------------------------------------
define log_write_error_close_message.
  rsal_save_subrc = sy-subrc.
  call function 'RSAL_LOG_WRITE'
       exporting
            i_close_log  = 'X'.
  message id sy-msgid type sy-msgty number sy-msgno
          with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 raising &1.
  sy-subrc = rsal_save_subrc.
end-of-definition.

* --------------------------------------------------------------------
*  Write internal log tables to database and close log
* --------------------------------------------------------------------
DEFINE LOG_CLOSE.
  RSAL_SAVE_SUBRC = SY-SUBRC.
  CALL FUNCTION 'RSAL_LOG_CLOSE'.
  SY-SUBRC = RSAL_SAVE_SUBRC.
END-OF-DEFINITION.

* --------------------------------------------------------------------
*  Rollback previous database operations write internal log
*  tables to database and close log
* --------------------------------------------------------------------
DEFINE LOG_CLOSE_AND_ROLLBACK.
  RSAL_SAVE_SUBRC = SY-SUBRC.
  ROLLBACK WORK.
  CALL FUNCTION 'RSAL_LOG_CLOSE'.
  SY-SUBRC = RSAL_SAVE_SUBRC.
END-OF-DEFINITION.


Ahora guarda y activa el módulo de función. Hasta ahí, ya tenemos la parte ABAP culminada y procedemos a generar la fuente de dato del extractor

Creamos el origen de datos genérico en RSO2 recuerda que el nombre que escojas es lo que vas colocar en el código de la función.


Incluimos el componente de aplicación, es necesario que completes los campos de descripción y para incluir la estructura y nuestro módulo de función presionamos el botón EXTRACCION VIA MF


Presionamos el botón DELTA GENERICO para generar el extractor DELTA y marcamos las siguientes opciones. Para el caso del número de componente tienes que preguntar al funcional o según el detalle de la especificación.

La función del Delta Genérico en los extractores es definir un campo de la tabla que se va a utilizar como base para la obtención (extracción) de registros nuevos. Así si por ejemplo se define un campo “Fecha de Creación” para el delta genérico y los datos que se extraen cada vez que se ejecuta el extractor son los que se crearon desde la última fecha que se ejecuto, en vez de hacer un “full”, es decir obtener todos los datos de la tabla cada vez que se ejecuta el mismo. A este tipo de extracción se la denomina extracción “Delta”.


Grabas 2 veces y tu fuente de datos estaría creada y lista para que puedas realizar tus pruebas.

Tags

Publicar un comentario

0Comentarios
Publicar un comentario (0)