Skip to Content
Technical Articles

The “use simple types” approach

As I promised in my last post, today I come back writing about my experiences with the “use simple types” approach I mentioned there.

The approach

  • Avoid references to DDIC types (i.e. structures, data elements, table types) as long as is it is not necessary. A necessity for a DDIC type reference could be:
    • A field shows up on the screen (conversion exits and labels are needed)
    • You are calling a function module and have to match the types used here
  • Use simple, base types for attributes, locals and parameters such as:
    • string
    • integer
    • date
    • time
    • float
    • abap_bool
    • string_table (in fact, this is a DDIC type, but it is very basic and very useful when working on arrays)
  • Use range of strings in case of the need of selection ranges. Put a type definition for this in some central class of your code base. DB selections will work fine with this
  • Use clear, descriptive names for the variables in order to not create confusion about their semantics

Experiences

When I first thought of this, I was afraid, I missed something and the approach could bring more harms than blessings. So I decided to “try it out” for a while.

After having created a number of applications following the approach, I must say that it comes in very handy. I’d like to share some snippets:

    methods pbo.

    methods set_conf_number
      importing in type string.

    methods set_work_station
      importing in type string.

    methods set_test_purpose
      importing in type string.

    methods set_remarks
      importing in type string.

    methods exit_command
      importing in type string.

    methods user_command
      importing in type string.

This is part of the declaration of a front end class that communicates with a function group that carries a dynpro. Imagine how easy it was to create those declarations using copy and paste!

The dynpro logic calls those methods on each event that happens on it:

module conf_number_input input.
  g_controller->set_conf_number( conv #( zst_pp39_qcheck_strip_screen-conf_number ) ).
endmodule.

module work_station_input input.
  g_controller->set_work_station( conv #( zst_pp39_qcheck_strip_screen-work_station ) ).
endmodule.

module test_purpose_input input.
  g_controller->set_test_purpose( conv #( zst_pp39_qcheck_strip_screen-test_purpose ) ).
endmodule.

module remarks_input input.
  g_controller->set_remarks( conv #( zst_pp39_qcheck_strip_screen-remark ) ).
endmodule.

module exit_0001 input.
  g_controller->exit_command( conv #( user_command ) ).
endmodule.

module user_command_0001 input.
  g_controller->user_command( conv #( user_command ) ).
endmodule.

Since I am on the front end representation layer here, all my data is typed by referring DDIC. So I have to do a conversion when passing them to my simple-typed class.

  private section.
    constants function_preview type string value '1'.
    constants function_print type string value '2'.
    constants info_structure_name type string value `ZST_PP39_CONFIRM_INFO`.
    constants work_station_parameter type memoryid value 'ZPP24_WSTAT'.
    constants confirm_number_parameter type memoryid value 'RCK'.
    constants info_value_width type i value 12.
    constants info_description_width type i value 30.

constants (and data) declarations are dominated by simple types. However, some ABAP statements (as for instance get parameter id) require non-string parameters so I had to make some exceptions to my rule.

* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_PP39_QCHECK_STRIP_BACKEND->FILL_PRINT_DATA
* +-------------------------------------------------------------------------------------------------+
* | [<-()] RESULT                         TYPE        ZST_PP39_QCHECK_STRIP_PRINT
* +--------------------------------------------------------------------------------------</SIGNATURE>
  method fill_print_data.
    result =
      value #(
        order_id             = |{ order_operation-order_id alpha = out }|
        material_number      = zcl_ca03_conversions=>matn1_output( order_operation-material_number )
        work_center_id       = work_center_id
        work_center_text     = work_center_text
        material_description = material_description
        test_purpose_text    = test_purpose_text
        remark               = remark ).
  endmethod.

This is a mapping method for a communication structure that is used in a smart form. Since the smart form is called via function module, I had to create a DDIC structure for the data that is to be printed. However, the fields of the structures are all simple strings (see below).

Note the conversions I do for the first two fields. For printing, I need the external representation. Here, one could say that using a DDIC field in the communication structure would have done the job of conversion (and I would agree – maybe I will change this).

class ZCL_PP39_QCHECK_STRIP_TYPES definition
  public
  final abstract
  create public .

public section.
  types:
    begin of ty_order_operation,
      conf_number type string,
      order_id type string,
      activity type string,
      material_number type string,
      work_center_id type string,
    end of ty_order_operation.

This is a class where I declare complex types for use within the application. As you see, the components are all strings.

    select single
      afvc~rueck as conf_number,
      afvc~vornr as activity,
      afvc~arbid as work_center_id,
      afpo~aufnr as order_id,
      afpo~matnr as material_number
      from afvc join afko on afko~aufpl = afvc~aufpl
                join afpo on afpo~aufnr = afko~aufnr
      where afvc~rueck = @in
      into corresponding fields of @result.

Here we have a select that fills the structure declared above. Obviously the import parameter in is a string. Using into corresponding fields does the job of converting everything to strings.

    data confirm_info type zst_pp39_confirm_info.

This is a structure I use for screen output. Of course, every field in this structure has its DDIC type.

Conclusion

Coding in this way seems more lightweight to me. I like the easy way I can create new parts in my coding doubling a row or region and then changing the essential, while the type references are often identical (referring to a string).

To me, the code remains readable and clean. To understand the purpose of coding logic, normally it is sufficient to understand if I am dealing with a text, a flag or a number. The rest of the semantic comes with clear names.

 

5 Comments
You must be Logged on to comment or reply to a post.
  • You might also consider the memory requirement of STRING in your analysis, compared to type C:

    • ABAP Documentation – Character String and Byte String Processing for Release 7.0, EhP2 – Modification 6 – Management of Short Strings
      • The internal management of short stings has been optimized to reduce the memory overhead that accumulates when short strings are managed for the relevant string header. For string lengths of less than 30 characters or 60 bytes, the string header now only requires between 10 and 40 bytes. For longer strings, this remains at approximately 50 bytes. Before Release 7.0, EhP2, the overhead of the string header was not related to the length of the string and was approximately 60 bytes for each string.
      • Strings are recommended instead of data objects for all character string and byte string operations where a fixed length is not important.
    • ABAP Documentation – Memory Requirement for Deep Data Objects
      • For performance reasons, the memory usage of a string header depends on the length of the string. Strings with a length of less than around 30 characters/60 bytes are called short strings. The memory overhead of the string header of short strings is between approximately 10 and 40 bytes, depending on the length of the string. For all other strings, the overhead is approximately 50 bytes, regardless of the string length.
  • Hi Jörg,

    Thanks for sharing your experience.

    Could you add some more info what is the advantage of using simple types instead of the standard SAP ERP types? Is it needed for the ABAP Cloud compatibility?

    Thanks,

    Peter

    • No, this is not needed for ABAP Cloud compatibility – it’s only an idea of mine, how to simplify coding.

      The initial impulse for this was a problem I had when I wanted to copy a programming utility from ERP to APO. Since I used SAP standard DDIC types in my classes and some of them did not exist in APO, the code did not compile. My starting point was: “try to depend from as few repository objects as possible!”. So i wondered if I could use “data material_number type string” instead of “data material type matnr”. As I described above, the application of this idea lead to a more lightweight way of coding. No more searches for the right data type – just use strings for text, i or f for numbers, d or t for date/type and so on.

      • Thanks for the info.

        Now it makes sense. I also had some similar “fun” when I moved some objects developed originally on ERP system to a Netweaver ABAP Only system. That time didn’t think of this approach.