Thursday, November 7, 2013

ABAP - RFC FM - How to get user's lockdown date from remote system

Sometime is needed to pickup database data from another SAP system. There is not so many options how to do that.

At first is proper to say, try to search for any already existing SAP standard function module, BAPI. In my case I tested various BAPIs as e.g. BAPI_USER_EXISTENCE_CHECK, BAPI_USER_GET_DETAIL. Non of them returns lockdown date. Note, the date of last modification could be, but does not need to be a date of lockdown.

Option RFC_READ_TABLE

One option is to use function module RFC_READ_TABLE. But it is unfortunately flagged as not purpossed for custommer development and it has no official Unicode support. As param you can provide rows of WHERE SQL conditions, what is quite useful. But no bigger SQL query constructions are allowed, furthermore there is a limit of 72 characters for each row condition.
There is very nice article (in German) describing how to get generic data from FM RFC_READ_TABLE. Normally you just obtain data which has to be additionaly parsed.
http://www.tricktresor.de/content/index.php?navID=123&aID=469


Option Remote-Enabled function module

In my case I used custom function module for reading remote db data. It has advantage of generic output and it is quite easy to use. You have everything under control. So lets have a look at some real simple example, reading of lockdown date. At first we need to setup Remote-Enabled function module. You can do it in standard transactions as SE37 or SE80.

Whole real miracle behind is done by ticking of one radion button "Remote-Enabled Module". It fully automatically gives to your FM functionality to call this FM on remote SAP system. The only thing you need is to add DESTINATION parameter to function call.

 


Setup import parameters - do not forget to tick the checkboxes




Setup export parameters - do not forget to tick the checkbox



Now we are getting close to core to source code itself. See the data below. Whenever a new user is created, a new record is placed also into table USH02. If sometime later is user locked, the column UFLAG contains non zero value. But the first record is normally with 0 flag. Local lockdown has value 64, otherwise Global lockdown contains the value 96.



Now, let's see the data. It is clear that after lockdown (in this case local lock) furthermore changes has been done later over user who has been already locked on 4.11. So we are looking for the first non zero value of UFLAG (any lockdown record) which is immediatelly following the last 0 UFLAG record (last non lockdown status).

It is possible to do it by one Open SQL query.

SELECT SINGLE modda FROM ush02
     INTO lockdown_date
     WHERE bname username
     AND   uflag <> 0
     AND   modda >= SELECT MAXmodda FROM ush02 WHERE bname username AND uflag ).


If return date value is empty, we know, there is no record with UFLAG = 0 or any locked. This rare situation could be solved as follows.

  IF lockdown_date IS INITIAL.
    SELECT MINmodda FROM ush02
       INTO lockdown_date
       WHERE bname username
       AND   uflag <> 0.
  ENDIF.



Now we need to add some standard checks and whole miracle is completed.

FUNCTION /YourNameSpace/rfc_get_lockdown_date.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(USERNAME) TYPE  XUBNAME OPTIONAL
*"  EXPORTING
*"     VALUE(LOCKDOWN_DATE) TYPE  D
*"  EXCEPTIONS
*"      PARAM_MISSING
*"      NOT_FOUND
*"      NOT_AUTHORIZED
*"      TABLE_NOT_AVAILABLE
*"----------------------------------------------------------------------

  CLEAR lockdown_date.

  " authority check
  CALL FUNCTION 'VIEW_AUTHORITY_CHECK'
    EXPORTING
      view_action                    'S'
      view_name                      'USH02'
    EXCEPTIONS
      no_authority                   2
      no_clientindependent_authority 2
      no_linedependent_authority     2
      OTHERS                         1.
  IF sy-subrc 2.
    RAISE not_authorized.
  ELSEIF sy-subrc 1.
    RAISE table_not_available.
  ENDIF.

  " check input param
  IF username IS INITIAL.
    RAISE param_missing.
  ENDIF.

  " get date on remote system
  SELECT SINGLE modda FROM ush02
     INTO lockdown_date
     WHERE bname username
     AND   uflag <> 0
     AND   modda >= SELECT MAXmodda FROM ush02 WHERE bname username AND uflag )
     .

  " if user has been created as already locked, it means USH02 has only locked records
  " there is no UFLAG = 0. It is exceptional case.
  IF lockdown_date IS INITIAL.
    SELECT MINmodda FROM ush02
       INTO lockdown_date
       WHERE bname username
       AND   uflag <> 0.
  ENDIF.

  IF sy-subrc NE 0.
    RAISE not_found.
  ENDIF.

ENDFUNCTION.


Do not miss to provide list of used exceptions within FM.




Now whenever you will desire to know when a specific user has been locked out, run function module as follows. That's it.


        CALL FUNCTION '/YourNameSpace/RFC_GET_LOCKDOWN_DATE' DESTINATION gs_uszbvlndrc-rcvsystem
          EXPORTING
            username            lv_username
          IMPORTING
            lockdown_date       lv_lockdown_date
          EXCEPTIONS
            not_authorized      1
            table_not_available 2
            param_missing       3
            not_found           4
            OTHERS              5.
          CASE sy-subrc.
            WHEN 1.
              " no authorization
            WHEN 2.
              " no required table on target system
            WHEN 3.
              " missing input parameter
            WHEN 4.
              " no data came
            WHEN OTHERS.
              " other ugly error
          ENDCASE.










Friday, July 19, 2013

Function modules reading user parameters



There exist a lot of various function modules reading user parameters. So what is useful? I found two of them most useful.

SUSR_GET_USER_DEFAULTS

Returns standard user SAP attributes as user's date format, language, printers etc.

Sample usage:

* Data for user parameter
  DATAlt_users LIKE usdef OCCURS WITH HEADER LINE.
  DATAls_users TYPE usdef.

* Get standard SAP user defaults - due to printer settings
  CALL FUNCTION 'SUSR_GET_USER_DEFAULTS'
    TABLES
      users  lt_users
    EXCEPTIONS
      OTHERS 0.

  READ TABLE lt_users INDEX INTO ls_users.
  " set printer
  IF sy-subrc EQ AND ls_users-spdb 'G' ).
    gs_control_structure-spdb 'X'.
  ENDIF.

There is an example of returned content for FM SUSR_GET_USER_DEFAULTS.





SUSR_USER_PARAMETERS_GET

It gives internal table filled with pairs - Id of parameter (parid) and it's value (parva). Here we speak about custom user parameters set in TPARA table (maintained via SM30).


Insert new user parmeter

transaction SM30, table TPARA



Reading of user parameter



* Get user's custom printing setting
  DATAlt_user_params TYPE ustyp_t_parameters,
              ls_user_param  LIKE LINE OF lt_user_params,
              lv_user TYPE usr02-bname.

* Name of searched parameter id (parid)
  CONSTANTScv_print_colli_usr_param TYPE string VALUE '/YourNameSpace/HU035_P_COLLI'. 


  MOVE sy-uname TO lv_user.

  " get custom user default parameters
  CALL FUNCTION 'SUSR_USER_PARAMETERS_GET'
    EXPORTING
      user_name       lv_user
    TABLES
      user_parameters lt_user_params.

  READ TABLE lt_user_params INTO ls_user_param WITH KEY parid cv_print_colli_usr_param.

  " set checkbox by user parameter
  IF ls_user_param-parva EQ abap_true.
    d1000-printbox 'X'.
  ENDIF.


There is an example of returned content for FM SUSR_USER_PARAMETERS_GET.





Tuesday, July 9, 2013

SAP Smartforms + Zebra printer = QR codes work

Personally I did some research for myself concerning possibilities to print QR codes within SAP Smartforms. The result was not so happy. There is no direct support from SAP for QRs in Smartforms these days, I mean year 2013.

Possible ways are as follows:

  • The solution from third parties 

  Zebra Designer – NiceLabel software
  http://www.nicelabel.com/products#designer

  • OR ??? ...read below...

QR code printing on Zebra printers

I did many various tests and spend enough time with Zebra support as well. My aim was to avoid any third party tools. Solution is finally no so difficult. The answer is Smartforms "Command node" and ZPL language of Zebra printers. 

Wee need following commands:

  • Position of QR on label
Any ZPL II command inserted into smart form via “command node” is not positioned in the end by smartform's window, but by another ZPL command FO e.g. ‘^FO100,100’.
  • Data - QR content
QR code data must be inserted as command node attribute just by one variable (here e.g. GV_QR_ZPL_CODE). I found this SAP info below and it started to work.
  • Avoid
Although many examples on internet uses starting and ending ZPL commands, but in smart forms you have to avoid of usage such a ZPL sequence ^XA… ^XZ, because it starts new label. It means, QR code is then going to be printed on separate label!


Now put everything together

1. Prepare data for QR in Smartform designer



2. Insert command node, that’s all

It could be placed under MAIN window. I used another window just for imagination of position within designer.




The only limitations is lengh for one Command node content. It is up to 200 characters including ZPL. But for many cases it is sufficient.