0% found this document useful (0 votes)
73 views11 pages

Dynamic Table Update

This document contains the code for a report that updates a database table from an Excel file. It includes forms for validating the table name, creating a dynamic table, converting the Excel data to an internal table, and performing the table update. The main processing includes calling these forms to validate input, convert the Excel data, and update the database table.

Uploaded by

Umesh G J
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
73 views11 pages

Dynamic Table Update

This document contains the code for a report that updates a database table from an Excel file. It includes forms for validating the table name, creating a dynamic table, converting the Excel data to an internal table, and performing the table update. The main processing includes calling these forms to validate input, convert the Excel data, and update the database table.

Uploaded by

Umesh G J
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

*&---------------------------------------------------------------------*

*& Report YDR_TABLE_UPDATE


*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT ydr_table_update.

FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE ##NEEDED,


<fs_struc> TYPE any ##NEEDED,
<fs_1> TYPE any ##NEEDED,
<fs_2> TYPE any ##NEEDED.

CONSTANTS : gc_s TYPE c VALUE 'S',


gc_e TYPE c VALUE 'E',
gc_eq TYPE string VALUE 'EQ'.

SELECTION-SCREEN : BEGIN OF BLOCK main WITH FRAME TITLE text-scr.


PARAMETERS : p_fpath TYPE ibipparms-path,
p_table TYPE tabname,
p_mode TYPE damodus.
* p_intr TYPE i.
SELECTION-SCREEN : END OF BLOCK main.

**--At Selection Screen


AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fpath.
"F4-Help to browse file path
PERFORM f4_filename.

START-OF-SELECTION.
"Start Processing
PERFORM start_processing.

*&---------------------------------------------------------------------*
*& Form F4_FILENAME
*&---------------------------------------------------------------------*
* F4 filename search help
*----------------------------------------------------------------------*
FORM f4_filename.

DATA: lv_rc TYPE i,


lt_ftab TYPE filetable.

* CONSTANTS : lc_window TYPE string VALUE 'Select a file'.

"F4 help for filename


CALL METHOD cl_gui_frontend_services=>file_open_dialog
* EXPORTING
* window_title = lc_window
* default_extension =
* default_filename =
* file_filter =
* with_encoding =
* initial_directory =
* multiselection =
CHANGING
file_table = lt_ftab
rc = lv_rc
EXCEPTIONS
file_open_dialog_failed = 1
cntl_error = 2
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5.
IF sy-subrc EQ 0.
READ TABLE lt_ftab ASSIGNING FIELD-SYMBOL(<fs_file>) INDEX 1.
IF sy-subrc EQ 0.
p_fpath = <fs_file>-filename.
ENDIF.
ENDIF.

IF p_fpath IS INITIAL.
"'Unable to fetch file path'
MESSAGE text-fpt TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.

ENDFORM. " F4_FILENAME

*&---------------------------------------------------------------------*
*& Form START_PROCESSING
*&---------------------------------------------------------------------*
* Start Processing
*----------------------------------------------------------------------*
FORM start_processing .

DATA : lt_dftab TYPE STANDARD TABLE OF dd03p,


lt_dyntab TYPE REF TO data,
lw_dyntab TYPE REF TO data,
lv_eflag TYPE boolean.

"Validate Table Name


PERFORM validate_table_name.

"Create Dynamic table and structure


PERFORM create_dyntab CHANGING lt_dftab
lt_dyntab.

IF lt_dyntab IS BOUND AND


lt_dyntab IS NOT INITIAL.
ASSIGN lt_dyntab->* TO <fs_table>.
CREATE DATA lw_dyntab LIKE LINE OF <fs_table>.
ASSIGN lw_dyntab->* TO <fs_struc>.

PERFORM convert_excel USING lt_dftab.

IF <fs_table> IS ASSIGNED AND


<fs_table> IS NOT INITIAL.
SORT <fs_table>.
PERFORM table_action USING lt_dftab
CHANGING <fs_table>
lv_eflag.
IF lv_eflag IS NOT INITIAL.
ROLLBACK WORK.
"'Unable to perform table action'
MESSAGE text-upt TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.
ENDIF.
ENDIF.
ENDFORM. " START_PROCESSING

*&---------------------------------------------------------------------*
*& Form VALIDATE_TABLE_NAME
*&---------------------------------------------------------------------*
* Validate Table Name
*----------------------------------------------------------------------*
FORM validate_table_name .

DATA : lv_tabname TYPE tabname.

CONSTANTS : lc_act TYPE c VALUE 'A',


lc_ver TYPE as4vers VALUE '0000'.

SELECT SINGLE tabname


FROM dd02l
INTO lv_tabname
WHERE tabname EQ p_table
AND as4local EQ lc_act
AND as4vers EQ lc_ver.
IF sy-subrc NE 0 OR
lv_tabname IS INITIAL.
"'Invalid Table name'
MESSAGE text-ifn TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.

ENDFORM. " VALIDATE_TABLE_NAME

*&---------------------------------------------------------------------*
*& Form CREATE_DYNTAB
*&---------------------------------------------------------------------*
* Create Dynamic table and structures
*----------------------------------------------------------------------*
FORM create_dyntab CHANGING y_dftab TYPE dd03ptab
y_dyntab TYPE REF TO data.

DATA : lt_fieldcat TYPE lvc_t_fcat.

CALL FUNCTION 'DDIF_TABL_GET'


EXPORTING
name = p_table
* STATE = 'A'
* LANGU = ' '
* IMPORTING
* GOTSTATE =
* DD02V_WA =
* DD09L_WA =
TABLES
dd03p_tab = y_dftab
* DD05M_TAB =
* DD08V_TAB =
* DD12V_TAB =
* DD17V_TAB =
* DD35V_TAB =
* DD36M_TAB =
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc EQ 0.
SORT y_dftab BY position.
LOOP AT y_dftab ASSIGNING FIELD-SYMBOL(<fs_dftab>).
APPEND INITIAL LINE TO lt_fieldcat ASSIGNING FIELD-SYMBOL(<fs_fieldcat>).
CASE <fs_dftab>-inttype.
WHEN 'C'.
<fs_fieldcat>-datatype = 'CHAR'.
WHEN 'N'.
<fs_fieldcat>-datatype = 'NUMC'.
WHEN 'D'.
<fs_fieldcat>-datatype = 'DATE'.
WHEN 'P'.
<fs_fieldcat>-datatype = 'PACK'.
WHEN OTHERS.
<fs_fieldcat>-datatype = <fs_dftab>-datatype.
ENDCASE.
<fs_fieldcat>-tabname = p_table.
<fs_fieldcat>-fieldname = <fs_dftab>-fieldname.
<fs_fieldcat>-inttype = <fs_dftab>-inttype.
<fs_fieldcat>-intlen = <fs_dftab>-intlen.
<fs_fieldcat>-decimals = <fs_dftab>-decimals.
UNASSIGN : <fs_fieldcat>.
ENDLOOP.
ELSE.
"'Unable to create dynamic table'
MESSAGE text-ucd TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.

IF lt_fieldcat IS NOT INITIAL.


CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
* i_style_table =
it_fieldcatalog = lt_fieldcat
i_length_in_byte = abap_true
IMPORTING
ep_table = y_dyntab
* e_style_fname =
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
IF sy-subrc NE 0.
"'Unable to create dynamic table'
MESSAGE text-ucd TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.
ENDIF.

ENDFORM. " CREATE_DYNTAB

*&---------------------------------------------------------------------*
*& Form CONVERT_EXCEL
*&---------------------------------------------------------------------*
* Convert Excel to Internal Table
*----------------------------------------------------------------------*
FORM convert_excel USING x_dftab TYPE dd03ptab.

DATA : lt_ttab TYPE STANDARD TABLE OF alsmex_tabline,


lt_ttmp TYPE STANDARD TABLE OF alsmex_tabline.

"Declaration of global constants


CONSTANTS : lc_1 TYPE i VALUE 1,
lc_cmax TYPE i VALUE 256,
lc_rmax TYPE i VALUE 100000.

"Convert excel to internal table


CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
EXPORTING
filename = p_fpath
i_begin_col = lc_1
i_begin_row = lc_1
i_end_col = lc_cmax
i_end_row = lc_rmax
TABLES
intern = lt_ttab
EXCEPTIONS
inconsistent_parameters = 1
upload_ole = 2
OTHERS = 3.
IF sy-subrc EQ 0.
SORT lt_ttab BY row col.
lt_ttmp[] = lt_ttab[].
DELETE ADJACENT DUPLICATES FROM lt_ttmp COMPARING row.

LOOP AT lt_ttmp ASSIGNING FIELD-SYMBOL(<fs_row>).


READ TABLE lt_ttab TRANSPORTING NO FIELDS
WITH KEY row = <fs_row>-row BINARY SEARCH.
IF sy-subrc EQ 0.
LOOP AT lt_ttab ASSIGNING FIELD-SYMBOL(<fs_col>)
FROM sy-tabix.
IF <fs_col>-row NE <fs_row>-row.
EXIT.
ENDIF.
READ TABLE x_dftab ASSIGNING FIELD-SYMBOL(<fs_dftab>)
WITH KEY position = <fs_col>-col BINARY SEARCH.
IF sy-subrc EQ 0.
IF p_mode EQ 'D' AND
<fs_dftab>-keyflag IS INITIAL.
CONTINUE.
ENDIF.
PERFORM populate_final_table USING <fs_col>
<fs_dftab>
CHANGING <fs_struc>.
ENDIF.
ENDLOOP.
APPEND <fs_struc> TO <fs_table>.
CLEAR : <fs_struc>.
ENDIF.
ENDLOOP.
ELSE.
"'Unable to read excel file'
MESSAGE text-ure TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.

ENDFORM. " CONVERT_EXCEL

*&---------------------------------------------------------------------*
*& Form POPULATE_FINAL_TABLE
*&---------------------------------------------------------------------*
* Populate Final Table
*----------------------------------------------------------------------*
FORM populate_final_table USING x_col TYPE alsmex_tabline
x_dftab TYPE dd03p
CHANGING x_struc TYPE any.

CONSTANTS : lc_erdat TYPE name_feld VALUE 'ERDAT',


lc_ernam TYPE name_feld VALUE 'ERNAM',
lc_aedat TYPE name_feld VALUE 'AEDAT',
lc_aenam TYPE name_feld VALUE 'AENAM',
lc_ertim TYPE name_feld VALUE 'ERTIM',
lc_aetim TYPE name_feld VALUE 'AETIM',
lc_mandt TYPE name_feld VALUE 'MANDT',
lc_change_tim TYPE name_feld VALUE 'CHANGE_TIME',
lc_value TYPE name_feld VALUE 'VALUE'.

ASSIGN COMPONENT lc_value OF STRUCTURE x_col TO <fs_1>.


ASSIGN COMPONENT x_dftab-fieldname OF STRUCTURE x_struc TO <fs_2>.

CASE x_dftab-inttype.
WHEN 'D'.
IF ( <fs_1> IS INITIAL AND
x_dftab-fieldname EQ lc_erdat ) OR
x_dftab-fieldname EQ lc_aedat.
<fs_2> = sy-datum.
ELSE.
<fs_2> = <fs_1>+6(4) && <fs_1>+3(2) && <fs_1>+0(2).
ENDIF.
* CALL FUNCTION 'DATE_CHECK_PLAUSIBILITY'
* EXPORTING
* date = <fs_2>
* EXCEPTIONS
* plausibility_check_failed = 1
* OTHERS = 2.
* IF sy-subrc NE 0.
* <fs_2> = sy-datum.
* ENDIF.
WHEN 'T'.
IF x_dftab-fieldname EQ lc_aetim OR
x_dftab-fieldname EQ lc_change_tim OR
( <fs_1> IS INITIAL AND
x_dftab-fieldname EQ lc_ertim ).
<fs_2> = sy-uzeit.
ELSE.
<fs_2> = <fs_1>+0(2) && <fs_1>+3(2) && <fs_1>+6(2) .
CALL FUNCTION 'TIME_CHECK_PLAUSIBILITY'
EXPORTING
time = <fs_2>
EXCEPTIONS
plausibility_check_failed = 1
OTHERS = 2.
IF sy-subrc NE 0.
<fs_2> = sy-uzeit.
ENDIF.
ENDIF.
WHEN 'C'.
IF x_dftab-fieldname EQ lc_aenam OR
( x_dftab-fieldname EQ lc_ernam AND
<fs_1> IS INITIAL ).
<fs_2> = sy-uname.
ELSEIF x_dftab-fieldname EQ lc_mandt.
<fs_2> = sy-mandt.
ELSE.
<fs_2> = <fs_1>.
ENDIF.
WHEN OTHERS.
<fs_2> = <fs_1>.
ENDCASE.

ENDFORM. " POPULATE_FINAL_TABLE

*&---------------------------------------------------------------------*
*& Form TABLE_ACTION
*&---------------------------------------------------------------------*
* Table Actions
*----------------------------------------------------------------------*
FORM table_action USING x_dftab TYPE dd03ptab
CHANGING y_tabdata TYPE ANY TABLE
y_eflag TYPE boolean.

DATA : lt_tabdata TYPE REF TO data,


lt_tfields TYPE dd03ptab,

lt_where TYPE TABLE OF edpline,


lw_where TYPE edpline,

lv_string TYPE string,


lv_count TYPE i.

*** lv_ref_tabname TYPE REF TO cl_abap_structdescr,


*** lv_ref_table TYPE REF TO cl_abap_structdescr.

FIELD-SYMBOLS : <fs_tabdata> TYPE ANY TABLE.

CONSTANTS : lc_mandt TYPE name_feld VALUE 'MANDT',


lc_hyphen TYPE c VALUE '-',
lc_tmptab TYPE string VALUE 'Y_TABDATA',
lc_and TYPE string VALUE 'AND'.

CREATE DATA lt_tabdata TYPE TABLE OF (p_table).


ASSIGN lt_tabdata->* TO <fs_tabdata>.
* <fs_tabdata> = Y_TABDATA.

IF x_dftab IS NOT INITIAL.


lt_tfields[] = x_dftab[].
ENDIF.

*---INSERT Operation for one or more records into Database Table


IF p_mode = zif_x_common_types_and_const=>gc_mode_insert.

LOOP AT x_dftab ASSIGNING FIELD-SYMBOL(<fs_dftab>)


WHERE keyflag EQ abap_true
AND fieldname NE lc_mandt.
CLEAR : lw_where, lv_string.

CONCATENATE lc_tmptab lc_hyphen <fs_dftab>-fieldname INTO lv_string.

IF lv_count IS INITIAL.
"'FIELDNAME EQ Y_TABDATA-FIELDNAME'
CONCATENATE <fs_dftab>-fieldname gc_eq lv_string
INTO lw_where SEPARATED BY space.
ELSE.
"'AND FIELDNAME EQ Y_TABDATA-FIELDNAME'
CONCATENATE lc_and <fs_dftab>-fieldname gc_eq lv_string
INTO lw_where SEPARATED BY space.
ENDIF.

lv_count = lv_count + 1.
APPEND lw_where TO lt_where.

ENDLOOP.

SELECT *
FROM (p_table)
INTO TABLE <fs_tabdata>
FOR ALL ENTRIES IN y_tabdata
WHERE (lt_where).
IF sy-subrc EQ 0.
IF 1 = 2.
* LOOP AT y_tabdata ASSIGNING FIELD-SYMBOL(<fs_tdata>).
* READ TABLE <fs_tdata> TRANSPORTING NO FIELDS
* WITH TABLE KEY
* ENDLOOP.
ENDIF.
PERFORM user_decision USING y_tabdata
CHANGING lt_tfields
y_eflag.
ELSE.
INSERT (p_table) FROM TABLE y_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT.
ELSE.
y_eflag = abap_true.
ENDIF.
ENDIF.
*---UPDATE Operation for one or more records into Database Table
ELSEIF p_mode = zif_x_common_types_and_const=>gc_mode_update.
PERFORM enqueue USING y_tabdata
CHANGING lt_tfields.
UPDATE (p_table) FROM TABLE y_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT.
ELSE.
y_eflag = abap_true.
ENDIF.
PERFORM dequeue USING y_tabdata
lt_tfields.
*---MODIFY Operation for one or more records into Database Table
ELSEIF p_mode = zif_x_common_types_and_const=>gc_mode_modify.
PERFORM enqueue USING y_tabdata
CHANGING lt_tfields.
MODIFY (p_table) FROM TABLE y_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT.
ELSE.
y_eflag = abap_true.
ENDIF.
PERFORM dequeue USING y_tabdata
lt_tfields.
*---DELETE Operation for one or more records into Database Table
ELSEIF p_mode = zif_x_common_types_and_const=>gc_mode_delete.
PERFORM enqueue USING y_tabdata
CHANGING lt_tfields.
DELETE (p_table) FROM TABLE y_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT.
ELSE.
y_eflag = abap_true.
ENDIF.
PERFORM dequeue USING y_tabdata
lt_tfields.
ENDIF.

ENDFORM. " TABLE_ACTION

*&---------------------------------------------------------------------*
*& Form ENQUEUE
*&---------------------------------------------------------------------*
* Enqueue Table Data
*----------------------------------------------------------------------*
FORM enqueue USING x_tabdata TYPE ANY TABLE
CHANGING y_tfields TYPE dd03ptab.

DATA : lv_varkey TYPE vim_enqkey,


lv_string TYPE string.

DELETE y_tfields WHERE keyflag IS INITIAL.


SORT y_tfields BY position.

LOOP AT x_tabdata ASSIGNING FIELD-SYMBOL(<fs_record>).


DO lines( y_tfields[] ) TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_record> TO FIELD-SYMBOL(<fs_varkey>).
lv_string = <fs_varkey>.
lv_varkey = lv_varkey && lv_string.
ENDDO.
CALL FUNCTION 'ENQUEUE_E_TABLEE'
EXPORTING
mode_rstable = gc_e
tabname = p_table
varkey = lv_varkey
_wait = abap_true
_collect = abap_true
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc EQ 0.
CLEAR : lv_varkey.
ENDIF.
ENDLOOP.

ENDFORM. " ENQUEUE

*&---------------------------------------------------------------------*
*& Form DEQUEUE
*&---------------------------------------------------------------------*
* Dequeue table data
*----------------------------------------------------------------------*
FORM dequeue USING x_tabdata TYPE ANY TABLE
x_tfields TYPE dd03ptab.

DATA : lv_varkey TYPE vim_enqkey,


lv_string TYPE string.

LOOP AT x_tabdata ASSIGNING FIELD-SYMBOL(<fs_record>).


CLEAR : lv_varkey.
DO lines( x_tfields[] ) TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_record> TO FIELD-SYMBOL(<fs_varkey>).
lv_string = <fs_varkey>.
lv_varkey = lv_varkey && lv_string.
ENDDO.
CALL FUNCTION 'DEQUEUE_E_TABLEE'
EXPORTING
mode_rstable = gc_e
tabname = p_table
varkey = lv_varkey
_collect = abap_true.
ENDLOOP.

ENDFORM. " DEQUEUE

*&---------------------------------------------------------------------*
*& Form USER_DECISION
*&---------------------------------------------------------------------*
* User Decision to proceed if records to are already present
*----------------------------------------------------------------------*
FORM user_decision USING x_tabdata TYPE ANY TABLE
CHANGING y_tfields TYPE dd03ptab
y_eflag TYPE boolean.

DATA : lt_spoplist TYPE STANDARD TABLE OF spopli,

lv_answer TYPE i.

DO 3 TIMES.
APPEND INITIAL LINE TO lt_spoplist ASSIGNING FIELD-SYMBOL(<fs_spoplist>).
CASE sy-index.
WHEN 1.
"'Delete existing records and insert'
<fs_spoplist>-varoption = text-del.
WHEN 2.
"'Modify/Update existing records'
<fs_spoplist>-varoption = text-mod.
WHEN OTHERS.
"'Cancel'
<fs_spoplist>-varoption = text-can.
ENDCASE.
UNASSIGN : <fs_spoplist>.
ENDDO.

CALL FUNCTION 'POPUP_TO_DECIDE_LIST'


EXPORTING
* CURSORLINE = 1
* MARK_FLAG = ' '
* MARK_MAX = 1
* START_COL = 0
* START_ROW = 0
textline1 = text-srp "'Some of the records are already present'
textline2 = text-pro "'Please select to proceed'
* textline3 = 'MayBe'
titel = text-opt "'Options'
* DISPLAY_ONLY = ' '
IMPORTING
answer = lv_answer
TABLES
t_spopli = lt_spoplist
EXCEPTIONS
not_enough_answers = 1
too_much_answers = 2
too_much_marks = 3
OTHERS = 4.
IF sy-subrc EQ 0.
IF lv_answer EQ 1.
"Enqueue Delete and Deque
PERFORM enqueue USING x_tabdata
CHANGING y_tfields.
DELETE (p_table) FROM TABLE x_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT. "Commit
ELSE.
y_eflag = abap_true.
ENDIF.
PERFORM dequeue USING x_tabdata
y_tfields.

IF y_eflag IS INITIAL.
"Insert Records and Commit
INSERT (p_table) FROM TABLE x_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT. "Commit
ELSE.
y_eflag = abap_true.
ENDIF.
ENDIF.

ELSEIF lv_answer EQ 2.
"Enqueue Modify and Deque
PERFORM enqueue USING x_tabdata
CHANGING y_tfields.
MODIFY (p_table) FROM TABLE x_tabdata.
IF sy-subrc EQ 0.
COMMIT WORK AND WAIT.
ELSE.
y_eflag = abap_true.
ENDIF.
PERFORM dequeue USING x_tabdata
y_tfields.
ELSE.
"'Cancelled by User'
MESSAGE text-cbu TYPE gc_s DISPLAY LIKE gc_e.
RETURN.
ENDIF.
ELSE.
y_eflag = abap_true.
ENDIF.

ENDFORM. " USER_DECISION

You might also like