Technical Articles
Jump-start your report writing using a template (AdT / Eclipse)
[Edit: 2020-08-31: While this blog is still a good read, if you are interested in the template, there is a better/newer one published here: https://blogs.sap.com/2020/06/18/cleaning-up-my-adt-report-template-part-2-more-cleanabap/ ]
You know how the say the best admins, developers (…) are the lazy ones – why? Because they automate everything that makes sense to automate: let repetitive tasks be done by some kind of automation, e.g. a script:
Once you have that, you’re way faster, you don’t make typing errors, and you script defines a kind of standard/best practice you can rely on, without having to think about it.
Of course, your script, template or whatever can and should improve if you gain new knowledge.
That being said, I often have to write a new ABAP-(ALV-)report from scratch:
Select some data
Maybe do something with it
Display in ALV.
This might be a throw-away report just to try something out, or a report to be used productively (or one – maybe silently – turning into the other, I guess you all know those examples).
Say you’d want a report, selecting data from a database tabel (e.g. VBAP), with a select-option on one of this table’s fields (e.g. ERNAM), displaying what was selected in a ALV-grid (with all features enabled).
Easy, isn’t it? Won’t take you longer that a few minutes, right?!
Guess how long it takes me: 3 seconds! (Time starts, when I can start coding in eclipse, e.g. I have supplied the name of the report, chosen a package and the transport request).
Here’s what I do:
jre_, + Ctrl+space + Enter
VBAP, Tab, ERNAM.
Activate (Ctrl+F3)
Run (F8!).
Did you take the time? It was fast, wasn’t it? 😉
And it’s not a quick-and-dirty style of writing (you know, just start coding with select * from … without caring to even create forms or methods), but a very nice one, according to whatever my standards are (e.g. everything in local classes, respecting naming conventions, strong (=non-generic) typing… etc.).
So, you already know how I did that: I create myself a report-template in AdT, with variables for the table- and field-name.
This is where it is defined:
The custom variables make it flexible:
And this is it’s full code for your inspiration:
*REPORT generic
Types: gty_data type ${my_table} ,
gty_tab_data TYPE STANDARD TABLE OF gty_data .
*data, solely for select-options.
data: gso_${my_table} type ${my_table}.
*Sel-Screen:
SELECTION-SCREEN BEGIN OF BLOCK sel_opt WITH FRAME TITLE text-t01.
SELECT-Options: so_${my_table_field} for gso_${my_table}-${my_table_field}.
SELECTION-SCREEN END OF BLOCK sel_opt.
SELECTION-SCREEN BEGIN OF BLOCK mode WITH FRAME TITLE text-t02.
PARAMETERS: pa_disp TYPE flag RADIOBUTTON GROUP mode DEFAULT 'X',
pa_proc TYPE flag RADIOBUTTON GROUP mode.
SELECTION-SCREEN END OF BLOCK mode.
CLASS lcl_report DEFINITION.
PUBLIC SECTION.
class-METHODS: init.
METHODS:
get_data CHANGING ct_data TYPE gty_tab_data,
display_data CHANGING ct_data TYPE gty_tab_data,
process_data IMPORTING it_data TYPE gty_tab_data.
ENDCLASS. "lcl_report DEFINITION
CLASS lcl_report IMPLEMENTATION.
METHOD process_data.
FIELD-SYMBOLS: <data> LIKE LINE OF it_data.
CHECK it_data IS NOT INITIAL.
LOOP AT it_data ASSIGNING <data>.
*do something
ENDLOOP.
ENDMETHOD. "process_data
METHOD display_data.
DATA: lr_alv TYPE REF TO cl_salv_table.
DATA: lr_functions TYPE REF TO cl_salv_functions_list,
lr_layout TYPE REF TO cl_salv_layout,
ls_key TYPE salv_s_layout_key.
TRY.
CALL METHOD cl_salv_table=>factory
EXPORTING
list_display = if_salv_c_bool_sap=>false
IMPORTING
r_salv_table = lr_alv
CHANGING
t_table = ct_data.
##NO_HANDLER.
CATCH cx_salv_msg .
ENDTRY.
lr_layout = lr_alv->get_layout( ).
ls_key-report = sy-repid.
lr_layout->set_key( ls_key ).
lr_layout->set_default( abap_true ).
lr_layout->set_save_restriction( if_salv_c_layout=>restrict_none ).
lr_functions = lr_alv->get_functions( ).
lr_functions->set_all( abap_true ).
CALL METHOD lr_alv->display.
ENDMETHOD. "display_data
METHOD get_data.
select * from ${my_table} into CORRESPONDING FIELDS OF table ct_data UP TO 500 ROWS
where ${my_table_field} in so_${my_table_field}
.
ENDMETHOD.
method init.
DATA: lt_data TYPE gty_tab_data,
lo_report TYPE REF TO lcl_report.
CREATE OBJECT lo_report.
lo_report->get_data( CHANGING ct_data = lt_data ).
check lt_data is not initial.
CASE abap_true.
WHEN pa_disp.
lo_report->display_data( changing ct_data = lt_data ).
WHEN pa_proc.
lo_report->process_data( EXPORTING it_data = lt_data ).
ENDCASE.
endmethod.
ENDCLASS. "lcl_report IMPLEMENTATION
START-OF-SELECTION.
lcl_report=>init( ).
Takaway: action you can take:
Invest a little time to create a very nice template.
From now one, use it whenever it is applicable.
If you spot an error, or a chance for improvement, not only correct the report you just wrote, but also adjust your template accordingly.
-> All further uses will benefit from that!
If you start dirty, you might stay dirty.
So start clean right away!
Constraints/further ideas/notes:
– You can put as much coding as you like in the template, but it will end up in only one report – structuring with includes (_sel, _top etc.) isn’t easily possible.
– Your template doesn’t have to be a whole report, it could also be a method you often code. (I have one where I simply pass in a (any) internal table, and it displays it in ALV).
– I the current unit-testing-hype it might be worth to think about to also have a temple (=jump-start) for the test class.
– The template is in Eclipse, so I can use it in any system I access! (As opposed to those old templates in SE80 – I admit, I never made to much use of them!)
– (You can probably share your template with your colleagues (and profit from their improvements to it) somehow e.g. with using git).
Now over to you:
How do you avoid repetitive tasks, while improving quality? Do you, too, use dedicated templates, or do you just copy and adept from another (well written) productive program?
Your input is most welcome!
Joachim
Thanks for the tip, Joachim!
I'm a big fan of templates and have been using them in SE38/SE80 for anything from just header comments in a program (either in German or English) to fairly complete program frames where I then just have to modify or add definition sections, data retrieval routines and any processing needed to get the output data (usually as an ALV) in the required format.
Personally, I've always prefered starting a new program from scratch via a template instead of as a copy of an already existing program. The latter usually brings with it a lot of "baggage" of unwanted code and I've seen more than my fair share of obviously copied and then never cleaned up programs. Another advantage of working with templates is, that the programs have a very similar look & feel which makes them a lot easier to "grasp" for myself as well as others.
It's also helpful to know that and how I can create my own patterns in Eclipse with the added bonus of parameters. What I never much liked with the patterns via the SAP-GUI is that they are not readily available to down- and upload in bulk and just get lost in the ether when a new GUI-version gets installed (after getting caught by this once, I now also have "my" patterns in a simple txt-file for safe-keeping).
Cheers
Bärbel
Hey Bärbel,
thanks a lot for your valuable input and feedback!
best
Joachim
Instead of saving templates in a txt file save all your templates in a Onenote file, much safer and much easier to search as well, Just a suggesion 🙂
Although I'm using OneNote for other stuff I prefer Notepad for code-snippets as copying & pasting from programs like OneNote can introduce unwanted formatting via HTML (at least I encountered that with code copied from Word - you don't necessarily see it but it can cause syntax errors nonetheless).
Yes, That happens sometimes
I do like text-files on my local hard-disk - they are easy to write, easy to read(e.g. Notepad opens very fast) and so small and thus very easy to backup
-> The backup file (I use a simple *.Zip) is:
2.1 can be stored nearly anywhere (old USB-stick, phone, e-mail-attachment ...)
2.2 can be stored away very fast.
Also textfiles are very inter-operable:
- the probably have the best chance of still being readable in 20+ years
- can easily be shared/used across platforms(Linux,MacOs,Win…)
- can easily be versioned with git
- ....
So: 'yay' for textfiles! 🙂
But of course it's ok for everyone to find solutions best fitting to them - and great that we share them here!
Best
Joachim
Cool tip. Thanks Joachim Rees In our GUI editor we have been using it for normally for header templates for developments.I believe this can be quite effective in the ABAP unit testing framework where basic set up is normally the same.
Did you check the default template "testClass"?
I actually was not much aware about it. This blog explain clearly about how to use patterns testclass being one of them. Thanks for sharing the same(getting used to eclipse:))
Hi Joachim,could have a little more new syntax;-)
Nice use case for the templates. Do not really see the case for me at all, because I really try to stay away from any report and do use instead of that today idata's in combination with the smart templates. So what's the use-case behind that in your daily work?
The method with the any and show an ALV I also do not get at all? Why not just make use of the SE16H with all the additional possibilities.
No matter what, I like the idea behind and maybe we need to talk a little longer about it when meeting for a coffee break:-)
~Florian
Hi Florian,
wow, thanks for your Feedback!
That's a lot of points you mention, let me try to get through them
1. More New Syntax:
Not sure if I see all the points you mean with that:
I could do some more inline-declaration, e.g. in method init, agreed. Are there other points you spotted?
(Also, I might use the template on an System >7.40, where things wouldn't work - but I could just have another template for that, or manually adapt to this seldom cases. I agree that templates should represent the current/newest best practices.)
2. May use-case in "daily" work:
mainly "try-something-out"-reports, for example like that one on new SQL-Syntax (you can tell I still used FORM in my template back then *shameOnMe* 😉 )
Without a template, I would just start typing into the empty editor.
With my template, I already have nice, running report, on which I can build.
3. Method to display "any table":
Uh, after re-reading that part, I see how this is confusing. I updated it to "internal table", as my intention is of course not to re-create se16(*).
Let me just show the method:
...and I use it to "nicely" look at the data I selected/processes. (As opposed to only being able to look at it in the Debugger).
A good use case example is again the link I provided above. (There it's still called "FORM display_data " but you get the point!)
4. And finally: coffee break: always a good idea! 🙂
Btw: Caroleigh Deneen how about the "catch a mentor"-mission, will we get that one back soon? 😉
best
Joachim
Recoginzed it because of the into-clause is not the last statement of the select and the missing inline decs.
The try-out in my daily work point is that I do not see a big benefit to have the "play"-programs a lot people do. I take one or two new elements and build it in productive code (if the system fits) and that takes some more time to finish it, but ends up that I really can use it for future developments. And as I'm not working to maintain systems it should be possible to stick to the new learned syntax:-)
Yes, that was the plan before the mission set was put on pause. Now that we are back and some time has gone by, we will re-visit and let you know as we get closer to the event.
Excellent idea. My "quick and dirty" programs will become very easy to write. I like that you used a simple approach first. It keeps it simple enough for me to follow.
What do I do now? Well I do copy some of my code. Sometimes I do have a template for it. If I am really reusing the code I try to create a class or function module.
Michelle
PS - you have comments don't delete this one!!! 🙂
exactly! And, as an added bonus, they will be of very high (formal) quality, as you do the typing once in the template, and the profit with every use.
Do share your experience with it, if you like!
best
Joachim
We use something alike. Though instead of writing heaps of code in templates, we put it in global classes and have the local classes inherit from them.
If needed the developer can always opt to redefine one method or another, but it really helps to keep the approach towards the creation of a report alike (we consider our developments to be a team effort, and we believe that you should not see immediately who has written the code just by looking at it).
By the way: Export/Import of those temples works very fine!
(brought to you by working via citrix and noticing my templates where missing there 😉 )
Hey Joachim,
this was a very nice read! Thanks!
Joachim
[Yes, I am complimenting myself - why not? 😉 ]
I can no longer edit the above blog post, so I add this here:
This is as of now the latest version of my report-template: https://blogs.sap.com/2021/12/09/improving-my-adt-report-template-part-3/