Skip to Content
Author's profile photo Sergio Ferrari

how many lines of custom ABAP code are inside your system?

Updated on December 16, 2009: How many lines of custom ABAP code are inside your system? – Part2

Updated on February 5, 2009: out-of-scope section was added

After the Simple ABAP Benchmark , I’m glad to share here in SDN another simple ABAP tool to monitor your system, it is called ZSDN_simple_ABAP_SLOC_COUNT.

Download 

The utility can be downloaded as Slinkee (SAPLINK) from the project home page http://code.google.com/p/abapsloc/ or create a report in SE38 and paste the following code.

Execute it and read the number of lines at the end of the list. 

SLOC Reference

Source lines of code (SLOC)  is just an indicator, I don’t want to give it too much relevance but it can be useful for example to estimate the upgrade effort or to evaluate the amount of work allocated for each of yours packages.

You can compare your system with well known software (source Wikipedia):

  • Windows XP:      45 million lines of code
  • Windows Vista:  50 million lines of code (see here)
  • Mac OS:              86 million lines of code ( see here

and also with the standard SAP system:

  • SAP (ABAP):      238 million lines of ABAP (see here)
Let’s build up our SDN database 

To compare apples with apples, I prepared a public Google spreadsheet where you can publish the SLOC of your ABAP system. It’s not suggested to specify your company but it could be interesting to know the country (where the system is maintained) and the year of the first implementation.

The form to update the spreadsheet is available here

The spreadsheet is available here 

Additional notes

The tool has been developed during our free time from work by Andrea Olivieri (he is really an ABAP Guru) and myself; please note that we had no time to optimize it.

We exclude ABAP generated by special frameworks (e.g. Report writer, SAP Query, Web Dynpro, LSMW, …) filtering by Source System, Owner and Package.

Supported releases

SAP ECC 6.0

Out-of-scope

This utility doesn’t take into account the code contained in the following objects:

  • BSP
  • Adobe Form/SMARTFORMs/SAPScript
  • XSLT

Assigned Tags

      17 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Martin Voros
      Martin Voros
      Hi,

      first of all thanks for sharing this nice program.

      I just have one comment. You've already  partly mentioned it in your blog. It does not make any sense to compare results from your neat program with SLOC of Windows or Mac OS X. The problem is in different programing languages. Some languages require more lines than others. Another problem is in application type. For example your program has only 361 lines. But something similar written in C would take much much more.

      It would be better to know for example all packages related to MM module and then get SLOC for MM.

      Cheers

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Hi Martin,
        here are some hints that apply to different scenarios:
      - I'm working for a company with a simple Landscape (e.g one SAP system): you could compare packages or developers
      - I'm working for a group with a complex Landscape (e.g an SAP system per company/region): you could compare systems
      - I'm working as an SAP consultant: you could compare different installations
      - last but not least, are you a member of SDN: as reported above in the chapter "Let's build up our SDN database", compare with the SDN database (hoping it will be populated)

      Will you the first using the public form https://spreadsheets.google.com/viewform?key=pvnwnKIJiJ7hhPUrVGxpxNw to populate the database?

      Sergio

      Author's profile photo Stefan Riedel-Seifert
      Stefan Riedel-Seifert
      ... the whole bunch of BSP-Pages will be not included 🙁
      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Yes Stefan, you are right.
      We will see if it will be possible to include also BSP...
      For the moment I added an out-of-scope section...
      Sergio
      Author's profile photo Former Member
      Former Member
      I put report in text file and renamed rep.sca. Then used Visual Admin for upload. But it is not working. Where is wrong?
      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Hi Kartik, this utility is only for ABAP not for Java.
      Transaction SE38 should be used...

      Sergio

      Author's profile photo Former Member
      Former Member
      Ah! Now I understand. Sorry for the inconvenience!
      Author's profile photo Former Member
      Former Member
      Would you have any options or suggestions for us being we are running 4.7c

      Thanks
      Diego

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Hi Diego,
        as soon as we will have access to a R4.7 system we will try to adopt the utility. Probably we'll comment out the analysis related to ABAP CLASSes (they were not so used in R4.7).

      Sergio

      Author's profile photo Former Member
      Former Member
      I ask the same of Diego. please provide.

      thank you. 🙂

      Author's profile photo Andrea Olivieri
      Andrea Olivieri
      Hello Diego,
      I quickly adapted the utility to the R4.7.
      Replace the contents of the routine FORM ALV and add those other routines: FORM SET_ORDER; FORM FIELDCAT2.

      *&---------------------------------------------------------------------*
      *& Form alv
      *&---------------------------------------------------------------------*
      * Created by ALVRobot.com.ar; Special thanks to Gabriel Jenik
      *----------------------------------------------------------------------*
      FORM alv.

      TYPE-POOLS: slis.
      * ALV required data objects.
      DATA: w_title TYPE lvc_title,
      w_repid TYPE syrepid,
      w_comm TYPE slis_formname,
      w_status TYPE slis_formname,
      x_layout TYPE slis_layout_alv,
      t_event TYPE slis_t_event,
      t_fieldcat TYPE slis_t_fieldcat_alv,
      t_sort TYPE slis_t_sortinfo_alv.

      REFRESH t_fieldcat.
      REFRESH t_event.
      REFRESH t_sort.
      CLEAR x_layout.
      CLEAR w_title.

      * Field Catalog
      PERFORM set_fieldcat2 USING:
      1 'DEVCLASS' 'DEVCLASS' 'TADIR' space space space space space space space space space space space space t_fieldcat ,
      2 'NAME' 'NAME' 'TRDIR' space space space space space space space space space space space space t_fieldcat ,
      3 'OBJECT' 'OBJECT' 'TADIR' space space space space space space space space space space space space t_fieldcat ,
      4 'SRCSYSTEM' 'SRCSYSTEM' 'TADIR' space space space space space space space space space space space space t_fieldcat ,
      5 'AUTHOR' 'AUTHOR' 'TADIR' space space space space space space space space space space space space t_fieldcat ,
      6 'SUBC' 'SUBC' 'TRDIR' space space space space space space space space space space space space t_fieldcat ,
      7 'SLOC' 'SLOC' space space space space space space space space space space space space 'X' t_fieldcat .

      * Layout
      x_layout-zebra = 'X'.

      w_repid = sy-repid.

      PERFORM set_order USING 'DEVCLASS' 'IT_DATA' 'X' space 'X' t_sort.
      PERFORM set_order USING 'NAME' 'IT_DATA' 'X' space space t_sort.

      * Displays the ALV grid
      CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
      i_callback_program = w_repid
      it_fieldcat = t_fieldcat
      is_layout = x_layout
      it_sort = t_sort
      i_save = 'X'
      it_events = t_event
      TABLES
      t_outtab = t_repository
      EXCEPTIONS
      program_error = 1
      OTHERS = 2.
      IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.

      ENDFORM. "alv
      *&------------------------------------------------------------------*
      *& Form set_order
      *&------------------------------------------------------------------*
      * Adds an entry to the order table.
      *-------------------------------------------------------------------*
      FORM set_order USING p_fieldname p_tabname p_up p_down p_subtot
      t_sort TYPE slis_t_sortinfo_alv.

      DATA: x_sort TYPE slis_sortinfo_alv.

      CLEAR x_sort.
      x_sort-fieldname = p_fieldname.
      x_sort-tabname = p_tabname.
      x_sort-up = p_up.
      x_sort-down = p_down.
      x_sort-subtot = p_subtot.
      APPEND x_sort TO t_sort.

      ENDFORM. "set_order

      *&------------------------------------------------------------------*
      *& Form set_fieldcat2
      *&------------------------------------------------------------------*
      FORM set_fieldcat2 USING
      p_colpos p_fieldname p_ref_fieldname p_ref_tabname
      p_outputlen p_noout
      p_seltext_m p_seltext_l p_seltext_s p_reptext_ddic p_ddictxt
      p_hotspot p_showasicon p_checkbox p_edit
      p_dosum
      t_fieldcat TYPE slis_t_fieldcat_alv.

      DATA: wa_fieldcat TYPE slis_fieldcat_alv.

      CLEAR wa_fieldcat.

      * General settings
      wa_fieldcat-fieldname = p_fieldname.
      wa_fieldcat-col_pos = p_colpos.
      wa_fieldcat-no_out = p_noout.
      wa_fieldcat-hotspot = p_hotspot.
      wa_fieldcat-checkbox = p_checkbox.
      wa_fieldcat-icon = p_showasicon.
      wa_fieldcat-do_sum = p_dosum.

      * Set reference fieldname, tablenam and rollname.
      * If p_ref_tabname is not given, the ref_fieldname given
      * is a data element.
      * If p_ref_tabname is given, the ref_fieldname given is a
      * field of a table.
      * In case ref_fieldname is not given,
      * it is copied from the fieldname.
      IF p_ref_tabname IS INITIAL.
      wa_fieldcat-rollname = p_ref_fieldname.
      ELSE.
      wa_fieldcat-ref_tabname = p_ref_tabname.
      IF p_ref_fieldname EQ space.
      wa_fieldcat-ref_fieldname = wa_fieldcat-fieldname.
      ELSE.
      wa_fieldcat-ref_fieldname = p_ref_fieldname.
      ENDIF.
      ENDIF.

      * Set output length.
      IF NOT p_outputlen IS INITIAL.
      wa_fieldcat-outputlen = p_outputlen.
      ENDIF.

      * Set text headers.
      IF NOT p_seltext_m IS INITIAL.
      wa_fieldcat-seltext_m = p_seltext_m.
      ENDIF.

      IF NOT p_seltext_l IS INITIAL.
      wa_fieldcat-seltext_l = p_seltext_l.
      ENDIF.

      IF NOT p_seltext_s IS INITIAL.
      wa_fieldcat-seltext_s = p_seltext_s.
      ENDIF.

      IF NOT p_reptext_ddic IS INITIAL.
      wa_fieldcat-reptext_ddic = p_reptext_ddic.
      ENDIF.

      IF NOT p_ddictxt IS INITIAL.
      wa_fieldcat-ddictxt = p_ddictxt.
      ENDIF.

      * Set as editable or not.
      IF NOT p_edit IS INITIAL.
      wa_fieldcat-input = 'X'.
      wa_fieldcat-edit = 'X'.
      ENDIF.

      APPEND wa_fieldcat TO t_fieldcat.

      ENDFORM. "set_fieldcat2

      Hope this helps.
      Andrea

      Author's profile photo Former Member
      Former Member

      A cpl of years ago this question was a contest at a company I as working. I did the measurement while my colleagues had to make the best guess. <br/>It was a 4.6c system and my measurement resulted in 85,361,427 lines of ABAP code, excluding custom development.<br/>Encountering this blog I re-run my program on an ECC6 system and it resulted in 155.388.133 lines. Almost doubled! (there's a dependency on installed components, patch level etc.. This a standard business system with few IS. No netweaver, only BI and PI plug-ins )<br/>The program I used is so simple that I add it here. You can install it and try out on your own system:<br/>--


      <br/>REPORT  ZABAP_COUNTER.<br/><br/>  tables: trdir.<br/><br/>  types: begin of ty_proginfo,<br/>           program type programm,<br/>           counter type i,<br/>           empty   type i,<br/>           comment type i,<br/>           source  type i,<br/>         end of ty_proginfo.<br/><br/>  data: st_proginfo  type ty_proginfo,<br/>        it_proginfo  type table of ty_proginfo,<br/>        st_progline  type ty_proginfo.<br/><br/>  field-symbols: <proginfo> type ty_proginfo.<br/><br/>  select-options: so_progr for trdir-name.<br/><br/>  select name from trdir into table it_proginfo<br/>                         where name in so_progr.<br/><br/>  loop at it_proginfo assigning <proginfo>.<br/>    perform count_program changing <proginfo>.<br/>    add: <proginfo>-counter to st_proginfo-counter,<br/>         <proginfo>-empty   to st_proginfo-empty,<br/>         <proginfo>-comment to st_proginfo-comment,<br/>         <proginfo>-source  to st_proginfo-source.<br/>  endloop.<br/><br/>  write:/ 'Programs',      20 st_proginfo-counter,<br/>        / 'Empty lines',   20 st_proginfo-empty,<br/>        / 'Comment lines', 20 st_proginfo-comment,<br/>        / 'Source lines',  20 st_proginfo-source.<br/><br/>*&


      <br/>&      Form  count_program<br/>*&


      <br/>FORM count_program USING p_proginfo TYPE ty_proginfo.<br/><br/>  data: abaptab type standard table of string,<br/>        abaplin type string.<br/><br/>  read report p_proginfo-program into abaptab.<br/>  check sy-subrc = 0.<br/><br/>  add 1 to p_proginfo-counter.<br/><br/>  loop at abaptab into abaplin.<br/>    if abaplin is initial.<br/>      add 1 to p_proginfo-empty.<br/>    elseif abaplin(1) = ''.<br/>      add 1 to p_proginfo-comment.<br/>    else.<br/>      add 1 to p_proginfo-source.<br/>    endif.<br/>  endloop.<br/><br/>ENDFORM.                    " count_program<br/>
      --


      <br/>It's quite simple-minded counting, but however you define SLOC (e.g. include flow-logic, or exclude generated programs) they make only small differences.<br/>When scheduling it in a job it takes about 1-2 hrs to scan the whole system.<br/>Good luck!

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Thanks Ben,
        you also provided the version for 4.6 and 4.7 as from other requests. The select-option "so_progr" allows the filter on custom objects (Y*, Z*). We will try to downgrade our version in any case.

        Slide 3 of the interesting presentation "SAP and Virtualization Some Thoughts" https://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/0005265f-e4f2-2a10-85ad-dced292c0c0d includes also Java, C, C++ and others.

        As you said, it's really impressive the difference between R4.6c to SAP ECC 6.0.
        ABAP OO, the new ALV, BSP, SAP Web AS, Web Dynpro for ABAP, GOS, Adobe Form and a huge number of new functionalities are there.

      Sergio

      Author's profile photo Former Member
      Former Member
      Hi,

      thanks for submitting this useful tool to the public. This is exactly what I have been looking for.

      During my first test run, I encountered one issue and one defect.

      1) Issue:
      Why did you choose
        AND   obj_name   IN xauthor
      along with
        AND   author     IN xauthor
      in the SELECT statement? If I ever choose an "inclusion" select option, for example "count lines of program ZTEST", it won't work, because the author won't match. Similarly "count lines of program by author GERTH" will never find any entries.
      I see that it works with exclusion, but in my opinion your program will work better if you have separated select options for author and object name.

      2) Defect
      The lines
      WHEN 'FUGR'.
        CONCATENATE 'SAPL' l_repository-name INTO l_irdir-name.
      do not work if namespaces are involved.
      I found function module FUNCTION_INCLUDE_CONCATENATE which might do the job (only fill parameter COMPLETE_AREA).

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Hi Björn,
        you're right, that night we developed we (me and Andera) were a bit tired.
        We'll include your suggestions soon...
      Sergio
      Author's profile photo Former Member
      Former Member
      Hi Sergio,

      I am trying to access the google spreadsheet, but it is asking me for techedge.it user ID.

      Can you please update the correct link which can be accessed.

      Regards,
      Atish

      Author's profile photo Sergio Ferrari
      Sergio Ferrari
      Blog Post Author
      Thanks for reporting the broken link Atish.
      It should work now.
      Sergio