Pick field value from an ABAP structure - abap

I'm trying to pick up the value from a field which is in a table line. But I cannot access it because my table has no header line.
I have the following code:
DATA: t2 TYPE TABLE OF komlfp,
go_settlement TYPE REF TO cl_wb2_rebate_settlement_2.
TRY.
CREATE OBJECT go_settlement.
go_settlement->settlement(
EXPORTING
iv_testrun = 'X'
iv_bldat = sy-datum
iv_wfdat = sy-datum
is_contract = wa_view
is_contract_first = wa_view
IMPORTING
et_komlfk = t1
et_komlfp = t2 ).
CATCH cx_wb2_rebates.
ENDTRY.
What I want now is to use the value t2-kzwi6d, but I always get:
"T2" is a table without a header line and therefore does not have a component
called "KZWI6D".
I've already tried declaring the table with a header line, but when I try that, I get:
Tables with headers are no longer supported in the OO context.
Can someone help me please?
Thanks

You created t2 as a table without a header line, so the program cannot recognize any column names.
One solution could be to define it as a table with a header line, though that approach is considered obsolete and outdated.
DATA: t2 TYPE STANDARD TABLE OF komlfp WITH HEADER LINE.
Another option is to dynamically get the field value. But then you have to make sure it actually exists and that the assign worked, so more error management is necessary.
DATA: t2 TYPE STANDARD TABLE OF komlfp.
FIELD-SYMBOLS: <t2_line> LIKE LINE OF t2,
<kzwi6d> TYPE kzwi6.
LOOP AT t2 ASSIGNING <t2_line>.
ASSIGN COMPONENT 'KZWI6D' OF STRUCTURE <t2_line> TO <kzwi6d>.
ENDLOOP.
Edit: As Sandra has pointed out, you don't have to do it dynamically and can just get the value directly like this as well:
DATA: t2 TYPE STANDARD TABLE OF komlfp.
FIELD-SYMBOLS: <t2_line> LIKE LINE OF t2.
LOOP AT t2 ASSIGNING <t2_line>.
" you now have access to the value using <t2_line>-kzwi6d
ENDLOOP.

Related

use SELECT on internal table (ABAP)

I am still very inexperienced with SAP ABAP.
I have an internal table that I want to filter further and further based on whether data is present.
I have tried the following, but unfortunately I cannot apply a SELECT to an internal table.
How can I solve this problem?
Hope I have explained my problem clearly enough!
"Here I'm getting the hole database into my internal table
SELECT * FROM TABLE
INTO CORRESPONDING FIELDS OF TABLE #itab.
"This should be my first filter if iv_name is not initial
IF iv_name IS NOT INITIAL.
SELECT * FROM itab
WHERE NAME = #iv_name
INTO CORRESPONDING FIELDS OF TABLE #itab.
ENDIF.
"This should be my second filter if iv_age is not initial
IF iv_age IS NOT INITIAL.
SELECT * FROM itab
WHERE AGE = #iv_age
INTO CORRESPONDING FIELDS OF TABLE #itab.
ENDIF.
There are several ways in ABAP to achieve your goal.
You can use the DELETE keyword to filter the data in an internal table:
IF iv_name IS NOT INITIAL
DELETE itab WHERE name NE iv_name.
ENDIF.
Another possibility is to use the FILTER keyword, but the prerequisite is, that the internal table is TYPE SORTED or HASHED:
itab = FILTER #( itab WHERE name = iv_name ).

Sorted table with parameter t_table of cl_salv_table class

If I use the internal table as a standard table the parameter T_TABLE accepts normally,
but when I declare as a sorted table this error happen: "ITUSER" is not type-compatible with formal parameter "T_TABLE".
Can you guys help me identify why this happens?
TABLES: USER_ADDR,USR41.
TYPES: BEGIN OF LINE02_TYPE,
Z_BNAME TYPE USER_ADDR-BNAME,
Z_NAME TYPE USER_ADDR-NAME_FIRST,
Z_LAST TYPE USER_ADDR-NAME_LAST,
Z_TERMI TYPE USR41-TERMINAL,
Z_LASTD TYPE USR41-LOGON_DATE,
Z_KOSTL TYPE USER_ADDR-KOSTL,
END OF LINE02_TYPE.
DATA: ITUSER TYPE SORTED TABLE OF LINE02_TYPE WITH UNIQUE KEY Z_BNAME,
"ITUSER TYPE standard TABLE OF line02_type,
R_TABLE TYPE REF TO CL_SALV_TABLE.
START-OF-SELECTION.
SELECT A~BNAME A~NAME_FIRST A~NAME_LAST B~TERMINAL B~LOGON_DATE A~KOSTL FROM USER_ADDR AS A
LEFT JOIN USR41 AS B ON B~BNAME = A~BNAME
INTO TABLE ITUSER.
CALL METHOD CL_SALV_TABLE=>FACTORY
IMPORTING
R_SALV_TABLE = R_TABLE
CHANGING
T_TABLE = ITUSER.
CALL METHOD R_TABLE->DISPLAY.
Unfortunately I do not see it is documented anywhere but T_TABLE has to be a STANDARD TABLE. If you dig deeper into FACTORY method the T_TABLE parameter is passed to SET_DATA method which requires the table as STANDARD TABLE
try.
r_salv_table->set_data(
changing
t_table = t_table ).
catch cx_salv_no_new_data_allowed. "#EC NO_HANDLER
endtry.
Moreover if you define the parameter as TABLE a STANDARD TABLE is implicitely meant. Here is the reference
As already pointed out, the signature for factory is changing t_table type table.
TABLE is a generic ABAP type which is the old way to say STANDARD TABLE.
This is required since actions you perform via the ALV are reflected on the table itself. When you press the sort button the internal table will also be sorted (hence also changing). So when you get e.g. the double click event, you can safely access my_table[ row ] since it's sorted in the same way as it's displayed to the user.
Such a sorting cannot be represented in HASHED TABLE or SORTED TABLE (sort can be on any column/s).

A short syntax to fill ABAP table from another table?

In the old ABAP syntax I have to loop over the source table, and inside of the loop append value to the table.
For example:
DATA:
it_source_table type table of mara,
et_result_table type table of matnr.
loop at it_source_table into data(ls_source_table).
append ls_source_table-matnr to et_result_table.
endloop.
Is there with a new ABAP syntax (750, 752) ("move-corresponding", "value#") a way to achieve the same in less sentences?
You can use the VALUE operator with the FOR ... IN addition:
et_result_table = VALUE #( FOR material IN it_source_table ( material-matnr ) ).

Given a field symbol pointing to a table, how do I assign it to a structure field symbol?

I have a field symbol <lt_something> which points to a table. This table has a single line as content. How do I assign that line in the table to a new field symbol, say <ls_something> ?
I tried :
READ TABLE <lt_something> INDEX 1 REFERENCE INTO <ls_something>.
But the above code dumps, what is the right approach to this problem?
You're mixing up field symbols and data references. Use either
DATA lr_foo TYPE REF TO something.
READ TABLE lt_something INDEX 1 REFERENCE INTO lr_foo.
lr_foo->bar = 'baz'.
or
FIELD-SYMBOLS <ls_foo> TYPE something.
READ TABLE lt_something INDEX 1 ASSIGNING <ls_foo>.
<ls_foo>-bar = 'baz'.
but do not merge the two ways.
Are you sure that your field symbol table is assigned before you perform your read? The general structure of your read table looks OK, but you should use ASSIGNING in your read statement:
FIELD-SYMBOLS: <lt_something> TYPE ANY TABLE,
<ls_something> TYPE ANY.
" ... blah blah presume you did some work on <lt_something>...
IF <lt_something> IS ASSIGNED.
READ TABLE <lt_something> INDEX 1 ASSIGNING <ls_something>.
" Check sy-subrc or <ls_something> IS ASSIGNED.
" Do work.
ENDIF.
The field-symbol needs to be the line type of the table, not the table itself.
DATA:
i_vbak type standard table of vbak.
FIELD-SYMBOLS:
<i_vbak> type vbak.
READ TABLE i_vbak ASSIGNING <i_vbak>.

How to set dynamic key for READ TABLE?

I'm trying to work out a way to read an internal table that has to be created dynamically. I have created the following report that fills a dynamic internal table with data.
On the last line, I'm trying to read it with a key (mandt for example), but I I get this syntax error:
The specified type has no structure and therefore no component called MANDT
I have debugged and I can see that <any_tab> has been populated successfully and the structure of the table (field names) are correct. The problem presents itself when I try to read the table into a work area. Maybe I'm doing this wrong, but it seems like something that should be possible to do, and I have a feeling I'm missing something small.
The reason I am trying this out is that I have found identical selects happening in a program and want to buffer records in memory and read them from there to avoid DB accesses. This is easy to implement, however I haven't done this when the table, where clause and into clause of the OPEN SQL statement I'm trying to optimize are dynamic.
How to correct the syntax error?
DATA: t681_rep TYPE TABLE OF t681 , wa_681 LIKE LINE OF t681_rep,
tabref TYPE REF TO data , waref TYPE REF TO data.
FIELD-SYMBOLS: <any_tab> TYPE ANY TABLE,
<any_wa> TYPE ANY,
<var1> TYPE ANY.
"fill t681_rep
SELECT *
FROM t681
INTO TABLE t681_rep
UP TO 1 ROWS WHERE kotab = 'A002'.
READ TABLE t681_rep INTO wa_681 WITH KEY kotab = 'A002'.
IF sy-subrc = 0.
"if A002 is found create a table of that type and fill it
CREATE DATA tabref TYPE TABLE OF (wa_681-kotab).
ASSIGN tabref->* TO <any_tab>.
SELECT * UP TO 10 ROWS
FROM (wa_681-kotab)
INTO TABLE <any_tab>.
ENDIF.
CREATE DATA waref TYPE a002.
ASSIGN waref->* TO <any_wa>.
READ TABLE <any_tab> ASSIGNING <any_wa> WITH KEY mandt = '800'. <- problem area
IF sy-subrc = 0.
"do stuff with <any_wa>...
ENDIF.
You just need to put the field name in parentheses.
data: field type string.
field = 'MANDT'.
READ TABLE <any_tab> ASSIGNING <any_wa> WITH KEY (field) = '800'.
IF sy-subrc = 0.
"do stuff with <any_wa>...
ENDIF.
AFAIK, you have to do it the 'long way round':
FIELD-SYMBOLS: <any_field> TYPE any.
LOOP AT <any_tab> ASSIGNING <any_wa>.
ASSIGN COMPONENT 'MANDT' OF STRUCTURE <any_wa> TO <any_field>.
IF <any_field> <> 800.
CONTINUE.
ENDIF.
" do stuff with <any_wa> - you will have to assign <any_field> again to access fields.
ENDLOOP.
You are trying to beat a database in efficiency, it is a loosing battle.
Just go to SE11, select your table, go to technical settings and change the technical settings ( buffering & buffering type ), you do not require an object modification key for this. You can also make sure that the size category is correct.
You can use RTTS to get the table keys.
data table_name type string.
table_name = 'A002'.
" Dynamically create the table type
data the_table type ref to data.
create data the_table type table of (table_name).
" Use RTTS to get table keys
data typedescription type ref to cl_abap_tabledescr.
typedescription ?= cl_abap_tabledescr=>describe_by_data_ref( the_table ).
data keys type abap_table_keydescr_tab.
keys = typedescription->get_keys( ).
REPORT y_test_dynamic_table.
DATA: table_name TYPE string,
typedescription TYPE REF TO cl_abap_tabledescr,
keys TYPE abap_keydescr_tab,
ls_key TYPE abap_keyname.
table_name = 'ZYFRM_STG'.
" Dynamically create the table type
DATA the_table TYPE REF TO data.
CREATE DATA the_table TYPE TABLE OF (table_name).
" Use RTTS to get table keys
typedescription ?= cl_abap_tabledescr=>describe_by_data_ref( the_table ).
keys = typedescription->KEY.
loop at keys INTO ls_key.
***
ENDLOOP.