Difference between revisions of "SAP ABAP DYNAMIC"
From SapWiki
Line 365: | Line 365: | ||
EXIT. | EXIT. | ||
ENDIF. | ENDIF. | ||
− | ENDDO.</nowiki | + | ENDDO.</nowiki> |
===Ejemplos=== | ===Ejemplos=== |
Revision as of 19:20, 6 September 2021
Contents
Jerarquía Tipo CLase
CL_ABAP_TYPEDESCR CL_ABAP_DATADESCR CL_ABAP_ELEMDESCR CL_ABAP_REFDESCR CL_ABAP_COMPLEXDESCR CL_ABAP_TABLEDESCR CL_ABAP_STRUCTDESCR CL_ABAP_OBJECTDESCR CL_ABAP_CLASSDESCR CL_ABAP_INTFDESCR
Ejemplo 01: generar archivo CSV independiente del tipo
FORM crear_csv USING p_tabla TYPE ANY TABLE CHANGING p_tabla_csv TYPE ppe_cust_table. CONSTANTS: c_field_separator TYPE c VALUE ';', c_darl_number(12) TYPE c VALUE '1234567890 '. DATA: cl_descr_struc_ref TYPE REF TO cl_abap_structdescr, it_components TYPE abap_compdescr_tab, wa_components LIKE LINE OF it_components. DATA lt_data TYPE ppe_cust_table. DATA: l_struc_index TYPE syindex, l_len_string TYPE i, l_max_field TYPE char1024, l_struc_raw_data TYPE char1024, l_start_string TYPE i, l_len_field_sep TYPE i, l_date_extern(30) TYPE c, l_help_id LIKE tline-tdline, l_tabix TYPE sytabix. FIELD-SYMBOLS <fs_field> TYPE ANY. FIELD-SYMBOLS <ls_envio> TYPE ANY. l_len_field_sep = STRLEN( c_field_separator ). LOOP AT p_tabla ASSIGNING <ls_envio>. CLEAR: l_struc_index, l_len_string, l_struc_raw_data, l_start_string. IF it_components[] IS INITIAL. cl_descr_struc_ref ?= cl_abap_typedescr=>describe_by_data( <ls_envio> ). * obtener campos de estructura it_components = cl_descr_struc_ref->components. ENDIF. DO. ADD 1 TO l_struc_index. CLEAR l_len_string. READ TABLE it_components INTO wa_components INDEX sy-index. IF sy-subrc = 0. ASSIGN COMPONENT wa_components-name OF STRUCTURE <ls_envio> TO <fs_field>. CASE wa_components-type_kind . WHEN 'P'. WRITE <fs_field> TO l_date_extern. CATCH SYSTEM-EXCEPTIONS conversion_errors = 4. IF sy-subrc <> '0'. * MESSAGE e899(ux) WITH l_type <f_source> l_help_id * l_tabix RAISING conversion_failed. ENDIF. ENDCATCH. CONDENSE l_date_extern. ASSIGN l_date_extern TO <fs_field>. WHEN 'D'. MOVE <fs_field> TO l_date_extern. *20191220 -> 20/12/2019 REPLACE FIRST OCCURRENCE OF REGEX '(\d{4})(\d{2})(\d{2})' IN l_date_extern WITH '$3/$2/$1'. ENDCASE. ELSE. EXIT. ENDIF. IF l_struc_index <> 1. l_max_field+l_len_string(l_len_field_sep) = c_field_separator. l_len_string = l_len_field_sep. ENDIF. l_max_field+l_len_string = <fs_field>. l_len_string = STRLEN( l_max_field ). CHECK l_len_string <> '0'. l_struc_raw_data+l_start_string(l_len_string) = l_max_field. l_start_string = l_start_string + l_len_string. ENDDO. APPEND l_struc_raw_data TO lt_data. ENDLOOP. p_tabla_csv[] = lt_data[]. ENDFORM. "crear_csv
Ejemplo 02: leer archivo desde servidor separado por tabs, independiente del tipo
types: ty_t001 type t001. DATA lt_t001 TYPE STANDARD TABLE OF ty_t001. PERFORM open_un USING '/tmp/t001_dat2.txt' CHANGING lt_t001. FORM open_un USING p_file CHANGING p_table TYPE ANY TABLE. DATA: lr_structdescr TYPE REF TO cl_abap_structdescr, lr_datadescr TYPE REF TO cl_abap_datadescr, lr_tabledescr TYPE REF TO cl_abap_tabledescr, line_descr TYPE REF TO cl_abap_typedescr. DATA: l_string TYPE string, l_string2 TYPE string, l_campo TYPE string, ld_name TYPE string. FIELD-SYMBOLS: <fs> TYPE any, <wa> TYPE any. DATA: wa_ref TYPE REF TO data. lr_tabledescr ?= cl_abap_tabledescr=>describe_by_data( p_table ). line_descr = lr_tabledescr->get_table_line_type( ). ld_name = line_descr->get_relative_name( ). * get the field list of the table linetype DATA(lt_components) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_name( ld_name ) )->components. CREATE DATA wa_ref TYPE (ld_name). "Suitable work area ASSIGN wa_ref->* TO <wa>. OPEN DATASET p_file FOR INPUT IN TEXT MODE ENCODING DEFAULT WITH SMART LINEFEED. IF sy-subrc <> 0. RETURN. ENDIF. WHILE sy-subrc = 0. READ DATASET p_file INTO l_string. CHECK l_string IS NOT INITIAL. DATA(l_index) = 1. WHILE l_string IS NOT INITIAL. SPLIT l_string AT cl_abap_char_utilities=>horizontal_tab INTO l_string2 l_string. READ TABLE lt_components INTO data(ls_comp) INDEX l_index. IF sy-subrc = 0. ADD 1 TO l_index. CONCATENATE '<WA>' ls_comp-name INTO l_campo SEPARATED BY '-'. ASSIGN (l_campo) TO <fs>. MOVE l_string2 TO <fs> . ELSE. EXIT. ENDIF. ENDWHILE. INSERT <wa> INTO TABLE p_table. ENDWHILE. ENDFORM.
Crear archivo CSV
Llamar a una Función dinamicamente
DATA: fm_name TYPE string, filename TYPE string, filetype TYPE c LENGTH 10, text_tab LIKE STANDARD TABLE OF line, fleng TYPE i, ptab TYPE abap_func_parmbind_tab, ptab_line LIKE LINE OF ptab, etab TYPE abap_func_excpbind_tab, etab_line LIKE LINE OF etab. fm_name = 'GUI_DOWNLOAD'. filename = 'C:\temp\pepetrueno.txt'. filetype = 'ASC'. ptab_line-name = 'FILENAME'. ptab_line-kind = abap_func_exporting. GET REFERENCE OF filename INTO ptab_line-value. INSERT ptab_line INTO TABLE ptab. ptab_line-name = 'FILETYPE'. ptab_line-kind = abap_func_exporting. GET REFERENCE OF filetype INTO ptab_line-value. INSERT ptab_line INTO TABLE ptab. data lt_t001 type TABLE OF t001. select * into table lt_t001 from t001. ptab_line-name = 'DATA_TAB'. ptab_line-kind = abap_func_tables. GET REFERENCE OF lt_t001 INTO ptab_line-value. INSERT ptab_line INTO TABLE ptab. ptab_line-name = 'FILELENGTH'. ptab_line-kind = abap_func_importing. GET REFERENCE OF fleng INTO ptab_line-value. INSERT ptab_line INTO TABLE ptab. * prepare exception-table data: lt_except type abap_func_excpbind_tab, wa_except like line of lt_except. wa_except-name = 'OTHERS'. wa_except-value = 22. insert wa_except into table lt_except. try. call function fm_name parameter-table ptab[] exception-table lt_except[]. catch cx_sy_dyn_call_error. exit. endtry. * extract return parameters out of table ptab read table ptab with key name = 'FILELENGTH' kind = abap_func_importing into ptab_line. * get content as field symbol field-symbols: <filelength> type i. assign ptab_line-value->* to <filelength>. write:/ <filelength>.
Llamar a un Método dinamicamente
DATA: line TYPE c LENGTH 80, text_tab LIKE STANDARD TABLE OF line, filename TYPE string, filetype TYPE c LENGTH 10, fleng TYPE i. DATA: meth TYPE string, class TYPE string, ptab TYPE abap_parmbind_tab, etab TYPE abap_excpbind_tab. DATA: exc_ref TYPE REF TO cx_sy_dyn_call_error. class = 'CL_GUI_FRONTEND_SERVICES'. meth = 'GUI_DOWNLOAD'. filename = 'c:\temp\text.txt'. filetype = 'ASC'. ptab = VALUE #( ( name = 'FILENAME' kind = cl_abap_objectdescr=>exporting value = REF #( filename ) ) ( name = 'FILETYPE' kind = cl_abap_objectdescr=>exporting value = REF #( filetype ) ) ( name = 'DATA_TAB' kind = cl_abap_objectdescr=>changing value = REF #( text_tab ) ) ( name = 'FILELENGTH' kind = cl_abap_objectdescr=>importing value = REF #( fleng ) ) ). etab = VALUE #( ( name = 'OTHERS' value = 4 ) ). TRY. CALL METHOD (class)=>(meth) PARAMETER-TABLE ptab EXCEPTION-TABLE etab. CASE sy-subrc. WHEN 4. ENDCASE. CATCH cx_sy_dyn_call_error INTO exc_ref. MESSAGE exc_ref->get_text( ) TYPE 'I'. ENDTRY.
Ejemplos Varios
Saber si un dato es de tipo moneda
TYPES: BEGIN OF ty_pernr, pernr TYPE p0001-pernr, begda TYPE begda, dias TYPE i, sueldo TYPE pad_amt7s, END OF ty_pernr. DATA: ls_pernr TYPE ty_pernr. FIELD-SYMBOLS: <lv_data> TYPE data. DATA: lr_descr TYPE REF TO cl_abap_elemdescr, lt_ddic_info TYPE dd_x031l_table, lrs_ddic_info TYPE REF TO x031l. *--------------------------------------------------------------------* ASSIGN ls_pernr-sueldo to <lv_data>. lr_descr ?= cl_abap_elemdescr=>describe_by_data( <lv_data> ). lt_ddic_info = lr_descr->get_ddic_object( ). READ TABLE lt_ddic_info INDEX 1 REFERENCE INTO lrs_ddic_info. IF sy-subrc = 0. if lrs_ddic_info->dtyp = 'CURR'. endif. ENDIF.
Saber si un dato es de tipo moneda, EX02
TYPES: BEGIN OF ty_pernr, pernr TYPE p0001-pernr, begda TYPE begda, dias TYPE i, sueldo TYPE pad_amt7s, waers TYPE waers, END OF ty_pernr. DATA: lt_pernr TYPE TABLE OF ty_pernr, ls_pernr TYPE ty_pernr. DATA: lr_tab TYPE REF TO data, lr_typedesc TYPE REF TO cl_abap_typedescr, lr_tabdesc TYPE REF TO cl_abap_tabledescr, lr_datadesc TYPE REF TO cl_abap_datadescr, lr_structdesc TYPE REF TO cl_abap_structdescr. DATA: lt_campo TYPE cl_abap_structdescr=>component_table, ls_campo TYPE abap_componentdescr. DATA: lr_descr TYPE REF TO cl_abap_elemdescr, lt_ddic_info TYPE dd_x031l_table, lrs_ddic_info TYPE REF TO x031l. *--------------------------------------------------------------------* DATA l_struc_index TYPE i. DATA l_date_extern(30) TYPE c. FIELD-SYMBOLS: <ls_structcomp> TYPE abap_compdescr. FIELD-SYMBOLS: <lv_data> TYPE data. FIELD-SYMBOLS <fs_field> TYPE any. FIELD-SYMBOLS <fs_field2> TYPE any. ls_pernr-pernr = '00000001'. ls_pernr-begda = sy-datum. ls_pernr-sueldo = 6200. ls_pernr-dias = 30. ls_pernr-waers = 'CLP'. ASSIGN ls_pernr TO <lv_data>. lr_structdesc ?= cl_abap_typedescr=>describe_by_data( <lv_data> ). lt_campo = lr_structdesc->get_components( ). DO. ADD 1 TO l_struc_index. READ TABLE lt_campo INTO ls_campo INDEX sy-index. IF sy-subrc = 0. ASSIGN COMPONENT ls_campo-name OF STRUCTURE <lv_data> TO <fs_field>. CASE ls_campo-type->type_kind. . WHEN 'P'. lr_descr ?= cl_abap_elemdescr=>describe_by_data( <fs_field> ). lt_ddic_info = lr_descr->get_ddic_object( ). READ TABLE lt_ddic_info INDEX 1 REFERENCE INTO lrs_ddic_info. IF sy-subrc = 0. IF lrs_ddic_info->dtyp = 'CURR'. ASSIGN COMPONENT 'WAERS' OF STRUCTURE <lv_data> TO <fs_field2>. WRITE <fs_field> TO l_date_extern CURRENCY <fs_field2> NO-GROUPING. CONDENSE l_date_extern. else. WRITE <fs_field> TO l_date_extern NO-GROUPING. CONDENSE l_date_extern. ENDIF. ENDIF. when OTHERS. * do something ENDCASE. ELSE. EXIT. ENDIF. ENDDO.
Ejemplos
DATA l_matnr type matnr VALUE '100'. DATA dref TYPE REF TO data. FIELD-SYMBOLS <fs> TYPE any. GET REFERENCE OF l_matnr into dref. ASSIGN dref->* TO <fs>. WRITE <fs>. *********************************************************************** FIELD-SYMBOLS <fs> TYPE DATA. DATA dref TYPE REF TO DATA. CREATE DATA dref TYPE i. ASSIGN dref->* TO <fs>. <fs> = 5. *********************************************************************** TYPES: ty_type TYPE p DECIMALS 2. DATA: v_data TYPE ty_type, r_typedescr TYPE REF TO cl_abap_typedescr. START-OF-SELECTION. r_typedescr = cl_abap_typedescr=>describe_by_data( v_data ). WRITE: / 'Kind:', r_typedescr->type_kind. WRITE: / 'Length:', r_typedescr->length. WRITE: / 'Decimals:', r_typedescr->decimals. *********************************************************************** DATA l_text(8) TYPE c VALUE '20111201'. FIELD-SYMBOLS <fs> TYPE sy-datum. ASSIGN l_text TO <fs> CASTING. WRITE <fs>. *********************************************************************** DATA: r_typedescr TYPE REF TO cl_abap_typedescr, r_structdescr TYPE REF TO cl_abap_structdescr, r_tabledescr TYPE REF TO cl_abap_tabledescr, r_table TYPE REF TO data, components TYPE cl_abap_structdescr=>component_table, component LIKE LINE OF components, ro_alv TYPE REF TO cl_salv_table. FIELD-SYMBOLS : <table> TYPE ANY TABLE. FORM get_table . r_typedescr = cl_abap_typedescr=>describe_by_name( p_table ). TRY. r_structdescr ?= r_typedescr. CATCH cx_sy_move_cast_error. ENDTRY. components = r_structdescr->get_components( ). TRY. r_structdescr = cl_abap_structdescr=>get( components ). r_tabledescr = cl_abap_tabledescr=>get( r_structdescr ). CATCH cx_sy_struct_creation. CATCH cx_sy_table_creation . ENDTRY. TRY. CREATE DATA r_table TYPE HANDLE r_tabledescr. ASSIGN r_table->* TO <table>. CATCH cx_sy_create_data_error. ENDTRY. TRY. SELECT * FROM (p_table) INTO CORRESPONDING FIELDS OF TABLE <table> WHERE (p_where). CATCH cx_sy_sql_error. ENDTRY. ENDFORM.
Crear tabla
FORM form01 USING p_tabla TYPE STANDARD TABLE. FIELD-SYMBOLS <work_tab> TYPE ANY TABLE. DATA work_tab_ref TYPE REF TO data. CREATE DATA work_tab_ref LIKE p_tabla[]. ASSIGN work_tab_ref->* TO <work_tab>. ENDFORM. FORM form02. FIELD-SYMBOLS <pannnn_wa> TYPE any. FIELD-SYMBOLS <pacccc_wa> TYPE c. FIELD-SYMBOLS <pannnn> TYPE STANDARD TABLE. DATA dbtab TYPE t777d-dbtab. DATA pannnn_ref TYPE REF TO data. DATA pannnn_wa_ref TYPE REF TO data. dbtab = 'PA0008'. CREATE DATA pannnn_ref TYPE STANDARD TABLE OF (dbtab). ASSIGN pannnn_ref->* TO <pannnn>. CREATE DATA pannnn_wa_ref TYPE (dbtab). ASSIGN pannnn_wa_ref->* TO <pannnn_wa>. ASSIGN <pannnn_wa> TO <pacccc_wa> CASTING. SELECT * FROM (dbtab) INTO TABLE <pannnn> UP TO 100 ROWS. LOOP AT <pannnn> INTO <pannnn_wa>. ENDLOOP. ENDFORM.
Crear tabla basado en campos
Tomar componentes de tabla T001, menos columna MANDT, y asignarlos dinamicamente a tabla interna.
FORM crear. DATA: struct_type TYPE REF TO cl_abap_structdescr, itab_type TYPE REF TO cl_abap_tabledescr, comp_tab TYPE cl_abap_structdescr=>component_table. DATA: lr_tabdata TYPE REF TO data. FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE. struct_type ?= cl_abap_typedescr=>describe_by_name( 'T001' ). CALL METHOD struct_type->get_components RECEIVING p_result = comp_tab. DELETE TABLE comp_tab WITH TABLE KEY name = 'MANDT'. TRY. CALL METHOD cl_abap_structdescr=>create EXPORTING p_components = comp_tab * p_strict = TRUE RECEIVING p_result = struct_type. CATCH cx_sy_struct_creation . ENDTRY. itab_type = cl_abap_tabledescr=>create( struct_type ). * combine CREATE DATA lr_tabdata TYPE HANDLE itab_type. ASSIGN lr_tabdata->* TO <lt_table>. ENDFORM.
Combine
form combine_recs_by_key using it_keys type abap_keydescr_tab changing ct_data type standard table . data: lr_tabdata type ref to data , lo_line_type type ref to cl_abap_structdescr , lo_tab_type type ref to cl_abap_tabledescr . field-symbols: <lt_combined> type sorted table , <ls_line> type any . * create new table with key lo_tab_type ?= cl_abap_tabledescr=>describe_by_data( ct_data ). lo_line_type ?= lo_tab_type->get_table_line_type( ). call method cl_abap_tabledescr=>create exporting p_line_type = lo_line_type p_table_kind = cl_abap_tabledescr=>tablekind_sorted p_unique = abap_true p_key = it_keys p_key_kind = cl_abap_tabledescr=>keydefkind_user receiving p_result = lo_tab_type. * combine create data lr_tabdata type handle lo_tab_type. assign lr_tabdata->* to <lt_combined>. loop at ct_data assigning <ls_line>. collect <ls_line> into <lt_combined>. endloop. clear ct_data. loop at <lt_combined> assigning <ls_line>. append <ls_line> to ct_data. endloop. sort ct_data. endform. " combine_recs_by_key