Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

FOR Expression usage in nested scenarios

former_member302911
Active Participant
0 Likes
1,448

Hi,

I have this scenario:

Contract Details (Structure)
- Number (123)
-- Contract Additional Info (Table)
--- Row 1
---- Additional Info Name (CONTRACT_TYPE)
---- Additional Info Values (Table)
----- Row 1
------ Value (Open Contract)
--- Row 2
---- Additional Info Name (COMPANY)
---- Additional Info Values (Table)
----- Row 1
------ Value (Company 1)
----- Row 2
------ Value (Company 2)
----- Row 3
------ Value (Company 3)

I'm using this code:

 lt_ctr =    VALUE #( FOR ls_contract_details IN lt_contracts<br>                      
                      FOR ls_additional_info  IN lt_contracts-additionalinfos WHERE ( name = 'COMPANY' )
                      FOR ls_companies        IN lt_contracts-additionalinfos-values
                      LET ls_ctr = VALUE <some_type>(

                      number    = ls_contract_details-number                     
                      type      = VALUE #( ls_contract_details-additionalinfos[ name = 'CONTRACT_TYPE' ]-values[ 01 ]-value DEFAULT space )
                      company   = ls_companies-values-value

                      ) IN ( ls_ctr ) ).   

The result of LT_CTR is:

Contract Number | Contract Type | Contract Company

123 | Open Contract | Company 1

123 | Open Contract | Company 2

123 | Open Contract | Company 3

This is ok for me but, if the Additional Info COMPANY missing, the FOR...LET Expression return no record in LT_CTR.

Contract Details (Structure)
- Number (123)
-- Contract Additional Info (Table)
--- Row 1
---- Additional Info Name (CONTRACT_TYPE)
---- Additional Info Values (Table)
----- Row 1
------ Value (Open Contract)

The procedure follow latest FOR expressions because i need to duplicate record based on companies:

FOR ls_additional_info IN lt_contracts-additionalinfos WHERE ( name = 'COMPANY' )

FOR ls_companies IN lt_contracts-additionalinfos-values

There is a way to set a condition ?

I would like the following result if company missing:

Contract Number | Contract Type | Contract Company

123 | Open Contract |

123 | Open Contract |

123 | Open Contract |

What is the smartest and compact code to do this ?

Thank you,

Angelo.

1 ACCEPTED SOLUTION
Read only

Sandra_Rossi
Active Contributor
0 Likes
1,380

You shouldn't use one constructor expression when it becomes too complex, it's hard to read.

Better define a new method (provided that you use ABAP Objects) for better legibility.

For example:

DATA(lt_ctr) = VALUE ty_ctrs( FOR ls_contract_details IN lt_contracts
                              LET aux_additionalinfos = COND ty_additionalinfos(
                                WHEN line_exists( ls_contract_details-additionalinfos[ name = 'COMPANY' ] )
                                THEN VALUE #( FOR ls_additional_info IN ls_contract_details-additionalinfos
                                              WHERE ( name = 'COMPANY' )
                                              ( ls_additional_info ) )
                                ELSE VALUE #( ( name   = 'COMPANY' 
                                                values = VALUE #( 
                                                        FOR i = 1 WHILE i <= 3
                                                        ( ) ) ) ) ) IN
                              FOR ls_additional_info  IN aux_additionalinfos
                              FOR ls_companies        IN ls_additional_info-values
                              LET ls_ctr = VALUE ty_ctr(
                                number    = ls_contract_details-number
                                type      = VALUE #( ls_contract_details-additionalinfos[ name = 'CONTRACT_TYPE' ]-values[ 1 ]-value OPTIONAL )
                                company   = ls_companies-value )
                              IN ( ls_ctr ) ).

Hi,

I have this scenario:

Contract Details (Structure)
- Number (123)
-- Contract Additional Info (Table)
--- Row 1
---- Additional Info Name (CONTRACT_TYPE)
---- Additional Info Values (Table)
----- Row 1
------ Value (Open Contract)
--- Row 2
---- Additional Info Name (COMPANY)
---- Additional Info Values (Table)
----- Row 1
------ Value (Company 1)
----- Row 2
------ Value (Company 2)
----- Row 3
------ Value (Company 3)

I'm using this code:

 lt_ctr =    VALUE #( FOR ls_contract_details IN lt_contracts<br>                      
                      FOR ls_additional_info  IN lt_contracts-additionalinfos WHERE ( name = 'COMPANY' )
                      FOR ls_companies        IN lt_contracts-additionalinfos-values
                      LET ls_ctr = VALUE <some_type>(

                      number    = ls_contract_details-number                     
                      type      = VALUE #( ls_contract_details-additionalinfos[ name = 'CONTRACT_TYPE' ]-values[ 01 ]-value DEFAULT space )
                      company   = ls_companies-values-value

                      ) IN ( ls_ctr ) ).   

The result of LT_CTR is:

Contract Number | Contract Type | Contract Company

123 | Open Contract | Company 1

123 | Open Contract | Company 2

123 | Open Contract | Company 3

This is ok for me but, if the Additional Info COMPANY missing, the FOR...LET Expression return no record in LT_CTR.

Contract Details (Structure)
- Number (123)
-- Contract Additional Info (Table)
--- Row 1
---- Additional Info Name (CONTRACT_TYPE)
---- Additional Info Values (Table)
----- Row 1
------ Value (Open Contract)

The procedure follow latest FOR expressions because i need to duplicate record based on companies:

FOR ls_additional_info IN lt_contracts-additionalinfos WHERE ( name = 'COMPANY' )

FOR ls_companies IN lt_contracts-additionalinfos-values

There is a way to set a condition ?

I would like the following result if company missing:

Contract Number | Contract Type | Contract Company

123 | Open Contract |

123 | Open Contract |

123 | Open Contract |

What is the smartest and compact code to do this ?

Thank you,

Angelo.

5 REPLIES 5
Read only

Sandra_Rossi
Active Contributor
0 Likes
1,380

You'd better simplify your question so that people can better understand.

Instead of writing approximate text, you could write a full ABAP example with actual and expected results.

Read only

Sandra_Rossi
Active Contributor
0 Likes
1,380

Test case 1 which works as expected:

TYPES: BEGIN OF ty_value,
         value TYPE string,
       END OF ty_value,
       ty_values TYPE STANDARD TABLE OF ty_value WITH EMPTY KEY,
       BEGIN OF ty_additionalinfo,
         name   TYPE string,
         values TYPE ty_values,
       END OF ty_additionalinfo,
       ty_additionalinfos TYPE STANDARD TABLE OF ty_additionalinfo WITH EMPTY KEY,
       BEGIN OF ty_contract_detail,
         number          TYPE i,
         additionalinfos TYPE ty_additionalinfos,
       END OF ty_contract_detail,
       ty_contracts TYPE STANDARD TABLE OF ty_contract_detail WITH EMPTY KEY,
       BEGIN OF ty_ctr,
         number  TYPE i,
         type    TYPE string,
         company TYPE string,
       END OF ty_ctr,
       ty_ctrs TYPE STANDARD TABLE OF ty_ctr WITH EMPTY KEY.
DATA(lt_contracts) = VALUE ty_contracts(
( number = 123
  additionalinfos = VALUE #(
    ( name   = 'CONTRACT_TYPE'
      values = VALUE #(
        ( value = 'Open Contract' ) ) )
    ( name   = 'COMPANY'
      values = VALUE #(
        ( value = 'Company 1' )
        ( value = 'Company 2' )
        ( value = 'Company 3' ) ) ) ) ) ).
DATA(lt_ctr) = VALUE ty_ctrs( FOR ls_contract_details IN lt_contracts
                     FOR ls_additional_info  IN ls_contract_details-additionalinfos
                         WHERE ( name = 'COMPANY' )
                     FOR ls_companies        IN ls_additional_info-values
                     LET ls_ctr = VALUE ty_ctr(
                       number    = ls_contract_details-number
                       type      = VALUE #( ls_contract_details-additionalinfos[ name = 'CONTRACT_TYPE' ]-values[ 1 ]-value OPTIONAL )
                       company   = ls_companies-value )
                     IN ( ls_ctr ) ).
ASSERT lt_ctr = VALUE ty_ctrs(
( number = '123' type = 'Open Contract' company = 'Company 1' )
( number = '123' type = 'Open Contract' company = 'Company 2' )
( number = '123' type = 'Open Contract' company = 'Company 3' ) ).
What algorithm for this test case 2:
DATA(lt_contracts) = VALUE ty_contracts(
( number = 123
  additionalinfos = VALUE #(
    ( name   = 'CONTRACT_TYPE'
      values = VALUE #(
        ( value = 'Open Contract' ) ) )
    ( name   = 'COMPANY'
      values = VALUE #( ) ) ) ) ).

to obtain this:

ASSERT lt_ctr = VALUE ty_ctrs(
( number = '123' type = 'Open Contract' company = '' )
( number = '123' type = 'Open Contract' company = '' )
( number = '123' type = 'Open Contract' company = '' ) ).

without changing the result of test case 1.

Read only

former_member302911
Active Participant
0 Likes
1,380

Hi Sandra,

sorry for bad explanation of test case scenarios and thank you for the effort to help me.

Taking your example and to simplify, i want to obtain this:

ASSERT lt_ctr = VALUE ty_ctrs(
( number = '123' type = 'Open Contract' company = '' )
( number = '123' type = 'Open Contract' company = '' )
( number = '123' type = 'Open Contract' company = '' ) ).

From this:

DATA(lt_contracts) = VALUE ty_contracts(
( number = 123
  additionalinfos = VALUE #(
    ( name   = 'CONTRACT_TYPE'
      values = VALUE #(
        ( value = 'Open Contract' ) ) ) ) ) ).

Thank you,

Angelo.

Read only

Sandra_Rossi
Active Contributor
0 Likes
1,381

You shouldn't use one constructor expression when it becomes too complex, it's hard to read.

Better define a new method (provided that you use ABAP Objects) for better legibility.

For example:

DATA(lt_ctr) = VALUE ty_ctrs( FOR ls_contract_details IN lt_contracts
                              LET aux_additionalinfos = COND ty_additionalinfos(
                                WHEN line_exists( ls_contract_details-additionalinfos[ name = 'COMPANY' ] )
                                THEN VALUE #( FOR ls_additional_info IN ls_contract_details-additionalinfos
                                              WHERE ( name = 'COMPANY' )
                                              ( ls_additional_info ) )
                                ELSE VALUE #( ( name   = 'COMPANY' 
                                                values = VALUE #( 
                                                        FOR i = 1 WHILE i <= 3
                                                        ( ) ) ) ) ) IN
                              FOR ls_additional_info  IN aux_additionalinfos
                              FOR ls_companies        IN ls_additional_info-values
                              LET ls_ctr = VALUE ty_ctr(
                                number    = ls_contract_details-number
                                type      = VALUE #( ls_contract_details-additionalinfos[ name = 'CONTRACT_TYPE' ]-values[ 1 ]-value OPTIONAL )
                                company   = ls_companies-value )
                              IN ( ls_ctr ) ).
Read only

1,380

Thank you Sandra for help.

Yes it is really hard to read and understand. 🙂

I'm tryng to understand the real potential of abap 7.4 and sometimes it is very hard to approach for particular scenario like this.

You can develop compact and smart code(i like it) but sometimes sacrificing readability.

P.s.: If I need an help, next time i will promise, i will write a full abap example.

Thank you again.