What Does your Scratch Pad Look Like?
Several times a week I need to try out a piece of coding that I don’t want to put into the production code right away.
I used to create little test reports to experiment with the code snippets I need.
The problem with this approach was that I collected too many reports and our development
box was littered with ZEMA* reports.
My Fancy Simplistic Scratch Pad
Now I collect all my brain dumps in one report. Nothing fancy about that, why would I even write about it?
I am using some little tricks that you might also like, so I thought that was worth sharing.
The name of my scratch pad report.
REPORT zematest. TABLES pmmo_assignment. TABLES sscrfields. INCLUDE rpmmo_last_variant. INCLUDE rpmmo_rtm_macros. TYPES BEGIN OF ty_comp. TYPES name TYPE c LENGTH 60. TYPES END OF ty_comp. TYPES ty_comp_tab TYPE STANDARD TABLE OF ty_comp. DATA gt_tokens TYPE stokes_tab. DATA gv_grpnr TYPE ps_posid. DATA gv_class TYPE bdc_fval. "seoclsname. DATA gv_subclass TYPE bdc_fval. "seoclsname. DATA gv_method TYPE bdc_fval. "abap_methname. DATA gv_stat TYPE j_status. DATA gv_tst TYPE c LENGTH 50. CLASS lcl_test DEFINITION DEFERRED. SELECTION-SCREEN FUNCTION KEY 1. "for last used variant PARAMETERS p_form TYPE char30. PARAMETERS p_brk TYPE pmmo_assignment-objnr_brk MATCHCODE OBJECT zpmmo_break_point_coll_sh NO-DISPLAY. SELECT-OPTIONS so_cron FOR pmmo_assignment-creationdatetime NO-DISPLAY. SELECT-OPTIONS so_tst FOR gv_tst VISIBLE LENGTH 25 NO-DISPLAY. SELECT-OPTIONS so_stat FOR gv_stat MATCHCODE OBJECT h_tj02 NO-DISPLAY. SELECT-OPTIONS p_class FOR gv_class NO-DISPLAY.
I add SELECT-OPTIONS and PARAMETERS as needed and when I don’t need them anymore, I add the NO-DISPLAY addition. That way my selection screen still looks halfway clean.
The only important piece here is the GT_TOKENS definition.
The magic happens in the INITIALIZATION event of the report.
INITIALIZATION. lcl_last_variant=>get( ). PERFORM get_default_form.
Let’s ignore the last_variant code for now. I’ll write about that in a separate post.
The form GET_DEFAULT_FORM is where it gets interesting:
FORM get_default_form. DATA lt_source TYPE string_table. DATA lt_statements TYPE sstmnt_tab. DATA lt_keywords TYPE STANDARD TABLE OF char30. DATA lt_report TYPE STANDARD TABLE OF sy-repid. DATA lv_form TYPE c LENGTH 6. lt_keywords = VALUE #( ( 'FORM' ) ). READ REPORT sy-repid INTO lt_source. SCAN ABAP-SOURCE lt_source TOKENS INTO gt_tokens STATEMENTS INTO lt_statements FRAME PROGRAM FROM sy-repid KEYWORDS FROM lt_keywords WITH INCLUDES. SORT gt_tokens BY str DESCENDING. LOOP AT gt_tokens INTO DATA(ls_token). lv_form = ls_token-str. IF lv_form(4) = 'TEST'. IF lv_form+4(2) CN '0123456789'. DELETE gt_tokens. ENDIF. ELSE. DELETE gt_tokens. ENDIF. ENDLOOP. p_form = gt_tokens[ 1 ]-str. ENDFORM.
The report scans itself for all the FORM routines that are defined. It then picks the one with
the highest number and moves that to the PARAMETER P_FORM.
For this to work, I follow a certain naming convention for the FORM routines:
The FORM name starts with TEST and is followed by a sequential number that I count up every time I try something new.
This just supports my laziness. If I want to test something new, I just create a new form and the report is smart enough to know that this is what I want to work with.
If I want to test another FORM instead then the F4 help for the FORM routine field allows me to do that too.
Here is the code for that:
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_form. PERFORM f4_form.
FORM f4_form. TYPES BEGIN OF ty_form. TYPES name TYPE char30. TYPES END OF ty_form. DATA lt_form TYPE STANDARD TABLE OF ty_form. LOOP AT gt_tokens INTO DATA(ls_token). APPEND ls_token-str TO lt_form. ENDLOOP. CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST' EXPORTING retfield = 'NAME' dynpprog = sy-repid dynpnr = sy-dynnr dynprofield = 'P_FORM' window_title = 'Select a FORM routine for Testing' value_org = 'S' TABLES value_tab = lt_form EXCEPTIONS parameter_error = 1 no_values_found = 2 OTHERS = 3. ENDFORM.
The last missing piece:
START-OF-SELECTION. lcl_last_variant=>save( ). PERFORM (p_form) IN PROGRAM (sy-repid) IF FOUND.
I hope you enjoy this little piece of my quirkiness. Let me know what your scratch pad looks like and what cool things have you found to make your programming life easier and/or more enjoyable.
Thanks for the idea. I've got the same issue. I used to have tiny pieces of code as text files that I just copy/paste when needed but I'm also thinking of creating one repository per test program in my GitHub account (or GitLab or whatever) and backup/restore via abapGit and cleanup after each use. I'm not sure how much abapGit needs to be customized to allow usage by several people and teams in the same SAP system, and it depends of course what is allowed by the company. If not permitted your solution is very good.
Thank you Sandra.