Additional Blogs by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member
0 Kudos

I got tired to create always test-data in R/3 that I'm able to test my delta load.
So the idea to reload the data again into delta queue came up and a development idea was born.
The idea is, to enter what you want to take over: Which datasource, which request, datapack, records.
With this information you enter in R/3 BW reads the data and write them into a table which is created on the fly and hands over this data to R/3 - you can still edit this information and after saving the data is written into deltaqueue and you're able to load the request again.
If you have the RFC'connection setup you would be able to take over some PSA requests from productive to quality/development system - so you can test your load with productive data.

The first problem was how to transfer data from BW to R/3. The rfc table read FM was not working, because its to small. Then the idea was calling an RFC FM in BW which fills a table and then return this data to R/3 again, but I don't wanted to create a table for each datasource.

That's why I did this dynamic solution. I'm not a perfect ABAP programer - so if you have some hints / ideas please let me know.

So first create in R/3 the Report ZBW_FILL_QUEUE with this code and includes

&----

*& Report  ZBW_FILL_QUEUE
*&
&----

*&
*&
&----


REPORT  ZBW_FILL_QUEUE.


type-pools : abap,
             SLIS.


DATA:  lt_FIELDCAT TYPE LVC_T_FCAT,
       ls_FIELDCAT TYPE LVC_S_FCAT,
       ls_LAYOUT   TYPE LVC_S_LAYO.


field-symbols: ----

***INCLUDE ZBW_FILL_QUEUE_CREATE_DYNAMF01 .
----

&----

*&      Form  create_dynamic_itab
&----

  •       text
----

  • -->  p1        text
  • <--  p2        text
----

FORM create_dynamic_itab .


  • Create dynamic internal table and assign to FS
  call method cl_alv_table_create=>create_dynamic_table
               exporting
                  it_fieldcatalog = ifc
               importing
                  ep_table        = dy_table.


  assign dy_table->* to .


  • Create dynamic work area and assign to FS
  create data dy_line like line of .


  • Create dynamic internal table and assign to FS
  call method cl_alv_table_create=>create_dynamic_table
               exporting
                  it_fieldcatalog = ifc_req
               importing
                  ep_table        = dy_table.


  assign dy_table->* to .


  • Create dynamic work area and assign to FS
  create data dy_line like line of ----

***INCLUDE ZBW_FILL_QUEUE_GET_STRUCTURF01 .
----

&----

*&      Form  get_structure
&----

  •       text
----

  • -->  p1        text
  • <--  p2        text
----

FORM get_structure .


data : idetails type abap_compdescr_tab,
       xdetails type abap_compdescr.


data : ls_dd03l type dd03l,
       lt_dd03l type table of dd03l.


data : ref_table_des type ref to cl_abap_structdescr.


  • Get the structure of the table.
  ref_table_des ?=
      cl_abap_typedescr=>describe_by_name( lv_STRUCTURE ).
  idetails[] = ref_table_des->components[].


select *
into corresponding fields of table lt_dd03l
from dd03l
where  tabname = lv_structure
order by position.


  clear xfc.
    xfc-fieldname = 'REQUEST' .
    xfc-datatype = 'RSREQUNR'.
    xfc-inttype = 'C'.
    xfc-intlen = '30'.
    xfc-decimals = ''.
    append xfc to ifc_req.
  clear xfc.
    xfc-fieldname = 'DATAPAKID' .
    xfc-datatype = 'RSDATAPID'.
    xfc-inttype = 'N'.
    xfc-intlen = '6'.
    xfc-decimals = ''.
    append xfc to ifc_req.
  clear xfc.
    xfc-fieldname = 'PARTNO' .
    xfc-datatype = 'RSPARTVAL'.
    xfc-inttype = 'I'.
    xfc-intlen = '4'.
    xfc-decimals = ''.
    append xfc to ifc_req.
  clear xfc.
    xfc-fieldname = 'RECORD' .
    xfc-datatype = 'RSARECORD'.
    xfc-inttype = 'I'.
    xfc-intlen = '4'.
    xfc-decimals = ''.
    append xfc to ifc_req.


Loop at lt_dd03l_fieldsbw into ls_dd03l_fieldsbw.
  read table lt_dd03l into ls_dd03l with key fieldname = ls_dd03l_fieldsbw-fieldname.
  if sy-subrc = 0.
    clear xfc.
    xfc-fieldname = ls_dd03l-fieldname.
    xfc-datatype  = ls_dd03l-rollname.
    xfc-inttype   = ls_dd03l-inttype.
    xfc-intlen    = ls_dd03l-leng.
    xfc-decimals  = ls_dd03l-decimals.
    append xfc to ifc_req.
  endif.
endloop.


  • loop at idetails into xdetails.
  •    clear xfc.
  •    xfc-fieldname = xdetails-name .
  •    xfc-datatype = xdetails-type_kind.
  •    xfc-inttype = xdetails-type_kind.
  •    xfc-intlen = xdetails-length.
  •    xfc-decimals = xdetails-decimals.
  •    append xfc to ifc_req.
  •    append xfc to ifc.
  • endloop.
loop at lt_dd03l into ls_dd03l.
  clear xfc.
  if ls_dd03l-fieldname ne 'MANDT'
    AND ls_dd03l-fieldname ne '.INCLUDE'
    AND ls_dd03l-fieldname ne '.INCLU--AP'.
    xfc-fieldname = ls_dd03l-fieldname.
    xfc-datatype  = ls_dd03l-rollname.
    xfc-inttype   = ls_dd03l-inttype.
    xfc-intlen    = ls_dd03l-leng.
    xfc-decimals  = ls_dd03l-decimals.
    append xfc to ifc.
  •    append xfc to ifc_req.
  endif.
endloop.


ENDFORM.                    " get_structure

Include ZBW_FILL_QUEUE_USER_COMMANDF01

----

***INCLUDE ZBW_FILL_QUEUE_USER_COMMANDF01 .
----

&----

*&      Form  USER_COMMAND
&----

  •       text
----

  • -->  p1        text
  • <--  p2        text
----


    form user_command using r_ucomm type sy-ucomm
                            rs_selfield type slis_selfield.


      if r_ucomm = '&DATA_SAVE'.


        message i000(0k) with 'Die Daten werden jetzt in die Delta Queue geschrieben'.


        CALL FUNCTION 'RSC1_TRFC_QUEUE_WRITE'
          EXPORTING
            I_ISOURCE           = lv_DATASOURCE
            I_NO_FLUSH          = 'X'
          IMPORTING
            E_SUBRC             = lv_subrc
          TABLES
            I_T_DATA            =
  •           E_T_CALLID          =
          EXCEPTIONS
            NAME_TOO_LONG       = 1
            OTHERS              = 2
                  .


        IF SY-SUBRC <> 0.
  •         MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
  •                 WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
        ENDIF.
        commit work.


        call function 'REUSE_ALV_LIST_DISPLAY'
             exporting
                  i_structure_name = lv_Structure
             tables
                  t_outtab         = ----

***INCLUDE ZBW_FILL_QUEUE_ZPSA_TASKINFF01 .
----

&----

*&      Form  ZPSA_TASKINFO
&----

  •       text
----

  • -->  p1        text
  • <--  p2        text
----

FORM ZPSA_TASKINFO USING lv_TASKNAME.
  • Receiving Results of aRFC
  •    RECEIVE RESULTS FROM FUNCTION 'ZPSA_FILL_TABLE'
  •         importing
  •               ex_spfli = spfli
  •               sys      = system
  •         exceptions
  •               invalid_data = 1.
*
    • Processing Wait Condition
  •         return = sy-subrc.
         lv_flag = 'X'.
  • Goto Wait Statement
ENDFORM.                    " ZPSA_TASKINFO




 

After you created this in R/3 you have to create the following Objects in BW:

Dict. Table ZPSA_TABLE - this table is deleted and recreated when you load data from the several datasources - depending on the structure of the corresponding datasource. But that you can create the functions, you have to create the tabel initialy with some fields. Create this table as a $tmp object - do not put this in a transport package. Othwerwise you cannot change it on the fly. If you transport the code form Dev to Qual system, you have first to create manually ZPSA_TABLE in Qual as $TMP object, and then transport the functions.

Class/Methode in BW: ZCL_BC_DYN

Parameters are:
- VALUE(TABNAME_TARGET) TYPE DD02L-TABNAME
- VALUE(TABNAME_SOURCE) TYPE DD02L-TABNAME
- STATUS TYPE SY-SUBRC

 

Then create the 4 Functions in BW - make sure they are RFC enabled:

Function ZPSA_CREATE_TABLE

FUNCTION ZPSA_CREATE_TABLE.
*"----
""Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(DATASOURCE) TYPE  ROOSOURCER
*"     VALUE(LOGSYS) TYPE  RSSLOGSYS
*"----


DATA: ls_RSDSTS TYPE RSDSTS,
      lt_RSDSTS TYPE TABLE OF RSDSTS.


DATA: tabname_target  TYPE dd02l-tabname,
      tabname_source  TYPE dd02l-tabname.


DATA: gt_cl_bc_dyn TYPE REF TO zcl_bc_dyn,
      status TYPE sy-subrc.


tabname_target = 'ZPSA_TABLE'.


SELECT * FROM RSDSTS
  INTO CORRESPONDING FIELDS OF TABLE lt_RSDSTS
  WHERE OBJVERS = 'A'
  AND   DATASOURCE = DATASOURCE
  AND   LOGSYS     = LOGSYS
  ORDER BY PSA_VERSION DESCENDING.


LOOP AT lt_RSDSTS INTO ls_RSDSTS.
  tabname_source = ls_RSDSTS-PSA_TABLE.
  EXIT.
ENDLOOP.


DELETE FROM ZPSA_TABLE.


CALL FUNCTION 'RS_DD_DELETE_OBJ'
  EXPORTING
    NO_ASK                     = 'X'
    OBJNAME                    = tabname_target
    OBJTYPE                    = 'T'
  • CHANGING
  •   CORRNUM                    = ' '
  • EXCEPTIONS
  •   NOT_EXECUTED               = 1
  •   OBJECT_NOT_FOUND           = 2
  •   OBJECT_NOT_SPECIFIED       = 3
  •   PERMISSION_FAILURE         = 4
  •   DIALOG_NEEDED              = 5
  •   OTHERS                     = 6
          .


CREATE OBJECT gt_cl_bc_dyn.


*START-OF-SELECTION.


CALL METHOD gt_cl_bc_dyn->create_table
EXPORTING
tabname_target = tabname_target
tabname_source = tabname_source
IMPORTING
status = status .


COMMIT WORK AND WAIT.


ENDFUNCTION.


Function  ZPSA_EXECUTE

FUNCTION ZPSA_EXECUTE.
*"----
""Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(DATASOURCE) TYPE  ROOSOURCER
*"     VALUE(LOGSYS) TYPE  RSSLOGSYS
*"     VALUE(REQUEST) TYPE  RSREQUNR
*"     VALUE(DATAPAKID_LOW) TYPE  RSDATAPID
*"     VALUE(DATAPAKID_HIGH) TYPE  RSDATAPID
*"     VALUE(RECORD_LOW) TYPE  RSARECORD
*"     VALUE(RECORD_HIGH) TYPE  RSARECORD
*"     VALUE(QUELLSYSTEM) TYPE  RSSLOGSYS
*"  TABLES
*"      FIELDS STRUCTURE  DD03L
*"----


DATA: lv_QUELLSYSTEM TYPE RSSLOGSYS,
      lv_DATASOURCE TYPE ROOSOURCER,
      lv_REQUEST TYPE RSREQUNR,
      lv_DATAPAKIDL TYPE RSDATAPID,
      lv_DATAPAKIDH TYPE RSDATAPID,
      lv_RECORDL    TYPE RSARECORD,
      lv_RECORDH    TYPE RSARECORD.
  •      lv_TASKINFO   TYPE ZTRFC_RETURN_STATUS.
  •      lv_TASKNAME   TYPE C LENGTH 8.


lv_QUELLSYSTEM = QUELLSYSTEM.
lv_REQUEST     = REQUEST.
lv_DATASOURCE  = DATASOURCE.
lv_DATAPAKIDL  = DATAPAKID_LOW.
lv_DATAPAKIDH  = DATAPAKID_HIGH.
lv_RECORDL     = RECORD_LOW.
lv_RECORDH     = RECORD_HIGH.


*lv_RFCSYSTEM = 'D72_603'.
*lv_QUELLSYSTEM = 'D12_565'.
*lv_DATASOURCE = '2LIS_02_S015'.
*lv_REQUEST    = 'REQU_43A0NKQXQTFKMYOT91QGJLOOS'. "77 Einträge
*lv_DATASOURCE = '0ARTICLE_ATTR'.
*lv_REQUEST    = 'REQU_49M6DMR9RKI5OK9NJZMFRQEKC'. "18388 Einträge


CALL FUNCTION 'ZPSA_CREATE_TABLE'
  EXPORTING
    DATASOURCE       = lv_DATASOURCE
    LOGSYS           = lv_QUELLSYSTEM
          .


COMMIT WORK AND WAIT.


*lv_TASKNAME = '1'.


*CALL FUNCTION 'ZPSA_FILL_TABLE' STARTING NEW TASK lv_TASKNAME
    • PERFORMING ZPSA_TASKINFO ON END OF TASK
  • EXPORTING
  •    DATASOURCE       = lv_DATASOURCE
  •    LOGSYS           = lv_QUELLSYSTEM
  •    REQUEST          = lv_REQUEST
  •    DATAPAKID_LOW    = lv_DATAPAKIDL
  •    DATAPAKID_HIGH   = lv_DATAPAKIDH
  •    RECORD_LOW       = lv_RECORDL
  •    RECORD_HIGH      = lv_RECORDH
  •          .
*WAIT UNTIL lv_TASKINFO = 1.
  • WRITE:/ 'task_running'.


COMMIT WORK AND WAIT.


SELECT *
INTO   table FIELDS
FROM   DD03L
WHERE  TABNAME = 'ZPSA_TABLE'
order by position.


ENDFUNCTION.


Function  ZPSA_FILL_TABLE

FUNCTION ZPSA_FILL_TABLE.
*"----
""Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(DATASOURCE) TYPE  ROOSOURCER
*"     VALUE(LOGSYS) TYPE  RSSLOGSYS
*"     VALUE(REQUEST) TYPE  RSREQUNR
*"     VALUE(DATAPAKID_LOW) TYPE  RSDATAPID
*"     VALUE(DATAPAKID_HIGH) TYPE  RSDATAPID
*"     VALUE(RECORD_LOW) TYPE  RSARECORD
*"     VALUE(RECORD_HIGH) TYPE  RSARECORD
*"----


DATA: ls_RSDSTS TYPE RSDSTS,
      lt_RSDSTS TYPE TABLE OF RSDSTS,
      lt_TARGET TYPE TABLE OF ZPSA_TABLE.


DATA: tabname_target  TYPE dd02l-tabname,
      tabname_source  TYPE dd02l-tabname.


DATA: gt_cl_bc_dyn TYPE REF TO zcl_bc_dyn,
      status TYPE sy-subrc.


DATA: lv_DATAPAKID TYPE RSDATAPID,
      lv_RECORD    TYPE RSARECORD.


RANGES: lr_DATAPAKID FOR lv_DATAPAKID,
        lr_RECORD    FOR lv_RECORD.


IF NOT DATAPAKID_LOW IS INITIAL.
  lr_DATAPAKID-SIGN = 'I'.
  lr_DATAPAKID-LOW  = DATAPAKID_LOW.
  IF NOT DATAPAKID_HIGH IS INITIAL.
      lr_DATAPAKID-OPTION = 'BT'.
      lr_DATAPAKID-HIGH = DATAPAKID_HIGH.
  ELSE.
      lr_DATAPAKID-OPTION = 'EQ'.
  ENDIF.
  APPEND lr_DATAPAKID.
ENDIF.


IF NOT RECORD_LOW IS INITIAL.
  lr_RECORD-SIGN = 'I'.
  lr_RECORD-LOW  = RECORD_LOW.
  IF NOT RECORD_HIGH IS INITIAL.
      lr_RECORD-OPTION = 'BT'.
      lr_RECORD-HIGH = RECORD_HIGH.
  ELSE.
      lr_RECORD-OPTION = 'EQ'.
  ENDIF.
  APPEND lr_RECORD.
ENDIF.


tabname_target = 'ZPSA_TABLE'.


SELECT * FROM RSDSTS
  INTO CORRESPONDING FIELDS OF TABLE lt_RSDSTS
  WHERE OBJVERS = 'A'
  AND   DATASOURCE = DATASOURCE
  AND   LOGSYS     = LOGSYS
  ORDER BY PSA_VERSION DESCENDING.


LOOP AT lt_RSDSTS INTO ls_RSDSTS.
  tabname_source = ls_RSDSTS-PSA_TABLE.
  EXIT.
ENDLOOP.


SELECT * FROM (tabname_source)
  INTO TABLE lt_TARGET
  WHERE REQUEST = REQUEST
    AND DATAPAKID in lr_DATAPAKID
    AND RECORD    in lr_RECORD.


INSERT ZPSA_TABLE FROM TABLE lt_TARGET.


commit work and wait.


ENDFUNCTION.


Function  ZPSA_READ_TABLE

FUNCTION ZPSA_READ_TABLE.
*"----
""Lokale Schnittstelle:
*"  TABLES
*"      PSA_DATA STRUCTURE  ZPSA_TABLE
*"----


DATA: lt_ZPSA_TABLE TYPE TABLE OF ZPSA_TABLE.


SELECT * FROM ZPSA_TABLE
  INTO CORRESPONDING FIELDS OF TABLE lt_ZPSA_TABLE.


PSA_DATA[] = lt_ZPSA_TABLE[].


ENDFUNCTION.


 

After creating all those objects you should be able to let run the report ZBW_FILL_QUEUE in R/3.
Now enter the
BW System: this must be the same as the RFC Connection and is used
R/3 System: this is needed to find in BW the corresponding PSA Table (it's always the latest version) in table RSTS / RSTSODS
Datasource: Enter the datasource you want to load - format e.g.:2LIS_13_VDITM
PSA Request: technical name of request
Datapacket number and Record only if needed - if empty the whole request is taken over

The Flag "Write Delta Queue" has the following function:
The first time you want to load data you have to run the report without enabled flag. This means, the report just change the ZPSA_TALBE in BW and make it ready to put data in. This you have to do every time you change the Datasource.
After then you can enable the Flag "Write Delta Queue" and let run the report again. Now you get the data from the request in a datagrid - you can change some values and with saving you put the data into delta queue.
Now you can let run the Delta Infopackage again and you should get the data 😉

 

There are now some development ideas open for this, but it was not necessary at the end to implement this:

    • Only one user can use this at the time, because the table ZPSA_TABLE is used for all
    • Implement the solution that you don't have to let run first time for only changing the table ZPSA_TABLE before you let it run with data-takeover
    • Not all errors are taken in account

Please use this solution on your own risk - I hope you're happy with this. Please let me know what you think about.

I also have a solution to take over MasterData from Production into Quality / Dev. without having to create for each IO export datasource. My solution is one FM in Quality which reads dynamically the MasterData Tables from Production, depending on which InfoObject you want to load (generic datasource with FM).

3 Comments