Friday, October 18, 2013

SAP Abap how to delete a directory from the presentation server (front end)




Hi folks,

here a little program to remove e directory on the presentation server.
Enjoy!

REPORT ZDIR.

parameters: p_dir type rlgrap-filename .

at selection-screen on value-request for p_dir .

  CALL FUNCTION 'F4_FILENAME'
  EXPORTING
   PROGRAM_NAME = SYST-CPROG
   DYNPRO_NUMBER = SYST-DYNNR
   FIELD_NAME = 'P_DIR'
  IMPORTING
   FILE_NAME = p_dir
.
start-of-selection .

  CALL FUNCTION 'GUI_REMOVE_DIRECTORY'
   EXPORTING
   DIRNAME = p_dir
  EXCEPTIONS
   FAILED = 1
   OTHERS = 2.

if sy-subrc eq 0.
  write:/ 'directory: ' , p_dir , ' removed.'.
endif.

SAP ABAP how to delete a file from the frontend

+
Hi Folks,
here an easy one: delete a file from the front end  (typically the PC of the user using the sapgui).
The function that does this is: GUI_DELETE_FILE

Enjoy it!

REPORT ZDEL

parameters: p_file type rlgrap-filename .
at selection-screen on value-request for p_file .

  CALL FUNCTION 'F4_FILENAME'
  EXPORTING
   PROGRAM_NAME = SYST-CPROG
   DYNPRO_NUMBER = SYST-DYNNR
   FIELD_NAME = 'P_FILE'
  IMPORTING
   FILE_NAME = p_file
.
start-of-selection .

  CALL FUNCTION 'GUI_DELETE_FILE'
   EXPORTING
   FILE_NAME = p_file
  EXCEPTIONS
   FAILED = 1
   OTHERS = 2
.
IF SY-SUBRC <> 0.
  write:/ 'file:' , p_file , ' not removed'.
ENDIF.

write:/ 'file:' , p_file , 'removed'.

Tuesday, October 8, 2013

How to clear ucomm in ALV grid SAP ABAP

Hi Folks,


The user command is stored in CL_GUI_ALV_GRID->M_UCOMM
So basically it is enough to clear m_ucomm

There is a method that can be called named SET_USER_COMMAND
It can be called like this
my_Grid->SET_USER_COMMAND
  exporting     i_ucomm = space.

It happens that you have an error condition triggered in your on_data_changed event handler.
If the error is red (blocking) no further processing can happen until the error is resolved.
Not even an undo button press is allowed.
So one can try to solve this situation by checking for a certain ucomm in the on data changed method.
But this does not work because once the ucomm is set, it stays set until another ucomm is selected, even throughout data changes in the ALV that have nothing to do with that ucomm.

To be honest the internal undo ucomm works even if there is an error, but you have to press it twice. Somewhat weird isn't it!?

Slowly i am realizing that the complexity of a non trivial data editing program with non trivial checks on the data ( like time constraints on time dependent data) based on ALV can be quite high, and that the ALV control itself does not help mastering this complexity: it adds more and more complexity with its weird control-flow structure.

How to create a control on a dynpro without a container using screen0 SAP ABAP


Hi Folks, 
here an easy nice tip: if you have only one alv or component on your dynpro you can disply it on the full dynpro just using the whole dynpro without using a control container.

You need to create a completely empty dynpro and that's it.


Here is an example:

DATA  lr_alv      TYPE REF TO   cl_gui_alv_grid.
DATA  lt_table  TYPE TABLE OF t529a.

SELECT * FROM t529a INTO TABLE lt_table.


CREATE OBJECT lr_alv
  EXPORTING
    i_parent = cl_gui_container=>screen0.

CALL METHOD lr_alv->set_table_for_first_display
  EXPORTING
    i_structure_name = 'T529A'
  CHANGING
    it_outtab        = lt_t529a

CALL SCREEN 100

Wednesday, October 2, 2013

the Class constructor and singleton in abap



Hi Folks,
i am hacking on an ALV oo program and needed or wanted to implement the singleton pattern.

A singleton is a class of which only one instance exists and some means is create to access the only instance without making it global of course...
Think of it as a global variable hidden behind a puzzling coding interface. At the very end it is just a single global instance of a class, but far more cool and  good looking :-)

Apart from jokes it makes sense. Obviously not in 10 lines programs. But in complex applications having a global in the scope of a whole project can be problematic... the singleton can be anice way to control this "global" and access it in a discplined and controlled manner

In my case i have program that runs on one person. So my "app" object is bound to the person and there is only one throuout the processing.

So i need a means to have a central object instance which can be accessed by all classes that need it.
In abap it can be done like in the following coding.

The class-method is a method that is run per "class" and not per "object" ( the instance of the class)
The class constructor is run only once per program before the class is called for the first time.

So the class construcor instantiates the object ( the only existing instance )
The class method gives access just to this one and only existing oblect of the given singleton class.

So in my program i can call it like this
...
DATA lr_my_app TYPE REF TO zcl_my_app.
  lr_my_app =  zcl_my_app=>get_singleton( ).
  CALL METHOD gr_my_app->init
....

Here the class example.


CLASS zcl_my_app DEFINITION.
  PUBLIC SECTION.
    class-METHODS: class_constructor.

    METHODS: init .

    CLASS-METHODS: get_ref RETURNING value(r_ref) TYPE REF TO zcl_my_app.

  PRIVATE SECTION.
    CLASS-DATA ar_singleton TYPE REF TO zcl_my_app.


CLASS zcl_my_app IMPLEMENTATION.

  METHOD: class_constructor.
    CREATE OBJECT ar_singleton.
  ENDMETHOD.                    "constructor

  METHOD: init.
*Do whatever
  ENDMETHOD.                    "init

  METHOD: get_ref.
    r_ref = ar_singleton.
  ENDMETHOD.                    "get_ref


One last word: i have seen implementations in the internet like this:

method GET_OBJECT.
" returning  value(R_OBJECT) type ref to ZCL_blabla .
*
  if zcl_blabla=>r_singleton is not bound.
    create object zcl_blabla=>r_singleton.
  endif.
*
  r_object = zcl_sblabla=>r_singleton .
endmethod.
 

Can i say that it is the same but at the same time it really sucks :-) LOL ?


Tuesday, September 24, 2013

how to Clone objects in SAP ABAP



Hi Folks,
this post is about cloning an object in ABAP.

You need to make an exact copy of your object. Duplicating everything contained in the object so that when you change something in the first object you get no effect on the cloned object (caveat: what happens with obj references in the attributes? read on...).

Manually you would implement a method clone which could basically look like this:

method: clone. "returning r_ref type ref to lcl_my_class.

data l_ref type ref to lcl_my_class.
create object l_ref.

*Copy all attributes.
l_ref->a_value = me->a_value.
l_ref->at_table = me->at_table.

*Clone contained objects recursively


r_ref = l_ref.
endmethod.

There is a simple and nice trick to get the job done in a fashion that resembles other programming languages.

Implemente the interface IF_OS_STATE
like this:
CLASS zcl_data_mgr DEFINITION.
  PUBLIC SECTION.
  interfaces IF_OS_CLONE .
 ...


In the method clone implementation of the interface add the following
method IF_OS_CLONE~CLONE.
  SYSTEM-CALL OBJMGR CLONE ME TO RESULT.
endmethod.
 

you can then clone your object with the following single line.

DATA lr_obj type ref to zcl_data_mgr.
lr_obj ?= gr_data_mgr->if_os_clone~clone( ).

Here the result of a test program that demonstrates that cloning clones attributes, but does not clone object references recursively.

The conclusion is that cloning is a nice feature that requires caution when you have objects with a status in the attributes: these do not get cloned but instead their references are copied and thus shared among the clones.





And here the test program coding:

*&---------------------------------------------------------------------*
*& Report  ZZ_test_clone
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT 
ZZ_test_clone.


*----------------------------------------------------------------------*
*       CLASS zcl_contained DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_contained DEFINITION.

  PUBLIC SECTION.
    INTERFACES if_os_clone .

    DATA a_c_value TYPE i.
    DATA a_c_table TYPE STANDARD TABLE OF sflight.

    METHODS: do_something_c.

ENDCLASS.                    "zcl_contained  DEFINITION

*----------------------------------------------------------------------*
*       CLASS zcl_contained  IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_contained  IMPLEMENTATION.

*TODO: TEst this methos and remove the "old fashioned one
  METHOD if_os_clone~clone.

    SYSTEM-CALL OBJMGR CLONE me TO result.

  ENDMETHOD.                    "IF_OS_CLONE~CLONE

  METHOD do_something_c.
    a_c_value = 1.
    SELECT * FROM sflight INTO TABLE a_c_table WHERE carrid = 'SQ'.
  ENDMETHOD.                    "do_something_c

ENDCLASS.                    "zcl_contained  IMPLEMENTATION


*----------------------------------------------------------------------*
*       CLASS zcl_data_mgr DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_data_mgr DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_os_clone .
    DATA a_value TYPE i.
    DATA a_table TYPE STANDARD TABLE OF sflight.
    DATA ar_object TYPE REF TO zcl_contained.

    METHODS: do_something.

ENDCLASS.                    "zcl_data_mgr DEFINITION

*----------------------------------------------------------------------*
*       CLASS zcl_data_mgr  IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_data_mgr  IMPLEMENTATION.

*TODO: TEst this methos and remove the "old fashioned one
  METHOD if_os_clone~clone.

    SYSTEM-CALL OBJMGR CLONE me TO result.

  ENDMETHOD.                    "IF_OS_CLONE~CLONE

  METHOD do_something.
    a_value = 1.
    SELECT * FROM sflight INTO TABLE a_table WHERE carrid = 'LH'.
    CREATE OBJECT ar_object.
    CALL METHOD ar_object->do_something_c.
  ENDMETHOD.                    "do_something

ENDCLASS.                    "zcl_data_mgr  IMPLEMENTATION

START-OF-SELECTION.

  DATA lr_ref type REF TO zcl_data_mgr.

  CREATE OBJECT lr_ref.
  CALL METHOD lr_ref->do_something.

  DATA lr_obj TYPE REF TO zcl_data_mgr.

  lr_obj ?= lr_ref->if_os_clone~clone( ).

  WRITE:/ 'Done.'.

Thursday, September 19, 2013

Regexp regular expression matching in ABAP

 

Hi Folks,
looking around while trying to search an abap pattern in the whole abap repository with the interesting "ABAP_SOURCE_CODE_SCAN" report i realized that SAP has built-in regexp pattern matching features into ABAP.

I had been waiting long time for such a feature.

An overview of the underlying abap syntax can be found looking at the demo source code and is quite simple:

          IF nocase = 'X'.
            FIND REGEX regex IN TABLE result_it IGNORING CASE
                 SUBMATCHES sub1 sub2 sub3 sub4 sub5 sub6.

            IF first = 'X'.
              REPLACE REGEX regex IN TABLE result_it
                      WITH new_marked IGNORING CASE.

            ELSE. " all = 'X'
              REPLACE ALL OCCURRENCES OF REGEX regex IN TABLE result_it
                      WITH new_marked IGNORING CASE.

            ENDIF.
          ELSE. " case = 'X'
            FIND REGEX regex IN TABLE result_it
                 SUBMATCHES sub1 sub2 sub3 sub4 sub5 sub6.

            IF first = 'X'.
              REPLACE REGEX regex IN TABLE result_it
                      WITH new_marked.
            ELSE. " all = 'X'
              REPLACE ALL OCCURRENCES OF REGEX regex IN TABLE result_it
                      WITH new_marked.

            ENDIF.

Here text lines in abap are represente as a "table of string data elements" which is quite common.

If you are interested in regexp there is an interesting tutorial here at
regexp tutorial

The syntax should be posix compliant. i tried some simple stuff and it works just fine.

SAP has released i nice toy test program acually called
DEMO_REGEX_TOY

Here a screen shot



So what does \b(\w+)\s+\1\b mean?

\b is the beginning of the word
\w+ means 1 or more alphanumeric chars
\s+ means 1 or more whitespace chars
\1 means the first subpattern matched
\b means end of the word in that position.

So basically you ask the regexp engine to match
a beginning word made of 1 or more alpha chars wollowed by one or more whitespace chars followed by the first matched subpattern (the (\w+)  ) followed by an ending word.
Funny isn't it?
But quite useful and powerful!