05-16-2013 8:57 AM
Good morning,
I'm facing a problem with fieldsymbols. First of all I'm not that conform in working with field symbols, because I just do the "normal" ASSIGN when working with structures and interal tables, so maybe my questions sound a bit rookie for you 🙂
My problem is that I want to create a dynamic internal table for getting it displayed in an ALV Grid. So I got a selopt in the selection screen which gives me the number of columns.
So I'm creating my internal table (simplified view) like this....
* Hilfsvariablen dynamischer Strukturaufbau
DATA: lr_element TYPE REF TO cl_abap_elemdescr,
lt_comp TYPE cl_abap_structdescr=>component_table,
ls_comp LIKE LINE OF lt_comp,
lr_data TYPE REF TO cl_abap_datadescr,
lr_struct TYPE REF TO cl_abap_structdescr,
lr_table TYPE REF TO cl_abap_tabledescr,
ld_table TYPE REF TO data,
ld_line TYPE REF TO data.
FIELD-SYMBOLS:
<ls_comp> TYPE ANY,
<ls_data_pro_ila> TYPE ANY,
<lt_data_pro_ila> TYPE table.
* Instandhaltungsleistungsarten gemäß Selektion auslesen
SELECT * FROM t353i_t INTO TABLE lt_ilart
WHERE spras EQ sy-langu
AND ilart IN s_ilart.
* Zusätzliche Spalten für Betrag und QM-Betrag pro ILA aufbauen
LOOP AT lt_ilart INTO ls_ilart.
CONCATENATE 'BTRI' ls_ilart-ilart INTO ls_comp-name.
lr_data ?= cl_abap_datadescr=>describe_by_data( gs_data_kst-btri ).
* Datentyp aufbauen
MOVE lr_data TO ls_comp-type.
* Komponente anhängen (= Spalte)
APPEND ls_comp TO lt_comp.
CONCATENATE 'QMVALUE' ls_ilart-ilart INTO ls_comp-name.
lr_data ?= cl_abap_datadescr=>describe_by_data( gs_data_kst-qmvaluei ).
* Datentyp aufbauen
MOVE lr_data TO ls_comp-type.
* Komponente anhängen (= Spalte)
APPEND ls_comp TO lt_comp.
ENDLOOP.
* Strukturbeschreibung auslesen
lr_struct ?= cl_abap_structdescr=>create( lt_comp ).
* Tabellenbeschreibung auslesen
lr_table ?= cl_abap_tabledescr=>create( lr_struct ).
* Struktur erstellen
CREATE DATA ld_line TYPE HANDLE lr_struct.
ASSIGN ld_line->* TO <ls_data_pro_ila>.
* Interne Tabelle erstellen
CREATE DATA ld_table TYPE HANDLE lr_table.
ASSIGN ld_table->* TO <lt_data_pro_ila>.
This works fine and I got my field symbol as interal table <lt_data_pro_ila>.
But now I want to fill the internal table with help of some data from database table but I do not know how to do it, because I cannot address the fields of the field symbol table because it is type table.
I tried with....
LOOP AT gt_psp_plan ASSIGNING <ls_psp_plan>.
ASSIGN <ls_psp_plan>-pspnr TO <ls_data_pro_ila>-pspnr.
[...]
APPEND <ls_data_pro_ila> TO <lt_data_pro_ila>.
ENDLOOP
and...
LOOP AT gt_psp_plan ASSIGNING <ls_psp_plan>.
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_psp_plan> TO <ls_data_pro_ila>-pspnr.
[...]
APPEND <ls_data_pro_ila> TO <lt_data_pro_ila>.
ENDLOOP
..but did not work because I cannot speak to fields of structure <ls_data_pro_ila>.
How can I do it?
Thanks a lot!
Regards
Michael
05-16-2013 9:21 AM
Hi,
From you code, I see the below is missing
field-symbols:<fs_source> type any,
<fs_target> type any.
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_psp_plan> TO <fs_source>.
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_data_pro_ila> TO <fs_target>.
<fa_target> = <fs_source>.
or
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_data_pro_ila> TO <fs_target>.
<fa_target> = <ls_psp_plan>-pspnr.
05-22-2013 12:21 PM
Hey Kesavadas,
thanks a lot that works.
So I have to do it for every single field like that or is there any easier way to assign several fields where target fieldname and source fieldname are the same?
And can you please explain how it works technically with this assign that you told me (I want to learn about this dynamic assign because I'm not that conform in it 🙂 ). Whats the difference between the....
"direct" assign
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_psp_plan> TO <ls_data_pro_ila>-pspnr.
and the "indirect" assign
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_data_pro_ila> TO <fs_target>.
<fs_target> = <ls_psp_plan>-pspnr.
Regards
Michael
05-29-2013 9:53 AM
So I have to do it for every single field like that or is there any easier way to assign several fields where target fieldname and source fieldname are the same?
How about MOVE-CORRESPONDING?
MOVE-CORRESPONDING <ls_psp_plan> TO <ls_data_pro_ila>.
You might also find the following technique useful. I have some generic methods, where I know the name of some of the fields. I use code like this:
LOOP AT <generic_table> ASSIGNING <generic_wa>.
MOVE-CORRESPONDING <generic_wa> TO ls_specific_wa_with_known_fields.
" Do stuff with ls_specific_wa_with_known_fields.
MOVE-CORRESPONDING ls_specific_wa_with_known_fields TO <generic_wa>.
ENDLOOP.
05-22-2013 12:18 PM
Hi Michael,
Since the field symbol is generic i think you cannot specify the field names directly. So do the changes as shown:
LOOP AT gt_psp_plan ASSIGNING <ls_psp_plan>.
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_psp_plan> TO <fs_value1>.
ASSIGN COMPONENT 'PSPNR' OF STRUCTURE <ls_data_pro_ila> TO <fs_value2>.
<fs_value2> = <fs_value1>.
APPEND <ls_data_pro_ila> TO <lt_data_pro_ila>.
ENDLOOP.
05-22-2013 1:48 PM
Hi Michael,
This is in line with what Kesavadas and Satish have said, but take a look at the following document which shows some examples of working with field-symbols to manipulate a generically typed internal table.
If a field-symbol is declared to have a static structure, then at design-time you are able to directly reference its structure fields, for example...
FIELD-SYMBOLS: <mara> TYPE mara.
...populate <mara>...
some_field = <mara>-matnr.
but if a field-symbols is declared to have a generic type, e.g., TYPE ANY or TYPE TABLE, then at design-time it has no fields to reference so you must use ASSIGN COMPONENT to reference the fields that will exist at runtime, for example...
FIELD-SYMBOLS: <mara> TYPE ANY.
...populate <mara>...
ASSIGN COMPONENT 'MATNR' OF STRUCTURE <mara> TO some_field.
Cheers,
Amy
05-29-2013 9:35 AM
Thanks for your link Amy.
Is there any easy way to ASSIGN the fields in a easier way? E.g. I have 20 fields that have to be assigned, do I have to the the ASSIGN COMPONENT statement 20 times?
If so, is it possible to do it in some kind of loop?
Regards
Michael
05-29-2013 1:56 PM
Hi Michael,
As long as a generic field-symbol has been given a structure at runtime (so that it has named fields) then move-corresponding will work as Matthew Billingham suggests above. An example from the linked document...
DATA line_reference TYPE REF TO data.
FIELD-SYMBOLS <source_package_line> TYPE ANY.
CREATE DATA line_reference LIKE LINE OF source_package.
ASSIGN line_reference->* TO <source_package_line>.
In the example, generic field-symbol <source_package_line> is given the same structure as a line of the source_package table, so you could then do the following according to Matthew's suggestion...
MOVE-CORRESPONDING <other_structured_data> to <source_package_line>.
You can try out the following code to see the technique in action...
DATA lt_mara TYPE STANDARD TABLE OF mara.
FIELD-SYMBOLS <mara> TYPE mara.
DATA line_reference TYPE REF TO data.
FIELD-SYMBOLS <generic_line> TYPE any.
CREATE DATA line_reference LIKE LINE OF lt_mara.
* Observe the following statement gives <generic_line> a structure.
ASSIGN line_reference->* TO <generic_line>.
SELECT *
FROM mara
INTO TABLE lt_mara
UP TO 10 ROWS.
LOOP AT lt_mara ASSIGNING <mara>.
* Both <mara> and <generic_line> have structure so we can use move-corresponding
MOVE-CORRESPONDING <mara> TO <generic_line>.
ENDLOOP.
Cheers,
Amy