Tuesday 2 March 2021

Function Module to Map a Deep Dictionary Structure : CATSXT_GET_DDIC_FIELDINFO

Having been asked to make some changes in a BADI, I was confronted by SAP Standard Structure MDG_BS_BP_S_EXTERN which is a structure made of lots of other structures. I'd been asked to make changes to content of a field, but it wasn't obvious where in the multi-structure environment the field resided. 

One option was to methodically go through all the structures looking for the relevant one. I thought there must be a way to explode this...

and so function module CATSXT_GET_DDIC_FIELDINFO...

Takes input of MDG_BS_BP_S_EXTERN  (which, if you look at in SE11 just has some structures:)


And explodes to the more realistic 1.6k ish fields:



Wednesday 9 December 2020

Do It Yourself EWB Programming

 So I recently had to perform tasks described in note: https://launchpad.support.sap.com/#/notes/488765 the EWB - Engineering WorkBench... now "Do it yourself" is an interesting Business Model... on the one hand, you're giving people the flexibility to create and craft as they see fit... on the other hand, one might be thinking "Come on SAP, there should be a BAPI there..."

They come close, but it seems not as simple as a BAPI. Why do they not just tie the steps they've described up into a BAPI... like "To make a change, first you need to do the locking, reload, then make the change..."???

Another thing they note is "If you have difficulties using the API, we would like to support you within consulting."

I bet you would.

Anyway, here's some code that removes a Sequence from the "Sequences" part of CA02.


data: ls_plfl type plfl.
PARAMETERS: p_plnal type plnal DEFAULT '01',
            p_plnnr type plnnr DEFAULT 'G0000338',
            p_plnfl type PLNFOLGE DEFAULT '000022',
            p_plnty type plnty DEFAULT 'N'.

START-OF-SELECTION.
select single * from plfl into ls_plfl where plnal = p_plnal
                                        and plnnr = p_plnnr
                                        and plnfl = p_plnfl
                                        and plnty = p_plnty.

 DATA: lt_SEQ_INV            TYPE CPCL_SEQ_VERS_TAB_TYPE,
       lt_SEQ_LOCK           TYPE CPCL_SEQ_LOCK_TAB_TYPE,
       lt_SEQ_IDENT_ECM      TYPE CPCL_SEQ_TAB_TYPE,
       ls_seq_class_data type SEQ_CLASS_DATA.
 DATA: lt_SEQ_IDENT          TYPE CPCL_SEQ_TAB_TYPE,
       ls_seq_ident          type cpcl_seq_ident_type.
MOVE-CORRESPONDING ls_plfl to ls_seq_ident.
append ls_plfl to lt_seq_ident.
CALL FUNCTION 'CP_CL_P_SEQ_LOAD'
  EXPORTING
    I_FLG_SET_LOCK             = 'X'
  IMPORTING
    E_SEQ_INV                  = lt_seq_inv
    E_SEQ_LOCK                 = lt_seq_lock
    E_SEQ_IDENT_ECM            = lt_seq_ident_ecm
  CHANGING
    c_seq_ident                = lt_seq_ident .

 DATA: E_TSK_INV                TYPE CPCL_TSK_VERS_TAB_TYPE,
       E_TSK_LOCK               TYPE CPCL_TSK_LOCK_TAB_TYPE,
       E_TSK_IDENT_LOCK         TYPE CPCL_TSK_TAB_TYPE,
       E_TSK_IDENT_ECM          TYPE CPCL_TSK_TAB_TYPE.
 DATA: lt_TSK_IDENT              TYPE CPCL_TSK_TAB_TYPE,
       ls_TSK_IDENT              TYPE cpcl_tsk_ident_type.
 loop at lt_seq_ident into ls_seq_ident.
   MOVE-CORRESPONDING ls_seq_ident to ls_tsk_ident.
   append ls_tsk_ident to lt_tsk_ident.
 endloop.


CALL FUNCTION 'CP_CL_P_TSK_LOAD'
  IMPORTING
    E_TSK_INV                      = E_TSK_INV
    E_TSK_LOCK                     = E_TSK_LOCK
    E_TSK_IDENT_LOCK               = E_TSK_IDENT_LOCK
    E_TSK_IDENT_ECM                = E_TSK_IDENT_ECM
  CHANGING
    c_tsk_ident                    = lt_tsk_ident
          .


 DATA ls_NAME              TYPE SY-MSGV1.
CALL FUNCTION 'CP_CL_SEQ_LOCK'
  EXPORTING
    PLNTY                    = ls_plfl-plnty
   PLNNR                     = ls_plfl-PLNNR
   PLNAL                     = ls_plfl-PLNAL
   PLNFL                     = ls_plfl-plnfl
    _WAIT                     = ' '
  IMPORTING
    E_NAME                    = ls_NAME
  EXCEPTIONS
    FOREIGN_LOCK              = 1
    SYSTEM_FAILURE            = 2
    OTHERS                    = 3.
MOVE-CORRESPONDING ls_plfl to ls_seq_class_data.
ls_seq_class_data-loekz = 'X'.
 DATA ls_ECM_DATA_ERROR_TYPE TYPE CPCC_MESSAGE_TYPE.
CALL FUNCTION 'CP_CL_S_SEQ_CHANGE'
  EXPORTING
    I_ECN_S                       = ls_plfl-aennr
    i_key_date_s                  = ls_plfl-datuv "sy-datum
    I_FLG_SEQ_CHECK               = ' '                     "default 'X' try switching it off!?
*   I_MARK_TXT_UPDATE             = ' '
    i_seq_class_data              = ls_seq_class_data
    I_FLG_COLLECT_ALL_MSG         = 'X'
  IMPORTING
    E_ECM_DATA_ERROR_TYPE         = ls_ECM_DATA_ERROR_TYPE
  EXCEPTIONS
    SEQUENCE_NOT_CONSISTENT       = 1
    NO_AUTHORITY                  = 2
    NO_VALID_SEQUENCE             = 3
    SEQUENCE_NOT_LOCKED           = 4
    ECM_DATA_NOT_SUITABLE         = 5
    OTHERS                        = 6.

CALL FUNCTION 'CP_CL_P_SEQ_SAVE'
  EXCEPTIONS
    NO_SEQ_TO_SAVE       = 1
    OTHERS               = 2.
commit work and wait.

Wednesday 2 December 2020

PLPO - PLFL link

Okay,  I know the Select * s are inefficient, but makes the code more readable.
Had been struggling to work out what made the Sequence Items in CA02 disappear when we "Delete" one of the lines. Not sure why PLPO doesn't get it's own LOEKZ updated, but hey...

This finds ACTIVE sequence lines for Routings.


PARAMETERSp_plnnr type plnnr DEFAULT '51000070',

            p_vornr type vornr DEFAULT '0010'.

select from plfl into TABLE lt_plfl where plnnr p_plnnr
                                        and loekz ' '.

select from plas into TABLE lt_plas where plnnr p_plnnr .

select from plpo into TABLE lt_plpo where plnnr p_plnnr
                                        and vornr p_vornr.

if lt_plpo is not INITIAL.
  select from crhd into table lt_crhd FOR ALL ENTRIES IN lt_plpo
     where crhd~objid lt_plpo-arbid.
endif.

  loop at lt_plfl into ls_plfl.
     READ TABLE lt_plas into ls_plas with key plnnr ls_plfl-plnnr
                                              plnfl ls_plfl-plnfl.
     if sy-subrc 0.
       READ TABLE lt_plpo into ls_plpo with key plnnr ls_plas-plnnr
                                                plnkn ls_plas-plnkn.
       if sy-subrc 0.
         READ TABLE lt_crhd into ls_crhd with key objid ls_plpo-arbid.
         if sy-subrc 0.
           write:/ ls_plpo-plnnr':' ls_plpo-vornr':' ls_plfl-plnfl':'ls_crhd-arbpl.
         endif.
       endif.
     endif.
  endloop.

Wednesday 26 August 2020

Calling MS-SQL stored procedure from ABAP

My SAP System had to call a stored procedure on a 3rd party MS-SQL database. As suggested by many blogs, I used DBCO to maintain the parameters of the database... (kind of a BASIS job, but anyway...)

Then found I could use the DBCursor mechanism to retrieve to a table... but my 3rd Party guy didn't want to use SELECT statements, he wanted to use a stored procedure.

Turns out you can use DBCursor to select from an Stored Procedure too...

We had to "qualify" the database name, pre-empting the stored procedure (see highlight)



data: ls_output type tty_output,                        "This bit will differ in each Stored Procedure,
      lt_output type TABLE of tty_output.         " so I have not put it in!! 

EXEC SQL.
  CONNECT TO 'CO11' AS 'V'
ENDEXEC.
EXEC SQL.
  SET CONNECTION 'V'
ENDEXEC.
EXEC SQL.
  open dbcursor for
  EXEC [DatabaseName].[dbo].[StoredProcedureName] 700, '2041', 'S1233124'
endexec.
DO.
  EXEC SQL.
    FETCH NEXT dbcursor INTO :ls_output-SerialNumber,
                             :ls_output-MACID
  ENDEXEC.
  IF sy-subrc = 0.
    APPEND ls_output to lt_output.
    clear ls_output.
    CONTINUE.
  else.
   exit.
endif.
enddo.


Monday 11 November 2019

SMARTForms Colour Border Gotcha

This just foxed me for an hour :(

When changing the border colours/widths/settings of a table (or I guess, a window, graphic, whatever) you have to re-create the entire border.

Weirdly, this means you can set the width to 5mm, and the colour to Green, and add a top border...
Then a 3mm brown left border, then a 10 TW lower border...

I was changing widths/colours of existing borders, but not re-creating. So you CAN'T just change them... (MEME ALERT)



Wednesday 2 October 2019

VOFM Copy Routine being ignored!?

I found that using the Modification Assistant meant that the VOFM changes were not registered, but switching it off got the object activated and RV45C601 inserted into the main RV45CNNN program.
Prior to that, I'd been running RV80HGEN and all that jazz, RV45C601 had been created, and had code in it, but because it hadn't been listed / registered / recorded in RV45CNN, it didn't have access to any of the variables and was not called.

Wednesday 10 July 2019

Android "App Not Installed" using Cordova

Okay, so there's a billion reasons why this might occur...

In my case, I managed to fix it by:

Checking the version of the phone [Settings->About Phone->Android Version] - mine was 5.1.1 i.e. Android Lollipop

Googling which SDKs were valid:

Codename
VersionAPI level/NDK release
Marshmallow6.0API level 23
Lollipop5.1API level 22
Lollipop5.0API level 21
KitKat4.4 - 4.4.4API level 19

So I'm shooting for API 22... 

Changing the app\config.xml


Also updated the version: