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.
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.
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.
I even edited the template definition to create my own custom report header.
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">----
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
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.