Difference between revisions of "SAP ABAP DYNAMIC"
From SapWiki
| Line 1: | Line 1: | ||
| + | ==Jerarquía Tipo CLase== | ||
| + | <nowiki>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</nowiki> | ||
==Ejemplo 01: generar archivo CSV independiente del tipo== | ==Ejemplo 01: generar archivo CSV independiente del tipo== | ||
<nowiki>FORM crear_csv USING p_tabla TYPE ANY TABLE | <nowiki>FORM crear_csv USING p_tabla TYPE ANY TABLE | ||
Revision as of 17:49, 23 June 2020
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.
Ejemplos varios
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
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
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.