Application Development 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: 

Update a select-option From Table

former_member221827
Active Participant
0 Kudos

Hi,

I'm originally a C++ developer trying to learn ABAP.

I want to append values to a select-option from a table if another select-option is specified.  I wrote some code that I believe will work but looks very inefficient to me.  Any advice on how to streamline this process would appreciated.

The following is pseudo code and I left out some tweaks for simplicity and understanding but the basic idea is there.  I want to add selection criteria to a select-option based upon a second select option (that may or may not be provided) table lookup.

Example:

DATA: groups TYPE table3.

SELECT-OPTIONS:

     s_accountNo FOR table1-accountNo,

     s_accountGroupNo FOR table2-accountGroupNo.

**** get the Account Groups that meet the selection criteria.

START-OF-SELECTION

     SELECT * INTO TABLE groups

          FROM table3

          WHERE accountGroupNo IN s_accountGroupNo.

**** Remove duplicate accounts from the Account Groups

SORT groups BY accountNo.

DELETE ADJACENT DUPLICATES FROM groups COMPARING accountNo.

**** Append the account #'s onto the s_accountNo range/select-option

LOOP AT groups.

     APPEND groups-accountNo TO s_accountNo.

ENDLOOP.

**** manually edit the  s_accountNo to have the correct option/sign for use in further select statements.

LOOP AT s_accountNo.

     s_accountNo-sign = 'I'.

     s_accountNo-option = 'EQ'.

     MODIFY s_accountNo.

ENDLOOP.

Thanks much,

-Chris

16 REPLIES 16

former_member226203
Active Contributor
0 Kudos

AT SELECTION-SCREEN OUTPUT. is to be used when you need to populate selection option based on the other.

After this statement u can have an IF condition based on which you will populate the values again.

atul_mohanty
Active Contributor
0 Kudos

Hi Chris -

If you are just interested in appending select option s_accountno in your example, please check the below code I modified

DATA: groups TYPE table3.

SELECT-OPTIONS:

     s_accountNo FOR table1-accountNo,

     s_accountGroupNo FOR table2-accountGroupNo.

**** get the Account Groups that meet the selection criteria.

START-OF-SELECTION

     SELECT * INTO TABLE groups

          FROM table3

          WHERE accountGroupNo IN s_accountGroupNo.

**** Remove duplicate accounts from the Account Groups

SORT groups BY accountNo.

DELETE ADJACENT DUPLICATES FROM groups COMPARING accountNo.

**** Append the account #'s onto the s_accountNo range/select-option

LOOP AT groups.

     s_accountNo-low = groups-accountNo

     s_accountNo-sign = 'I'.

     s_accountNo-option = 'EQ'.

     APPEND s_accountNo.

ENDLOOP.

Let us know, if it works.

matt
Active Contributor
0 Kudos

1. Only SELECT the field you need - if you select 100 fields using * and only need one this is a performance hit. Likewise the table you're selecting into needs only one field

2. Use SELECT DISTINCT - that way you get just one entry and don't need to remove duplicates

3. Use a work area - tables with header lines are obsolete

4.

LOOP AT groups.

     APPEND groups-accountNo TO s_accountNo.

ENDLOOP.

The second line won't work, since s_accountNo is a structure (sign, option, low, high). Should be s_accountNo-low.

5.

You don't need 4) and the following loop. Instead combine them.

s_accountNo_line-sign = 'I'.

s_accountNo-line-option = 'EQ'.

LOOP AT groups INTO group.

   s_accountNo-low = group.

    INSERT s_accountNo_line INTO TABLE s_accountNo.

ENDLOOP.

0 Kudos

Thank you greatly for the input, I paired it down to the following.
:

Data: groups TYPE table3,
         s_accountNo_line LIKE LINE OF s_accountNo.

SELECT-OPTIONS:

     s_accountNo FOR table1-accountNo.

     s_accountGroupNo FOR table2-accountGroupNo

START-OF-SELECTION

     SELECT DISTINCT accountNo

     FROM table3

     INTO CORRESPONDING FIELDS OF TABLE groups

     WHERE accountGroupNo IN s_accountGroupNo.

s_accountNo_line-sign = 'I'.

s_accountNo_line-option = 'EQ'.

LOOP AT groups

     s_accountNo_line-low = groups-accountNo

     INSERT s_accountNo_line INTO TABLE s_accountNo.

ENDLOOP.

This is more efficient and concise by a longshot.  I have tried googling and looking up work area vs internal table and I'm not grasping the concept well.  I'll continue looking into it, but if you have any more input in that area I'd appreciate it.

-Chris

matt
Active Contributor
0 Kudos

There is no "work area vs internal table". But these concepts are widely documented, so do no bear repeating here. Your best bet is to run in debug and watch how data moves around.

Jelena
Active Contributor
0 Kudos

I'm really confused why do you have SELECT-OPTION and then change it in START-OF-SELECTION event. This doesn't seem to make a lot of sense... Select options are meant for users to enter their, well, selection criteria. If someone enters one thing and then the program plays "switcheroo" on them wouldn't that be confusing?

If you need to pre-fill some values for the users (i.e. defaults) then it needs to be done in INITIALIZATION. Or if you just need to build a range to use in SELECT somewhere then take a look at Help article for 'range'. Or maybe you don't even need anything and could just use SELECT ... JOIN. This example looks very confusing to be honest.

And if you're selecting just one field then you don't need INTO CORRESPONDING FIELDS.

Internal tables are similar to arrays in other languages. Not exactly the same but close enough.

I'm also not sure why would anyone want to learn ABAP at this point since it's clearly a dying breed but that's another story.

matt
Active Contributor
0 Kudos

Jelena Perfiljeva wrote:

I'm also not sure why would anyone want to learn ABAP at this point since it's clearly a dying breed but that's another story.

Rumours of ABAP's demise have been circulating for at least fifteen years. And yet, still here we are!

0 Kudos

The goal is that rather than having to key in sometimes large quantities of account numbers in the account select-option the user has the option to enter an account group which will then add all the account numbers associated with that group to the account number selection criteria.  (if that makes sense).

As far as learning ABAP, I look at it as a chance to get better with database manipulation as much as anything

Thanks for the into corresponding fields tip.

Jelena
Active Contributor
0 Kudos

Chris - but wouldn't this relationship be stored somewhere in SAP? I just feel you don't need to manipulate select options at all, although I'm not sure what data you'll be getting exactly. You might want to post what tables you're planning to read - if those are standard ones (those that don't start with Y or Z) then we would know them too, it's not a secret.

For example, for table KNA1 (customer master) we could have the selection options for account number (KUNNR) and country (LAND1). The users could fill in either one of them or both or none.

Then there would be a SELECT statement like this (just a very simple example):


SELECT KUNNR NAME1

INTO TABLE itab_customers

FROM KNA1

WHERE KUNNR IN SO_KUNNR

AND LAND1 IN SO_LAND1.

If, for example, the users only select 'US' for the country (LAND1), the program does not need to go and fill in SO_KUNNR with the customer numbers that fit that criteria. SELECT statement takes care of that. If both selection options are left blank then SELECT would just read the whole KNA1 table (blank select option translates to "include all", not to "equals blank" - this part can be confusing for beginners).

Again, not sure what you're doing exactly further in the program but I feel you might be just misunderstanding how selection options work.

Former Member
0 Kudos

Chris Bosler wrote:

...  sometimes large quantities of account numbers in the account select-option.. .

Another consideration will be the size of the SQL statement that is generated by ABAP and sent to the database. If you end up with too many " OR AccountNo = 'XXXXXXXX'" options, you may get a dump.

Rob

0 Kudos

Are you referring to a select-option with doing the multiple selections, i.e.

     sign 'I', option 'EQ', low 'value'

meaning this will be turned into an SQL statement with OR AccountNo = 'XXXXXX' and a ton of these could cause an error?

as opposed to doing a range

     sign 'I' option 'BT' or whatever between is?

Former Member
0 Kudos

Yes.

Another option would be to use a sub-query to pass the account numbers from the Account Group table.

Rob

0 Kudos

The actual selection is fairly complicated from my point of view.  I wrote the accountNo example to make things less confusing for me as much as anyone else, not to hide anything.  I also didn't expect this amount of feedback, though it is appreciated.

The eventual select statement that is done is the following:

  SELECT DISTINCT vttp~zseq_num

                  likp~vbeln

                  likp~lprio

                  likp~vstel

                  lips~werks

                  likp~lgnum

                  lips~posnr

                  lips~lgort

                  lips~vgbel

                  lips~vgpos

                  lips~sobkz

                  lips~lfimg

                  lips~vrkme

                  lips~matnr

                  lips~volum

                  mara~raube

                  vttk~dplbg

                  vttp~tknum

                  vttp~tpnum

                  likp~berot

                  likp~vkorg

                  likp~lfart

                  INTO TABLE temp_deliveries

  FROM vttk

       INNER JOIN vttp

       ON vttk~tknum = vttp~tknum

       INNER JOIN likpuk AS likp

       ON vttp~vbeln = likp~vbeln

       INNER JOIN lipsup AS lips

       ON likp~vbeln = lips~vbeln

       INNER JOIN mara

       ON lips~matnr = mara~matnr

  WHERE likp~vstel = p_vstel

    AND lips~werks = p_werks

    AND likp~lgnum IN s_lgnum

    AND likp~vbeln IN s_vbeln

    AND lips~vgbel IN s_vgbel

    AND vttk~dplbg IN s_dplbg

    AND vttk~tknum IN s_tknum

    AND mara~raube = p_raube

    AND likp~lfart IN ('ZLF', 'NL')

    AND lips~kosta <> 'C'

    AND lips~kosta <> ''

    AND likp~kostk <> 'C'

    AND likp~vbtyp = outbound.

and the structure it is put into is the following:

TYPES: BEGIN OF type_deliveries,

          zseq_num    TYPE vttp-zseq_num,

          vbeln       TYPE likp-vbeln,

          lprio       TYPE likp-lprio,

          vstel       TYPE likp-vstel,

          werks       TYPE likp-werks,

          lgnum       TYPE likp-lgnum,

          posnr       TYPE lips-posnr,

          lgort       TYPE lips-lgort,

          vgbel       TYPE lips-vgbel,

          vgpos       TYPE lips-vgpos,

          sobkz       TYPE lips-sobkz,

          lfimg       TYPE lips-lfimg,

          vrkme       TYPE lips-vrkme,

          matnr       TYPE lips-matnr,

          volum       TYPE lips-volum,

          raube       TYPE mara-raube,

          dplbg       TYPE vttk-dplbg,

          tknum       TYPE vttk-tknum,

          tpnum       TYPE vttp-tpnum,

          berot       TYPE likp-berot,

          vkorg       TYPE likp-vkorg,

          lfart       TYPE likp-lfart,

          sdabw       type likp-sdabw,

          orig_lgort  TYPE lips-zzorig_lgort,

          selected    TYPE flag,

          counter(15) TYPE n,

        END OF type_deliveries.


Currently there is a select option for tknum and I am attempting (successfully with my change shown above, though as many have pointed out I may be misusing the intended functionality) to add another select-option for s_pickno which is a field of a custom table that has pickno as one of it's unique keys and tknum as another of it's fields.  The idea is to be able to take a pickno and use it to find all the tknum's associated and then use them in the select statement above as well as any tknum's provided as initial input by the user.  If there is a better method than modifying the s_tknum selection I'm open to feedback.


Apologies that my initial example did not portray this, but being new I was a little overwhelmed myself and want something I can wrap my head around better.  There's my wall of text

0 Kudos

This is the "answer" I went with.  A sub-query worked perfectly for the situation.  Thanks for the reply.

former_member196064
Active Participant
0 Kudos

This message was moderated.

0 Kudos

Seems very concise and straightforward, Thank you.