During part of this week I've been fighting with an old adversary,output determination. In the fracas, I spent some time inside RSNAST00 (the selection program for issuing output) and couldn't help noticing, in passing, that it used FIELD-GROUPS. This relatively old area of ABAP got me thinking about logical databases (LDBs) and their use in writing reports. You know the sort of thing:
GET KNA1. SUMMARY. WRITE: / ... GET KNB1. DETAIL. WRITE: / ... EXTRACT ...When you execute a report that uses a logical database, you're really just hitching a ride on the back of the database program that actually reads through the logical database you've specified; your GET statements are reactive, event handlers almost, that do something when passed a segment (ahem, node) of data by means of the proactivePUT statements in the database program (e.g. SAPDBDDF for the DD-F logical database).
Anyway, this brings me to something that's been floating around in the back of my mind since TechEd last month in Basel. I attended a great session on ABAP Objects, given by Stefan Bresch and Horst Keller (thanks, chaps). In a section championing the explicit nature of ABAP Objects, there was a fascinating example of an implementation of a simple LDB using a class, and using ABAP Object events (RAISE EVENT ... EXPORTING) and event subscriptions to achieve the PUT / GET relationship. Here's that example.
There's the 'ldb' class that implements a simple database read program for the the single-node (SPFLI) logical database:
class ldb definition. public section. methods read_spfli. events spfli_ready exporting value(values) type spfli. private section. data spfli_wa type spfli. endclass. class ldb implementation. method read_spfli. select * from spfli into spfli_wa. raise event spfli_ready exporting values = spfli_wa. endselect. endmethod. endclass.Here we have a single public method READ_SPFLI that reads the table SPFLI, raising the event SPFLI_READY for each record it finds. This is like the PUT from our traditional database program.
Then we have a report that uses that logical database. It's also written as a class:
class rep definition. public section. methods start. private section. data spfli_tab type table of spfli. methods: get_spfli for event spfli_ready of ldb importing values, display_spfli. endclass. class rep implementation. method start. data ldb type ref to ldb. create object ldb. set handler me->get_spfli for ldb. ldb->read_spfli( ). display_spfli( ). endmethod. method get_spfli. append values to spfli_tab. endmethod. method display_spfli. data alv_list type ref to cl_gui_alv_grid. create object alv_list exporting i_parent = cl_gui_container=>screen0. alv_list->set_table_for_first_display( exporting i_structure_name = 'SPFLI' changing it_outtab = spfli_tab ). call screen 100. endmethod. endclass.In the START method we effectively are declaring the use of the logical database by instantiating an 'ldb' object, doing the equivalent of specifying a logical database in a report program's attributes section. Then we define the method GET_SPFLI as the handler for the events that will be raised (SPFLI_READY) when we trigger the database's reading with the invocation of the READ_SPFLI method. This of course is the equivalent of a GET SPFLI statement. To initiate the reading of the database we invoke the READ_SPFLI method. Finally there's a DISPLAY_SPFLI event in the 'rep' class using ALV to present the data on the screen.
I don't know about you, but I was taken aback by the beauty of this. As we're approaching the weekend, a time to unwind and reflect, I just thought I'd share it with you.
Comments