Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
thomas_jung
Developer Advocate
Developer Advocate

Updated!

If you really can't wait for the new Editor, read Speak Your Voice; New ABAP Editor for Older Releases. Add your opinion to the list and see if there is enough interest for SAP to back-port the new editor to older releases.

Introduction

I have never been accused of being a patient person. As a child, I just couldn't wait to open the presents on Christmas morning. I would poke and prod everything under the tree. I have even been know to peel back the wrapping ever so slightly to get a peek at what is inside.


If you are like me and just can't wait for the new ABAP editor, then this weblog might help you get through the ordeal. I decided that I didn't want to wait until I had access to a WebAS 7.0 system. I set out to create a small ABAP dialog program that could be run even in older releases that would allow me to try out some of the features in the new editor. The trick to this whole thing is that you must have SAPGui 640 Patch 10 or higher loaded on your system (Technially the ABAP editor is delivered in Patch 10. However due to some bugs in patch 10 unrelated to the ABAP editor, you probably want to skip 10 and go directly for patch 11 just to be safe). This is the patch level and release where the front end components of the new ABAP editor are delivered. Remember that the SAPGui is backwards compatible, so you can run the SAPGui 640 on your PC and still connect just fine even to older 46X releases.


The ABAP Editor Control


The new ABAP editor is implemented as an ActiveX control running on your windows client machine. It is integrated with ABAP using the Control Framework. That means that if you have the control running on your PC, all you need to do is create an ABAP Proxy class for it to be able to access its most basic features. If you want more details on this general technology see: Using Classic ActiveX Controls in the ABAP Control Framework. The first thing we need to do is determine some information about the control; like what are its methods and attributes. To do this I included the OCX into a project in Microsoft Visual Studio .Net 2003. I then used the Object browser to lookup the details.


!https://weblogs.sdn.sap.com/weblogs/images/1918/EditorObject_In_VS.jpg|height=325|alt=image|width=59...!




The ABAP Proxy Class


Armed with the information about the control, we are ready to create our ABAP proxy class. I created a class called ZCL_ES_GUI_ABAP_EDITOR that inherits from CL_GUI_CONTROL and has a forward declaration for CNTL. To get started, we will have to implement just two methods in this class.


The first method is the CONSTRUCTOR. This method will instantiate the control on the front-end and register it with the control framework. The parameters of the method are shown as comments at the beginning of the method.



METHOD CONSTRUCTOR .

*@78QImporting@     VALUE( STYLE )     TYPE I  DEFAULT 0     control style, if initial a defined value is choosen

*@78QImporting@     VALUE( PARENT )     TYPE REF TO CL_GUI_CONTAINER     Parent Container

*@78QImporting@     VALUE( LIFETIME )     TYPE I OPTIONAL     for life time management

*@78QImporting@     VALUE( NAME )     TYPE STRING OPTIONAL     name for the control

*@03QException@     ERROR_CNTL_CREATE          Error Creating Control

*@03QException@     ERROR_CNTL_INIT          Error Initializing Control

*@03QException@     ERROR_CNTL_LINK          Error Linking Control

*@03QException@     ERROR_DP_CREATE          DataProvider Error

*@03QException@     GUI_TYPE_NOT_SUPPORTED          This type of GUI is not supported!

  DATA prog_id(80).

  IF parent IS INITIAL.

    RAISE error_cntl_create.

  ENDIF.

  CLASS cl_gui_cfw DEFINITION LOAD.

  • assign prog_id to get the frontend specific control

  IF NOT activex IS INITIAL.

    prog_id = 'SAPGUI.AbapEditor.1'.

  ELSEIF NOT javabean IS INITIAL.

    RAISE gui_type_not_supported.

  ENDIF.

  IF prog_id IS INITIAL.

    RAISE gui_type_not_supported.

  ENDIF.

  • Set the window styles of the control when style parameter was not

  • set with constructor call.

  • For more information on the styles see WIN32 SDK

  IF style IS INITIAL.

  • otherwise the control would be invisible and the mistake would be

  • hard to find

    style = cl_gui_control=>ws_visible

            + cl_gui_control=>ws_child

            + cl_gui_control=>ws_clipsiblings.

  ENDIF.

  • Create the control

  CALL METHOD super->constructor

    EXPORTING

      clsid = prog_id

      shellstyle = style

      parent = parent

      lifetime = lifetime

      name = name

   EXCEPTIONS

      OTHERS    = 1.

  CALL METHOD cl_gui_cfw=>flush

    EXCEPTIONS

      cntl_system_error = 1

      cntl_error        = 2

      OTHERS            = 3.

  IF sy-subrc <> 0.

    RAISE error_cntl_create.

  ENDIF.

  • register instance at framework

  CALL METHOD cl_gui_cfw=>subscribe

    EXPORTING

       shellid = h_control-shellid

       ref = me

    EXCEPTIONS

      OTHERS    = 1.

  IF sy-subrc <> 0.
RAISE error_cntl_create.
ENDIF.


ENDMETHOD.




The second method, called ADD_EMPTY_DOC, will initialize an empty document into the editor. It has parameter to set the language type (ABAP, BSP, etc) and Read Only mode.




Test Program

We now need a relatively simple test program. I create a dialog program with a single screen. On the screen, in the screen painter, I inserted a custom control. The only special coding we really need is in the PBO. This is where we will create the instances of the custom container and the ABAP editor.














Lacking
documentation on the actual values for the parameters, I had to play with a little to get it working. But in the end I have a sample program with the empty editor.


!https://weblogs.sdn.sap.com/weblogs/images/1918/NewEditorOutput.jpg|height=395|alt=image|width=406|s...


This gives me enough functionality to try out the auto complete, code collapse, key word coloring, and several other features.


The next two screen shots show how you can use templates to insert a new method.


!https://weblogs.sdn.sap.com/weblogs/images/1918/NewEditorInsertMethod.jpg|height=159|alt=image|width...!




       


I even edited the template definition to create my own custom report header.


!https://weblogs.sdn.sap.com/weblogs/images/1918/NewEditorOptions.jpg|height=345|alt=image|width=534|...!





!https://weblogs.sdn.sap.com/weblogs/images/1918/NewEditorOptionsInAction.jpg|height=188|alt=image|wi...!





The new editor's front end export (Text, PDF, and HTML) all appear to be working fine as well. I exported my test document and added here to the weblog (that's inline HTML generated by the ABAP Editor - not an Image). It turned out looking quite nice.



SPAN {

font-family: "Courier New";

font-size: 10pt;

color: #000000;

background: #FFFFFF;

}

.L0S31 {

font-style: italic;

color: #808080;

}

.L0S32

.L0S51

.L0S52

.L0S54

.L0S55


>

class="L0S31">----




class="L0S31">* Report : Test Program

class="L0S31">* Author : Thomas Jung - Alpha Nerd

class="L0S31">----




class="L0S51">REPORT   Test  class="L0S51">Program

class="L0S55">no  class="L0S55">standard  class="L0S55">page heading

class="L0S55">line- class="L0S55">size   class="L0S32">80

class="L0S55">line- class="L0S55">count  class="L0S32">65( class="L0S32">0)

class="L0S55">message- class="L0S55">id 

defining  class="L0S55">database  .



start- class="L0S54">of-selection.

class="L0S54">perform test1.

class="L0S31">**********************************************************************

class="L0S31">* FORM    :  test1

class="L0S31">* Created :  03.08.2005 13:05:38

class="L0S31">**********************************************************************

class="L0S54">FORM test1  class="L0S55">USING  

class="L0S55">CHANGING .

   class="L0S54">IF sy-subrc =  class="L0S32">0.



   class="L0S54">ENDIF.

class="L0S54">ENDFORM.  class="L0S31">"test1

class="L0S52">class  class="L0S52">implementation lcl_test.

class="L0S31">**********************************************************************

class="L0S31">* METHOD    :  test1

class="L0S31">* Created   :  03.08.2005 13:09:43

class="L0S31">**********************************************************************

class="L0S54">METHOD test1 .



class="L0S54">ENDMETHOD.  class="L0S31">"test1






Updated on August 9th 2005

For those of you who may have thought that the original version of this example wrapper didn't go far enough, I now have a new version.



Thanks to help from Alexey Arseniev (the author of the new ABAP editor), I have a newer enhanced version of the demo of the new ABAP editor. This new demo includes MUCH more coding in the control proxy class.



UPDATED August 11th



I now have the link where you can download the code.

Code Download

Let me know if you have any problems. There should be screen shots of any table types or structures that you need to declare. Many of the other other type definitions are declared in-line in the class. This sample was written on 640 SP12.



!https://weblogs.sdn.sap.com/weblogs/images/1918/QuickInfo.jpg|height=207|alt=image|width=509|src=htt...!



The new version also only works in WebAS 610 and higher. It turns out that the new ABAP editor expects to receive its source code in Unicode (UTF-16LE to be exact). Therefore you need certain functions to perform the conversion.



I will list a few of the updated methods here that allow you to load any program into the editor, in case anyone just can't wait until they get file download.


METHOD constructor .

*@78QImporting@     VALUE( STYLE )     TYPE I  DEFAULT 0     control style, if initial a defined value is choosen

*@78QImporting@     VALUE( PARENT )     TYPE REF TO CL_GUI_CONTAINER     Parent Container

*@78QImporting@     VALUE( LIFETIME )     TYPE I OPTIONAL     for life time management

*@78QImporting@     VALUE( NAME )     TYPE STRING OPTIONAL     name for the control

*@78QImporting@     REPORT_NAME     TYPE SYREPID OPTIONAL     ABAP Program: Current Main Program

*@03QException@     ERROR_CNTL_CREATE          Error Creating Control

*@03QException@     ERROR_CNTL_INIT          Error Initializing Control

*@03QException@     ERROR_CNTL_LINK          Error Linking Control

*@03QException@     ERROR_DP_CREATE          DataProvider Error

*@03QException@     GUI_TYPE_NOT_SUPPORTED          This type of GUI is not supported!

  DATA prog_id(80).

  IF parent IS INITIAL.

    RAISE error_cntl_create.

  ENDIF.

  CLASS cl_gui_cfw DEFINITION LOAD.

  • assign prog_id to get the frontend specific control

  IF NOT activex IS INITIAL.

    prog_id = 'SAPGUI.AbapEditor.1'.

  ELSEIF NOT javabean IS INITIAL.

    RAISE gui_type_not_supported.

  ENDIF.

  IF prog_id IS INITIAL.

    RAISE gui_type_not_supported.

  ENDIF.

  • Set the window styles of the control when style parameter was not

  • set with constructor call.

  • For more information on the styles see WIN32 SDK

  IF style IS INITIAL.

  • otherwise the control would be invisible and the mistake would be

  • hard to find

    style = cl_gui_control=>ws_visible

            + cl_gui_control=>ws_child

            + cl_gui_control=>ws_clipsiblings.

  ENDIF.

  • Create the control

  CALL METHOD super->constructor

    EXPORTING

      clsid      = prog_id

      shellstyle = style

      parent     = parent

      lifetime   = lifetime

      name       = name

    EXCEPTIONS

      OTHERS     = 1.

  CALL METHOD cl_gui_cfw=>flush

    EXCEPTIONS

      cntl_system_error = 1

      cntl_error        = 2

      OTHERS            = 3.

  IF sy-subrc <> 0.

    RAISE error_cntl_create.

  ENDIF.

  • register instance at framework

  CALL METHOD cl_gui_cfw=>subscribe

    EXPORTING

      shellid = h_control-shellid

      ref     = me

    EXCEPTIONS

      OTHERS  = 1.

  IF sy-subrc <> 0.

    RAISE error_cntl_create.

  ENDIF.

  • create and initialize dataprovider =>  m_dp_handle

  CALL FUNCTION 'DP_CREATE'

    CHANGING

      h_dp             = m_dp_handle

    EXCEPTIONS

      dp_create_error  = 1

      dp_install_error = 2

      dp_error         = 3

      OTHERS           = 4.

  IF sy-subrc <> 0.

    RAISE error_dp_create.

  ENDIF.

  •   Register control events

  CALL METHOD register_events.

  •   Enable control events

  CALL METHOD call_method

    EXPORTING

      method  = 'SubscribeOnCommand'

      p1      = 37311

      p2      = cfalse

      p_count = 2

    EXCEPTIONS

      OTHERS  = 1.

  • CALL METHOD set_property

  •    EXPORTING

  •      property = 'bNavigateOnDblClick'

  •      value    = ctrue.

*

    •   Set default language to ABAP

  • CALL METHOD set_property

  •    EXPORTING

  •      property = 'sProgLanguage'

  •      value    = 'ABAP4'.

  •   If report name provided - load it

  CHECK NOT report_name IS INITIAL.

  CALL METHOD load

    EXPORTING

      report_name = report_name.

ENDMETHOD.                    "constructor

  LIKE LINE OF lt_report.

  CHECK NOT report_name IS INITIAL.

  • Check existense and attributes

  CALL FUNCTION 'RPY_EXISTENCE_CHECK_PROG'

    EXPORTING

      name        = report_name

    TABLES

      progdir_tab = lt_progdir

    EXCEPTIONS

      not_exist   = 1

      OTHERS      = 2.

  CHECK sy-subrc EQ 0.

  gt_progdir = lt_progdir.

  gv_report_name = report_name.

  • Get main program

  CALL FUNCTION 'RS_GET_MAINPROGRAMS'

    EXPORTING

      name            = gv_report_name

      dialog_required = gc_true

    TABLES

      mainprograms    = lt_mainprog

    EXCEPTIONS

      OTHERS          = 1.

  IF sy-subrc EQ 0.

    READ TABLE lt_mainprog INDEX 1 INTO gv_main_prog.

  ENDIF.

  •   Load report

READ REPORT gv_report_name INTO lt_report.

  • send table to control

  CALL METHOD set_text_as_r3table

    EXPORTING

      table = lt_report.

  CALL METHOD call_method

    EXPORTING

      method  = 'LoadDocFromDP'

      p1      = report_name

      p2      = m_dp_handle

      p_count = 2

    EXCEPTIONS

      OTHERS  = 1.

ENDMETHOD.                    "LOAD





METHOD set_text_as_r3table.

*@78QImporting@     TABLE     TYPE STANDARD TABLE     

*@03QException@     ERROR_DP          

  •   set_table_property table. "'YES_ABAP_EDITOR'.

  TYPES: x256(120) TYPE x.

  DATA: l_table TYPE TABLE OF x256.

  DATA: x_test TYPE xstring.

  DATA: s_test TYPE string.

  FIELD-SYMBOLS:  0.

  ENDIF.

  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'

    EXPORTING

      buffer                = x_test

    TABLES

      binary_tab            = l_table.

  • create dataprovider object and send data to frontend

  call function 'DP_CREATE_FROM_STREAM'

    exporting

      type                 = cndp_sap_tab_mimetype

      subtype              = 'ABAP_SOURCE' " cndp_sap_subtype_unknown

  •      size                 = len

    tables

      data                 = l_table

    changing

      h_dp                 = m_dp_handle

    exceptions

      DP_ERROR_GENERAL     = 1

      DP_ERROR_CREATE      = 2

      DP_ERROR_SEND        = 3

      others               = 4.

ENDMETHOD.





Closing

The new ABAP editor has tons of methods, many of which would be necessary for unlocking all the features it has. I have only scratched the surface here. There is just enough to wet your appetite for more. I really wanted to implement enough methods to be able to load an existing program from the back end into the editor. However the contents of the program are loaded as DP Objects to the front end control and therefore I don't have good documentation on the format of the internal table to pass in.

67 Comments