[Solved] CALL_FUNCTION_UC_STRUCT in PRGN_STRU_SAVE_NODES

SAP Security

Moderators: Snowy, thx4allthefish, jurjen

Post Reply
thx4allthefish
Posts: 5694
Joined: Sat Oct 26, 2002 6:18 pm
Location: barolo barrel

[Solved] CALL_FUNCTION_UC_STRUCT in PRGN_STRU_SAVE_NODES

Post by thx4allthefish » Thu Nov 11, 2010 3:07 am

Yesterday I was copy/pasting an abap out of the Internet, courtesy of Bas Jansen, 2005. This piece of code is supposed to re-build the menu of a composite role by reading all the menus of all the included single roles. As you can see in the link this was somewhere between 2005 and 2007 and Mr. Jansen probably didn't develop this code on a unicode ECC 5.0 - which is why it dumps at me with error:
Runtime Error CALL_FUNCTION_UC_STRUCT
Except. CX_SY_DYN_CALL_ILLEGAL_TYPE
giving the explanation:
An Exquisite Bit of Vogon Poetry wrote:
The reason for the exception is:
In the function "PRGN_STRU_SAVE_NODES" the STRUCTURE parameter
"SOURCE_AGR_TIME" is typed in such a way
that actual parameters are not valid, unless they are compatible
according to the Unicode fragment view. The actual parameter "'X'" does
not, however, have a compatible fragment view.

Excuse me? What ???

I am not an abapper but usually I get along with the little bit of coding that comes my way - but this one has me stunned :shock: I don't even understand what it is trying to tell me, which is why I would be ever so grateful, if you could look the code over and tell me what I will have to change. Thank you in advance.

Here's the code:

Code: Select all

REPORT  ZAGR_REFRESH.

TABLES:
  agr_define.

* DATA Declaration

TYPES: BEGIN OF result,
        agr_define TYPE agr_define.
TYPES: chflag(1) TYPE c,
       END OF result.
TYPES: BEGIN OF role,
        agr_name TYPE agr_name,
       END OF role.

DATA: role TYPE TABLE OF role,
      wa_role LIKE LINE OF role,
      wa2_role LIKE LINE OF role.
DATA:  result TYPE TABLE OF result,
      wa_result TYPE result.

DATA: new_menu_node TYPE TABLE OF agr_shier,
      new_menu_ref TYPE TABLE OF agr_buffi,
      new_menu_text TYPE TABLE OF agr_shiert.

DATA: copy_new_menu_node TYPE TABLE OF agr_hier,
      copy_new_menu_ref TYPE TABLE OF agr_buffi,
      copy_new_menu_text TYPE TABLE OF agr_hiert.

DATA: old_menu_node TYPE TABLE OF agr_hier,
      old_menu_ref TYPE TABLE OF agr_buffi,
      old_menu_text TYPE TABLE OF agr_hiert.

DATA: okcode LIKE sy-ucomm.

*-----------------------------------------------------SELECT-OPTIONS
* Select Options
TABLES sscrfields.
*selection-screen begin of screen.
SELECTION-SCREEN BEGIN OF BLOCK 1 WITH FRAME.
*selection-screen start of line.
SELECTION-SCREEN COMMENT 1(70) text-s01.
SELECTION-SCREEN COMMENT /1(70) text-s02.
SELECTION-SCREEN COMMENT /1(70) text-s03.
*selection-screen end of line.
SELECTION-SCREEN END OF BLOCK 1.
SELECT-OPTIONS: s_role FOR agr_define-agr_name OBLIGATORY.
*selection-screen end of screen.
*-----------------------------------------------------------------

* Start of Selection
START-OF-SELECTION.

  perform select_roles_to_be_changed.

* Now for every composite role find the single roles it consists of,
* find their menu info , delete it's original menu info and insert the
* new one.
  perform find_single_roles.

End-Of-Selection.
  perform write_report.

*&---------------------------------------------------------------------*
*&      Form  select_roles_to_be_changed
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form select_roles_to_be_changed.
*First select all the roles to be changed
  SELECT * FROM agr_define INTO CORRESPONDING FIELDS OF
wa_result-agr_define
              WHERE agr_name IN s_role .
    APPEND wa_result TO result.
  ENDSELECT.
endform.                    " select_roles_to_be_changed

*&---------------------------------------------------------------------*
*&      Form  find_single_roles
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form find_single_roles.
  LOOP AT result INTO wa_result.

    SELECT child_agr FROM agr_agrs INTO table role
                    WHERE agr_name = wa_result-agr_define-agr_name.

    IF sy-subrc NE 0.
*check if this indeed is a compostie role
      wa_result-chflag = 'C'. "for reporting
      MODIFY result FROM wa_result.
      CONTINUE.
    ENDIF.

* in case of an existing masterrole add this too.
    loop at role into wa_role.
      select single parent_agr from agr_define into wa2_role
            where agr_name = wa_role-agr_name.
      if not wa2_role is initial.
        append wa2_role to role.
      endif.
    endloop.
    sort role.
    delete adjacent duplicates from role.
    REFRESH new_menu_node.
    REFRESH new_menu_text.

* For each childrole find the menu node entries and put them in
*new_menu together
    LOOP AT role INTO wa_role.
      perform append_menu_structures.
    ENDLOOP.
    perform write_new_menu.
  ENDLOOP.
endform.                    " find_single_roles

*&---------------------------------------------------------------------*
*&      Form  append_menu_structures
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form append_menu_structures.
  REFRESH copy_new_menu_node.
  REFRESH copy_new_menu_text.

  SELECT * FROM agr_hier INTO TABLE copy_new_menu_node
                WHERE agr_name = wa_role-agr_name.
  SELECT * FROM agr_hiert INTO TABLE copy_new_menu_text
                WHERE agr_name = wa_role-agr_name.

  CALL FUNCTION 'PRGN_STRU_ADD_AGR_TO_NODETAB'
   EXPORTING
     compute_sort_order       = 'X'
* IMPORTING
*   NEW_START_ID             =
    TABLES
      selected_nodes           = copy_new_menu_node
      selected_texts           = copy_new_menu_text
*   SELECTED_URLS            =
      i_nodes                  = new_menu_node
      i_texts                  = new_menu_text.

endform.                    " append_menu_structures
*&---------------------------------------------------------------------*
*&      Form  write_new_menu
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form write_new_menu.
*Now first remove all old entries to prevent double entries in the menu.
  SELECT * FROM agr_hier INTO TABLE old_menu_node
                     WHERE agr_name = wa_result-agr_define-agr_name.

  CALL FUNCTION 'PRGN_DELETE_FOLDERS_AGR_HIER'
    TABLES
      i_nodes_to_process = old_menu_node.

*At the end all the added menu's are saved to the Database.
  CALL FUNCTION 'PRGN_STRU_SAVE_NODES'
    EXPORTING
      activity_group                =  wa_result-agr_define-agr_name
     use_global_tables             = ' '
*   ONLY_SY_LANGU                 = ' '
     authority_check               = 'X'
     enqueue                       = 'X'
 source_agr_time               = 'X'
   TABLES
     menu_hierarchy                = new_menu_node
     menu_texts                    = new_menu_text
   EXCEPTIONS
     not_authorized                = 1
     activity_group_enqueued       = 2
     OTHERS                        = 3
            .
  IF sy-subrc <> 0.
    wa_result-chflag = sy-subrc. "for reporting
    MODIFY result FROM wa_result.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

endform.                    " write_new_menu
*&---------------------------------------------------------------------*
*&      Form  write_report
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form write_report.
  SKIP 5.
  WRITE: / 'Recreated menu for following roles:'.
  WRITE: /40  'Recreated Menu',
        60 'Single role',
        90 'Errors'.
  WRITE: /60      '(no adjustments made)'.
  ULINE.
  SKIP 1.
  LOOP AT result INTO wa_result.
    WRITE / wa_result-agr_define-agr_name.
    CASE wa_result-chflag.
      WHEN '1'.
        WRITE 80 'You have no Authorisation'.
      WHEN '2'.
        WRITE 80 'Role is allready being edited, unable to change'.
      WHEN '3'.
        WRITE 80 'Unspecified Error'.
      WHEN 'C'.
        WRITE 60 'X'.
      WHEN OTHERS.
        WRITE 40 'X'.
    ENDCASE.
  ENDLOOP.
  SKIP 1.
  WRITE:  'total number of roles: ', sy-tfill.
endform.                    " write_report
curiousorange wrote: I give up. Humanity isn't worth saving. Why is there never a Vogon Constructor Fleet around when you really need one?

Baz
Posts: 4748
Joined: Fri Nov 08, 2002 5:54 am
Location: He's out there! somewhere!!!!
Contact:

Re: CALL_FUNCTION_UC_STRUCT in PRGN_STRU_SAVE_NODES

Post by Baz » Thu Nov 11, 2010 3:37 am

Hi Fish

I added the code, compiled it, and it executes in my system!
sorry i can't be of help in this instance...
Baz

AsPiRiNg tUlY iDiOt Image

http://www.catb.org/~esr/faqs/smart-questions.html

Image

check out my Podcasts http://dj-baz.podomatic.com

AndyW
Posts: 70
Joined: Wed Jan 02, 2008 10:27 am
Location: North Norfolk, UK

Re: CALL_FUNCTION_UC_STRUCT in PRGN_STRU_SAVE_NODES

Post by AndyW » Thu Nov 11, 2010 4:20 am

Hi Fish
Try looking at the PRGN_STRU_SAVE_NODES function module in SE37 and note the type that SRC_AGR_TIME has been defined as. Then back in the program define a new variable of that type and assign the value 'X' to it. Then use the variable rather than the 'X' literal in the function call.

Hope all that makes sense - come back if not! We're still on 4.6C and definitely not unicode so I can't be sure this will work but it might be worth a go.

Andy

thx4allthefish
Posts: 5694
Joined: Sat Oct 26, 2002 6:18 pm
Location: barolo barrel

Re: CALL_FUNCTION_UC_STRUCT in PRGN_STRU_SAVE_NODES

Post by thx4allthefish » Thu Nov 11, 2010 5:11 am

Today's hugs go to AndyW :lol:

Add as a data definition:

DATA: wa_agr_time LIKE agr_time.

Later call the function module:

Code: Select all

  CALL FUNCTION 'PRGN_STRU_SAVE_NODES'
    EXPORTING
      activity_group                =  wa_result-agr_define-agr_name
     use_global_tables             = ' '
*   ONLY_SY_LANGU                 = ' '
     authority_check               = 'X'
     enqueue                       = 'X'
*    source_agr_time               = 'X'
     source_agr_time               =  wa_agr_time      <-----
   TABLES
     menu_hierarchy                = new_menu_node
     menu_texts                    = new_menu_text
   EXCEPTIONS
     not_authorized                = 1
     activity_group_enqueued       = 2
     OTHERS                        = 3
Btw.: this report works extremely well and does exactly what it says it does ... I will shadow this in the Security forum, just in case somebody is looking for such a tool.

Thank you for taking the time, AndyW.

Here's the 'new' coding for copy/pasters like me:

Code: Select all


REPORT  ZAGR_REFRESH.

TABLES:
  agr_define.

* DATA Declaration

TYPES: BEGIN OF result,
        agr_define TYPE agr_define.
TYPES: chflag(1) TYPE c,
       END OF result.
TYPES: BEGIN OF role,
        agr_name TYPE agr_name,
       END OF role.

DATA: role TYPE TABLE OF role,
      wa_role LIKE LINE OF role,
      wa2_role LIKE LINE OF role.
DATA:  result TYPE TABLE OF result,
      wa_result TYPE result.

DATA: new_menu_node TYPE TABLE OF agr_shier,
      new_menu_ref TYPE TABLE OF agr_buffi,
      new_menu_text TYPE TABLE OF agr_shiert.

DATA: copy_new_menu_node TYPE TABLE OF agr_hier,
      copy_new_menu_ref TYPE TABLE OF agr_buffi,
      copy_new_menu_text TYPE TABLE OF agr_hiert.

DATA: old_menu_node TYPE TABLE OF agr_hier,
      old_menu_ref TYPE TABLE OF agr_buffi,
      old_menu_text TYPE TABLE OF agr_hiert.

DATA: wa_agr_time LIKE agr_time.

DATA: okcode LIKE sy-ucomm.

*-----------------------------------------------------SELECT-OPTIONS
* Select Options
TABLES sscrfields.
*selection-screen begin of screen.
SELECTION-SCREEN BEGIN OF BLOCK 1 WITH FRAME.
*selection-screen start of line.
SELECTION-SCREEN COMMENT 1(70) text-s01.
SELECTION-SCREEN COMMENT /1(70) text-s02.
SELECTION-SCREEN COMMENT /1(70) text-s03.
*selection-screen end of line.
SELECTION-SCREEN END OF BLOCK 1.
SELECT-OPTIONS: s_role FOR agr_define-agr_name OBLIGATORY.
*selection-screen end of screen.
*-----------------------------------------------------------------

* Start of Selection
START-OF-SELECTION.

  perform select_roles_to_be_changed.

* Now for every composite role find the single roles it consists of,
* find their menu info , delete it's original menu info and insert the
* new one.
  perform find_single_roles.

End-Of-Selection.
  perform write_report.

*&---------------------------------------------------------------------*
*&      Form  select_roles_to_be_changed
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form select_roles_to_be_changed.
*First select all the roles to be changed
  SELECT * FROM agr_define INTO CORRESPONDING FIELDS OF
wa_result-agr_define
              WHERE agr_name IN s_role .
    APPEND wa_result TO result.
  ENDSELECT.
endform.                    " select_roles_to_be_changed

*&---------------------------------------------------------------------*
*&      Form  find_single_roles
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form find_single_roles.
  LOOP AT result INTO wa_result.

    SELECT child_agr FROM agr_agrs INTO table role
                    WHERE agr_name = wa_result-agr_define-agr_name.

    IF sy-subrc NE 0.
*check if this indeed is a compostie role
      wa_result-chflag = 'C'. "for reporting
      MODIFY result FROM wa_result.
      CONTINUE.
    ENDIF.

* in case of an existing masterrole add this too.
    loop at role into wa_role.
      select single parent_agr from agr_define into wa2_role
            where agr_name = wa_role-agr_name.
      if not wa2_role is initial.
        append wa2_role to role.
      endif.
    endloop.
    sort role.
    delete adjacent duplicates from role.
    REFRESH new_menu_node.
    REFRESH new_menu_text.

* For each childrole find the menu node entries and put them in
*new_menu together
    LOOP AT role INTO wa_role.
      perform append_menu_structures.
    ENDLOOP.
    perform write_new_menu.
  ENDLOOP.
endform.                    " find_single_roles

*&---------------------------------------------------------------------*
*&      Form  append_menu_structures
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form append_menu_structures.
  REFRESH copy_new_menu_node.
  REFRESH copy_new_menu_text.

  SELECT * FROM agr_hier INTO TABLE copy_new_menu_node
                WHERE agr_name = wa_role-agr_name.
  SELECT * FROM agr_hiert INTO TABLE copy_new_menu_text
                WHERE agr_name = wa_role-agr_name.

  CALL FUNCTION 'PRGN_STRU_ADD_AGR_TO_NODETAB'
   EXPORTING
     compute_sort_order       = 'X'
* IMPORTING
*   NEW_START_ID             =
    TABLES
      selected_nodes           = copy_new_menu_node
      selected_texts           = copy_new_menu_text
*   SELECTED_URLS            =
      i_nodes                  = new_menu_node
      i_texts                  = new_menu_text.

endform.                    " append_menu_structures
*&---------------------------------------------------------------------*
*&      Form  write_new_menu
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form write_new_menu.
*Now first remove all old entries to prevent double entries in the menu.
  SELECT * FROM agr_hier INTO TABLE old_menu_node
                     WHERE agr_name = wa_result-agr_define-agr_name.

  CALL FUNCTION 'PRGN_DELETE_FOLDERS_AGR_HIER'
    TABLES
      i_nodes_to_process = old_menu_node.

*At the end all the added menu's are saved to the Database.
  CALL FUNCTION 'PRGN_STRU_SAVE_NODES'
    EXPORTING
      activity_group                =  wa_result-agr_define-agr_name
     use_global_tables             = ' '
*   ONLY_SY_LANGU                 = ' '
     authority_check               = 'X'
     enqueue                       = 'X'
*    source_agr_time               = 'X'
     source_agr_time               =  wa_agr_time
   TABLES
     menu_hierarchy                = new_menu_node
     menu_texts                    = new_menu_text
   EXCEPTIONS
     not_authorized                = 1
     activity_group_enqueued       = 2
     OTHERS                        = 3
            .
  IF sy-subrc <> 0.
    wa_result-chflag = sy-subrc. "for reporting
    MODIFY result FROM wa_result.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

endform.                    " write_new_menu
*&---------------------------------------------------------------------*
*&      Form  write_report
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form write_report.
  SKIP 5.
  WRITE: / 'Recreated menu for following roles:'.
  WRITE: /40  'Recreated Menu',
        60 'Single role',
        90 'Errors'.
  WRITE: /60      '(no adjustments made)'.
  ULINE.
  SKIP 1.
  LOOP AT result INTO wa_result.
    WRITE / wa_result-agr_define-agr_name.
    CASE wa_result-chflag.
      WHEN '1'.
        WRITE 80 'You have no Authorisation'.
      WHEN '2'.
        WRITE 80 'Role is allready being edited, unable to change'.
      WHEN '3'.
        WRITE 80 'Unspecified Error'.
      WHEN 'C'.
        WRITE 60 'X'.
      WHEN OTHERS.
        WRITE 40 'X'.
    ENDCASE.
  ENDLOOP.
  SKIP 1.
  WRITE:  'total number of roles: ', sy-tfill.
endform.                    " write_report
curiousorange wrote: I give up. Humanity isn't worth saving. Why is there never a Vogon Constructor Fleet around when you really need one?

AndyW
Posts: 70
Joined: Wed Jan 02, 2008 10:27 am
Location: North Norfolk, UK

Re: [Solved] CALL_FUNCTION_UC_STRUCT in PRGN_STRU_SAVE_NODES

Post by AndyW » Thu Nov 11, 2010 6:03 am

Lucky me! :D

Glad to help - its not often I'm able to 'give back' but I'm getting there!!

Andy

Post Reply