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: 

Is there a clever way to exclude initial values from nmin function?

bernd_dittrich
Active Participant
0 Kudos

I want to extract the smallest non-initial value from a set of fields from a structure, let+s say with 3 different time stamps, time1, time 2 and time3


  lv_timst = nmin( val1 = ls_times-time1

                           val2 =ls_times-time2

                            val2 =ls_times-time3

                     ).

All of them could be initial and I don´t want to get back initial values.

Is there a clever and fast way to achieve this without calling helper methods, replacing initial times in the structure before doing the nmin?

Thanks for your help!

1 ACCEPTED SOLUTION

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

What about  something like

  lv_timst = nmin(
        val1 = cond type( when  ls_times-time1 is not initial then ls_times-time1 else max_value )

  val2 = cond type( when  ls_times-time2 is not initial then ls_times-time2 else max_value )

... )

19 REPLIES 19

Former Member
0 Kudos

What do you want if all values are initial?

Rob

0 Kudos

Good question, reading it through my quation was not really precise. In my specific case there will be one at least one field be not initial, so I didn´t thought of it yet.

So the correct question would be:


All of them could be initial, but at least one of them will not be initial. And I don´t want to get back initial as a result in case at least one of the value sis not initial.

Thanks already so far!

0 Kudos

Well, I suppose you could use an NMAX function first to determine if there is a non-initial value, but I don't know if you would consider this "clever".

Rob

0 Kudos

I would consider it clever , but I don´t see how this would work, I tried to use nmax to compare with an non-initial-value, but then this non-initial value is considered as min as well.

If the non-initial value is lower then an existing value it is considered instead of the real value, if it is higher then it is considered as well instead of the real value.

I tried like this:


  lv_timst = nmin( val1 = nmax( val1 = ls_times-time1 val2 = lc_noninitial)

                            val2 = nmax( val1 = ls_times-time2 val2 = lc_noninitial)

                            val3 = nmax( val1 = ls_times-time3 val2 = lc_noninitial)

).

Let´s assume time2 is 20150323000000.

Now if my lc_noninitial is e.g. 190001010000 or something low, it is considered as higher than the initial value(in the namx e.g. for time1 which is initial), but lower than my time 2 and I get it back  as minimum.

If lc_noninitial is higher, e.g. 99993112000000 then it replaces my relevant time 2 in the nmax expression. Wrong again .

But maybe you have something different in mind?

0 Kudos

Yes - I meant doing a separate NMAX before doing the NMIN, to find the maximum value of the fields. If the result is not null, then there must be at least one not null entry.

All bets are off in the case of negative numbers though.

Rob

Message was edited by: Rob Burbank

0 Kudos

ok, but assuming I have at least one not-null value based on the first nmax check, how would I now extract the lowest non-initial value then in the second step? There could still be initial values in e.g. time3 which would give me an initial value back as result of nmin, right?

0 Kudos

And as those are all timestamps, no negative values ot be relevant here

0 Kudos

True

Rob

0 Kudos

Thanks for looking into this anyhow!

0 Kudos

Well, there's probably a way of doing this using field symbols or DO VARYING.

Rob

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

What about  something like

  lv_timst = nmin(
        val1 = cond type( when  ls_times-time1 is not initial then ls_times-time1 else max_value )

  val2 = cond type( when  ls_times-time2 is not initial then ls_times-time2 else max_value )

... )

0 Kudos

Thank you Horst, works like a pro


Maybe it is worth mentioning in the ABAP docu for nmin, as initial values are always tricky for minimum calculations. Mid-term it would be cool if nmin might get an parameter like "IGNORING INITIAL VALUES" or so.

For those not too familar with the cond syntax (like myself :->): type is the data type of the data element considered in the condition, in my example e.g. a timestamp. In my eyample the data element for the time fields is e.g./TM/TIMESTAMP, then the synrtay goes like this:

  lv_timst = nmin(
        val1 = cond /TM/TIMESTAMP( when  ls_times-time1 is not initial then ls_times-time1 else max_value )

  val2 = cond /TM/TIMESTAMP( when  ls_times-time2 is not initial then ls_times-time2 else max_value )

... )

Thanks again, Horst!

0 Kudos

Hi,

What is max_value?

Is that a constant or some hidden ABAP command/function?

horst_keller
Product and Topic Expert
Product and Topic Expert
0 Kudos

A constant with an appropriate value. For some numerical data types you can use attributes of CL_ABAP_MATH, but that's not possible for type p.

0 Kudos

Thanks.

I thought I've missed another new built-in function/command in NW 7.4 (or earlier release)

rdiger_plantiko2
Active Contributor
0 Kudos

Now the problem is solved by Horst, let me dream a bit...

data(lv_min)  =  nmin(  tab = filter( tab = lt_times

                                                       cond = table_line is not initial ) )

I'll come back to this comment in five years 🙂

0 Kudos

The master says

reduce #( init m = max
          for x in tab where ( x is not initial )
          next m = nmin( val1 = m val2 = x ) )

0 Kudos

Had an interesting discussion with some colleagues and we tried to push this a bit futher:

Assuming we have a table like this:

Value 1          Value2

10                    A

12                    B

5                      C

16                    D

We would now like to extract not only 5 as the minimum value, but also the other value of the same line, in our case C. We where not successful so far, feels like it must be included in the nmin expression, but this does not really work. Addinf another condition after the min did also not bring expected results so far...

Any hints?

Bernd

0 Kudos

Hello Bernd,

following the lines of Horst (or his "master in the background" )


data(min= reduce ty_struc( init r = value ty_struc( col1 = nmax col2 = '' )

                               for m in itab

                               next r = cond ty_struc(

                                 when r-col1 < m-col1 then r else m ) ).

The output class will then print the row with 5 and 'C'

cl_demo_output=>display( min ).

supposed we preceded the code with the usual declaratory bla-bla:



constants: nmax type i value cl_abap_math=>MAX_INT4.

types: begin of ty_struc,

   col1 type i,

   col2 type c,

   end of ty_struc,

   ty_struc_tab type table of ty_struc with empty key.

data(itab) = value ty_struc_tab(

                ( col1 = 10 col2  = 'A' )

                ( col1 = 12 col2  = 'B' )

                ( col1 5 col2  = 'C' )

                ( col1 = 16 col2  = 'D' ) ).

I don't know whether there is a shorter expression for it than the above REDUCE term.