Skip to Content
Technical Articles

Hybrid Programming – OOP ALV CDS Fiori

I haven’t been on here in awhile. But today I was looking out my window in April in Michigan at the snow.  For those of you reading it not thinking that is a big deal. It’s been since the 1800s since we’ve gotten snow this late in April. And yes, I’m inside looking at that snow.  Take a look at the ground – yes lovely green grass and my pine tree looks happy.  It’s a bit of a hybrid out there spring and winter on the ground. I am getting to the real point of my blog.

So I’m learning.  Yes, never stop learning. But I’m trying to cram as much information into my brain as possible. Then I remind myself when I started with SAP – I was cramming then too.  Anyway, while cramming things into my brain, I still have due dates.  So being me, I want to use the newer stuff.  So I have been taking a hybrid approach. Perhaps not the best way, but it’s been what I can do.

We have HANA on-premise.  What makes this important is we still can use older techniques and then simply call them from FIORI.  In a pinch I can use all old programming.  I thought I’d give an example of my “Hybrid” programming.  OOP ALV has been my friend for a long time.  It’s so easy to use to present information.

So here are some bits and pieces of my program. (Watch me go back and fourth to Eclipse, I’ll eventually learn all the short cuts there, but haven’t yet.  My piece of wisdom for you – learn Eciplse as soon as possible.

The Requirement:

A way to pull together ingredient contracts and the sales order relating to them.  Next if they are checked, remove them from the balance.  Yes, the simple requirements usually end up being a problem.  <Laughing>

Part 1 – getting the data. For this I got to use some of the new “stuff”! Yes, I used Eclipse.

It would have made more sense to use CDS.  For those of you learning like me.   (I love comments)  Please take a look at  Mike Pokraka’s comments at the end.  I’m going to quote them here.

“Personally I’d suggest using CDS in first instance and go for AMDP if you need features such as scripting or to extract that last little squeak in performance.

In your scenario, you can do the JOINs in one or more CDS view(s) and then do a SELECT with FOR ALL ENTRIES or a temporary table. A great reason for CDS is you can build up complex joins in layers of multiple views, which is easier to build and test than a single complex SELECT with a bunch of JOINs.

Have a look at some of the SAP CDS views for this area, you might even find one that already supplies most of what you need and you can then either extend it or build your own view on top of it.”

  METHOD get_so_co_detail BY DATABASE PROCEDURE
                                 FOR HDB
                                 LANGUAGE SQLSCRIPT
                                 OPTIONS READ-ONLY
                                 USING   vbak vbap
                                 vbkd vbep tvagt
                                 vbpa kna1.

    tmp1 = apply_filter( vbap, :iv_where);

     et_log = select
            a.MANDT,
            a.VBELN ,
            b.POSNR,
            b.matnr,
              case
                 when b.gbsta = 'A'
                  then 'Open'
                when b.gbsta= 'B'
                   then 'Open'
                  when b.gbsta = 'C'
                     then 'Closed'
               end as stat,
           c.bezei as rej,
           concat( b.werks, concat( '/', b.lgort ) ) as werk_sloc,
           b.ERDAT,
           a.VKORG,
           b.ERNAM,
           vbep.EDATU,
           b.KWMENG,
           b.VRKME,
           vbkd.BSTKD,
           ship.kunnr as shipto,
           kna1.name1 as shipto_name,
           kna1.ORT01 as city,
           kna1.regio as region,
           merch.kunnr as merch,
           z2_kna1.name1 as merch_name,
           a.kunnr as soldto,
           soldto.name1 as soldto_name
           from
             :tmp1 as b

           inner join vbak as a on a.mandt = b.mandt and
                              a.vbeln = b.vbeln

           left outer join tvagt as c
               on a.mandt = c.mandt and
                  b.abgru = c.abgru and
                  c.spras = 'E'

             left outer join vbep as vbep
                 on a.mandt = vbep.mandt and
                    b.vbeln = vbep.vbeln and
                    b.posnr = vbep.posnr and
                    vbep.bmeng > 0

             left outer join vbkd as vbkd
                  on a.mandt = vbkd.mandt and
                     b.vbeln = vbkd.vbeln and
                     vbkd.posnr = '000000'

             left outer join vbpa as ship
              on a.mandt = ship.mandt and
                 a.vbeln = ship.vbeln and
                 ship.posnr = '000000' and
                 ship.parvw = 'WE'

            left outer join kna1 as kna1
                 on  a.mandt = kna1.mandt and
                     ship.kunnr = kna1.kunnr

            left outer join vbpa as merch
              on a.mandt = merch.mandt and
                 a.vbeln = merch.vbeln and
                 b.posnr = merch.posnr and
                 merch.parvw = 'Z2'

           left outer join kna1 as z2_kna1
               on a.mandt = z2_kna1.mandt and
                  merch.mandt = z2_kna1.mandt and
                  merch.kunnr = z2_kna1.kunnr


            left outer join kna1 as soldto
                 on a.mandt = soldto.mandt and
                    a.kunnr = soldto.kunnr

Mike Pokraka’s For those of you wondering if you can use new and old methods – yes you can. You can only change them in Eclipse.

  method fill_dates.
    data: lv_from        type dats,
          lv_to          type dats,
          lv_one(10),
          lv_between(30).

    lv_from = im_from.
    lv_to = im_to.
*  Explode BOM
        CALL FUNCTION 'CS_BOM_EXPL_MAT_V2'
          EXPORTING
            auskz                 = abap_true
            brems                 = abap_true
            capid                 = 'PP01'
            datuv                 = sy-datlo    " Valid-From Date
            mktls                 = abap_true
            mehrs                 = abap_true
            mtnrv                 = ls_stko-matnr
            stlal                 = ls_stko-stlal
            stlan                 = ls_stko-stlan
            werks                 = ls_stko-werks
          TABLES
            stb                   = lt_stb

 

So yes – a bit of a hybrid there.  Now we can take a peak at how I called them.

* CONVERT the SELECTION to where clause
  DATA(lv_where) = cl_shdb_seltab=>combine_seltabs(
   it_named_seltabs = VALUE #(
    ( name = 'VBELN'      dref = REF #( s_vbeln[] ) )
    ( name = 'POSNR'      dref = REF #( s_item[] ) )
    )
  iv_client_field = 'MANDT'
    ).

* Get contract details
  TRY.
      zcl_get_ingred_log=>get_so_co_detail(
      EXPORTING
          iv_where = lv_where
          iv_client = sy-mandt
      IMPORTING
          et_log = DATA(lt_result) ).
    CATCH cx_amdp_error INTO DATA(amdp_error).
      cl_demo_output=>display( amdp_error->get_text( ) ).
      RETURN.
  ENDTRY.

OK, we’ve got our data – yes – not my total program.  But just snippets.  The fun part of my ALV – not the entire thing.

   gs_variant-report = sy-repid.
    DATA: it_fieldcat TYPE lvc_t_fcat,
          x_fieldcat  TYPE lvc_s_fcat.
    x_fieldcat-col_pos = 1.
    x_fieldcat-seltext = 'APPLIED'.
    x_fieldcat-fieldname = 'APPLIED'.
    x_fieldcat-edit = abap_true.
    x_fieldcat-checkbox = abap_true.
    x_fieldcat-tabname = 'GT_SALES_DETAIL'.
    APPEND x_fieldcat TO it_fieldcat.
 CALL METHOD grid1->set_table_for_first_display
      EXPORTING
        i_bypassing_buffer   = abap_true
        i_structure_name     = 'ZINGRD_CONTRACT'
        is_print             = gs_print
        is_layout            = gs_layout
        it_toolbar_excluding = lt_exc
        i_save               = gv_save
        is_variant           = gs_variant
      CHANGING
        it_fieldcatalog      = it_fieldcat
        it_outtab            = gt_sales_detail.
    gv_check = abap_true.

    CALL METHOD cl_gui_control=>set_focus EXPORTING control = grid1.

Last thing to do is to create the FIORI tile. Yes a lot different than normal.Security is based a lot on where you place your tile. You will want to download the Step by Step guide to do this.  And since it is amazing, I won’t share the step by step here.

So my lovely FIORI report.  Yes, you can’t see much of it.  Just the headings. Why? No company information.

 

 

That’s my hybrid approach. Now a challenge for you.

First my code. I’m sure there are things I could have done better. Please share in the comments so someone else doesn’t duplicate my interesting code thinking that’s the best way of doing it.

Second this is how I’m learning? How about you? Are you using some of the SAP created procedures. If your comment is too long. A blog would be awesome! Are you using a hybrid approach or simply switching to doing things the new way? How about those of you that have never programmed the old way? How about you not on-premise? I have a lot of question and am loving reading the blogs when I get a chance.

 

4

19 Comments
You must be Logged on to comment or reply to a post.
  • Just a quick comment on your AMDP implementation:

    You filter VBAP based on a dynamic selection table which includes the client field. However, then you join the result to lots of other tables not specifying MANDT in the ON clauses. There is no implicit client handling in AMDP. I therefore assume you will get cross client data if these tables have content in other clients (!).

    • Nice catch.  No I sure do not want the data from all the other clients.  Fixing my code and my blog.  I wondered about the large select – but it runs very fast.

      Thank you!

  • On a more general note, is there a specific reason for choosing AMDP over CDS views?

    AMDP is the heavy duty artillery you roll out when CDS doesn’t cut it. CDS is easier and tends to be more reusable.

      • OK, I had my suspicions that may be the case. Well, you picked the deep end, which I guess fulfils your learning goals 🙂

        Personally I’d suggest using CDS in first instance and go for AMDP if you need features such as scripting or to extract that last little squeak in performance.

        In your scenario, you can do the JOINs in one or more CDS view(s) and then do a SELECT with FOR ALL ENTRIES or a temporary table. A great reason for CDS is you can build up complex joins in layers of multiple views, which is easier to build and test than a single complex SELECT with a bunch of JOINs.

        Have a look at some of the SAP CDS views for this area, you might even find one that already supplies most of what you need and you can then either extend it or build your own view on top of it.

        • I like it.  It would make it more readable and testable.  I’ll take a look.  If I have time – it seems like never, I’ll duplicate what I did in CDS and then compare the two.

          I’ll take a look at the already created CDS views too.

          So much to learn so little time.

          • Note there is nothing wrong with your use of AMDP. It’s a database procedure that does a SELECT. In legacy terms it’s a bit like putting your SELECT into a function module vs creating a DDIC view. Both have pros and cons.

          • Oh boy!  You are saying the same thing that always haunts me.  “It depends”….

            But I really do like the approach of a CDS better in this case.  Basically because of the testablity and debug if there is an issue.  I’m also wondering if some of my code could have been shifted into the AMDP to make it a better option.  I’ve been trying to do only one thing in a method.  It is slowly driving me insane.

          • Michelle Crapo ðŸ˜€ It happens, Initially when I was learning about CDS views, My first thought was what will happen if there is a bug? How to debug it? and why can’t I debug it so easily like ABAP? and thought It might mess up my whole program and might end up rewriting it..

            But believe me, you will get over it very soon and you will feel super confident about using CDS in a very little time. I believe it was due to my background (Electronic &Communications) and moreover I started my career with ABAP without learning proper db concepts or even SQL 😀 :D.

            If possible put multiple layers of CDS views in case of complex queries so you can figure out the issues easily as well.

            Regards,

            Mahesh

          • Thank you – that sums it up nicely.   Multiple layered CDS should have been what I went for in this case.  It would make it easier to find a mistake.

            There is an added advantage of being able to reuse them easily.  I’m so glad for these comments!  Steering anyone the wrong way – that’s always my greatest nightmare.

             

        • Hi Mike,

          Wouldn’t FOR ALL ENTRIES have some performance issues? With the Open SQL usually the definition of number data records to process in the system is 5. Say an internal table with 100 rows would execute the same Select statement 20 times for different set of data records. My DBA’s always complain about the traditional “FOR ALL ENTRIES” in our organization when we have to process huge data in the program.

          We just started our new implementation of S4 Hana and trying to learn all the new stuff with Open SQL, CDS and AMDP (Code Push Down) techniques. From the best practices perspective I don’t think other than the above 3 very rarely have seen people using Native SQL, ADBC.

          Nice blog Michelle Crapo I though AMDP would be a good fit for your use case based on what I was reading to avoid the For All Entries. May be I am wrong. I would like to stand corrected if any of you think other wise.

          • I’m not sure yet.  It was the idea I had at the time.   I really have to try the same thing with CDS views and see what I end up with.

          • Yes and no, that’s why I wrote FaE or a temporary table.

            I don’t know where you got the number 5 from, but I’d certainly use FaE for more than that. It is database-dependent, older versions of Oracle had a 64k limit, you can fit a few more than 5 conditions in there.

            And the other options are of course code pushdown via CDS or AMDP. It is scenario-dependent which of these four (or other) strategies you choose, there is no universal ‘best’ approach. Testing is the best way to determine the optimum approach if you are not sure.