Академический Документы
Профессиональный Документы
Культура Документы
" Any fool can write code that a computer can understand.
Good programmers write code that humans can understand. "
--- Martin Fowler, Refactoring: Improving the Design of Existing Code
ABAP pretty printer is good for code but not supportive for data declarations.
As a result ABAP code often tends to need more labour to maintain.
1. YClipJNC based on
http://sap.ionelburlacu.ro/abap/sap2/Beautify_Source_Code.html
but improved to include table~column half-line commenting.
Take any ABAP code (should have survived syntax check) including that "." DOT
terminator.
Copy to Clipboard & F8 on YClipJNC will create the beautiful version in
clipboard
ready for pasting back.
The big advantage is that you can send for beautification only portions of
code
- this is vital in maintaining someone else's badly written code.
These 3 utilities should give a big boost to good clean commented ABAP
code.
==================================================================================
=======
*&---------------------------------------------------------------------*
*& Beautify ABAP Code Via Clip
*
*&---------------------------------------------------------------------*
*-----------------------------------------------------------------------
* This program takes ABAP code in ClipBoard, and does the following:
* - Attempts to move comments to the end of the line
* - Adds comments (table name) for the tables listed after a TABLES
* statement if the line has not been commented already.
* - Adds comments (field name) for data elements, parameters, and
* select-options that are defined using the LIKE or FOR statement
* - For ENDLOOP/ENDSELECT adds comment identify the LOOP/SELECT
* that is being closed
* - For FORM/ENDFORM adds comment identify the FORM that is being
* closed
* - Calls function PRETTY_PRINTER to do the SAP standard pretty print
* after the custom comments have been created
* Returns Modified Code Via ClipBoard
*-----------------------------------------------------------------------
REPORT yclipjnc. .
TABLES:
e071 , " Change & Transport System: Object Entries of
Requests/Tasks
tadir , " Directory of Repository Objects
trdir , " Generated Table for View TRDIR
dd02t . " R/3 DD: SAP table texts
DATA:
* Hold an entire statement, even if it spans multiple lines
BEGIN OF mtab_long_line OCCURS 0,
start TYPE i,
end TYPE i,
code(9999) TYPE c, "For type "C", a maximum length specification of 65535 is
allowed.
END OF mtab_long_line.
* Queue to hold list of internal table names for commenting the ENDLOOP
* line
DATA: BEGIN OF mtab_itab_names OCCURS 0,
tabname(40) TYPE c,
END OF mtab_itab_names.
* Queue to hold list of table names for commenting the ENDSELECT line
DATA: BEGIN OF mtab_tab_names OCCURS 0,
tabname(40) TYPE c,
END OF mtab_tab_names.
* START of EXECUTION
IF sy-subrc NE 0.
WRITE: / `Unable to read ClipBoard`.
WRITE: / `Exiting program`.
ENDIF.
PERFORM format_program.
LOOP AT mtab_jnc_prog.
IF mtab_jnc_prog = space.
SKIP 1.
ENDIF.
WRITE: / mtab_jnc_prog.
ENDLOOP. " LOOP AT MTAB_JNC_PROG
*---------------------------------------------------------------------*
* FORM CREATE_CONDENSED_TABLE *
*---------------------------------------------------------------------*
* Create a table that has all statements condensed onto 1 line *
*---------------------------------------------------------------------*
FORM create_condensed_table
TABLES ftab_old_prog STRUCTURE mtab_old_prog
ftab_long_line STRUCTURE mtab_long_line.
DATA:
* Structure to hold program code/comment
BEGIN OF fstr_line,
code(172) TYPE c, " Program Code
comment(172) TYPE c, " Inline comments
END OF fstr_line.
LOOP AT ftab_old_prog.
IF ftab_long_line-start = 0.
ftab_long_line-start = ftab_long_line-end + 1.
CLEAR ftab_long_line-end.
ENDIF.
* Strip off any inline comments so they do not get in the way
* If comments are not separated, then words in the comments could
* look like keywords, and cause problems
SPLIT ftab_old_prog-line AT `"` INTO fstr_line-code fstr_line-comment.
* Put all lines that make up a single statement into one field
* This will make it easier to isolate key words. For example, if you
* want to process a TABLES statement, but exclude the TABLES part of a
* function call, or a subroutine call.
CONCATENATE ftab_long_line-code fstr_line-code
INTO ftab_long_line-code SEPARATED BY space.
APPEND ftab_long_line.
*---------------------------------------------------------------------*
* FORM FORMAT_PROGRAM *
*---------------------------------------------------------------------*
FORM format_program.
LOOP AT mtab_long_line.
TRANSLATE mtab_long_line-code TO UPPER CASE.
mtab_new_prog-line = mtab_old_prog-line.
APPEND mtab_new_prog.
APPEND mtab_new_prog.
*---------------------------------------------------------------------*
* FORM GET_TABLE_NAMES_FROM_STATEMENT *
*---------------------------------------------------------------------*
FORM get_table_names_from_statement TABLES ftab_tabname
STRUCTURE mtab_tabname
USING fc_statement.
CLEAR ftab_tabname.
REFRESH ftab_tabname.
*---------------------------------------------------------------------*
* FORM GET_TABLE_DESCRIPTIONS *
*---------------------------------------------------------------------*
FORM get_table_descriptions TABLES ftab_tabname STRUCTURE mtab_tabname.
LOOP AT ftab_tabname.
SELECT SINGLE * FROM dd02t
WHERE tabname = ftab_tabname-tabname
AND ddlanguage = sy-langu.
IF sy-subrc = 0.
ftab_tabname-tabdesc = dd02t-ddtext.
MODIFY ftab_tabname.
ENDIF.
*---------------------------------------------------------------------*
* FORM BUILD_NEW_TABLES_STATEMENT *
*---------------------------------------------------------------------*
FORM build_new_tables_statement USING fstr_long_line LIKE
mtab_long_line.
mtab_new_prog-line = `TABLES:`.
APPEND mtab_new_prog.
LOOP AT mtab_tabname.
IF sy-tabix = li_rows.
lc_sep = `.`.
ELSE.
lc_sep = `,`.
ENDIF.
*---------------------------------------------------------------------*
* FORM GET_FOR/LIKE_COMMENT *
*---------------------------------------------------------------------*
FORM get_for_like_comment USING value(f_old_prog) LIKE mtab_old_prog
CHANGING f_new_prog LIKE mtab_new_prog
.
DATA:
lc_dummy(1) TYPE c,
lc_tabname(40) TYPE c,
wordlen TYPE i,
ltab_nametab LIKE dntab OCCURS 0 WITH HEADER LINE,
lstr_old_prog LIKE LINE OF mtab_old_prog,
BEGIN OF lstr_field,
tabname LIKE dd02t-tabname, " Table name
fldname LIKE dd02t-tabname, " Table name
END OF lstr_field.
ELSE.
f_new_prog = lstr_old_prog-line.
RETURN.
ENDIF.
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
IF sy-subrc = 0.
ELSE.
f_new_prog = lstr_old_prog-line.
ENDIF.
DATA:
lc_dummy(1) TYPE c,
lc_itab(40) TYPE c.
mtab_itab_names = lc_itab.
* Always have the most recent LOOP AT table as the first entry in the
* queue
INSERT mtab_itab_names INDEX 1.
*---------------------------------------------------------------------*
* FORM ADD_COMMENT_TO_ENDLOOP *
*---------------------------------------------------------------------*
FORM add_comment_to_endloop USING fstr_long_line LIKE mtab_old_prog-line
CHANGING f_prog_line LIKE mtab_new_prog-line
.
*---------------------------------------------------------------------*
* FORM ENQUEUE_TAB_NAME *
*---------------------------------------------------------------------*
FORM enqueue_tab_name USING f_line LIKE mtab_old_prog-line.
DATA:
lc_dummy(1) TYPE c,
lc_tab(40) TYPE c.
mtab_tab_names = lc_tab.
* Always have the most recent LOOP AT table as the first entry in the
* queue
INSERT mtab_tab_names INDEX 1.
*---------------------------------------------------------------------*
* FORM ADD_COMMENT_TO_SELECT *
*---------------------------------------------------------------------*
FORM add_comment_to_select USING fstr_long_line LIKE mtab_old_prog-line
CHANGING f_prog_line.
*---------------------------------------------------------------------*
* FORM ADD_COMMENT_TO_ENDFORM *
*---------------------------------------------------------------------*
FORM add_comment_to_endform USING fstr_long_line LIKE
mtab_old_prog-line
CHANGING f_prog_line.
*---------------------------------------------------------------------*
* FORM ENQUEUE_FORM_NAME *
*---------------------------------------------------------------------*
FORM enqueue_form_name USING f_line.
DATA:
lc_dummy(1) TYPE c,
lc_tab(40) TYPE c.
mtab_form_names = lc_tab.
* Always have the most recent LOOP AT table as the first entry in the
* queue
INSERT mtab_form_names INDEX 1.
==================================================================================
=======
*&---------------------------------------------------------------------*
*& Beautify ABAP Code Via Clip
*
*&---------------------------------------------------------------------*
*-----------------------------------------------------------------------
* This program takes Structure & internal table declarations in ClipBoard,
* and does prefect alignment as possible
* Returns Modified Code Via ClipBoard
*-----------------------------------------------------------------------
REPORT yclip2jnc.
IF sy-subrc NE 0.
WRITE: / `Unable to read ClipBoard`.
WRITE: / `Exiting program`.
ENDIF.
CONDENSE mtab_old_prog-line.
REPLACE ALL OCCURRENCES OF ' ,' IN mtab_old_prog-line WITH ','.
LOOP AT i_words.
wordlen = STRLEN( i_words-word ).
IF wordlen > 60
OR i_words-word+0(1) < space
OR i_words-word+0(1) > '~'.
DELETE mtab_old_prog INDEX saveix.
EXIT.
ENDIF.
ENDLOOP.
ENDLOOP.
LOOP AT mtab_old_prog.
CONDENSE mtab_old_prog-line.
REPLACE ALL OCCURRENCES OF ' ,' IN mtab_old_prog-line WITH ','.
SPLIT mtab_old_prog-line AT space INTO TABLE i_words.
MOVE 1 TO colnum.
LOOP AT i_words.
wordlen = STRLEN( i_words-word ).
CASE colnum.
WHEN 1.
IF wordlen > maxlen1.
MOVE wordlen TO maxlen1.
ENDIF.
WHEN 2.
IF wordlen > maxlen2.
MOVE wordlen TO maxlen2.
ENDIF.
WHEN 3.
IF wordlen > maxlen3.
MOVE wordlen TO maxlen3.
ENDIF.
ENDCASE.
ADD 1 TO colnum.
ENDLOOP.
ENDLOOP.
LOOP AT mtab_old_prog.
workline = mtab_old_prog-line.
CONDENSE workline.
REPLACE ALL OCCURRENCES OF ' ,' IN mtab_old_prog-line WITH ','.
LOOP AT i_words.
FIND i_words-word IN mtab_old_prog-line MATCH OFFSET wordoff.
EXIT.
ENDLOOP.
EXIT.
ENDLOOP.
LOOP AT mtab_old_prog.
CONDENSE mtab_old_prog-line.
REPLACE ALL OCCURRENCES OF ' ,' IN mtab_old_prog-line WITH ','.
MOVE 1 TO colnum.
LOOP AT i_words.
wordlen = STRLEN( i_words-word ).
CASE colnum.
WHEN 1.
PERFORM f_diff_calc USING maxlen1 wordlen
CHANGING diff.
CONCATENATE myhats+0(wordoff) i_words-word myhats+0(diff) INTO
mtab_new_prog-line.
WHEN 2.
PERFORM f_diff_calc USING maxlen2 wordlen
CHANGING diff.
CONCATENATE mtab_new_prog-line i_words-word myhats+0(diff) INTO
mtab_new_prog-line.
WHEN 3.
PERFORM f_diff_calc USING maxlen3 wordlen
CHANGING diff.
CONCATENATE mtab_new_prog-line i_words-word myhats+0(diff) INTO
mtab_new_prog-line.
WHEN OTHERS.
CONCATENATE mtab_new_prog-line ` ` i_words-word INTO mtab_new_prog-line.
ENDCASE.
ADD 1 TO colnum.
ENDLOOP.
TRANSLATE mtab_new_prog-line USING `^ `.
APPEND mtab_new_prog.
ENDLOOP.
LOOP AT mtab_new_prog.
IF mtab_new_prog = space.
SKIP 1.
ENDIF.
WRITE: / mtab_new_prog.
ENDLOOP. " LOOP AT MTAB_NEW_PROG
*&--------------------------------------------------------------------*
*& Form f_diff_calc
*&--------------------------------------------------------------------*
FORM f_diff_calc USING value(maxlen) TYPE i
value(wordlen) TYPE i
CHANGING diff TYPE i.
==================================================================================
=======
*&---------------------------------------------------------------------*
*& Beautiful Function Module Call via clipboard
*
*&---------------------------------------------------------------------*
*-----------------------------------------------------------------------
* This program takes a parameter as a Function Module Name
* and does a documented "pattern paste"
* Returns pattern Code Via ClipBoard
*-----------------------------------------------------------------------
PROGRAM yclip3jnc.
TYPE-POOLS : slis.
DATA: funcdesc LIKE tftit-stext, " Short text for function module
mylen TYPE i,
myrc TYPE i.
SELECT SINGLE
tftit~stext " Short text for function module
INTO funcdesc
FROM tftit
WHERE tftit~funcname = p_func
AND tftit~spras = sy-langu.
SELECT
fupararef~funcname " Name of Function Module
fupararef~paramtype " Parameter type
fupararef~pposition " Internal Table, Current Line Index
fupararef~optional " Optional parameters
fupararef~parameter " Parameter name
fupararef~defaultval " Default value for import parameter
fupararef~structure " Associated Type of an Interface
Parameter
funct~stext " Short text
INTO TABLE i_tab
FROM fupararef
INNER JOIN funct
ON fupararef~funcname = funct~funcname
AND fupararef~parameter = funct~parameter
AND funct~spras = sy-langu
WHERE fupararef~funcname = p_func
AND fupararef~r3state = 'A'
ORDER BY fupararef~paramtype
fupararef~pposition.
LOOP AT i_tab.
AT NEW paramtype.
CASE i_tab-paramtype.
WHEN 'C'.
MOVE ' CHANGING' TO mtab_new_prog-line.
WHEN 'E'.
MOVE ' IMPORTING' TO mtab_new_prog-line.
WHEN 'I'.
MOVE ' EXPORTING' TO mtab_new_prog-line.
WHEN 'T'.
MOVE ' TABLES' TO mtab_new_prog-line.
WHEN 'X'.
MOVE ' EXCEPTIONS' TO mtab_new_prog-line.
ENDCASE.
APPEND mtab_new_prog.
ENDAT.
IF i_tab-optional = 'X'.
mtab_new_prog-line = `*^^^`.
ELSE.
mtab_new_prog-line = `^^^^`.
ENDIF.
IF i_tab-paramtype = 'X'.
MOVE i_tab-pposition TO i_tab-defaultval.
CONDENSE i_tab-defaultval.
ELSE.
TRANSLATE i_tab-parameter TO LOWER CASE.
ENDIF.
APPEND mtab_new_prog.
ENDLOOP. " LOOP AT I_TAB
LOOP AT mtab_new_prog.
TRANSLATE mtab_new_prog-line USING `^ `.
MODIFY mtab_new_prog.
IF mtab_new_prog = space.
SKIP 1.
ENDIF.
WRITE: / mtab_new_prog.
ENDLOOP. " LOOP AT MTAB_NEW_PROG
Author Message
admin Posted: Mon Oct 01, 2007 12:31 am Post subject: Improved Pretty Print
Администратор program used Clipboard
In order to use this application simple copy your desired code into the
clipboard (should have survived syntax check) and execute this program. A
beautiful version of the code will then be created in clipboard ready for pasting
back.
One big advantage is that you can send for beautification only portions of code
which can be vital when maintaining someone else's badly written/formatted
code.
Code:
*&------------------------------------------------------------
---------*
*& Beautify ABAP Code Via
Clip *
*&------------------------------------------------------------
---------*
*-------------------------------------------------------------
----------
* This program takes ABAP code in ClipBoard, and does the
following:
* - Attempts to move comments to the end of the line
* - Adds comments (table name) for the tables listed after
a TABLES
* statement if the line has not been commented already.
* - Adds comments (field name) for data elements,
parameters, and
* select-options that are defined using the LIKE or FOR
statement
* - For ENDLOOP/ENDSELECT adds comment identify the
LOOP/SELECT
* that is being closed
* - For FORM/ENDFORM adds comment identify the FORM that is
being
* closed
* - Calls function PRETTY_PRINTER to do the SAP standard
pretty print
* after the custom comments have been created
* Returns Modified Code Via ClipBoard
*-------------------------------------------------------------
----------
REPORT zclip_pretty. .
TABLES:
e071 , " Change & Transport System: Object Entries of
Requests/Tasks
tadir , " Directory of Repository Objects
trdir , " Generated Table for View TRDIR
dd02t . " R/3 DD: SAP table texts
DATA:
* Hold an entire statement, even if it spans multiple lines
BEGIN OF mtab_long_line OCCURS 0,
start TYPE i,
end TYPE i,
code(9999) TYPE c, "For type "C", a maximum length
specification
"of 65535 is allowed.
END OF mtab_long_line.
* START of EXECUTION
IF sy-subrc NE 0.
WRITE: / `Unable to read ClipBoard`.
WRITE: / `Exiting program`.
ENDIF.
PERFORM format_program.
LOOP AT mtab_jnc_prog.
IF mtab_jnc_prog = space.
SKIP 1.
ENDIF.
WRITE: / mtab_jnc_prog.
ENDLOOP. " LOOP AT MTAB_JNC_PROG
*-------------------------------------------------------------
--------*
* FORM CREATE_CONDENSED_TABLE *
*-------------------------------------------------------------
--------*
* Create a table that has all statements condensed onto
1 line *
*-------------------------------------------------------------
--------*
FORM create_condensed_table
TABLES ftab_old_prog STRUCTURE mtab_old_prog
ftab_long_line STRUCTURE mtab_long_line.
DATA:
* Structure to hold program code/comment
BEGIN OF fstr_line,
code(172) TYPE c, " Program Code
comment(172) TYPE c, " Inline comments
END OF fstr_line.
LOOP AT ftab_old_prog.
IF ftab_long_line-start = 0.
ftab_long_line-start = ftab_long_line-end + 1.
CLEAR ftab_long_line-end.
ENDIF.
APPEND ftab_long_line.
*-------------------------------------------------------------
--------*
* FORM
FORMAT_PROGRAM *
*-------------------------------------------------------------
--------*
FORM format_program.
DATA: lstr_old_prog LIKE LINE OF mtab_old_prog.
LOOP AT mtab_long_line.
mtab_new_prog-line = mtab_old_prog-line.
APPEND mtab_new_prog.
APPEND mtab_new_prog.
*-------------------------------------------------------------
--------*
* FORM
GET_TABLE_NAMES_FROM_STATEMENT *
*-------------------------------------------------------------
--------*
FORM get_table_names_from_statement TABLES ftab_tabname
STRUCTURE mtab_tabname
USING fc_statement.
CLEAR ftab_tabname.
REFRESH ftab_tabname.
*-------------------------------------------------------------
--------*
* FORM
GET_TABLE_DESCRIPTIONS *
*-------------------------------------------------------------
--------*
FORM get_table_descriptions TABLES ftab_tabname STRUCTURE
mtab_tabname.
LOOP AT ftab_tabname.
SELECT SINGLE * FROM dd02t
WHERE tabname = ftab_tabname-tabname
AND ddlanguage = sy-langu.
IF sy-subrc = 0.
ftab_tabname-tabdesc = dd02t-ddtext.
MODIFY ftab_tabname.
ENDIF.
*-------------------------------------------------------------
--------*
* FORM
BUILD_NEW_TABLES_STATEMENT *
*-------------------------------------------------------------
--------*
FORM build_new_tables_statement USING fstr_long_line LIKE
mtab_long_line.
mtab_new_prog-line = `TABLES:`.
APPEND mtab_new_prog.
LOOP AT mtab_tabname.
IF sy-tabix = li_rows.
lc_sep = `.`.
ELSE.
lc_sep = `,`.
ENDIF.
wordlen = STRLEN( mtab_tabname-tabname ).
APPEND mtab_new_prog.
*-------------------------------------------------------------
--------*
* FORM
GET_FOR/LIKE_COMMENT *
*-------------------------------------------------------------
--------*
FORM get_for_like_comment USING value(f_old_prog) LIKE
mtab_old_prog
CHANGING f_new_prog LIKE
mtab_new_prog
.
DATA:
lc_dummy(1) TYPE c,
lc_tabname(40) TYPE c,
wordlen TYPE i,
ltab_nametab LIKE dntab OCCURS 0 WITH HEADER LINE,
lstr_old_prog LIKE LINE OF mtab_old_prog,
BEGIN OF lstr_field,
tabname LIKE dd02t-tabname, " Table name
fldname LIKE dd02t-tabname, " Table name
END OF lstr_field.
ELSE.
f_new_prog = lstr_old_prog-line.
RETURN.
ENDIF.
IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
IF sy-subrc = 0.
ELSE.
f_new_prog = lstr_old_prog-line.
ENDIF.
*-------------------------------------------------------------
--------*
* FORM
ENQUEUE_ITAB_NAME *
*-------------------------------------------------------------
--------*
FORM enqueue_itab_name USING value(f_line) LIKE
mtab_long_line-code.
DATA:
lc_dummy(1) TYPE c,
lc_itab(40) TYPE c.
mtab_itab_names = lc_itab.
* Always have the most recent LOOP AT table as the first entry
in the
* queue
INSERT mtab_itab_names INDEX 1.
*-------------------------------------------------------------
--------*
* FORM
ADD_COMMENT_TO_ENDLOOP *
*-------------------------------------------------------------
--------*
FORM add_comment_to_endloop USING fstr_long_line LIKE
mtab_old_prog-line
CHANGING f_prog_line LIKE
mtab_new_prog-line
.
*-------------------------------------------------------------
--------*
* FORM
ENQUEUE_TAB_NAME *
*-------------------------------------------------------------
--------*
FORM enqueue_tab_name USING f_line LIKE mtab_old_prog-line.
DATA:
lc_dummy(1) TYPE c,
lc_tab(40) TYPE c.
mtab_tab_names = lc_tab.
* Always have the most recent LOOP AT table as the first entry
in the
* queue
INSERT mtab_tab_names INDEX 1.
*-------------------------------------------------------------
--------*
* FORM
ADD_COMMENT_TO_SELECT *
*-------------------------------------------------------------
--------*
FORM add_comment_to_select USING fstr_long_line LIKE
mtab_old_prog-line
CHANGING f_prog_line.
*-------------------------------------------------------------
--------*
* FORM
ADD_COMMENT_TO_ENDFORM *
*-------------------------------------------------------------
--------*
FORM add_comment_to_endform USING fstr_long_line LIKE
mtab_old_prog-line
CHANGING f_prog_line.
*-------------------------------------------------------------
--------*
* FORM
ENQUEUE_FORM_NAME *
*-------------------------------------------------------------
--------*
FORM enqueue_form_name USING f_line.
DATA:
lc_dummy(1) TYPE c,
lc_tab(40) TYPE c.
mtab_form_names = lc_tab.
* Always have the most recent LOOP AT table as the first entry
in the
* queue
INSERT mtab_form_names INDEX 1.