Advertisement
Guest User

ZTOAD Modification

a guest
Aug 4th, 2015
737
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ABAP 113.44 KB | None | 0 0
  1. *&---------------------------------------------------------------------*
  2. *& Program : ZTOAD
  3. *& Author  : S. Hermann
  4. *& Date    : 13.06.2015
  5. *& Version : 3.0
  6. *& Required: Table ZTOAD
  7. *&---------------------------------------------------------------------*
  8. *& This program allow you to execute query directly on the server
  9. *& 1/ Write your query in the editor window (ABAP SQL)
  10. *& 2/ View the result in ALV window (in case of SELECT query)
  11. *&
  12. *3 Features :
  13. *& The top center pane allow you to write your query in ABAP SQL format.
  14. *= Query can be complex with JOIN, UNION and subqueries. You can write
  15. *= query on several lines. You could also add spaces.
  16. *= To add comment, start the line by * or prefix your comment by "
  17. *&
  18. *& You could write several queries in the query editor, separated by
  19. *= dot ".". To execute one of them, highlight all the wanted query,
  20. *= or just put the cursor anywhere inside the wanted query.
  21. *= By default, the last query is executed.
  22. *&
  23. *& In case of error, you can display generated code to help you to
  24. *= correct your query (only if you have S_DEVELOP access)
  25. *&
  26. *& The top left pane allow you to store your query :
  27. *& - You could save your query to reuse it later
  28. *& - You could share your query : define users, usergroup, all
  29. *& - You could export query into file to reuse it on another server
  30. *&
  31. *& The top right pane display ddic object that is currently used to help
  32. *= you to write the proper query
  33. *& Synergy with ZSPRO program : display tables defined in ZSPRO in the
  34. *= ddic tree
  35. *& Tips : You can search a table in the tree using header clic
  36. *&
  37. *3 Managed queries
  38. *& SELECT, INSERT, UPDATE, DELETE
  39. *&
  40. *3 Select Clause managed
  41. *& SELECT [DISTINCT / SINGLE] select clause
  42. *& FROM from clause
  43. *& [UP TO x ROWS]
  44. *& [WHERE cond1]
  45. *& [GROUP BY fields1]
  46. *& [HAVING cond2]
  47. *& [ORDER BY fields2]
  48. *& [UNION SELECT...]
  49. *&
  50. *& UP TO 100 ROWS added at end of query if forgotten
  51. *&
  52. *& COUNT, AVG, MAX, MIN, SUM are managed
  53. *& DO NOT FORGET SPACE in ( ) of aggregat
  54. *&
  55. *& F1 Help is managed to help you on ABAP SQL Syntax
  56. *&
  57. *3 Insert special syntax
  58. *& In ABAP, insert query is always used with given structure
  59. *& In this SQL editor, you have 2 ways to do an INSERT :
  60. *& - By passing each value, 1 by 1
  61. *E INSERT SEOCLASSTX VALUES ( 'ZZMACLASS', ' ', 'Test claSS' )
  62. *&
  63. *& - By passing value of used fields only
  64. *E INSERT SEOCLASSTX SET CLSNAME = 'ZZMACLASS' DESCRIPT = 'TeSt class'
  65. *&
  66. *3 Sample of query :
  67. *&
  68. *E SELECT SINGLE * FROM VBAP WHERE VBELN = '00412345678'
  69. *&
  70. *E SELECT COUNT( * ) SUBC MAX( PROG ) FROM TRDIR GROUP BY SUBC
  71. *&
  72. *E SELECT VBAK~* from VBAK UP TO 3 ROWS ORDER BY VKORG.
  73. *&
  74. *E SELECT T1~VBELN T2~POSNR FROM VBAk AS T1
  75. *E        JOIN VBAP AS T2 ON T1~VBELN = T2~VBELN
  76. *&
  77. *E INSERT SEOCLASSTX VALUES ( 'ZZMACLASS', ' ', 'Test claSS' )
  78. *&
  79. *E INSERT SEOCLASSTX SET CLSNAME = 'ZZMACLASS' DESCRIPT = 'TeSt class'
  80. *&
  81. *E UPDATE SEOCLASSTX SET DESCRIPT = 'txt' WHERE CLSNAME = 'ZZMACLASS'
  82. *&
  83. *E DELETE SEOCLASSTX WHERE CLSNAME = 'ZZMACLASS'
  84. *&
  85. *& Please send comment & improvements to http://quelquepart.biz
  86. *&---------------------------------------------------------------------*
  87. *& History :
  88. *& 2015.06.13 v3.0  :Add INSERT, UPDATE, DELETE command
  89. *&                   Add Authorization management
  90. *&                   Add History tree display first query line if it
  91. *&                       is a comment line
  92. *&                   Mod Code cleaning
  93. *& 2015.03.05 v2.1.1:Mod grid size is no more changed before display
  94. *&                       query result
  95. *& 2015.01.11 v2.1  :Add UNION instruction managed to merge 2 queries
  96. *&                   Mod Do not refresh result grid for count(*)
  97. *&                   Mod Back close the grid instead of leave program if
  98. *&                       result grid is displayed
  99. *&                   Add Display program header as default help
  100. *&                   Add Run highlighted query
  101. *&                   Mod Documentation rewritten
  102. *& 2014.10.23 v2.0.2:Add Display number of entries found
  103. *&                   Add Confirmation before exit for unsaved queries
  104. *& 2014.10.19 v2.0.1:Fix bug on search ddic function
  105. *& 2014.08.03 v2.0 : Completely rewritten version
  106. *&                   - Save and share queries with colaborators
  107. *&                   - Queries are now saved in database
  108. *&                   - Display tables (+ fields) of the where clause
  109. *&                   - Display ZSPRO entries in ddic tree
  110. *&                   - Allow direct change in query after execution
  111. *&                   - Count( * ) allowed
  112. *&                   - Can display generated code
  113. *&                   - Display query execution time
  114. *&                   - Allow write of several queries (but 1 executed)
  115. *& 2013.12.03 v1.3 : Allow case sensitive constant in where clause
  116. *& 2012.08.30 v1.2 : Rewrite data definition to avoid dump on too long
  117. *&                   fieldname
  118. *& 2012.04.01 v1.1 : Updated to work also on BW system
  119. *& 2009.10.26 v1.0 : Initial release
  120. *&---------------------------------------------------------------------*
  121.  
  122. REPORT ztoad.
  123.  
  124. *######################################################################*
  125. *
  126. *                        CUSTOMIZATION SECTION
  127. *
  128. *######################################################################*
  129. DATA : BEGIN OF s_auth,                                     "#EC NEEDED
  130. * You could define your authorization object to restrict
  131. * function usage by user
  132. * If you dont define auth object, all users will have same access as
  133. * defined bellow
  134. * The auth object must manage 4 IDs.
  135. * ID must be : SELECT, INSERT, UPDATE, DELETE
  136. * FIELD contain allowed table name pattern
  137. * '*' to allow all table, 'Z*' to allow all specific tables...
  138.          auth_object(20) TYPE c VALUE '', "'ZTOAD_AUTH',
  139.  
  140. * Bellow is default AUTH used if no auth_object is defined
  141. * Allow SELECT query on SAP table (restricted by given pattern)
  142.          select TYPE string VALUE '*',
  143. * Allow INSERT query on SAP table (restricted by given pattern)
  144.          insert TYPE string VALUE '*',
  145. * Allow UPDATE query on SAP table (restricted by given pattern)
  146.          update TYPE string VALUE '*',
  147. * Allow DELETE query on SAP table (restricted by given pattern)
  148.          delete TYPE string VALUE 'Z*',
  149.        END OF s_auth.
  150.  
  151. *######################################################################*
  152. *
  153. *                             DATA SECTION
  154. *
  155. *######################################################################*
  156. * Objects
  157. CLASS lcl_application DEFINITION DEFERRED.
  158.  
  159. * Screen objects
  160. DATA : o_handle_event TYPE REF TO lcl_application,
  161.        o_container TYPE REF TO cl_gui_custom_container,
  162.        o_splitter TYPE REF TO cl_gui_splitter_container,
  163.        o_splitter_top TYPE REF TO cl_gui_splitter_container,
  164.        o_container_top TYPE REF TO cl_gui_container,
  165.        o_container_repository TYPE REF TO cl_gui_container,
  166.        o_container_query TYPE REF TO cl_gui_container,
  167.        o_container_ddic TYPE REF TO cl_gui_container,
  168.        o_container_result TYPE REF TO cl_gui_container,
  169.  
  170. * Editor data
  171.        o_textedit TYPE REF TO cl_gui_abapedit,
  172.  
  173. * Repository data
  174.        o_tree_repository TYPE REF TO cl_gui_simple_tree,
  175.        w_dragdrop_handle_tree TYPE i,
  176.        BEGIN OF s_node_repository.
  177.         INCLUDE TYPE treev_node. "mtreesnode.
  178. DATA :  text(100) TYPE c,
  179.         edit(1) TYPE c,
  180.          queryid TYPE ztoad-queryid,
  181.        END OF s_node_repository,
  182.        t_node_repository LIKE TABLE OF s_node_repository,
  183.  
  184. * DDIC data
  185.        o_tree_ddic TYPE REF TO cl_gui_column_tree,
  186.        t_node_ddic TYPE treev_ntab,
  187.        t_item_ddic TYPE TABLE OF mtreeitm,
  188.        o_alv_result TYPE REF TO cl_gui_alv_grid,
  189. * ZSPRO data
  190.        t_node_zspro LIKE t_node_ddic,
  191.        t_item_zspro LIKE t_item_ddic,
  192.  
  193. * Save option
  194.        BEGIN OF s_options,
  195.          name TYPE ztoad-text,
  196.          visibility TYPE ztoad-visibility,
  197.          visibilitygrp TYPE usr02-class,
  198.        END OF s_options,
  199.  
  200. * Keep last loaded id
  201.        w_last_loaded_query TYPE ztoad-queryid.
  202.  
  203. DATA : w_okcode LIKE sy-ucomm.
  204.  
  205. * Global types
  206. TYPES : BEGIN OF ty_fieldlist,
  207.           field TYPE string,
  208.           ref_table TYPE string,
  209.           ref_field TYPE string,
  210.         END OF ty_fieldlist,
  211.         ty_fieldlist_table TYPE STANDARD TABLE OF ty_fieldlist.
  212.  
  213. * Constants
  214. CONSTANTS : c_ddic_col1 TYPE mtreeitm-item_name
  215.                         VALUE 'col1',                       "#EC NOTEXT
  216.             c_ddic_col2 TYPE mtreeitm-item_name
  217.                         VALUE 'col2',                       "#EC NOTEXT
  218.             c_ddic_header TYPE tv_hdrname
  219.                           VALUE 'HierarchyHeader',          "#EC NOTEXT
  220.             c_visibility_all TYPE ztoad-visibility VALUE '2',
  221.             c_visibility_shared TYPE ztoad-visibility VALUE '1',
  222.             c_visibility_my TYPE ztoad-visibility VALUE '0',
  223.             c_nodekey_repo_my TYPE mtreesnode-node_key VALUE 'MY',
  224.             c_nodekey_repo_shared TYPE mtreesnode-node_key
  225.                                   VALUE 'SHARED',
  226.             c_nodekey_repo_history TYPE mtreesnode-node_key
  227.                                    VALUE 'HISTO',
  228.             c_line_max TYPE i VALUE 255,
  229.             c_msg_success TYPE c VALUE 'S',
  230.             c_msg_error TYPE c VALUE 'E',
  231.             c_vers_active TYPE as4local VALUE 'A',
  232.             c_ddic_dtelm TYPE comptype VALUE 'E'.
  233.  
  234. *######################################################################*
  235. *
  236. *                             CLASS SECTION
  237. *
  238. *######################################################################*
  239.  
  240. CLASS lcl_drag_object DEFINITION.
  241.   PUBLIC SECTION.
  242.     DATA node_key TYPE tv_nodekey.
  243.     DATA text TYPE string.
  244. ENDCLASS.                    "lcl_drag_object DEFINITION
  245.  
  246. *----------------------------------------------------------------------*
  247. *       CLASS lcl_application DEFINITION
  248. *----------------------------------------------------------------------*
  249. *       Class to handle application events
  250. *----------------------------------------------------------------------*
  251. CLASS lcl_application DEFINITION FINAL.
  252.   PUBLIC SECTION.
  253.     METHODS :
  254. * Handle F1 call on ABAP editor
  255.                handle_f1_textedit
  256.                    FOR EVENT f1 OF cl_gui_abapedit,
  257. * Handle Header clic on ddic tree
  258.                handle_header_click_ddic
  259.                    FOR EVENT header_click OF cl_gui_column_tree
  260.                    IMPORTING header_name,
  261. * Handle Node double clic on ddic tree
  262.                handle_item_dblclick_ddic
  263.                    FOR EVENT item_double_click OF cl_gui_column_tree
  264.                    IMPORTING node_key,
  265. * Handle context menu display on repository tree
  266.               handle_context_menu_repository
  267.                    FOR EVENT node_context_menu_request
  268.                    OF cl_gui_simple_tree
  269.                      IMPORTING menu,
  270. * Handle context menu clic on repository tree
  271.                handle_context_menu_sel_repo
  272.                    FOR EVENT node_context_menu_select
  273.                    OF cl_gui_simple_tree
  274.                        IMPORTING fcode,
  275. * Handle Node double clic on repository tree
  276.                handle_dblclick_repository
  277.                    FOR EVENT node_double_click OF cl_gui_simple_tree
  278.                    IMPORTING node_key,
  279. * Handle toolbar display on ALV result
  280.                handle_toolbar_result
  281.                    FOR EVENT toolbar OF cl_gui_alv_grid
  282.                    IMPORTING e_object,
  283. * Handle toolbar clic on ALV result
  284.                handle_user_command_result
  285.                    FOR EVENT user_command OF cl_gui_alv_grid
  286.                    IMPORTING e_ucomm,
  287.  
  288.                handle_tree_drag FOR EVENT on_drag OF cl_gui_column_tree
  289.                  IMPORTING node_key item_name drag_drop_object,
  290.                handle_edit_drop FOR EVENT on_drop OF cl_gui_abapedit
  291.                  IMPORTING index line pos dragdrop_object.
  292.  
  293.   PRIVATE SECTION.
  294.     METHODS:
  295.       tree_node_field_get IMPORTING iv_node_key TYPE tv_nodekey
  296.                           RETURNING value(rv_field) TYPE string,
  297.  
  298.       string_blanks_get IMPORTING iv_position TYPE numeric
  299.                         RETURNING value(rv_text) TYPE string,
  300.  
  301.       code_text_insert IMPORTING iv_text TYPE csequence.
  302.  
  303. ENDCLASS.                    "lcl_application DEFINITION
  304.  
  305. *----------------------------------------------------------------------*
  306. *       CLASS LCL_APPLICATION IMPLEMENTATION
  307. *----------------------------------------------------------------------*
  308. *       Class to handle application events                             *
  309. *----------------------------------------------------------------------*
  310. CLASS lcl_application IMPLEMENTATION.
  311. *&---------------------------------------------------------------------*
  312. *&      CLASS lcl_application
  313. *&      METHOD handle_context_menu_repository
  314. *&---------------------------------------------------------------------*
  315. *       Handle context menu display on repository tree
  316. *----------------------------------------------------------------------*
  317.   METHOD handle_context_menu_repository.
  318.     DATA l_node_key TYPE tv_nodekey.
  319.  
  320. * Add Delete option only for own queries
  321.     CALL METHOD o_tree_repository->get_selected_node
  322.       IMPORTING
  323.         node_key = l_node_key.
  324.     READ TABLE t_node_repository INTO s_node_repository
  325.                WITH KEY node_key = l_node_key.
  326.     IF sy-subrc NE 0 OR s_node_repository-edit = space.
  327.       RETURN.
  328.     ENDIF.
  329.  
  330.     CALL METHOD menu->add_function
  331.       EXPORTING
  332.         text  = 'Delete'(m01)
  333.         icon  = '@02@'
  334.         fcode = 'DELETE_QUERY'.
  335.   ENDMETHOD.                    "handle_context_menu_repository
  336.  
  337. *&---------------------------------------------------------------------*
  338. *&      CLASS lcl_application
  339. *&      METHOD handle_context_menu_sel_repo
  340. *&---------------------------------------------------------------------*
  341. *       Handle context menu clic on repository tree
  342. *----------------------------------------------------------------------*
  343.   METHOD handle_context_menu_sel_repo.
  344.     DATA l_node_key TYPE tv_nodekey.
  345. * Delete stored query
  346.     IF fcode = 'DELETE_QUERY'.
  347.       CALL METHOD o_tree_repository->get_selected_node
  348.         IMPORTING
  349.           node_key = l_node_key.
  350.       READ TABLE t_node_repository INTO s_node_repository
  351.                  WITH KEY node_key = l_node_key.
  352.       IF sy-subrc = 0 AND s_node_repository-edit NE space.
  353.         DELETE FROM ztoad WHERE queryid = s_node_repository-queryid.
  354.         IF sy-subrc = 0.
  355.           CALL METHOD o_tree_repository->delete_node
  356.             EXPORTING
  357.               node_key = l_node_key.
  358.           MESSAGE 'Query deleted'(m02) TYPE c_msg_success.
  359.         ELSE.
  360.           MESSAGE 'Error when deleting the query'(m03)
  361.                   TYPE c_msg_success.
  362.         ENDIF.
  363.       ENDIF.
  364.     ENDIF.
  365.   ENDMETHOD.                    "handle_context_menu_sel_repo
  366.  
  367. *&---------------------------------------------------------------------*
  368. *&      CLASS lcl_application
  369. *&      METHOD handle_f1_textedit
  370. *&---------------------------------------------------------------------*
  371. *       Handle F1 call on ABAP editor
  372. *----------------------------------------------------------------------*
  373.   METHOD handle_f1_textedit.
  374.     DATA : lw_cursor_line_from TYPE i,
  375.            lw_cursor_line_to TYPE i,
  376.            lw_cursor_pos_from TYPE i,
  377.            lw_cursor_pos_to TYPE i,
  378.            lw_offset TYPE i,
  379.            lw_length TYPE i,
  380.            lt_query TYPE soli_tab,
  381.            ls_query LIKE LINE OF lt_query,
  382.            lw_sel TYPE string.
  383.  
  384. * Get content of abap edit box
  385.     CALL METHOD o_textedit->get_text
  386.       IMPORTING
  387.         table  = lt_query[]
  388.       EXCEPTIONS
  389.         OTHERS = 1.
  390.  
  391. * Find active query
  392.     CALL METHOD o_textedit->get_selection_pos
  393.       IMPORTING
  394.         from_line = lw_cursor_line_from
  395.         from_pos  = lw_cursor_pos_from
  396.         to_line   = lw_cursor_line_to
  397.         to_pos    = lw_cursor_pos_to.
  398.  
  399.     READ TABLE lt_query INTO ls_query INDEX lw_cursor_line_from.
  400.     IF lw_cursor_line_from = lw_cursor_line_to.
  401.       IF lw_cursor_pos_to <> lw_cursor_pos_from.
  402.         lw_length = lw_cursor_pos_to - lw_cursor_pos_from.
  403.         lw_offset = lw_cursor_pos_from - 1.
  404.         lw_sel = ls_query+lw_offset(lw_length).
  405.       ENDIF.
  406.     ELSE.
  407.       lw_offset = lw_cursor_pos_from - 1.
  408.       lw_sel = ls_query+lw_offset.
  409.     ENDIF.
  410.     CALL FUNCTION 'ABAP_DOCU_START'
  411.       EXPORTING
  412.         word = lw_sel.
  413.   ENDMETHOD.                    "handle_f1_textedit
  414.  
  415. *&---------------------------------------------------------------------*
  416. *&      CLASS lcl_application
  417. *&      METHOD handle_header_click_ddic
  418. *&---------------------------------------------------------------------*
  419. *       Handle Header clic on ddic tree :
  420. *       - Refresh tree on click on first column header
  421. *       - Search term on click on second column header
  422. *----------------------------------------------------------------------*
  423.   METHOD handle_header_click_ddic.
  424.     DATA : lw_query TYPE string,
  425.            lw_query2 TYPE string,
  426.            lw_select TYPE string,
  427.            lw_from TYPE string,
  428.            lw_from2 TYPE string,
  429.            lw_where TYPE string,
  430.            lw_union TYPE string,
  431.            lw_rows(6) TYPE n,
  432.            ls_sval TYPE sval,
  433.            lt_sval LIKE TABLE OF ls_sval,
  434.            lw_returncode TYPE c,
  435.            lw_search TYPE string,
  436.            lt_search LIKE TABLE OF lw_search,
  437.            ls_item_ddic LIKE LINE OF t_item_ddic,
  438.            lw_search_term TYPE string,
  439.            lw_search_line TYPE i,
  440.            lw_rest TYPE i,
  441.            lw_node_key TYPE tv_nodekey,
  442.            lt_nodekey TYPE TABLE OF tv_nodekey,
  443.            lw_noauth(1) TYPE c.
  444.  
  445. * For column 1 click => Refresh tree
  446.     IF header_name = c_ddic_header OR header_name = c_ddic_col1.
  447. * Get only usefull code for current query
  448.       PERFORM get_query USING space CHANGING lw_query.
  449.  
  450. * Parse Query
  451.       PERFORM parse_query USING lw_query
  452.                           CHANGING lw_select lw_from lw_where
  453.                                    lw_union lw_rows lw_noauth.
  454.       IF lw_noauth NE space.
  455.         RETURN.
  456.       ELSEIF lw_select IS INITIAL.
  457.         PERFORM parse_query_noselect USING lw_query
  458.                                      CHANGING lw_noauth lw_select
  459.                                               lw_from lw_where.
  460.         IF lw_noauth NE space.
  461.           RETURN.
  462.         ENDIF.
  463.       ENDIF.
  464. * Manage unioned queries
  465.       WHILE NOT lw_union IS INITIAL.
  466. * Parse Query
  467.         lw_query2 = lw_union.
  468.         PERFORM parse_query USING lw_query2
  469.                             CHANGING lw_select lw_from2 lw_where
  470.                                      lw_union lw_rows lw_noauth.
  471.         IF NOT lw_from2 IS INITIAL.
  472.           CONCATENATE lw_from 'JOIN' lw_from2
  473.                       INTO lw_from SEPARATED BY space.
  474.         ENDIF.
  475.         IF lw_noauth NE space.
  476.           RETURN.
  477.         ENDIF.
  478.       ENDWHILE.
  479.  
  480. * Refresh ddic tree with list of table/fields of the actual query
  481.       PERFORM set_ddic_tree USING lw_from.
  482. * For column 2 click => Search in description
  483.     ELSE.
  484. * Build search table
  485.       REFRESH lt_search.
  486.       LOOP AT t_item_ddic INTO ls_item_ddic.
  487.         lw_search = ls_item_ddic-text.
  488.         APPEND lw_search TO lt_search.
  489.         APPEND ls_item_ddic-node_key TO lt_nodekey.
  490.       ENDLOOP.
  491.  
  492. * Ask for selection search
  493.       ls_sval-tabname = 'RSDXX'.
  494.       ls_sval-fieldname = 'FINDSTR'.
  495.       ls_sval-value = space.
  496.       APPEND ls_sval TO lt_sval.
  497.       DO.
  498.         CALL FUNCTION 'POPUP_GET_VALUES'
  499.           EXPORTING
  500.             popup_title     = space
  501.           IMPORTING
  502.             returncode      = lw_returncode
  503.           TABLES
  504.             fields          = lt_sval
  505.           EXCEPTIONS
  506.             error_in_fields = 1
  507.             OTHERS          = 2.
  508.         IF sy-subrc NE 0 OR lw_returncode NE space.
  509.           EXIT. "exit do
  510.         ENDIF.
  511.         READ TABLE lt_sval INTO ls_sval INDEX 1.
  512.         IF ls_sval-value = space.
  513.           EXIT. "exit do
  514.         ENDIF.
  515.  
  516. * For new search, start from line 1
  517.         IF lw_search_term NE ls_sval-value.
  518.           lw_search_term = ls_sval-value.
  519.           lw_search_line = 1.
  520. * For next result of same search, start from next line
  521.         ELSE.
  522.           lw_rest = lw_search_line MOD 2.
  523.           lw_search_line = lw_search_line + 1 + lw_rest.
  524.         ENDIF.
  525.  
  526.         FIND FIRST OCCURRENCE OF ls_sval-value IN TABLE lt_search
  527.              FROM lw_search_line
  528.              IN CHARACTER MODE IGNORING CASE
  529.              MATCH LINE lw_search_line
  530.              .
  531.  
  532. * Search string &1 not found
  533.         IF sy-subrc NE 0 AND lw_search_line = 1.
  534.           MESSAGE s065(0k) WITH lw_search_term DISPLAY LIKE c_msg_error.
  535.           CLEAR lw_search_line.
  536.           CLEAR lw_search_term.
  537.  
  538. * Last selected entry reached
  539.         ELSEIF sy-subrc NE 0.
  540.           MESSAGE s066(0k) DISPLAY LIKE c_msg_error.
  541.           CLEAR lw_search_line.
  542.           CLEAR lw_search_term.
  543.  
  544. * Found
  545.         ELSE.
  546.           MESSAGE 'String found'(m04) TYPE c_msg_success.
  547.           READ TABLE lt_nodekey INTO lw_node_key INDEX lw_search_line.
  548.           CALL METHOD o_tree_ddic->set_selected_node
  549.             EXPORTING
  550.               node_key = lw_node_key.
  551.           CALL METHOD o_tree_ddic->ensure_visible
  552.             EXPORTING
  553.               node_key = lw_node_key.
  554.         ENDIF.
  555.  
  556.       ENDDO.
  557.     ENDIF.
  558.   ENDMETHOD.                    "handle_header_click_ddic
  559.  
  560. *&---------------------------------------------------------------------*
  561. *&      CLASS lcl_application
  562. *&      METHOD handle_item_dblclick_ddic
  563. *&---------------------------------------------------------------------*
  564. *       Handle Node double clic on ddic tree
  565. *----------------------------------------------------------------------*
  566.   METHOD handle_item_dblclick_ddic.
  567.     DATA : lw_message TYPE string,
  568.            lw_subrc TYPE i,
  569.            lw_data(75) TYPE c,
  570.            lt_data LIKE TABLE OF lw_data.                   "#EC NEEDED
  571.  
  572.     lw_data = tree_node_field_get( node_key ).
  573.     IF lw_data IS NOT INITIAL.
  574.       code_text_insert( lw_data ).
  575.  
  576.       APPEND lw_data TO lt_data.
  577.       CALL METHOD cl_gui_frontend_services=>clipboard_export
  578.         IMPORTING
  579.           data = lt_data
  580.         CHANGING
  581.           rc   = lw_subrc.
  582.  
  583.       CONCATENATE lw_data 'sent to clipboard'(m27)
  584.                   INTO lw_message SEPARATED BY space.
  585.       MESSAGE lw_message TYPE c_msg_success.
  586.     ENDIF.
  587.   ENDMETHOD.                    "handle_item_dblclick_ddic
  588.  
  589. *&---------------------------------------------------------------------*
  590. *&      CLASS lcl_application
  591. *&      METHOD handle_dblclick_repository
  592. *&---------------------------------------------------------------------*
  593. *       Handle Node double clic on repository tree
  594. *----------------------------------------------------------------------*
  595.   METHOD handle_dblclick_repository.
  596.     DATA lt_query TYPE TABLE OF string.
  597.     READ TABLE t_node_repository INTO s_node_repository
  598.                WITH KEY node_key = node_key.
  599.     IF sy-subrc = 0 AND NOT s_node_repository-relatkey IS INITIAL.
  600.       PERFORM load_query USING s_node_repository-queryid
  601.                          CHANGING lt_query.
  602.  
  603.       CALL METHOD o_textedit->set_text
  604.         EXPORTING
  605.           table  = lt_query
  606.         EXCEPTIONS
  607.           OTHERS = 0.
  608.  
  609.       o_handle_event->handle_header_click_ddic( c_ddic_header ).
  610.     ENDIF.
  611.   ENDMETHOD. "handle_dblclick_repository
  612.  
  613. *&---------------------------------------------------------------------*
  614. *&      CLASS lcl_application
  615. *&      METHOD handle_toolbar_result
  616. *&---------------------------------------------------------------------*
  617. *       Handle grid toolbar to add specific button
  618. *----------------------------------------------------------------------*
  619.   METHOD handle_toolbar_result.
  620.     DATA: ls_toolbar  TYPE stb_button.
  621.  
  622. * Add Separator
  623.     CLEAR ls_toolbar.
  624.     ls_toolbar-function = '&&SEP99'.
  625.     ls_toolbar-butn_type = 3.
  626.     APPEND ls_toolbar TO e_object->mt_toolbar.
  627.  
  628. * Add button to close the grid
  629.     CLEAR ls_toolbar.
  630.     ls_toolbar-function = 'CLOSE_GRID'.
  631.     ls_toolbar-icon = '@3X@'.
  632.     ls_toolbar-quickinfo = 'Close Grid'(m05).
  633.     ls_toolbar-text = 'Close'(m06).
  634.     ls_toolbar-butn_type = 0.
  635.     ls_toolbar-disabled = space.
  636.     APPEND ls_toolbar TO e_object->mt_toolbar.
  637.   ENDMETHOD.                    "handle_toolbar_result
  638.  
  639. *&---------------------------------------------------------------------*
  640. *&      CLASS lcl_application
  641. *&      METHOD handle_user_command
  642. *&---------------------------------------------------------------------*
  643. *       Handle grid user command to manage specific fcode
  644. *       (menus & toolbar)
  645. *----------------------------------------------------------------------*
  646.   METHOD handle_user_command_result.
  647.     IF e_ucomm = 'CLOSE_GRID'.
  648.       CALL METHOD o_splitter->set_row_height
  649.         EXPORTING
  650.           id     = 1
  651.           height = 100.
  652.     ENDIF.
  653.   ENDMETHOD. "handle_user_command_result
  654.  
  655.   METHOD handle_tree_drag.
  656.     DATA lo_drag_object TYPE REF TO lcl_drag_object.
  657.  
  658.     CREATE OBJECT lo_drag_object.
  659.     lo_drag_object->node_key = node_key.
  660.     lo_drag_object->text = tree_node_field_get( node_key ).
  661.     drag_drop_object->object = lo_drag_object.
  662.  
  663.   ENDMETHOD.                    "handle_tree_drag
  664.  
  665.   METHOD handle_edit_drop.
  666.  
  667.     DATA lo_drag_object TYPE REF TO lcl_drag_object.
  668.  
  669.     lo_drag_object ?= dragdrop_object->object.
  670.     code_text_insert( lo_drag_object->text ).
  671.  
  672.   ENDMETHOD.                    "HANDLE_EDIT_DROP
  673.  
  674.   METHOD tree_node_field_get.
  675.     DATA : ls_item LIKE LINE OF t_item_ddic,
  676.            ls_node LIKE LINE OF t_node_ddic,
  677.            ls_item_parent LIKE LINE OF t_item_ddic,
  678.            lw_table TYPE string,
  679.            lw_alias TYPE string.
  680.  
  681.     CLEAR rv_field.
  682.  
  683.     READ TABLE t_node_ddic INTO ls_node
  684.                WITH KEY node_key = iv_node_key.
  685.     IF sy-subrc NE 0 OR ls_node-isfolder = abap_true.
  686.       RETURN.
  687.     ENDIF.
  688.  
  689.     READ TABLE t_item_ddic INTO ls_item
  690.                WITH KEY node_key = iv_node_key
  691.                         item_name = c_ddic_col1.
  692.  
  693.     READ TABLE t_item_ddic INTO ls_item_parent
  694.                WITH KEY node_key = ls_node-relatkey
  695.                         item_name = c_ddic_col1.
  696.  
  697.     SPLIT ls_item_parent-text AT ' AS ' INTO lw_table lw_alias.
  698.     IF NOT lw_alias IS INITIAL.
  699.       lw_table = lw_alias.
  700.     ENDIF.
  701.  
  702.     CONCATENATE lw_table '~' ls_item-text INTO rv_field.
  703.   ENDMETHOD.                    "tree_node_field_get
  704.  
  705.   METHOD string_blanks_get.
  706.     DATA: lv_blanks TYPE i.
  707.  
  708.     CLEAR rv_text.
  709.  
  710.     lv_blanks = iv_position - 1.
  711.     DO lv_blanks TIMES.
  712.       CONCATENATE rv_text space INTO rv_text RESPECTING BLANKS.
  713.     ENDDO.
  714.  
  715.   ENDMETHOD.                    "string_blanks_get
  716.  
  717.   METHOD code_text_insert.
  718.  
  719.     DATA: lt_text TYPE string_table,
  720.           lv_text TYPE string,
  721.           lv_line TYPE i,
  722.           lv_line_end TYPE i,
  723.           lv_pos TYPE i,
  724.           lv_pos_end TYPE i.
  725.  
  726.     o_textedit->get_selection_pos(
  727.        IMPORTING
  728.          from_line              = lv_line    " line from which selection starts
  729.          from_pos               = lv_pos    " starting position of selection in line linefrom
  730.          to_line                = lv_line_end    " line at which selection ends
  731.          to_pos                 = lv_pos_end    " end position of selection within line lineto
  732. *      EXCEPTIONS
  733. *        error_cntl_call_method = 1
  734. *        others                 = 2
  735.     ).
  736.  
  737. *   If text is selected/highlighted - First delete text
  738. *   (Text should be replaced)
  739.     IF lv_line <> lv_line_end OR
  740.        lv_pos <> lv_pos_end.
  741.       o_textedit->delete_text(
  742.         EXPORTING
  743.           from_line = lv_line    " from line
  744.           from_pos  = lv_pos    " from position
  745.           to_line   = lv_line_end    " to line
  746.           to_pos    = lv_pos_end    " to position
  747.       ).
  748.     ENDIF.
  749.  
  750. *   Set text with new line
  751.     lv_text = iv_text.
  752.     APPEND lv_text TO lt_text.
  753.     lv_text = string_blanks_get( lv_pos ).
  754.     APPEND lv_text TO lt_text.
  755.  
  756.     o_textedit->insert_block_at_position(
  757.       EXPORTING
  758.         line     = lv_line
  759.         pos      = lv_pos
  760.         text_tab = lt_text
  761. *     EXCEPTIONS
  762. *       error_dp = 1
  763. *       others   = 2
  764.     ).
  765.  
  766. *   Set focus in new line
  767.     lv_line = lv_line + 1.
  768.     o_textedit->set_selection_pos_in_line(
  769.       EXPORTING
  770.         line                   = lv_line    " line number
  771.          pos                   = lv_pos
  772. *     EXCEPTIONS
  773. *       error_cntl_call_method = 1
  774. *       others                 = 2
  775.     ).
  776.  
  777.     cl_gui_control=>set_focus(
  778.       EXPORTING
  779.         control           = o_textedit    " Control
  780. *     EXCEPTIONS
  781. *       cntl_error        = 1
  782. *       cntl_system_error = 2
  783. *       others            = 3
  784.     ).
  785.  
  786.   ENDMETHOD.                    "code_text_add
  787.  
  788. ENDCLASS.                    "lcl_application IMPLEMENTATION
  789.  
  790.  
  791. *######################################################################*
  792. *
  793. *                             MAIN SECTION
  794. *
  795. *######################################################################*
  796. START-OF-SELECTION.
  797.   CALL SCREEN 100.
  798.  
  799.  
  800. *######################################################################*
  801. *
  802. *                             PBO SECTION
  803. *
  804. *######################################################################*
  805. *&---------------------------------------------------------------------*
  806. *&      Module  STATUS_0100  OUTPUT
  807. *&---------------------------------------------------------------------*
  808. *       Set status for main screen
  809. *       and initialize custom container at first run
  810. *----------------------------------------------------------------------*
  811. MODULE status_0100 OUTPUT.
  812. * Initialization of object screen
  813.   IF o_container IS INITIAL.
  814.     PERFORM init_screen.
  815.   ENDIF.
  816.  
  817.   AUTHORITY-CHECK OBJECT 'S_DEVELOP' ID 'ACTVT' FIELD '03'
  818.                                      ID 'DEVCLASS' DUMMY
  819.                                      ID 'OBJTYPE' DUMMY
  820.                                      ID 'OBJNAME' DUMMY
  821.                                      ID 'P_GROUP' DUMMY.
  822.   IF sy-subrc = 0.
  823.     SET PF-STATUS 'STATUS100'.
  824.   ELSE.
  825. * If you dont have S_DEVELOP access in display, you probably dont
  826. * understand the code generated => do not display the button
  827.     SET PF-STATUS 'STATUS100' EXCLUDING 'SHOWCODE'.
  828.   ENDIF.
  829.   SET TITLEBAR 'STATUS100'.
  830.  
  831. ENDMODULE.                 " STATUS_0100  OUTPUT
  832.  
  833. *&---------------------------------------------------------------------*
  834. *&      Module  STATUS_0200  OUTPUT
  835. *&---------------------------------------------------------------------*
  836. *       Set status for modal box (save options)
  837. *----------------------------------------------------------------------*
  838. MODULE status_0200 OUTPUT.
  839.  
  840. * Fill dropdown listbox with values
  841.   PERFORM init_listbox_0200.
  842.  
  843.   SET PF-STATUS 'STATUS200'.
  844.   SET TITLEBAR 'STATUS200'.
  845.  
  846. ENDMODULE.                 " STATUS_0200  OUTPUT
  847.  
  848.  
  849. *######################################################################*
  850. *
  851. *                             PAI SECTION
  852. *
  853. *######################################################################*
  854.  
  855. *&---------------------------------------------------------------------*
  856. *&      Module  USER_COMMAND_0200  INPUT
  857. *&---------------------------------------------------------------------*
  858. *       PAI module for modal box (save options)
  859. *----------------------------------------------------------------------*
  860. MODULE user_command_0200 INPUT.
  861.   CASE w_okcode.
  862.     WHEN 'CLOSE'.
  863.       CLEAR s_options.
  864.       LEAVE TO SCREEN 0.
  865.     WHEN 'OK'.
  866.       LEAVE TO SCREEN 0.
  867.   ENDCASE.
  868. ENDMODULE.                 " USER_COMMAND_0200  INPUT
  869.  
  870. *&---------------------------------------------------------------------*
  871. *&      Module  USER_COMMAND_0100  INPUT
  872. *&---------------------------------------------------------------------*
  873. *       User command for main screen
  874. *----------------------------------------------------------------------*
  875. MODULE user_command_0100 INPUT.
  876.  
  877.   CASE w_okcode.
  878.     WHEN 'EXIT'.
  879.       PERFORM exit_program.
  880.     WHEN 'EXECUTE'.
  881.       PERFORM process_query USING space.
  882.     WHEN 'SAVE'.
  883.       PERFORM save_query.
  884.     WHEN 'SHOWCODE'.
  885.       PERFORM process_query USING abap_true.
  886.     WHEN 'HELP'.
  887.       PERFORM display_help.
  888.   ENDCASE.
  889. ENDMODULE.                 " USER_COMMAND_0100  INPUT
  890.  
  891. *######################################################################*
  892. *
  893. *                             FORM SECTION
  894. *
  895. *######################################################################*
  896.  
  897. *&---------------------------------------------------------------------*
  898. *&      Form  INIT_SCREEN
  899. *&---------------------------------------------------------------------*
  900. *       Initialize all objects on the screen
  901. *----------------------------------------------------------------------*
  902. FORM init_screen.
  903. * Create the handle object (required to catch events)
  904.   CREATE OBJECT o_handle_event.
  905.  
  906. * Split the screen into 4 parts
  907.   PERFORM init_splitter.
  908.  
  909. * Init History Tree
  910.   PERFORM init_repository.
  911.  
  912. * Init DDic tree
  913.   PERFORM init_ddic.
  914.  
  915. * Init Query editor
  916.   PERFORM init_editor.
  917.  
  918. * Init ALV result object
  919.   PERFORM init_result.
  920.  
  921. ENDFORM.                    " INIT_SCREEN
  922.  
  923. *&---------------------------------------------------------------------*
  924. *&      Form  INIT_SPLITTER
  925. *&---------------------------------------------------------------------*
  926. *       Split the main screen in 2 lines
  927. * 1 line with 3 columns : Repository tree / Query code / Ddic tree
  928. * 1 line with ALV result
  929. *----------------------------------------------------------------------*
  930. FORM init_splitter.
  931. * Create the custom container
  932.   CREATE OBJECT o_container
  933.     EXPORTING
  934.       container_name = 'CUSTCONT'.
  935.  
  936. * Insert splitter into this container
  937.   CREATE OBJECT o_splitter
  938.     EXPORTING
  939.       parent  = o_container
  940.       rows    = 2
  941.       columns = 1.
  942.  
  943. * Get the first row of the main splitter
  944.   CALL METHOD o_splitter->get_container
  945.     EXPORTING
  946.       row       = 1
  947.       column    = 1
  948.     RECEIVING
  949.       container = o_container_top.
  950.  
  951. *  Spliter for the high part (first row)
  952.   CREATE OBJECT o_splitter_top
  953.     EXPORTING
  954.       parent  = o_container_top
  955.       rows    = 1
  956.       columns = 3.
  957.  
  958. * Affect an object to each "cell" of the high sub splitter
  959.   CALL METHOD o_splitter_top->get_container
  960.     EXPORTING
  961.       row       = 1
  962.       column    = 1
  963.     RECEIVING
  964.       container = o_container_repository.
  965.  
  966.   CALL METHOD o_splitter_top->get_container
  967.     EXPORTING
  968.       row       = 1
  969.       column    = 2
  970.     RECEIVING
  971.       container = o_container_query.
  972.  
  973.   CALL METHOD o_splitter_top->get_container
  974.     EXPORTING
  975.       row       = 1
  976.       column    = 3
  977.     RECEIVING
  978.       container = o_container_ddic.
  979.  
  980.   CALL METHOD o_splitter->get_container
  981.     EXPORTING
  982.       row       = 2
  983.       column    = 1
  984.     RECEIVING
  985.       container = o_container_result.
  986.  
  987. * Initial repartition :
  988. *   line 1 = 100% (code+repo+ddic)
  989. *   line 2 = 0% (result)
  990. *   line 1 col 1 & 3 = 20% (repo & ddic)
  991. *   line 1 col 2 = 60% (code)
  992.   CALL METHOD o_splitter->set_row_height
  993.     EXPORTING
  994.       id     = 1
  995.       height = 100.
  996.  
  997.   CALL METHOD o_splitter_top->set_column_width
  998.     EXPORTING
  999.       id    = 1
  1000.       width = 20.
  1001.   CALL METHOD o_splitter_top->set_column_width
  1002.     EXPORTING
  1003.       id    = 3
  1004.       width = 20.
  1005.  
  1006. ENDFORM.                    " INIT_SPLITTER
  1007.  
  1008. *&---------------------------------------------------------------------*
  1009. *&      Form  INIT_EDITOR
  1010. *&---------------------------------------------------------------------*
  1011. *       Initialize the sql editor object
  1012. *       Fill it with last query, or template if no previous query
  1013. *----------------------------------------------------------------------*
  1014. FORM init_editor.
  1015.   DATA : lt_events TYPE cntl_simple_events,
  1016.          ls_event TYPE cntl_simple_event,
  1017.          lt_default TYPE TABLE OF string,
  1018.          lw_queryid TYPE ztoad-queryid.
  1019.  
  1020.   DATA: lo_dragrop TYPE REF TO cl_dragdrop.
  1021.  
  1022. * Get last query used
  1023.   CONCATENATE sy-uname '#%' INTO lw_queryid.
  1024.   SELECT queryid
  1025.          INTO lw_queryid
  1026.          FROM ztoad
  1027.          UP TO 1 ROWS
  1028.          WHERE queryid LIKE lw_queryid
  1029.          AND owner = sy-uname
  1030.          ORDER BY aedat DESCENDING.
  1031.   ENDSELECT.
  1032.   IF sy-subrc = 0.
  1033.     PERFORM load_query USING lw_queryid
  1034.                        CHANGING lt_default.
  1035.     PERFORM focus_repository USING lw_queryid.
  1036.   ENDIF.
  1037.  
  1038. * If no last query found, use default template
  1039.   IF lt_default IS INITIAL.
  1040.     APPEND 'SELECT *' TO lt_default.                        "#EC NOTEXT
  1041.     APPEND 'FROM xxx' TO lt_default.                        "#EC NOTEXT
  1042.     APPEND 'UP TO 100 ROWS' TO lt_default.                  "#EC NOTEXT
  1043.     APPEND 'WHERE xxx' TO lt_default.                       "#EC NOTEXT
  1044.     APPEND '.' TO lt_default.                               "#EC NOTEXT
  1045.   ENDIF.
  1046.  
  1047. * Create the sql editor
  1048.   CREATE OBJECT o_textedit
  1049.     EXPORTING
  1050.       parent = o_container_query.
  1051.  
  1052. * Register events
  1053.   SET HANDLER o_handle_event->handle_f1_textedit FOR o_textedit.
  1054.   SET HANDLER o_handle_event->handle_edit_drop FOR o_textedit.
  1055.  
  1056.   ls_event-eventid = cl_gui_textedit=>event_f1.
  1057.   APPEND ls_event TO lt_events.
  1058.  
  1059.   CALL METHOD o_textedit->set_registered_events
  1060.     EXPORTING
  1061.       events                    = lt_events
  1062.     EXCEPTIONS
  1063.       cntl_error                = 1
  1064.       cntl_system_error         = 2
  1065.       illegal_event_combination = 3.
  1066.  
  1067.   IF sy-subrc <> 0.
  1068.     IF sy-msgno IS NOT INITIAL.
  1069.       MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
  1070.               DISPLAY LIKE c_msg_error
  1071.               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 .
  1072.     ENDIF.
  1073.   ENDIF.
  1074.  
  1075.   CREATE OBJECT lo_dragrop.
  1076.   CALL METHOD lo_dragrop->add
  1077.     EXPORTING
  1078.       flavor     = 'EDIT_INSERT'
  1079.       dragsrc    = ' '
  1080.       droptarget = 'X'
  1081.       effect     = cl_dragdrop=>copy.
  1082.   CALL METHOD o_textedit->set_dragdrop
  1083.     EXPORTING
  1084.       dragdrop = lo_dragrop.
  1085.  
  1086. * Set Default template
  1087.   CALL METHOD o_textedit->set_text
  1088.     EXPORTING
  1089.       table  = lt_default
  1090.     EXCEPTIONS
  1091.       OTHERS = 0.
  1092.  
  1093. * Set focus
  1094.   CALL METHOD o_textedit->set_focus
  1095.     EXPORTING
  1096.       control = o_textedit
  1097.     EXCEPTIONS
  1098.       OTHERS  = 0.
  1099.  
  1100.   o_handle_event->handle_header_click_ddic( c_ddic_header ).
  1101.  
  1102. ENDFORM.                    " INIT_EDITOR
  1103.  
  1104. *&---------------------------------------------------------------------*
  1105. *&      Form  process_query
  1106. *&---------------------------------------------------------------------*
  1107. *       Process selected query : execute or display code
  1108. *----------------------------------------------------------------------*
  1109. *      -->FP_DISPLAY : Flag abap_true to display code
  1110. *----------------------------------------------------------------------*
  1111. FORM process_query USING fp_display TYPE c.
  1112.   DATA : lw_query TYPE string,
  1113.          lw_select TYPE string,
  1114.          lw_from TYPE string,
  1115.          lw_where TYPE string,
  1116.          lw_union TYPE string,
  1117.          lw_query2 TYPE string,
  1118.          lw_command TYPE string,
  1119.          lw_rows(6) TYPE n,
  1120.          lw_program TYPE sy-repid,
  1121.          lo_result TYPE REF TO data,
  1122.          lo_result2 TYPE REF TO data,
  1123.          lt_fieldlist TYPE ty_fieldlist_table,
  1124.          lt_fieldlist2 TYPE ty_fieldlist_table,
  1125.          lw_count_only(1) TYPE c,
  1126.          lw_time TYPE p LENGTH 8 DECIMALS 2,
  1127.          lw_time2 LIKE lw_time,
  1128.          lw_count TYPE i,
  1129.          lw_count2 LIKE lw_count,
  1130.          lw_charnumb(12) TYPE c,
  1131.          lw_msg TYPE string,
  1132.          lw_noauth(1) TYPE c,
  1133.          lw_answer(1) TYPE c.
  1134.  
  1135.   FIELD-SYMBOLS : <lft_data> TYPE STANDARD TABLE,
  1136.                   <lft_data2> TYPE STANDARD TABLE.
  1137.  
  1138. * Get only usefull code for current query
  1139.   PERFORM get_query USING space CHANGING lw_query.
  1140.  
  1141. * Parse SELECT Query
  1142.   PERFORM parse_query USING lw_query
  1143.                       CHANGING lw_select lw_from lw_where
  1144.                                lw_union lw_rows lw_noauth.
  1145. * Not a select query
  1146.   IF lw_select IS INITIAL.
  1147.     PERFORM parse_query_noselect USING    lw_query
  1148.                                  CHANGING lw_noauth
  1149.                                           lw_command
  1150.                                           lw_from
  1151.                                           lw_where.
  1152.     IF lw_noauth NE space.
  1153.       RETURN.
  1154.     ENDIF.
  1155.     PERFORM generate_subroutine_noselect USING lw_command lw_from
  1156.                                                lw_where fp_display
  1157.                                          CHANGING lw_program.
  1158.     CONCATENATE 'Are you sure you want to do a'(m31) lw_command
  1159.                 'on table'(m32) lw_from '?'(m33)
  1160.                 INTO lw_msg SEPARATED BY space.
  1161.     CALL FUNCTION 'POPUP_TO_CONFIRM'
  1162.       EXPORTING
  1163.         titlebar              = 'Warning : critical operation'(t04)
  1164.         text_question         = lw_msg
  1165.         default_button        = '2'
  1166.         display_cancel_button = space
  1167.       IMPORTING
  1168.         answer                = lw_answer
  1169.       EXCEPTIONS
  1170.         text_not_found        = 1
  1171.         OTHERS                = 2.
  1172.     IF sy-subrc NE 0 OR lw_answer NE '1'.
  1173.       RETURN.
  1174.     ENDIF.
  1175.     lw_count_only = abap_true. "no result grid to display
  1176.   ELSEIF lw_noauth NE space.
  1177.     RETURN.
  1178.   ELSEIF lw_from IS INITIAL.
  1179.     MESSAGE 'Cannot parse the query'(m07) TYPE c_msg_error.
  1180.   ELSE.
  1181. * Generate SELECT subroutine
  1182.     PERFORM generate_subroutine USING lw_select lw_from
  1183.                                       lw_where fp_display
  1184.                                 CHANGING lw_program lw_rows
  1185.                                          lt_fieldlist lw_count_only.
  1186.   ENDIF.
  1187.  
  1188.  
  1189. * Call the generated subroutine
  1190.   IF NOT lw_program IS INITIAL.
  1191.     PERFORM run_sql IN PROGRAM (lw_program)
  1192.                     CHANGING lo_result lw_time lw_count.
  1193.  
  1194. * For union, process second (and further) query
  1195.     WHILE NOT lw_union IS INITIAL.
  1196. * Parse Query
  1197.       lw_query2 = lw_union.
  1198.       PERFORM parse_query USING lw_query2
  1199.                           CHANGING lw_select lw_from lw_where
  1200.                                    lw_union lw_rows lw_noauth.
  1201.       IF lw_noauth NE space.
  1202.         RETURN.
  1203.       ELSEIF lw_select IS INITIAL OR lw_from IS INITIAL.
  1204.         MESSAGE 'Cannot parse the unioned query'(m08) TYPE c_msg_error.
  1205.         EXIT. "exit while
  1206.       ENDIF.
  1207. * Generate subroutine
  1208.       PERFORM generate_subroutine USING lw_select lw_from
  1209.                                         lw_where fp_display
  1210.                                   CHANGING lw_program lw_rows
  1211.                                            lt_fieldlist2 lw_count_only.
  1212. * Call the generated subroutine
  1213.       PERFORM run_sql IN PROGRAM (lw_program)
  1214.                       CHANGING lo_result2 lw_time2 lw_count2.
  1215. * Append lines of the further queries to the first query
  1216.       ASSIGN lo_result->* TO <lft_data>.
  1217.       ASSIGN lo_result2->* TO <lft_data2>.
  1218.       APPEND LINES OF <lft_data2> TO <lft_data>.
  1219.       REFRESH <lft_data2>.
  1220.       lw_time = lw_time + lw_time2.
  1221.       lw_count = lw_count + lw_count2.
  1222.     ENDWHILE.
  1223.  
  1224. * Display message
  1225.     lw_charnumb = lw_time.
  1226.     CONCATENATE 'Query executed in'(m09) lw_charnumb INTO lw_msg
  1227.                 SEPARATED BY space.
  1228.     lw_charnumb = lw_count.
  1229.     IF NOT lw_select IS INITIAL.
  1230.       CONCATENATE lw_msg 'seconds.'(m10)
  1231.                   lw_charnumb 'entries found'(m11)
  1232.                   INTO lw_msg SEPARATED BY space.
  1233.     ELSE.
  1234.       CONCATENATE lw_msg 'seconds.'(m10)
  1235.                   lw_charnumb 'entries affected'(m12)
  1236.                   INTO lw_msg SEPARATED BY space.
  1237.     ENDIF.
  1238.     CONDENSE lw_msg.
  1239.     MESSAGE lw_msg TYPE c_msg_success.
  1240.  
  1241.  
  1242. * Display result except for count(*)
  1243.     IF lw_count_only IS INITIAL.
  1244.       PERFORM display_alv_data USING lo_result lt_fieldlist lw_query.
  1245.     ENDIF.
  1246.  
  1247.     PERFORM save_current_query.
  1248.   ENDIF.
  1249. ENDFORM.                    " PROCESS_QUERY
  1250.  
  1251. *&---------------------------------------------------------------------*
  1252. *&      Form  GET_QUERY
  1253. *&---------------------------------------------------------------------*
  1254. *       Return active query without comment
  1255. *----------------------------------------------------------------------*
  1256. *      -->FP_FORCE_LAST  Keep last request
  1257. *      <--FP_QUERY       Query code
  1258. *----------------------------------------------------------------------*
  1259. FORM get_query USING fp_force_last TYPE c
  1260.                CHANGING fp_query TYPE string.
  1261.   DATA : lt_query TYPE soli_tab,
  1262.          ls_query LIKE LINE OF lt_query,
  1263.          ls_find TYPE match_result,
  1264.          lt_find TYPE match_result_tab,
  1265.          lw_cursor_line TYPE i,
  1266.          lw_cursor_pos TYPE i,
  1267.          lw_delto_line TYPE i,
  1268.          lw_delto_pos TYPE i,
  1269.          lw_cursor_offset TYPE i,
  1270.          lw_last TYPE c.
  1271.  
  1272.   CLEAR fp_query.
  1273.  
  1274. * Get selected content
  1275.   CALL METHOD o_textedit->get_selected_text_as_table
  1276.     IMPORTING
  1277.       table = lt_query[].
  1278.  
  1279. * if no selected content, get complete content of abap edit box
  1280.   IF lt_query[] IS INITIAL.
  1281.     CALL METHOD o_textedit->get_text
  1282.       IMPORTING
  1283.         table  = lt_query[]
  1284.       EXCEPTIONS
  1285.         OTHERS = 1.
  1286.   ENDIF.
  1287.  
  1288. * Remove * comment
  1289.   LOOP AT lt_query INTO ls_query WHERE line(1) = '*'.
  1290.     CLEAR ls_query-line.
  1291.     MODIFY lt_query FROM ls_query.
  1292.   ENDLOOP.
  1293.  
  1294. * Remove " comment
  1295.   LOOP AT lt_query INTO ls_query WHERE line CS '"'.
  1296.     FIND FIRST OCCURRENCE OF '"' IN ls_query-line RESULTS ls_find.
  1297.     CHECK sy-subrc = 0.
  1298.     ls_find-offset = ls_find-offset - 1.
  1299.     ls_query-line = ls_query-line(ls_find-offset).
  1300.     MODIFY lt_query FROM ls_query.
  1301.   ENDLOOP.
  1302.  
  1303. * Find active query
  1304.   CALL METHOD o_textedit->get_selection_pos
  1305.     IMPORTING
  1306.       from_line = lw_cursor_line
  1307.       from_pos  = lw_cursor_pos.
  1308.   lw_cursor_offset = lw_cursor_pos - 1.
  1309.  
  1310.   FIND ALL OCCURRENCES OF '.' IN TABLE lt_query RESULTS lt_find.
  1311.   CLEAR : lw_delto_line,
  1312.           lw_delto_pos,
  1313.           lw_last.
  1314.   LOOP AT lt_find INTO ls_find.
  1315.     AT LAST.
  1316.       lw_last = abap_true.
  1317.     ENDAT.
  1318. * Active Query
  1319.     IF ls_find-line GT lw_cursor_line
  1320.     OR ( ls_find-line = lw_cursor_line
  1321.          AND ls_find-offset GE lw_cursor_offset )
  1322.     OR ( lw_last = abap_true AND fp_force_last = abap_true ).
  1323. * Delete all query after query active
  1324.       ls_find-line = ls_find-line + 1.
  1325.       DELETE lt_query FROM ls_find-line.
  1326.       ls_find-line = ls_find-line - 1.
  1327. * Do not keep the . for active query
  1328.       IF ls_find-offset = 0.
  1329.         DELETE lt_query FROM ls_find-line.
  1330.       ELSE.
  1331.         READ TABLE lt_query INTO ls_query INDEX ls_find-line.
  1332.         ls_query-line = ls_query-line(ls_find-offset).
  1333.         MODIFY lt_query FROM ls_query INDEX ls_find-line.
  1334.       ENDIF.
  1335.       EXIT.
  1336. * Query before active
  1337.     ELSE.
  1338.       lw_delto_line = ls_find-line.
  1339.       lw_delto_pos = ls_find-offset + 1.
  1340.     ENDIF.
  1341.   ENDLOOP.
  1342.  
  1343. * Delete all query before query active
  1344.   IF NOT lw_delto_line IS INITIAL.
  1345.     IF lw_delto_line GT 1.
  1346.       lw_delto_line = lw_delto_line - 1.
  1347.       DELETE lt_query FROM 1 TO lw_delto_line.
  1348.     ENDIF.
  1349.     READ TABLE lt_query INTO ls_query INDEX 1.
  1350.     ls_query-line(lw_delto_pos) = ''.
  1351.     MODIFY lt_query FROM ls_query INDEX 1.
  1352.   ENDIF.
  1353.  
  1354. * Delete empty lines
  1355.   DELETE lt_query WHERE line CO ' .'.
  1356.  
  1357. * Build query string & Remove unnessential spaces
  1358.   LOOP AT lt_query INTO ls_query.
  1359.     CONDENSE ls_query-line.
  1360.     SHIFT ls_query-line LEFT DELETING LEADING space.
  1361.     CONCATENATE fp_query ls_query-line INTO fp_query SEPARATED BY space.
  1362.   ENDLOOP.
  1363.   IF NOT fp_query IS INITIAL.
  1364.     fp_query = fp_query+1.
  1365.   ENDIF.
  1366.  
  1367. * If no query selected, try to get the last one
  1368.   IF lt_query IS INITIAL AND fp_force_last = space.
  1369.     PERFORM get_query USING abap_true
  1370.                       CHANGING fp_query.
  1371.   ENDIF.
  1372. ENDFORM.                    " GET_QUERY
  1373.  
  1374. *&---------------------------------------------------------------------*
  1375. *&      Form  PARSE_QUERY
  1376. *&---------------------------------------------------------------------*
  1377. *       Split the query into 3 parts : Select / From / Where
  1378. *       - Select : List of the fields to extract
  1379. *       - From   : List of the tables - with join condition
  1380. *       - Where  : List of filters + group, order, having clauses
  1381. *----------------------------------------------------------------------*
  1382. *      -->FP_QUERY   Query to parse
  1383. *      <--FP_SELECT  Select part of the query
  1384. *      <--FP_FROM    From part of the query
  1385. *      <--FP_WHERE   Where part of the query
  1386. *      <--FP_ROWS    Number of rows to display
  1387. *      <--FP_UNION   Union part of the query
  1388. *      <--FP_NOAUTH  Unallowed table entered
  1389. *----------------------------------------------------------------------*
  1390. FORM parse_query  USING    fp_query TYPE string
  1391.                   CHANGING fp_select TYPE string
  1392.                            fp_from TYPE string
  1393.                            fp_where TYPE string
  1394.                            fp_union TYPE string
  1395.                            fp_rows TYPE n
  1396.                            fp_noauth TYPE c.
  1397.   DATA : ls_find_select TYPE match_result,
  1398.          ls_find_from TYPE match_result,
  1399.          ls_find_where TYPE match_result,
  1400.          ls_sub LIKE LINE OF ls_find_select-submatches,
  1401.          lw_offset TYPE i,
  1402.          lw_length TYPE i,
  1403.          lw_query TYPE string,
  1404.          lo_regex TYPE REF TO cl_abap_regex,
  1405.          lt_split TYPE TABLE OF string,
  1406.          lw_string TYPE string,
  1407.          lw_tabix TYPE i,
  1408.          lw_table TYPE tabname.
  1409.  
  1410.   CLEAR : fp_select,
  1411.           fp_from,
  1412.           fp_where,
  1413.           fp_rows,
  1414.           fp_union,
  1415.           fp_noauth.
  1416.  
  1417.   lw_query = fp_query.
  1418.  
  1419. * Search union
  1420.   FIND FIRST OCCURRENCE OF ' UNION SELECT ' IN lw_query
  1421.        RESULTS ls_find_select IGNORING CASE.
  1422.   IF sy-subrc = 0.
  1423.     lw_offset = ls_find_select-offset + 7.
  1424.     fp_union = lw_query+lw_offset.
  1425.     lw_query = lw_query(ls_find_select-offset).
  1426.   ENDIF.
  1427.  
  1428. * Create regex
  1429.   CREATE OBJECT lo_regex
  1430.     EXPORTING
  1431.       pattern     = 'UP TO ([0-9]+) ROWS'
  1432.       ignore_case = abap_true.
  1433.  
  1434. * Search UP TO xxx ROWS.
  1435. * Catch the number of rows, delete command in query
  1436.   FIND FIRST OCCURRENCE OF REGEX lo_regex
  1437.        IN fp_query RESULTS ls_find_select.
  1438.   IF sy-subrc = 0.
  1439.     READ TABLE ls_find_select-submatches INTO ls_sub INDEX 1.
  1440.     IF sy-subrc = 0.
  1441.       fp_rows = lw_query+ls_sub-offset(ls_sub-length).
  1442.     ENDIF.
  1443.     REPLACE FIRST OCCURRENCE OF REGEX lo_regex IN lw_query WITH ''.
  1444.   ENDIF.
  1445.  
  1446.   FIND FIRST OCCURRENCE OF 'SELECT ' IN lw_query
  1447.        RESULTS ls_find_select IGNORING CASE.
  1448.   IF sy-subrc NE 0.
  1449.     RETURN.
  1450.   ENDIF.
  1451.  
  1452.   FIND FIRST OCCURRENCE OF ' FROM '
  1453.        IN SECTION OFFSET ls_find_select-offset OF lw_query
  1454.        RESULTS ls_find_from IGNORING CASE.
  1455.   IF sy-subrc NE 0.
  1456.     RETURN.
  1457.   ENDIF.
  1458.  
  1459.   FIND FIRST OCCURRENCE OF ' WHERE '
  1460.        IN SECTION OFFSET ls_find_from-offset OF lw_query
  1461.        RESULTS ls_find_where IGNORING CASE.
  1462.   IF sy-subrc NE 0.
  1463.     FIND FIRST OCCURRENCE OF ' GROUP BY ' IN lw_query
  1464.          RESULTS ls_find_where IGNORING CASE.
  1465.   ENDIF.
  1466.   IF sy-subrc NE 0.
  1467.     FIND FIRST OCCURRENCE OF ' HAVING ' IN lw_query
  1468.          RESULTS ls_find_where IGNORING CASE.
  1469.   ENDIF.
  1470.   IF sy-subrc NE 0.
  1471.     FIND FIRST OCCURRENCE OF ' ORDER BY ' IN lw_query
  1472.          RESULTS ls_find_where IGNORING CASE.
  1473.   ENDIF.
  1474.  
  1475.   lw_offset = ls_find_select-offset + 7.
  1476.   lw_length = ls_find_from-offset - ls_find_select-offset - 7.
  1477.   fp_select = lw_query+lw_offset(lw_length).
  1478.  
  1479.   lw_offset = ls_find_from-offset + 6.
  1480.   IF ls_find_where IS INITIAL.
  1481.     fp_from = lw_query+lw_offset.
  1482.     fp_where = ''.
  1483.   ELSE.
  1484.     lw_length = ls_find_where-offset - ls_find_from-offset - 6.
  1485.     fp_from = lw_query+lw_offset(lw_length).
  1486.     lw_offset = ls_find_where-offset.
  1487.     fp_where = lw_query+lw_offset.
  1488.   ENDIF.
  1489.  
  1490. * Set default number of rows to 100
  1491.   IF fp_rows IS INITIAL.
  1492.     fp_rows = 100.
  1493.   ENDIF.
  1494.  
  1495. * Authority-check on used select tables
  1496.   IF s_auth-auth_object NE space OR s_auth-select NE '*'.
  1497.     CONCATENATE 'JOIN' fp_from INTO lw_string SEPARATED BY space.
  1498.     TRANSLATE lw_string TO UPPER CASE.
  1499.     SPLIT lw_string AT space INTO TABLE lt_split.
  1500.     LOOP AT lt_split INTO lw_string.
  1501.       lw_tabix = sy-tabix + 1.
  1502.       CHECK lw_string = 'JOIN'.
  1503. * Read next line (table name)
  1504.       READ TABLE lt_split INTO lw_table INDEX lw_tabix.
  1505.       CHECK sy-subrc = 0.
  1506.  
  1507.       IF s_auth-auth_object NE space.
  1508.         AUTHORITY-CHECK OBJECT s_auth-auth_object
  1509.                  ID 'SELECT' FIELD lw_table.
  1510.       ELSEIF s_auth-select NE '*' AND NOT lw_table CP s_auth-select.
  1511.         sy-subrc = 4.
  1512.       ENDIF.
  1513.       IF sy-subrc NE 0.
  1514.         CONCATENATE 'No authorisation for table'(m13) lw_table
  1515.                     INTO lw_string SEPARATED BY space.
  1516.         MESSAGE lw_string TYPE c_msg_success DISPLAY LIKE c_msg_error.
  1517.         CLEAR fp_from.
  1518.         fp_noauth = abap_true.
  1519.         RETURN.
  1520.       ENDIF.
  1521.     ENDLOOP.
  1522.   ENDIF.
  1523.  
  1524. ENDFORM.                    " PARSE_QUERY
  1525.  
  1526. *&---------------------------------------------------------------------*
  1527. *&      Form  add_line_to_table
  1528. *&---------------------------------------------------------------------*
  1529. *       Add a string line in a table
  1530. *       Break line at 255 char, respecting words if possible
  1531. *----------------------------------------------------------------------*
  1532. *      -->FP_LINE    Line to add in table
  1533. *      <--FT_TABLE   Table to append
  1534. *----------------------------------------------------------------------*
  1535. FORM add_line_to_table USING fp_line TYPE string
  1536.                        CHANGING ft_table TYPE table.
  1537.   DATA : lw_length TYPE i,
  1538.          lw_offset TYPE i,
  1539.          ls_find TYPE match_result.
  1540.  
  1541.   lw_length = strlen( fp_line ).
  1542.   lw_offset = 0.
  1543.   DO.
  1544.     IF lw_length LE c_line_max.
  1545.       APPEND fp_line+lw_offset(lw_length) TO ft_table.
  1546.       EXIT. "exit do
  1547.     ELSE.
  1548.       FIND ALL OCCURRENCES OF REGEX '\s' "search space
  1549.            IN SECTION OFFSET lw_offset LENGTH c_line_max
  1550.            OF fp_line RESULTS ls_find.
  1551.       IF sy-subrc NE 0.
  1552.         APPEND fp_line+lw_offset(c_line_max) TO ft_table.
  1553.         lw_length = lw_length - c_line_max.
  1554.         lw_offset = lw_offset + c_line_max.
  1555.       ELSE.
  1556.         ls_find-length = ls_find-offset - lw_offset.
  1557.         APPEND fp_line+lw_offset(ls_find-length) TO ft_table.
  1558.         lw_length = lw_length + lw_offset - ls_find-offset - 1.
  1559.         lw_offset = ls_find-offset + 1.
  1560.       ENDIF.
  1561.     ENDIF.
  1562.   ENDDO.
  1563.  
  1564. ENDFORM.                    "add_line_to_table
  1565.  
  1566. *&---------------------------------------------------------------------*
  1567. *&      Form  GENERATE_SUBROUTINE
  1568. *&---------------------------------------------------------------------*
  1569. *       Create SELECT SQL query in a new generated temp program
  1570. *----------------------------------------------------------------------*
  1571. *      -->FP_SELECT    Select part of the query
  1572. *      -->FP_FROM      From part of the query
  1573. *      -->FP_WHERE     Where part of the query
  1574. *      -->FP_DISPLAY   Display code instead of generated routine
  1575. *      <--FP_PROGRAM   Name of the generated program
  1576. *      <--FP_ROWS      Number of rows to display
  1577. *      <--FT_FIELDLIST List of fields to display
  1578. *----------------------------------------------------------------------*
  1579. FORM generate_subroutine  USING    fp_select TYPE string
  1580.                                    fp_from TYPE string
  1581.                                    fp_where TYPE string
  1582.                                    fp_display TYPE c
  1583.                           CHANGING fp_program TYPE sy-repid
  1584.                                    fp_rows TYPE n
  1585.                                    ft_fieldlist TYPE ty_fieldlist_table
  1586.                                    fp_count TYPE c.
  1587.  
  1588.   DATA : lt_code_string TYPE TABLE OF string,
  1589.          lt_split TYPE TABLE OF string,
  1590.          lw_string TYPE string,
  1591.          lw_string2 TYPE string,
  1592.          BEGIN OF ls_table_alias,
  1593.            table(50) TYPE c,
  1594.            alias(50) TYPE c,
  1595.          END OF ls_table_alias,
  1596.          lt_table_alias LIKE TABLE OF ls_table_alias,
  1597.          lw_select TYPE string,
  1598.          lw_from TYPE string,
  1599.          lw_index TYPE i,
  1600.          lw_select_distinct TYPE c,
  1601.          lw_select_length TYPE i,
  1602.          lw_char_10(10) TYPE c,
  1603.          lw_field_number(6) TYPE n,
  1604.          lw_current_line TYPE i,
  1605.          lw_current_length TYPE i,
  1606.          lw_struct_line TYPE string,
  1607.          lw_struct_line_type TYPE string,
  1608.          lw_select_table TYPE string,
  1609.          lw_select_field TYPE string,
  1610.          lw_dd03l_fieldname TYPE dd03l-fieldname,
  1611.          lw_position_dummy TYPE dd03l-position,
  1612.          lw_mess(255),
  1613.          lw_line TYPE i,
  1614.          lw_word(30),
  1615.          ls_fieldlist TYPE ty_fieldlist,
  1616.          lw_strlen_string TYPE string,
  1617.          lw_explicit TYPE string.
  1618.  
  1619.   DEFINE c.
  1620.     lw_strlen_string = &1.
  1621.     perform add_line_to_table using lw_strlen_string
  1622.                               changing lt_code_string.
  1623.   END-OF-DEFINITION.
  1624.  
  1625.   CLEAR : lw_select_distinct,
  1626.           fp_count.
  1627.  
  1628. * Write Header
  1629.   c 'PROGRAM SUBPOOL.'.
  1630.   c '** GENERATED PROGRAM * DO NOT CHANGE IT **'.
  1631.   c 'TYPE-POOLS: slis.'.                                    "#EC NOTEXT
  1632.   c ''.
  1633.  
  1634.   lw_select = fp_select.
  1635.   TRANSLATE lw_select TO UPPER CASE.
  1636.  
  1637.   lw_from = fp_from.
  1638.   TRANSLATE lw_from TO UPPER CASE.
  1639.  
  1640. * Search special term "single" or "distinct"
  1641.   lw_select_length = strlen( lw_select ).
  1642.   IF lw_select_length GE 7.
  1643.     lw_char_10 = lw_select(7).
  1644.     IF lw_char_10 = 'SINGLE'.
  1645. * Force rows number = 1 for select single
  1646.       fp_rows = 1.
  1647.       lw_select = lw_select+7.
  1648.       lw_select_length = lw_select_length - 7.
  1649.     ENDIF.
  1650.   ENDIF.
  1651.   IF lw_select_length GE 9.
  1652.     lw_char_10 = lw_select(9).
  1653.     IF lw_char_10 = 'DISTINCT'.
  1654.       lw_select_distinct = abap_true.
  1655.       lw_select = lw_select+9.
  1656.       lw_select_length = lw_select_length - 9.
  1657.     ENDIF.
  1658.   ENDIF.
  1659.  
  1660. * Search for special syntax "count( * )"
  1661.   IF lw_select = 'COUNT( * )'.
  1662.     fp_count = abap_true.
  1663.   ENDIF.
  1664.  
  1665. * Create alias table mapping
  1666.   SPLIT lw_from AT space INTO TABLE lt_split.
  1667.   LOOP AT lt_split INTO lw_string.
  1668.     IF lw_string IS INITIAL OR lw_string CO space.
  1669.       DELETE lt_split.
  1670.     ENDIF.
  1671.   ENDLOOP.
  1672.   DO.
  1673.     READ TABLE lt_split TRANSPORTING NO FIELDS WITH KEY = 'AS'.
  1674.     IF sy-subrc NE 0.
  1675.       EXIT.
  1676.     ENDIF.
  1677.     lw_index = sy-tabix - 1.
  1678.     READ TABLE lt_split INTO lw_string INDEX lw_index.
  1679.     ls_table_alias-table = lw_string.
  1680.     DELETE lt_split INDEX lw_index. "delete table field
  1681.     DELETE lt_split INDEX lw_index. "delete keywork AS
  1682.     READ TABLE lt_split INTO lw_string INDEX lw_index.
  1683.     ls_table_alias-alias = lw_string.
  1684.     DELETE lt_split INDEX lw_index. "delete alias field
  1685.     APPEND ls_table_alias TO lt_table_alias.
  1686.   ENDDO.
  1687. * If no alias table found, create just an entry for "*"
  1688.   IF lt_table_alias[] IS INITIAL.
  1689.     READ TABLE lt_split INTO lw_string INDEX 1.
  1690.     ls_table_alias-table = lw_string.
  1691.     ls_table_alias-alias = '*'.
  1692.     APPEND ls_table_alias TO lt_table_alias.
  1693.   ENDIF.
  1694.  
  1695. * Write Data declaration
  1696.   c '***************************************'.              "#EC NOTEXT
  1697.   c '*      Begin of data declaration      *'.              "#EC NOTEXT
  1698.   c '*   Used to store lines of the query  *'.              "#EC NOTEXT
  1699.   c '***************************************'.              "#EC NOTEXT
  1700.   c 'DATA: BEGIN OF s_result'.                              "#EC NOTEXT
  1701.   lw_field_number = 1.
  1702.   SPLIT lw_select AT space INTO TABLE lt_split.
  1703.  
  1704.   LOOP AT lt_split INTO lw_string.
  1705.     lw_current_line = sy-tabix.
  1706.     lw_current_length = strlen( lw_string ).
  1707.  
  1708.     CLEAR ls_fieldlist.
  1709.     ls_fieldlist-ref_field = lw_string.
  1710. * Manage "Count"
  1711.     IF lw_current_length GE 6.
  1712.       lw_char_10 = lw_string(6).
  1713.     ELSE.
  1714.       CLEAR lw_char_10.
  1715.     ENDIF.
  1716.     IF lw_char_10 = 'COUNT('.
  1717.       CONCATENATE 'F' lw_field_number INTO ls_fieldlist-field.
  1718.       CONCATENATE ',' ls_fieldlist-field INTO lw_struct_line.
  1719.  
  1720.       lw_index = lw_current_line + 1.
  1721.       DO.
  1722.         SEARCH lw_string FOR ')'.
  1723.         IF sy-subrc = 0.
  1724.           EXIT.
  1725.         ELSE.
  1726. * If there is space in the "count()", delete next lines
  1727.           READ TABLE lt_split INTO lw_string INDEX lw_index.
  1728.           IF sy-subrc NE 0.
  1729.             EXIT.
  1730.           ENDIF.
  1731.           CONCATENATE ls_fieldlist-ref_field lw_string
  1732.                       INTO ls_fieldlist-ref_field SEPARATED BY space.
  1733.           DELETE lt_split INDEX lw_index.
  1734.         ENDIF.
  1735.       ENDDO.
  1736.       CONCATENATE lw_struct_line 'TYPE i'                   "#EC NOTEXT
  1737.                   INTO lw_struct_line SEPARATED BY space.
  1738.       c lw_struct_line.
  1739.       APPEND ls_fieldlist TO ft_fieldlist.
  1740.       lw_field_number = lw_field_number + 1.
  1741.       CONTINUE.
  1742.     ENDIF.
  1743.  
  1744. * Manage Agregate AVG
  1745.     IF lw_current_length GE 4.
  1746.       lw_char_10 = lw_string(4).
  1747.     ELSE.
  1748.       CLEAR lw_char_10.
  1749.     ENDIF.
  1750.     IF lw_char_10 = 'AVG('.
  1751.       CONCATENATE 'F' lw_field_number INTO ls_fieldlist-field.
  1752.       CONCATENATE ',' ls_fieldlist-field INTO lw_struct_line.
  1753.  
  1754.       lw_index = lw_current_line + 1.
  1755.       DO.
  1756.         SEARCH lw_string FOR ')'.
  1757.         IF sy-subrc = 0.
  1758.           EXIT.
  1759.         ELSE.
  1760. * If there is space in the agregate, delete next lines
  1761.           READ TABLE lt_split INTO lw_string INDEX lw_index.
  1762.           IF sy-subrc NE 0.
  1763.             EXIT.
  1764.           ENDIF.
  1765.           CONCATENATE ls_fieldlist-ref_field lw_string
  1766.                       INTO ls_fieldlist-ref_field SEPARATED BY space.
  1767.           DELETE lt_split INDEX lw_index.
  1768.         ENDIF.
  1769.       ENDDO.
  1770.       CONCATENATE lw_struct_line 'TYPE f'                   "#EC NOTEXT
  1771.                   INTO lw_struct_line SEPARATED BY space.
  1772.       c lw_struct_line.
  1773.       APPEND ls_fieldlist TO ft_fieldlist.
  1774.       lw_field_number = lw_field_number + 1.
  1775.       CONTINUE.
  1776.     ENDIF.
  1777.  
  1778. * Manage agregate SUM, MAX, MIN
  1779.     IF lw_current_length GE 4.
  1780.       lw_char_10 = lw_string(4).
  1781.     ELSE.
  1782.       CLEAR lw_char_10.
  1783.     ENDIF.
  1784.     IF lw_char_10 = 'SUM(' OR lw_char_10 = 'MAX('
  1785.     OR lw_char_10 = 'MIN('.
  1786.       lw_index = lw_current_line + 1.
  1787.       DO.
  1788.         SEARCH lw_string FOR ')'.
  1789.         IF sy-subrc = 0.
  1790.           EXIT.
  1791.         ELSE.
  1792. * Search name of the field in next lines.
  1793.           READ TABLE lt_split INTO lw_string INDEX lw_index.
  1794.           IF sy-subrc NE 0.
  1795.             EXIT.
  1796.           ENDIF.
  1797.           CONCATENATE ls_fieldlist-ref_field lw_string
  1798.                       INTO ls_fieldlist-ref_field SEPARATED BY space.
  1799.           IF lw_string2 IS INITIAL.
  1800.             lw_string2 = lw_string.
  1801.           ENDIF.
  1802. * Delete lines of agregage in field table
  1803.           DELETE lt_split INDEX lw_index.
  1804.         ENDIF.
  1805.       ENDDO.
  1806.       lw_string = lw_string2.
  1807.     ENDIF.
  1808.  
  1809. * Now lw_string contain a field name.
  1810. * We have to find the field description
  1811.     SPLIT lw_string AT '~' INTO lw_select_table lw_select_field.
  1812.     IF lw_select_field IS INITIAL.
  1813.       lw_select_field = lw_select_table.
  1814.       lw_select_table = '*'.
  1815.     ENDIF.
  1816. * Search if alias table used
  1817.     CLEAR ls_table_alias.
  1818.     READ TABLE lt_table_alias INTO ls_table_alias
  1819.                WITH KEY alias = lw_select_table             "#EC WARNOK
  1820.                BINARY SEARCH.
  1821.     IF sy-subrc = 0.
  1822.       lw_select_table = ls_table_alias-table.
  1823.     ENDIF.
  1824.     ls_fieldlist-ref_table = lw_select_table.
  1825.     IF lw_string = '*' OR lw_select_field = '*'. " expansion table~*
  1826.       CLEAR lw_explicit.
  1827.       SELECT fieldname position
  1828.       INTO   (lw_dd03l_fieldname,lw_position_dummy)
  1829.       FROM   dd03l
  1830.       WHERE  tabname    = lw_select_table
  1831.       AND    fieldname <> 'MANDT'
  1832.       AND    as4local   = c_vers_active
  1833.       AND    as4vers    = space
  1834.       AND (  comptype   = c_ddic_dtelm
  1835.           OR comptype   = space )
  1836.       ORDER BY position.
  1837.  
  1838.         lw_select_field = lw_dd03l_fieldname.
  1839.  
  1840.         CONCATENATE 'F' lw_field_number INTO ls_fieldlist-field.
  1841.         ls_fieldlist-ref_field = lw_select_field.
  1842.         APPEND ls_fieldlist TO ft_fieldlist.
  1843.         CONCATENATE ',' ls_fieldlist-field INTO lw_struct_line.
  1844.  
  1845.         CONCATENATE lw_select_table '-' lw_select_field
  1846.                     INTO lw_struct_line_type.
  1847.         CONCATENATE lw_struct_line 'TYPE' lw_struct_line_type
  1848.                     INTO lw_struct_line
  1849.                     SEPARATED BY space.
  1850.         c lw_struct_line.
  1851.         lw_field_number = lw_field_number + 1.
  1852. * Explicit list of fields instead of *
  1853. * Generate longer query but mandatory in case of T1~* or MARA~*
  1854. * Required also in some special cases, for example if table use include
  1855.         IF ls_table_alias-alias = space OR ls_table_alias-alias = '*'.
  1856.           CONCATENATE lw_explicit lw_select_table
  1857.                       INTO lw_explicit SEPARATED BY space.
  1858.         ELSE.
  1859.           CONCATENATE lw_explicit ls_table_alias-alias
  1860.                       INTO lw_explicit SEPARATED BY space.
  1861.         ENDIF.
  1862.         CONCATENATE lw_explicit '~' lw_select_field INTO lw_explicit.
  1863.       ENDSELECT.
  1864.       IF sy-subrc NE 0.
  1865.         MESSAGE e701(1r) WITH lw_select_table. "table does not exist
  1866.       ENDIF.
  1867.       IF NOT lw_explicit IS INITIAL.
  1868.         REPLACE FIRST OCCURRENCE OF lw_string
  1869.                 IN lw_select WITH lw_explicit.
  1870.       ENDIF.
  1871.  
  1872.     ELSE. "Simple field
  1873.       CONCATENATE 'F' lw_field_number INTO ls_fieldlist-field.
  1874.       ls_fieldlist-ref_field = lw_select_field.
  1875.       APPEND ls_fieldlist TO ft_fieldlist.
  1876.  
  1877.       CONCATENATE ',' ls_fieldlist-field INTO lw_struct_line.
  1878.  
  1879.       CONCATENATE lw_select_table '-' lw_select_field
  1880.                   INTO lw_struct_line_type.
  1881.       CONCATENATE lw_struct_line 'TYPE' lw_struct_line_type
  1882.                   INTO lw_struct_line
  1883.                   SEPARATED BY space.
  1884.       c lw_struct_line.
  1885.       lw_field_number = lw_field_number + 1.
  1886.     ENDIF.
  1887.   ENDLOOP.
  1888.  
  1889.   c ', END OF s_result'.                                    "#EC NOTEXT
  1890.   c ', t_result like table of s_result'.                    "#EC NOTEXT
  1891.   c ', w_timestart type timestampl'.                        "#EC NOTEXT
  1892.   c ', w_timeend type timestampl.'.                         "#EC NOTEXT
  1893.  
  1894. * Write the dynamic subroutine that run the SELECT
  1895.   c 'FORM run_sql CHANGING fp_result TYPE REF TO data'.     "#EC NOTEXT
  1896.   c '                      fp_time type p'.                 "#EC NOTEXT
  1897.   c '                      fp_count type i.'.               "#EC NOTEXT
  1898.   c '***************************************'.              "#EC NOTEXT
  1899.   c '*            Begin of query           *'.              "#EC NOTEXT
  1900.   c '***************************************'.              "#EC NOTEXT
  1901.   c 'get TIME STAMP FIELD w_timestart.'.                    "#EC NOTEXT
  1902.   IF fp_count = abap_true.
  1903.     CONCATENATE 'SELECT SINGLE' lw_select                   "#EC NOTEXT
  1904.                 INTO lw_select SEPARATED BY space.
  1905.     c lw_select.
  1906.     c 'INTO s_result-f000001'.                              "#EC NOTEXT
  1907.   ELSE.
  1908.     IF lw_select_distinct NE space.
  1909.       CONCATENATE 'SELECT DISTINCT' lw_select               "#EC NOTEXT
  1910.                   INTO lw_select SEPARATED BY space.
  1911.     ELSE.
  1912.       CONCATENATE 'SELECT' lw_select                        "#EC NOTEXT
  1913.                   INTO lw_select SEPARATED BY space.
  1914.     ENDIF.
  1915.     c lw_select.
  1916.     c 'INTO TABLE t_result'.                                "#EC NOTEXT
  1917.  
  1918. * Add UP TO xxx ROWS
  1919.     c 'UP TO'.                                              "#EC NOTEXT
  1920.     c fp_rows.
  1921.     c 'ROWS'.                                               "#EC NOTEXT
  1922.   ENDIF.
  1923.  
  1924.   c 'FROM'.                                                 "#EC NOTEXT
  1925.   c lw_from.
  1926.  
  1927. * Where, group by, having, order by
  1928.   IF NOT fp_where IS INITIAL.
  1929.     c fp_where.
  1930.   ENDIF.
  1931.   c '.'.
  1932.  
  1933. * Display query execution time
  1934.   c 'get TIME STAMP FIELD w_timeend.'.                      "#EC NOTEXT
  1935.   c 'fp_time = w_timeend - w_timestart.'.                   "#EC NOTEXT
  1936.   c 'fp_count = sy-dbcnt.'.                                 "#EC NOTEXT
  1937.  
  1938. * If select count( * ), display number of results
  1939.   IF fp_count NE space.
  1940.     c 'MESSAGE i753(TG) WITH s_result-f000001.'.            "#EC NOTEXT
  1941.   ENDIF.
  1942.  
  1943.   c 'GET REFERENCE OF t_result INTO fp_result.'.            "#EC NOTEXT
  1944.   c 'ENDFORM.'.                                             "#EC NOTEXT
  1945.   CLEAR : lw_line,
  1946.           lw_word,
  1947.           lw_mess.
  1948.   SYNTAX-CHECK FOR lt_code_string PROGRAM sy-repid
  1949.                MESSAGE lw_mess LINE lw_line WORD lw_word.
  1950.   IF sy-subrc NE 0 AND fp_display = space.
  1951.     MESSAGE lw_mess TYPE c_msg_error.
  1952.   ENDIF.
  1953.  
  1954.   IF fp_display = space.
  1955.     GENERATE SUBROUTINE POOL lt_code_string NAME fp_program.
  1956.   ELSE.
  1957.     IF lw_mess IS NOT INITIAL.
  1958.       lw_explicit = lw_line.
  1959.       CONCATENATE lw_mess '(line'(m28) lw_explicit ',word'(m29)
  1960.                   lw_word ')'(m30)
  1961.                   INTO lw_mess SEPARATED BY space.
  1962.       MESSAGE lw_mess TYPE c_msg_success DISPLAY LIKE c_msg_error.
  1963.     ENDIF.
  1964.     EDITOR-CALL FOR lt_code_string DISPLAY-MODE
  1965.                 TITLE 'Generated code for current query'(t01).
  1966.   ENDIF.
  1967.  
  1968. ENDFORM.                    " GENERATE_SUBROUTINE
  1969.  
  1970. *&---------------------------------------------------------------------*
  1971. *&      Form  DISPLAY_ALV_DATA
  1972. *&---------------------------------------------------------------------*
  1973. *       Display data table in the bottom ALV part of the screen
  1974. *----------------------------------------------------------------------*
  1975. *      -->FP_RESULT    Reference to data to display
  1976. *      -->FT_FIELDLIST List of fields to display
  1977. *      -->FP_TITLE     Title of the ALV
  1978. *----------------------------------------------------------------------*
  1979. FORM display_alv_data  USING fp_result TYPE REF TO data
  1980.                              ft_fieldlist TYPE ty_fieldlist_table
  1981.                              fp_title TYPE string.
  1982.   TYPE-POOLS lvc.
  1983.  
  1984.   DATA : ls_layout TYPE lvc_s_layo,
  1985.          lt_fieldcat TYPE lvc_t_fcat,
  1986.          ls_fieldlist TYPE ty_fieldlist,
  1987.          ls_fieldcat LIKE LINE OF lt_fieldcat.
  1988.   DATA : lo_descr_table TYPE REF TO cl_abap_tabledescr,
  1989.          lo_descr_line TYPE REF TO cl_abap_structdescr,
  1990.          ls_compx TYPE abap_compdescr,
  1991.          lw_height TYPE i.
  1992.  
  1993.   FIELD-SYMBOLS: <lft_data> TYPE ANY TABLE.
  1994.  
  1995.   ASSIGN fp_result->* TO <lft_data>.
  1996.  
  1997. * Get data type for COUNT & AVG fields
  1998.   lo_descr_table ?=
  1999.     cl_abap_typedescr=>describe_by_data_ref( fp_result ).
  2000.   lo_descr_line ?= lo_descr_table->get_table_line_type( ).
  2001.  
  2002.   LOOP AT ft_fieldlist INTO ls_fieldlist.
  2003.     CLEAR ls_fieldcat.
  2004.     ls_fieldcat-fieldname = ls_fieldlist-field.
  2005.  
  2006.     IF NOT ls_fieldlist-ref_table IS INITIAL.
  2007.       ls_fieldcat-ref_field = ls_fieldlist-ref_field.
  2008.       ls_fieldcat-ref_table = ls_fieldlist-ref_table.
  2009.       ls_fieldcat-reptext = ls_fieldlist-ref_field.
  2010.     ELSE. "COUNT & AVG field
  2011.       READ TABLE lo_descr_line->components INTO ls_compx
  2012.                  WITH KEY name = ls_fieldlist-field.        "#EC WARNOK
  2013.       ls_fieldcat-intlen = ls_compx-length.
  2014.       ls_fieldcat-decimals = ls_compx-decimals.
  2015.       ls_fieldcat-inttype = ls_compx-type_kind.
  2016.       ls_fieldcat-reptext = ls_fieldlist-ref_field.
  2017.     ENDIF.
  2018.     APPEND ls_fieldcat TO lt_fieldcat.
  2019.   ENDLOOP.
  2020.  
  2021.   ls_layout-smalltitle = abap_true.
  2022.   ls_layout-zebra = abap_true.
  2023.   ls_layout-cwidth_opt = abap_true.
  2024.   ls_layout-grid_title = fp_title.
  2025.  
  2026. * Set the grid config and content
  2027.   CALL METHOD o_alv_result->set_table_for_first_display
  2028.     EXPORTING
  2029.       is_layout       = ls_layout
  2030.     CHANGING
  2031.       it_outtab       = <lft_data>
  2032.       it_fieldcatalog = lt_fieldcat.
  2033.  
  2034. * Search if grid is currently displayed
  2035.   CALL METHOD o_splitter->get_row_height
  2036.     EXPORTING
  2037.       id     = 1
  2038.     IMPORTING
  2039.       result = lw_height.
  2040.   CALL METHOD cl_gui_cfw=>flush.
  2041.  
  2042. * If grid is hidden, display it
  2043.   IF lw_height = 100.
  2044.     CALL METHOD o_splitter->set_row_height
  2045.       EXPORTING
  2046.         id     = 1
  2047.         height = 20.
  2048.   ENDIF.
  2049. ENDFORM.                    " DISPLAY_ALV_DATA
  2050.  
  2051. *&---------------------------------------------------------------------*
  2052. *&      Form  INIT_DDIC
  2053. *&---------------------------------------------------------------------*
  2054. *       Init ddic tree
  2055. *----------------------------------------------------------------------*
  2056. FORM init_ddic.
  2057.   DATA : ls_header TYPE treev_hhdr,
  2058.          ls_event TYPE cntl_simple_event,
  2059.          lt_events TYPE cntl_simple_events.
  2060.  
  2061.   DATA: lo_dragdrop TYPE REF TO cl_dragdrop.
  2062.  
  2063.   ls_header-heading = 'SAP Table/Fields'(t02).
  2064.   ls_header-t_image = '@42@'. "Refresh icon
  2065.   ls_header-width = 30.
  2066.  
  2067.   CREATE OBJECT o_tree_ddic
  2068.     EXPORTING
  2069.       parent                      = o_container_ddic
  2070.       node_selection_mode         = cl_gui_column_tree=>node_sel_mode_single
  2071.       item_selection              = abap_true
  2072.       hierarchy_column_name       = c_ddic_col1
  2073.       hierarchy_header            = ls_header
  2074.     EXCEPTIONS
  2075.       cntl_system_error           = 1
  2076.       create_error                = 2
  2077.       failed                      = 3
  2078.       illegal_node_selection_mode = 4
  2079.       illegal_column_name         = 5
  2080.       lifetime_error              = 6.
  2081.   IF sy-subrc <> 0.
  2082.     MESSAGE a000(tree_control_msg).
  2083.   ENDIF.
  2084.  
  2085. * Column2
  2086.   CALL METHOD o_tree_ddic->add_column
  2087.     EXPORTING
  2088.       name                         = c_ddic_col2
  2089.       width                        = 21
  2090.       header_text                  = 'Description'(t03)
  2091.       header_image                 = '@13@'
  2092.     EXCEPTIONS
  2093.       column_exists                = 1
  2094.       illegal_column_name          = 2
  2095.       too_many_columns             = 3
  2096.       illegal_alignment            = 4
  2097.       different_column_types       = 5
  2098.       cntl_system_error            = 6
  2099.       failed                       = 7
  2100.       predecessor_column_not_found = 8.
  2101.  
  2102. * Manage Header clic event to refresh screen
  2103.   ls_event-eventid = cl_gui_column_tree=>eventid_header_click.
  2104.   ls_event-appl_event = abap_true.
  2105.   APPEND ls_event TO lt_events.
  2106.  
  2107. * Manage Item clic event to copy value in clipboard
  2108.   ls_event-eventid = cl_gui_column_tree=>eventid_item_double_click.
  2109.   ls_event-appl_event = abap_true.
  2110.   APPEND ls_event TO lt_events.
  2111.  
  2112.   CALL METHOD o_tree_ddic->set_registered_events
  2113.     EXPORTING
  2114.       events                    = lt_events
  2115.     EXCEPTIONS
  2116.       cntl_error                = 1
  2117.       cntl_system_error         = 2
  2118.       illegal_event_combination = 3.
  2119.   IF sy-subrc <> 0.
  2120.     MESSAGE a000(tree_control_msg).
  2121.   ENDIF.
  2122.  
  2123. * Create dragNdrop handler
  2124.   CREATE OBJECT lo_dragdrop.
  2125.   CALL METHOD lo_dragdrop->add
  2126.     EXPORTING
  2127.       flavor     = 'EDIT_INSERT'
  2128.       dragsrc    = 'X'
  2129.       droptarget = ' '
  2130.       effect     = cl_dragdrop=>copy.
  2131.   lo_dragdrop->get_handle(
  2132.      IMPORTING
  2133.        handle      = w_dragdrop_handle_tree
  2134. *    EXCEPTIONS
  2135. *      obj_invalid = 1
  2136. *      others      = 2
  2137.   ).
  2138.  
  2139.   SET HANDLER o_handle_event->handle_header_click_ddic FOR o_tree_ddic.
  2140.   SET HANDLER o_handle_event->handle_item_dblclick_ddic FOR o_tree_ddic.
  2141.   SET HANDLER o_handle_event->handle_tree_drag FOR o_tree_ddic.
  2142.  
  2143. ENDFORM.                    " INIT_DDIC
  2144.  
  2145. *&---------------------------------------------------------------------*
  2146. *&      Form  SET_DDIC_TREE
  2147. *&---------------------------------------------------------------------*
  2148. *       Refresh query with list of table/fields of the given query
  2149. *       Add User defined tree from ZSPRO (if relevant)
  2150. *----------------------------------------------------------------------*
  2151. *      -->FP_FROM  From part of the query
  2152. *----------------------------------------------------------------------*
  2153. FORM set_ddic_tree USING fp_from TYPE string.
  2154.  
  2155.   DATA : lw_from TYPE string,
  2156.          lt_split TYPE TABLE OF string,
  2157.          lw_string TYPE string,
  2158.          lw_tabix TYPE i,
  2159.          BEGIN OF ls_table_list,
  2160.            table(30),
  2161.            alias(30),
  2162.          END OF ls_table_list,
  2163.          lt_table_list LIKE TABLE OF ls_table_list,
  2164.          lw_node_number(6) TYPE n,
  2165.          ls_node LIKE LINE OF t_node_ddic,
  2166.          ls_item LIKE LINE OF t_item_ddic,
  2167.          lw_parent_node LIKE ls_node-node_key,
  2168.          BEGIN OF ls_ddic_fields,
  2169.            tabname TYPE dd03l-tabname,
  2170.            fieldname TYPE dd03l-fieldname,
  2171.            position TYPE dd03l-position,
  2172.            keyflag TYPE dd03l-keyflag,
  2173.            ddtext1 TYPE dd03t-ddtext,
  2174.            ddtext2 TYPE dd04t-ddtext,
  2175.          END OF ls_ddic_fields,
  2176.          lt_ddic_fields LIKE TABLE OF ls_ddic_fields.
  2177.  
  2178.   CONCATENATE 'FROM' fp_from INTO lw_from SEPARATED BY space.
  2179.  
  2180.   TRANSLATE lw_from TO UPPER CASE.
  2181.  
  2182.   SPLIT lw_from AT space INTO TABLE lt_split.
  2183.   LOOP AT lt_split INTO lw_string.
  2184.     lw_tabix = sy-tabix + 1.
  2185.     CHECK sy-tabix = 1 OR lw_string = 'JOIN'.
  2186. * Read next line (table name)
  2187.     READ TABLE lt_split INTO lw_string INDEX lw_tabix.
  2188.     CHECK sy-subrc = 0.
  2189.  
  2190.     CLEAR ls_table_list.
  2191.     ls_table_list-table = lw_string.
  2192.  
  2193.     lw_tabix = lw_tabix + 1.
  2194. * Read next line (search alias)
  2195.     READ TABLE lt_split INTO lw_string INDEX lw_tabix.
  2196.     IF sy-subrc = 0 AND lw_string = 'AS'.
  2197.       lw_tabix = lw_tabix + 1.
  2198.       READ TABLE lt_split INTO lw_string INDEX lw_tabix.
  2199.       IF sy-subrc = 0.
  2200.         ls_table_list-alias = lw_string.
  2201.       ENDIF.
  2202.     ENDIF.
  2203.     APPEND ls_table_list TO lt_table_list.
  2204.   ENDLOOP.
  2205.  
  2206. * Get list of fields for selected tables
  2207.   IF NOT lt_table_list IS INITIAL.
  2208.     SELECT dd03l~tabname dd03l~fieldname dd03l~position
  2209.            dd03l~keyflag dd03t~ddtext dd04t~ddtext
  2210.            INTO TABLE lt_ddic_fields
  2211.            FROM dd03l
  2212.            LEFT OUTER JOIN dd03t
  2213.            ON dd03l~tabname = dd03t~tabname
  2214.            AND dd03l~fieldname = dd03t~fieldname
  2215.            AND dd03l~as4local = dd03t~as4local
  2216.            AND dd03t~ddlanguage = sy-langu
  2217.            LEFT OUTER JOIN dd04t
  2218.            ON dd03l~rollname = dd04t~rollname
  2219.            AND dd03l~as4local = dd04t~as4local
  2220.            AND dd04t~ddlanguage = sy-langu
  2221.            FOR ALL ENTRIES IN lt_table_list
  2222.            WHERE dd03l~tabname = lt_table_list-table
  2223.            AND dd03l~as4local = c_vers_active
  2224.            AND dd03l~as4vers = space
  2225.            AND ( dd03l~comptype = c_ddic_dtelm
  2226.            OR    dd03l~comptype = space ).
  2227.     SORT lt_ddic_fields BY tabname keyflag DESCENDING position.
  2228.     DELETE ADJACENT DUPLICATES FROM lt_ddic_fields
  2229.                                COMPARING tabname fieldname.
  2230.   ENDIF.
  2231.  
  2232. * Build Node & Item tree
  2233.   REFRESH : t_node_ddic,
  2234.             t_item_ddic.
  2235.   lw_node_number = 0.
  2236.   LOOP AT lt_table_list INTO ls_table_list.
  2237. * Check table exists (has at least one field)
  2238.     READ TABLE lt_ddic_fields TRANSPORTING NO FIELDS
  2239.                WITH KEY tabname = ls_table_list-table.
  2240.     IF sy-subrc NE 0.
  2241.       DELETE lt_table_list.
  2242.       CONTINUE.
  2243.     ENDIF.
  2244.  
  2245.     lw_node_number = lw_node_number + 1.
  2246.     CLEAR ls_node.
  2247.     ls_node-node_key = lw_node_number.
  2248.     ls_node-isfolder = abap_true.
  2249.     ls_node-n_image = '@PO@'.
  2250.     ls_node-exp_image = '@PO@'.
  2251.     ls_node-expander = abap_true.
  2252.     APPEND ls_node TO t_node_ddic.
  2253.  
  2254.     CLEAR ls_item.
  2255.     ls_item-node_key = lw_node_number.
  2256.     ls_item-class = cl_gui_column_tree=>item_class_text.
  2257.     ls_item-item_name = c_ddic_col1.
  2258.     IF ls_table_list-alias IS INITIAL.
  2259.       ls_item-text = ls_table_list-table.
  2260.     ELSE.
  2261.       CONCATENATE ls_table_list-table 'AS' ls_table_list-alias
  2262.                    INTO ls_item-text SEPARATED BY space.
  2263.     ENDIF.
  2264.     APPEND ls_item TO t_item_ddic.
  2265.     ls_item-item_name = c_ddic_col2.
  2266.     SELECT SINGLE ddtext INTO ls_item-text
  2267.            FROM dd02t
  2268.            WHERE tabname = ls_table_list-table
  2269.            AND ddlanguage = sy-langu
  2270.            AND as4local = c_vers_active
  2271.            AND as4vers = space.
  2272.     IF sy-subrc NE 0.
  2273.       ls_item-text = ls_table_list-table.
  2274.     ENDIF.
  2275.     APPEND ls_item TO t_item_ddic.
  2276.  
  2277. * Display list of fields
  2278.     lw_parent_node = ls_node-node_key.
  2279.     LOOP AT lt_ddic_fields INTO ls_ddic_fields
  2280.             WHERE tabname = ls_table_list-table.
  2281.       CLEAR ls_node.
  2282.       lw_node_number = lw_node_number + 1.
  2283.       ls_node-node_key = lw_node_number.
  2284.       ls_node-relatkey = lw_parent_node.
  2285.       ls_node-relatship = cl_gui_column_tree=>relat_last_child.
  2286.       IF ls_ddic_fields-keyflag = space.
  2287.         ls_node-n_image = '@3W@'.
  2288.         ls_node-exp_image = '@3W@'.
  2289.       ELSE.
  2290.         ls_node-n_image = '@3V@'.
  2291.         ls_node-exp_image = '@3V@'.
  2292.       ENDIF.
  2293.       ls_node-dragdropid = w_dragdrop_handle_tree.
  2294.       APPEND ls_node TO t_node_ddic.
  2295.  
  2296.       CLEAR ls_item.
  2297.       ls_item-node_key = lw_node_number.
  2298.       ls_item-class = cl_gui_column_tree=>item_class_text.
  2299.       ls_item-item_name = c_ddic_col1.
  2300.       ls_item-text = ls_ddic_fields-fieldname.
  2301.       APPEND ls_item TO t_item_ddic.
  2302.       ls_item-item_name = c_ddic_col2.
  2303.       IF NOT ls_ddic_fields-ddtext1 IS INITIAL.
  2304.         ls_item-text = ls_ddic_fields-ddtext1.
  2305.       ELSE.
  2306.         ls_item-text = ls_ddic_fields-ddtext2.
  2307.       ENDIF.
  2308.       APPEND ls_item TO t_item_ddic.
  2309.     ENDLOOP.
  2310.   ENDLOOP.
  2311.  
  2312. * Add User defined tree from ZSPRO (if relevant)
  2313.   IF NOT t_node_zspro IS INITIAL.
  2314.     APPEND LINES OF t_node_zspro TO t_node_ddic.
  2315.     APPEND LINES OF t_item_zspro TO t_item_ddic.
  2316.   ENDIF.
  2317.  
  2318.   CALL METHOD o_tree_ddic->delete_all_nodes.
  2319.  
  2320.   CALL METHOD o_tree_ddic->add_nodes_and_items
  2321.     EXPORTING
  2322.       node_table                     = t_node_ddic
  2323.       item_table                     = t_item_ddic
  2324.       item_table_structure_name      = 'MTREEITM'
  2325.     EXCEPTIONS
  2326.       failed                         = 1
  2327.       cntl_system_error              = 3
  2328.       error_in_tables                = 4
  2329.       dp_error                       = 5
  2330.       table_structure_name_not_found = 6.
  2331.   IF sy-subrc <> 0.
  2332.     MESSAGE a000(tree_control_msg).
  2333.   ENDIF.
  2334.  
  2335.   DESCRIBE TABLE lt_table_list LINES lw_tabix.
  2336.  
  2337. * If no table found, display message
  2338.   IF lw_tabix = 0.
  2339.     MESSAGE 'No valid table found'(m15) TYPE c_msg_success
  2340.             DISPLAY LIKE c_msg_error.
  2341. * If 1 table found, expand it
  2342.   ELSEIF lw_tabix = 1.
  2343.     o_tree_ddic->expand_root_nodes( ).
  2344.   ENDIF.
  2345. ENDFORM.                    " SET_DDIC_TREE
  2346.  
  2347. *&---------------------------------------------------------------------*
  2348. *&      Form  SAVE_QUERY
  2349. *&---------------------------------------------------------------------*
  2350. *       Save query
  2351. *----------------------------------------------------------------------*
  2352. FORM save_query.
  2353.   DATA : lt_query TYPE soli_tab,
  2354.          ls_query LIKE LINE OF lt_query,
  2355.          lw_query_with_cr TYPE string,
  2356.          lw_guid TYPE guid_32,
  2357.          ls_ztoad TYPE ztoad,
  2358.          lw_timestamp(14) TYPE c.
  2359.  
  2360. * Set default options
  2361.   SELECT SINGLE class INTO s_options-visibilitygrp
  2362.          FROM usr02
  2363.          WHERE bname = sy-uname.
  2364.   s_options-visibility = '0'.
  2365.  
  2366. * Ask for options / query name
  2367.   CALL SCREEN 0200 STARTING AT 10 5
  2368.                   ENDING AT 60 7.
  2369.   IF s_options IS INITIAL.
  2370.     MESSAGE 'Action cancelled'(m14) TYPE c_msg_success
  2371.             DISPLAY LIKE c_msg_error.
  2372.     RETURN.
  2373.   ENDIF.
  2374.  
  2375. * Get content of abap edit box
  2376.   CALL METHOD o_textedit->get_text
  2377.     IMPORTING
  2378.       table  = lt_query[]
  2379.     EXCEPTIONS
  2380.       OTHERS = 1.
  2381.  
  2382. * Serialize query into a string
  2383.   CLEAR lw_query_with_cr.
  2384.   LOOP AT lt_query INTO ls_query.
  2385.     CONCATENATE lw_query_with_cr ls_query cl_abap_char_utilities=>cr_lf
  2386.                 INTO lw_query_with_cr.
  2387.   ENDLOOP.
  2388.  
  2389. * Generate new GUID
  2390.   DO 100 TIMES.
  2391.     TRY.
  2392.         lw_guid = cl_system_uuid=>create_uuid_c32_static( ).
  2393.       CATCH cx_uuid_error.
  2394.         EXIT. "exit do
  2395.     ENDTRY.
  2396.     SELECT SINGLE queryid INTO ls_ztoad-queryid
  2397.            FROM ztoad
  2398.            WHERE queryid = lw_guid.
  2399.  
  2400.     IF sy-subrc NE 0.
  2401.       EXIT. "exit do
  2402.     ENDIF.
  2403.   ENDDO.
  2404.  
  2405.   ls_ztoad-queryid = lw_guid.
  2406.   ls_ztoad-owner = sy-uname.
  2407.   lw_timestamp(8) = sy-datum.
  2408.   lw_timestamp+8 = sy-uzeit.
  2409.   ls_ztoad-aedat = lw_timestamp.
  2410.   ls_ztoad-text = s_options-name.
  2411.   ls_ztoad-visibility = s_options-visibility.
  2412.   ls_ztoad-visibility_group = s_options-visibilitygrp.
  2413.   ls_ztoad-query = lw_query_with_cr.
  2414.   INSERT ztoad FROM ls_ztoad.
  2415.   IF sy-subrc = 0.
  2416.     MESSAGE s031(r9). "Query saved
  2417.   ELSE.
  2418.     MESSAGE e220(iqapi). "Error when saving the query
  2419.   ENDIF.
  2420.  
  2421. * Reset the modified status
  2422.   o_textedit->set_textmodified_status( ).
  2423.  
  2424.   PERFORM fill_repository.
  2425.   PERFORM focus_repository USING lw_guid.
  2426. ENDFORM.                    " SAVE_QUERY
  2427.  
  2428. *&---------------------------------------------------------------------*
  2429. *&      Form  INIT_REPOSITORY
  2430. *&---------------------------------------------------------------------*
  2431. *       Initialize repository tree
  2432. *----------------------------------------------------------------------*
  2433. FORM init_repository.
  2434.   DATA: lt_event TYPE cntl_simple_events,
  2435.         ls_event TYPE cntl_simple_event.
  2436.  
  2437. * Create a tree control
  2438.   CREATE OBJECT o_tree_repository
  2439.     EXPORTING
  2440.       parent              = o_container_repository
  2441.       node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single
  2442.     EXCEPTIONS
  2443.       lifetime_error      = 1
  2444.       cntl_system_error   = 2
  2445.       create_error        = 3
  2446.       failed              = 4
  2447.       OTHERS              = 5.
  2448.   IF sy-subrc <> 0.
  2449.     MESSAGE a000(tree_control_msg).
  2450.   ENDIF.
  2451.  
  2452. * Catch double clic to open query
  2453.   ls_event-eventid = cl_gui_simple_tree=>eventid_node_double_click.
  2454.   ls_event-appl_event = abap_true. " no PAI if event occurs
  2455.   APPEND ls_event TO lt_event.
  2456.  
  2457. * Catch context menu call
  2458.   ls_event-eventid = cl_gui_simple_tree=>eventid_node_context_menu_req.
  2459.   ls_event-appl_event = abap_true. " no PAI if event occurs
  2460.   APPEND ls_event TO lt_event.
  2461.  
  2462.   CALL METHOD o_tree_repository->set_registered_events
  2463.     EXPORTING
  2464.       events                    = lt_event
  2465.     EXCEPTIONS
  2466.       cntl_error                = 1
  2467.       cntl_system_error         = 2
  2468.       illegal_event_combination = 3.
  2469.   IF sy-subrc <> 0.
  2470.     MESSAGE a000(tree_control_msg).
  2471.   ENDIF.
  2472.  
  2473.   DATA: lo_dragrop TYPE REF TO cl_dragdrop.
  2474.   CREATE OBJECT lo_dragrop.
  2475.   CALL METHOD lo_dragrop->add
  2476.     EXPORTING
  2477.       flavor     = 'EDIT_INSERT'
  2478.       dragsrc    = ' '
  2479.       droptarget = 'X'
  2480.       effect     = cl_dragdrop=>copy.
  2481.   lo_dragrop->get_handle(
  2482.      IMPORTING
  2483.        handle      = w_dragdrop_handle_tree
  2484. *  EXCEPTIONS
  2485. *    obj_invalid = 1
  2486. *    others      = 2
  2487.   ).
  2488.  
  2489. * Assign event handlers in the application class to each desired event
  2490.   SET HANDLER o_handle_event->handle_dblclick_repository
  2491.       FOR o_tree_repository.
  2492.   SET HANDLER o_handle_event->handle_context_menu_repository
  2493.       FOR o_tree_repository.
  2494.   SET HANDLER o_handle_event->handle_context_menu_sel_repo
  2495.       FOR o_tree_repository.
  2496.  
  2497.   PERFORM fill_repository.
  2498.  
  2499. ENDFORM.                    " INIT_REPOSITORY
  2500.  
  2501. *&---------------------------------------------------------------------*
  2502. *&      Form  FILL_REPOSITORY
  2503. *&---------------------------------------------------------------------*
  2504. *       Fill repository tree with all allowed queries
  2505. *----------------------------------------------------------------------*
  2506. FORM fill_repository.
  2507.   DATA : lw_usergroup TYPE usr02-class,
  2508.          BEGIN OF ls_query,
  2509.            queryid TYPE ztoad-queryid,
  2510.            aedat TYPE ztoad-aedat,
  2511.            visibility TYPE ztoad-visibility,
  2512.            text TYPE ztoad-text,
  2513.            query TYPE ztoad-query,
  2514.          END OF ls_query,
  2515.          lt_query_my LIKE TABLE OF ls_query,
  2516.          lt_query_shared LIKE TABLE OF ls_query,
  2517.          lw_node_key(6) TYPE n,
  2518.          lw_queryid TYPE ztoad-queryid,
  2519.          lw_dummy(1) TYPE c.                                "#EC NEEDED
  2520.  
  2521. * Get usergroup
  2522.   SELECT SINGLE class INTO lw_usergroup
  2523.          FROM usr02
  2524.          WHERE bname = sy-uname.
  2525.  
  2526. * Get all my queries
  2527.   SELECT queryid aedat visibility text query INTO TABLE lt_query_my
  2528.          FROM ztoad
  2529.          WHERE owner = sy-uname.
  2530.  
  2531. * Get all queries that i can use
  2532.   SELECT queryid aedat visibility text INTO TABLE lt_query_shared
  2533.          FROM ztoad
  2534.          WHERE owner NE sy-uname
  2535.          AND ( visibility = c_visibility_all
  2536.                OR ( visibility = c_visibility_shared
  2537.                     AND visibility_group = lw_usergroup )
  2538.              ).
  2539.   REFRESH t_node_repository.
  2540.  
  2541.   CALL METHOD o_tree_repository->delete_all_nodes.
  2542.  
  2543.   CLEAR s_node_repository.
  2544.   s_node_repository-node_key = c_nodekey_repo_my.
  2545.   s_node_repository-isfolder = abap_true.
  2546. *  s_node-n_image = s_node-exp_image = '@MV@'.
  2547.   s_node_repository-text = 'My queries'(m16).
  2548.   APPEND s_node_repository TO t_node_repository.
  2549.  
  2550.   CLEAR lw_node_key.
  2551.   CONCATENATE sy-uname '+++' INTO lw_queryid.
  2552.   LOOP AT lt_query_my INTO ls_query WHERE queryid NP lw_queryid.
  2553.     lw_node_key = lw_node_key + 1.
  2554.     CLEAR s_node_repository.
  2555.     s_node_repository-node_key = lw_node_key.
  2556.     s_node_repository-relatkey = c_nodekey_repo_my.
  2557.     s_node_repository-relatship = cl_gui_simple_tree=>relat_last_child.
  2558.     IF ls_query-visibility = c_visibility_my.
  2559.       s_node_repository-n_image = s_node_repository-exp_image = '@LC@'.
  2560.     ELSE.
  2561.       s_node_repository-n_image = s_node_repository-exp_image = '@L9@'.
  2562.     ENDIF.
  2563.     s_node_repository-text = ls_query-text.
  2564.     s_node_repository-queryid = ls_query-queryid.
  2565.     s_node_repository-edit = abap_true.
  2566.     APPEND s_node_repository TO t_node_repository.
  2567.   ENDLOOP.
  2568.  
  2569.   CLEAR s_node_repository.
  2570.   s_node_repository-node_key = c_nodekey_repo_shared.
  2571.   s_node_repository-isfolder = abap_true.
  2572. *  s_node-n_image = s_node-exp_image = '@MV@'.
  2573.   s_node_repository-text = 'Shared queries'(m17).
  2574.   APPEND s_node_repository TO t_node_repository.
  2575.  
  2576.   LOOP AT lt_query_shared INTO ls_query.
  2577.     lw_node_key = lw_node_key + 1.
  2578.     CLEAR s_node_repository.
  2579.     s_node_repository-node_key = lw_node_key.
  2580.     s_node_repository-relatkey = c_nodekey_repo_shared.
  2581.     s_node_repository-relatship = cl_gui_simple_tree=>relat_last_child.
  2582.     s_node_repository-n_image = s_node_repository-exp_image = '@L9@'.
  2583.     s_node_repository-text = ls_query-text.
  2584.     s_node_repository-queryid = ls_query-queryid.
  2585.     s_node_repository-edit = space.
  2586.     APPEND s_node_repository TO t_node_repository.
  2587.   ENDLOOP.
  2588.  
  2589. * Add history node
  2590.   CLEAR s_node_repository.
  2591.   s_node_repository-node_key = c_nodekey_repo_history.
  2592.   s_node_repository-isfolder = abap_true.
  2593. *  s_node-n_image = s_node-exp_image = '@MV@'.
  2594.   s_node_repository-text = 'History'(m18).
  2595.   APPEND s_node_repository TO t_node_repository.
  2596.  
  2597.   DELETE lt_query_my WHERE queryid NP lw_queryid.
  2598.   SORT lt_query_my BY aedat DESCENDING.
  2599.   LOOP AT lt_query_my INTO ls_query.
  2600.     lw_node_key = lw_node_key + 1.
  2601.     CLEAR s_node_repository.
  2602.     s_node_repository-node_key = lw_node_key.
  2603.     s_node_repository-relatkey = c_nodekey_repo_history.
  2604.     s_node_repository-relatship = cl_gui_simple_tree=>relat_last_child.
  2605.     s_node_repository-n_image = s_node_repository-exp_image = '@LC@'.
  2606.     s_node_repository-text = ls_query-text.
  2607.     s_node_repository-queryid = ls_query-queryid.
  2608.     s_node_repository-edit = abap_true.
  2609.     IF ls_query-query(1) = '*'.
  2610.       SPLIT ls_query-query+1 AT cl_abap_char_utilities=>cr_lf
  2611.             INTO ls_query-query lw_dummy.
  2612.       CONCATENATE s_node_repository-text ':' ls_query-query
  2613.                   INTO s_node_repository-text SEPARATED BY space.
  2614.     ENDIF.
  2615.     APPEND s_node_repository TO t_node_repository.
  2616.   ENDLOOP.
  2617.  
  2618.   CALL METHOD o_tree_repository->add_nodes
  2619.     EXPORTING
  2620.       table_structure_name           = 'MTREESNODE'
  2621.       node_table                     = t_node_repository
  2622.     EXCEPTIONS
  2623.       failed                         = 1
  2624.       error_in_node_table            = 2
  2625.       dp_error                       = 3
  2626.       table_structure_name_not_found = 4
  2627.       OTHERS                         = 5.
  2628.   IF sy-subrc <> 0.
  2629.     MESSAGE a000(tree_control_msg).
  2630.   ENDIF.
  2631.  
  2632. * Exand all root nodes (my, shared, history)
  2633.   CALL METHOD o_tree_repository->expand_root_nodes.
  2634. ENDFORM.                    " FILL_REPOSITORY
  2635.  
  2636. *&---------------------------------------------------------------------*
  2637. *&      Form  SAVE_CURRENT_QUERY
  2638. *&---------------------------------------------------------------------*
  2639. *       Save query in the history area
  2640. *       Keep only 100 last queries
  2641. *----------------------------------------------------------------------*
  2642. FORM save_current_query.
  2643.   DATA : lt_query TYPE soli_tab,
  2644.          ls_query LIKE LINE OF lt_query,
  2645.          lw_query_with_cr TYPE string,
  2646.          ls_ztoad TYPE ztoad,
  2647.          lw_number(2) TYPE n,
  2648.          lw_timestamp(14) TYPE c,
  2649.          lw_dummy(1) TYPE c,                                "#EC NEEDED
  2650.          lw_query_last TYPE string,
  2651.          lw_date(10) TYPE c,
  2652.          lw_time(8) TYPE c.
  2653.  
  2654. * Get content of abap edit box
  2655.   CALL METHOD o_textedit->get_text
  2656.     IMPORTING
  2657.       table  = lt_query[]
  2658.     EXCEPTIONS
  2659.       OTHERS = 1.
  2660.  
  2661. * Serialize query into a string
  2662.   CLEAR lw_query_with_cr.
  2663.   LOOP AT lt_query INTO ls_query.
  2664.     CONCATENATE lw_query_with_cr ls_query cl_abap_char_utilities=>cr_lf
  2665.                 INTO lw_query_with_cr.
  2666.   ENDLOOP.
  2667.  
  2668. * Define timestamp
  2669.   lw_timestamp(8) = sy-datum.
  2670.   lw_timestamp+8 = sy-uzeit.
  2671.   ls_ztoad-aedat = lw_timestamp.
  2672.  
  2673. * Search if query is same as last loaded
  2674.   SELECT SINGLE query INTO lw_query_last
  2675.          FROM ztoad
  2676.          WHERE queryid = w_last_loaded_query.
  2677.   IF sy-subrc = 0 AND lw_query_last = lw_query_with_cr.
  2678.     RETURN.
  2679.   ENDIF.
  2680.  
  2681. * Get usergroup
  2682.   SELECT SINGLE class INTO ls_ztoad-visibility_group
  2683.          FROM usr02
  2684.          WHERE bname = sy-uname.
  2685.  
  2686.   CLEAR lw_number.
  2687.  
  2688. * Get last query from history
  2689.   CONCATENATE sy-uname '#%' INTO ls_ztoad-queryid.
  2690.   SELECT queryid
  2691.          INTO ls_ztoad-queryid
  2692.          FROM ztoad
  2693.          UP TO 1 ROWS
  2694.          WHERE queryid LIKE ls_ztoad-queryid
  2695.          AND owner = sy-uname
  2696.          ORDER BY aedat DESCENDING.
  2697.   ENDSELECT.
  2698.   IF sy-subrc = 0.
  2699.     SPLIT ls_ztoad-queryid AT '#' INTO lw_dummy lw_number.
  2700.   ENDIF.
  2701.  
  2702.   lw_number = lw_number + 1.
  2703.  
  2704. * For history query, guid = <sy-uname>#NN
  2705.   CONCATENATE sy-uname '#' lw_number INTO ls_ztoad-queryid.
  2706.   ls_ztoad-owner = sy-uname.
  2707.   ls_ztoad-visibility = c_visibility_my.
  2708.  
  2709. * Define text for query as timestamp
  2710.   WRITE sy-datlo TO lw_date.
  2711.   WRITE sy-timlo TO lw_time.
  2712.   CONCATENATE lw_date lw_time INTO ls_ztoad-text SEPARATED BY space.
  2713.  
  2714.   ls_ztoad-query = lw_query_with_cr.
  2715.   MODIFY ztoad FROM ls_ztoad.
  2716.  
  2717.   w_last_loaded_query = ls_ztoad-queryid.
  2718.  
  2719. * Reset the modified status
  2720.   o_textedit->set_textmodified_status( ).
  2721.  
  2722. * Refresh repository
  2723.   PERFORM fill_repository.
  2724.  
  2725. * Focus on new query
  2726.   PERFORM focus_repository USING ls_ztoad-queryid.
  2727. ENDFORM.                    " SAVE_CURRENT_QUERY
  2728.  
  2729. *&---------------------------------------------------------------------*
  2730. *&      Form  LOAD_QUERY
  2731. *&---------------------------------------------------------------------*
  2732. *       Load query
  2733. *----------------------------------------------------------------------*
  2734. *      -->FP_QUERYID QueryID to load
  2735. *      <--FT_QUERY   Saved query
  2736. *----------------------------------------------------------------------*
  2737. FORM load_query USING fp_queryid TYPE ztoad-queryid
  2738.                 CHANGING ft_query TYPE table.
  2739.   DATA lw_query_with_cr TYPE string.
  2740.   REFRESH ft_query.
  2741.  
  2742.   SELECT SINGLE query INTO lw_query_with_cr
  2743.          FROM ztoad
  2744.          WHERE queryid = fp_queryid.
  2745.   IF sy-subrc = 0.
  2746.     SPLIT lw_query_with_cr AT cl_abap_char_utilities=>cr_lf
  2747.                            INTO TABLE ft_query.
  2748.   ENDIF.
  2749.   w_last_loaded_query = fp_queryid.
  2750. ENDFORM.                    " LOAD_QUERY
  2751.  
  2752. *&---------------------------------------------------------------------*
  2753. *&      Form  FOCUS_REPOSITORY
  2754. *&---------------------------------------------------------------------*
  2755. *       Focus repository tree on a given queryid
  2756. *----------------------------------------------------------------------*
  2757. *      -->FP_QUERYID  ID of the query to focus
  2758. *----------------------------------------------------------------------*
  2759. FORM focus_repository USING fp_queryid TYPE ztoad-queryid.
  2760.  
  2761.   READ TABLE t_node_repository INTO s_node_repository
  2762.              WITH KEY queryid = fp_queryid.
  2763.   IF sy-subrc NE 0.
  2764.     RETURN.
  2765.   ENDIF.
  2766.  
  2767.   CALL METHOD o_tree_repository->set_selected_node
  2768.     EXPORTING
  2769.       node_key = s_node_repository-node_key.
  2770.  
  2771. ENDFORM.                    " FOCUS_REPOSITORY
  2772.  
  2773. *&---------------------------------------------------------------------*
  2774. *&      Form  INIT_RESULT
  2775. *&---------------------------------------------------------------------*
  2776. *       Init ALV grid
  2777. *----------------------------------------------------------------------*
  2778. FORM init_result.
  2779.  
  2780. * Create ALV
  2781.   CREATE OBJECT o_alv_result
  2782.     EXPORTING
  2783.       i_parent = o_container_result.
  2784.  
  2785. * Register event toolbar to add button
  2786.   SET HANDLER o_handle_event->handle_toolbar_result FOR o_alv_result.
  2787.   SET HANDLER o_handle_event->handle_user_command_result
  2788.       FOR o_alv_result.
  2789.  
  2790. ENDFORM.                    " INIT_RESULT
  2791.  
  2792. *&---------------------------------------------------------------------*
  2793. *&      Form  INIT_LISTBOX_0200
  2794. *&---------------------------------------------------------------------*
  2795. *       Fill dropdown listbox with value on screen 200
  2796. *----------------------------------------------------------------------*
  2797. FORM init_listbox_0200 .
  2798.   DATA : lt_visibility TYPE vrm_values,
  2799.          ls_visibility LIKE LINE OF lt_visibility.
  2800.  
  2801.   REFRESH lt_visibility.
  2802.  
  2803.   ls_visibility-key = c_visibility_my.
  2804.   ls_visibility-text = 'Personal'(m19).
  2805.   APPEND ls_visibility TO lt_visibility.
  2806.  
  2807.   ls_visibility-key = c_visibility_shared.
  2808.   ls_visibility-text = 'User group'(m20).
  2809.   APPEND ls_visibility TO lt_visibility.
  2810.  
  2811.   ls_visibility-key = c_visibility_all.
  2812.   ls_visibility-text = 'All'(m21).
  2813.   APPEND ls_visibility TO lt_visibility.
  2814.  
  2815.   CALL FUNCTION 'VRM_SET_VALUES'
  2816.     EXPORTING
  2817.       id     = 'S_OPTIONS-VISIBILITY'
  2818.       values = lt_visibility.
  2819.  
  2820. ENDFORM.                    " INIT_LISTBOX_0200
  2821.  
  2822. *&---------------------------------------------------------------------*
  2823. *&      Form  EXIT_PROGRAM
  2824. *&---------------------------------------------------------------------*
  2825. *       Close the grid. If grid is closed, leave program
  2826. *       If sql text area is modified, ask confirmation before leave
  2827. *----------------------------------------------------------------------*
  2828. FORM exit_program .
  2829.   DATA : lw_status TYPE i,
  2830.          lw_answer(1) TYPE c,
  2831.          lw_size TYPE i.
  2832.  
  2833. * Check if grid is displayed
  2834.   CALL METHOD o_splitter->get_row_height
  2835.     EXPORTING
  2836.       id     = 1
  2837.     IMPORTING
  2838.       result = lw_size.
  2839.   CALL METHOD cl_gui_cfw=>flush.
  2840.  
  2841. * If grid is displayed, BACK action is only to close the grid
  2842.   IF lw_size < 100.
  2843.     CALL METHOD o_splitter->set_row_height
  2844.       EXPORTING
  2845.         id     = 1
  2846.         height = 100.
  2847.     RETURN.
  2848.   ENDIF.
  2849.  
  2850. * Check if textedit is modified
  2851.   CALL METHOD o_textedit->get_textmodified_status
  2852.     IMPORTING
  2853.       status = lw_status.
  2854.   IF lw_status NE 0.
  2855.     CALL FUNCTION 'POPUP_TO_CONFIRM'
  2856.       EXPORTING
  2857.         text_question         =                                    ".
  2858. 'Current query is not saved. Are you sure you want to exit ?'(m22) ".
  2859.         text_button_1         = 'Exit'(m23)
  2860.         icon_button_1         = '@01@'
  2861.         text_button_2         = 'Cancel'(m24)
  2862.         icon_button_2         = '@02@'
  2863.         default_button        = '2'
  2864.         display_cancel_button = space
  2865.       IMPORTING
  2866.         answer                = lw_answer.
  2867.     IF lw_answer NE '1'.
  2868.       RETURN.
  2869.     ENDIF.
  2870.   ENDIF.
  2871.  
  2872.   LEAVE TO SCREEN 0.
  2873. ENDFORM.                    " EXIT_PROGRAM
  2874.  
  2875. *&---------------------------------------------------------------------*
  2876. *&      Form  DISPLAY_HELP
  2877. *&---------------------------------------------------------------------*
  2878. *       Display help for this program
  2879. *----------------------------------------------------------------------*
  2880. FORM display_help.
  2881.   DATA : l_report TYPE string,
  2882.          l_report_char1(1) TYPE c,
  2883.          l_report_char3(3) TYPE c,
  2884.          l_comment_found TYPE i,
  2885.          lt_report LIKE TABLE OF l_report,
  2886.          lt_lines TYPE rcl_bag_tline,
  2887.          ls_line LIKE LINE OF lt_lines,
  2888.          ls_help TYPE help_info,
  2889.          lt_exclude TYPE STANDARD TABLE OF string.
  2890.  
  2891. * Get program source code
  2892.   READ REPORT sy-repid INTO lt_report.
  2893.  
  2894.   ls_line-tdformat = 'U1'.
  2895.   ls_line-tdline = sy-title.
  2896.   APPEND ls_line TO lt_lines.
  2897.  
  2898.   ls_line-tdformat = 'U3'.
  2899.   ls_line-tdline = '&PURPOSE&'.
  2900.   APPEND ls_line TO lt_lines.
  2901.  
  2902.   LOOP AT lt_report INTO l_report.
  2903.     l_report_char1 = l_report.
  2904.     CHECK l_report_char1 = '*'.
  2905.  
  2906. * Keep only the second block of comment
  2907. * (first block is technical info, third is history)
  2908.     l_report_char3 = l_report.
  2909.     IF l_report_char3 = '*&-'.
  2910.       l_comment_found = l_comment_found + 1.
  2911.       IF l_comment_found LE 2.
  2912.         CONTINUE.
  2913.       ELSE. "l_comment_found > 2
  2914.         EXIT.
  2915.       ENDIF.
  2916.     ENDIF.
  2917.     IF l_comment_found = 2.
  2918.       l_report = l_report+1.
  2919.       l_report_char1 = l_report.
  2920.       CASE l_report_char1.
  2921.         WHEN '='.
  2922.           ls_line-tdformat = '='.
  2923.         WHEN '3'.
  2924.           ls_line-tdformat = 'U3'.
  2925.         WHEN 'E'.
  2926.           ls_line-tdformat = 'PE'.
  2927.         WHEN OTHERS.
  2928.           ls_line-tdformat = '*'.
  2929.       ENDCASE.
  2930.       IF NOT l_report_char1 IS INITIAL.
  2931.         l_report = l_report+1.
  2932.       ENDIF.
  2933.       IF l_report IS INITIAL.
  2934.         ls_line-tdformat = 'LZ'.
  2935.       ENDIF.
  2936.       ls_line-tdline = l_report.
  2937.       APPEND ls_line TO lt_lines.
  2938.     ENDIF.
  2939.   ENDLOOP.
  2940.  
  2941.   CALL FUNCTION 'HELP_DOCULINES_SHOW'
  2942.     EXPORTING
  2943.       help_infos = ls_help
  2944.     TABLES
  2945.       excludefun = lt_exclude
  2946.       helplines  = lt_lines.
  2947.  
  2948. ENDFORM.                    " DISPLAY_HELP
  2949.  
  2950. *&---------------------------------------------------------------------*
  2951. *&      Form  PARSE_QUERY_NOSELECT
  2952. *&---------------------------------------------------------------------*
  2953. *       Check if query is a known SQL command and if user is allowed
  2954. *----------------------------------------------------------------------*
  2955. *      -->FP_QUERY   Query to check
  2956. *      <--FP_NOAUTH  Unallowed table or command entered
  2957. *      <--FP_COMMAND Command to execute (INSERT, DELETE, ...)
  2958. *      <--FP_TABLE   Target table of the query
  2959. *      <--FP_PARAM   Parameters for the command (WHERE, SET, ...)
  2960. *----------------------------------------------------------------------*
  2961. FORM parse_query_noselect  USING    fp_query TYPE string
  2962.                            CHANGING fp_noauth TYPE c
  2963.                                     fp_command TYPE string
  2964.                                     fp_table TYPE string
  2965.                                     fp_param TYPE string.
  2966.   DATA : lw_query TYPE string,
  2967.          lw_table TYPE tabname.
  2968.  
  2969.   CLEAR : fp_noauth,
  2970.           fp_table,
  2971.           fp_command,
  2972.           fp_param.
  2973.  
  2974.   lw_query = fp_query.
  2975.   SPLIT lw_query AT space INTO fp_command lw_query.
  2976.   TRANSLATE fp_command TO UPPER CASE.
  2977.   CASE fp_command.
  2978.     WHEN 'INSERT'.
  2979.       SPLIT lw_query AT space INTO fp_table fp_param.
  2980.       TRANSLATE fp_table TO UPPER CASE.
  2981.       CLEAR sy-subrc.
  2982.       IF s_auth-auth_object NE space.
  2983.         lw_table = fp_table.
  2984.         AUTHORITY-CHECK OBJECT s_auth-auth_object
  2985.                  ID 'INSERT' FIELD lw_table.
  2986.       ELSEIF s_auth-insert NE '*' AND fp_table NP s_auth-insert.
  2987.         sy-subrc = 4.
  2988.       ENDIF.
  2989.       IF sy-subrc NE 0.
  2990.         CONCATENATE 'No authorisation for table'(m13) fp_table
  2991.                     INTO lw_query SEPARATED BY space.
  2992.         MESSAGE lw_query TYPE c_msg_success DISPLAY LIKE c_msg_error.
  2993.         fp_noauth = abap_true.
  2994.         RETURN.
  2995.       ENDIF.
  2996.  
  2997.     WHEN 'UPDATE'.
  2998.       SPLIT lw_query AT space INTO fp_table fp_param.
  2999.       TRANSLATE fp_table TO UPPER CASE.
  3000.       CLEAR sy-subrc.
  3001.       IF s_auth-auth_object NE space.
  3002.         lw_table = fp_table.
  3003.         AUTHORITY-CHECK OBJECT s_auth-auth_object
  3004.                  ID 'UPDATE' FIELD lw_table.
  3005.       ELSEIF s_auth-update NE '*' AND fp_table NP s_auth-update.
  3006.         sy-subrc = 4.
  3007.       ENDIF.
  3008.       IF sy-subrc NE 0.
  3009.         CONCATENATE 'No authorisation for table'(m13) fp_table
  3010.                     INTO lw_query SEPARATED BY space.
  3011.         MESSAGE lw_query TYPE c_msg_success DISPLAY LIKE c_msg_error.
  3012.         fp_noauth = abap_true.
  3013.         RETURN.
  3014.       ENDIF.
  3015.  
  3016.     WHEN 'DELETE'.
  3017.       SPLIT lw_query AT space INTO fp_table fp_param.
  3018.       TRANSLATE fp_table TO UPPER CASE.
  3019.       IF fp_table = 'FROM'.
  3020.         SPLIT fp_param AT space INTO fp_table fp_param.
  3021.         TRANSLATE fp_table TO UPPER CASE.
  3022.       ENDIF.
  3023.       CLEAR sy-subrc.
  3024.       IF s_auth-auth_object NE space.
  3025.         lw_table = fp_table.
  3026.         AUTHORITY-CHECK OBJECT s_auth-auth_object
  3027.                  ID 'DELETE' FIELD lw_table.
  3028.       ELSEIF s_auth-insert NE '*' AND NOT fp_table CP s_auth-insert.
  3029.         sy-subrc = 4.
  3030.       ENDIF.
  3031.       IF sy-subrc NE 0.
  3032.         CONCATENATE 'No authorisation for table'(m13) fp_table
  3033.                     INTO lw_query SEPARATED BY space.
  3034.         MESSAGE lw_query TYPE c_msg_success DISPLAY LIKE c_msg_error.
  3035.         fp_noauth = abap_true.
  3036.         RETURN.
  3037.       ENDIF.
  3038.  
  3039.     WHEN OTHERS.
  3040.       CONCATENATE 'SQL command not allowed :'(m25) fp_command
  3041.                   INTO lw_query.
  3042.       MESSAGE lw_query TYPE c_msg_success DISPLAY LIKE c_msg_error.
  3043.       fp_noauth = abap_true.
  3044.       RETURN.
  3045.   ENDCASE.
  3046. ENDFORM.                    " PARSE_QUERY_NOSELECT
  3047.  
  3048. *&---------------------------------------------------------------------*
  3049. *&      Form  GENERATE_SUBROUTINE_NOSELECT
  3050. *&---------------------------------------------------------------------*
  3051. *       Create all other than SELECT SQL query in a new generated
  3052. *       temp program
  3053. *----------------------------------------------------------------------*
  3054. *      -->FP_COMMAND Query type
  3055. *      -->FP_TABLE   Target table of the query
  3056. *      -->FP_PARAM   Parameters of the query
  3057. *      -->FP_DISPLAY   Display code instead of generated routine
  3058. *      <--FP_PROGRAM Name of the generated program
  3059. *----------------------------------------------------------------------*
  3060. FORM generate_subroutine_noselect  USING    fp_command TYPE string
  3061.                                             fp_table TYPE string
  3062.                                             fp_param TYPE string
  3063.                                             fp_display TYPE c
  3064.                                    CHANGING fp_program TYPE sy-repid.
  3065.  
  3066.   DATA : lt_code_string TYPE TABLE OF string,
  3067.          lw_mess(255),
  3068.          lw_line TYPE i,
  3069.          lw_word(30),
  3070.          lw_strlen_string TYPE string,
  3071.          lw_explicit TYPE string,
  3072.          lw_length TYPE i,
  3073.          lw_pos TYPE i,
  3074.          lw_fieldnum TYPE i,
  3075.          lw_fieldval TYPE string,
  3076.          lw_fieldname TYPE string,
  3077.          lw_wait_name(1) TYPE c,
  3078.          lw_char(1) TYPE c,
  3079.          lw_started(1) TYPE c,
  3080.          lw_started_field(1) TYPE c.
  3081.  
  3082.   DEFINE c.
  3083.     lw_strlen_string = &1.
  3084.     perform add_line_to_table using lw_strlen_string
  3085.                               changing lt_code_string.
  3086.   END-OF-DEFINITION.
  3087.  
  3088. * Write Header
  3089.   c 'PROGRAM SUBPOOL.'.                                     "#EC NOTEXT
  3090.   c '** GENERATED PROGRAM * DO NOT CHANGE IT **'.           "#EC NOTEXT
  3091.   c 'type-pools: slis.'.                                    "#EC NOTEXT
  3092.   c 'DATA : w_timestart type timestampl,'.                  "#EC NOTEXT
  3093.   c '       w_timeend type timestampl.'.                    "#EC NOTEXT
  3094.   c ''.
  3095.   IF fp_command = 'INSERT'.
  3096.     c 'DATA s_insert type'.                                 "#EC NOTEXT
  3097.     c fp_table.
  3098.     c '.'.                                                  "#EC NOTEXT
  3099.     c 'FIELD-SYMBOLS <fs> TYPE ANY.'.                       "#EC NOTEXT
  3100.     c '.'.                                                  "#EC NOTEXT
  3101.   ENDIF.
  3102.  
  3103. * Write the dynamic subroutine that run the SELECT
  3104.   c 'FORM run_sql CHANGING fp_result TYPE REF TO data'.     "#EC NOTEXT
  3105.   c '                      fp_time TYPE p'.                 "#EC NOTEXT
  3106.   c '                      fp_count TYPE i.'.               "#EC NOTEXT
  3107.   c '***************************************'.              "#EC NOTEXT
  3108.   c '*            Begin of query           *'.              "#EC NOTEXT
  3109.   c '***************************************'.              "#EC NOTEXT
  3110.   c 'CLEAR fp_count.'.                                      "#EC NOTEXT
  3111.   c 'GET TIME STAMP FIELD w_timestart.'.                    "#EC NOTEXT
  3112.  
  3113.   CASE fp_command.
  3114.     WHEN 'UPDATE'.
  3115.       c fp_command.
  3116.       c fp_table.
  3117.       c fp_param.
  3118.       c '.'.
  3119.     WHEN 'DELETE'.
  3120.       c fp_command.
  3121.       c 'FROM'.                                             "#EC NOTEXT
  3122.       c fp_table.
  3123.       c fp_param.
  3124.       c '.'.
  3125.     WHEN 'INSERT'.
  3126.  
  3127.       IF fp_param(6) = 'VALUES'.
  3128.         lw_length = strlen( fp_param ).
  3129.         lw_pos = 6.
  3130.         lw_fieldnum = 0.
  3131.         WHILE lw_pos < lw_length.
  3132.           lw_char = fp_param+lw_pos(1).
  3133.           lw_pos = lw_pos + 1.
  3134.           IF lw_started = space.
  3135.             IF lw_char NE '('. "begin of the list
  3136.               CONTINUE.
  3137.             ENDIF.
  3138.             lw_started = abap_true.
  3139.             CONTINUE.
  3140.           ENDIF.
  3141.           IF lw_started_field = space.
  3142.             IF lw_char = ')'. "end of the list
  3143.               EXIT. "exit while
  3144.             ENDIF.
  3145.  
  3146.             IF lw_char NE ''''. "field value must start by '
  3147.               CONTINUE.
  3148.             ENDIF.
  3149.             lw_started_field = abap_true.
  3150.             lw_fieldval = lw_char.
  3151.             lw_fieldnum = lw_fieldnum + 1.
  3152.             CONTINUE.
  3153.           ENDIF.
  3154.           IF lw_char = space.
  3155.             CONCATENATE lw_fieldval lw_char INTO lw_fieldval
  3156.                         SEPARATED BY space.
  3157.           ELSE.
  3158.             CONCATENATE lw_fieldval lw_char INTO lw_fieldval.
  3159.           ENDIF.
  3160.           IF lw_char = ''''. "end of a field ?
  3161.             IF lw_pos < lw_length.
  3162.               lw_char = fp_param+lw_pos(1).
  3163.             ELSE.
  3164.               CLEAR lw_char.
  3165.             ENDIF.
  3166.             IF lw_char = ''''. "not end !
  3167.               CONCATENATE lw_fieldval lw_char INTO lw_fieldval.
  3168.               lw_pos = lw_pos + 1.
  3169.               CONTINUE.
  3170.             ELSE. "end of a field!
  3171.               c 'ASSIGN COMPONENT'.                         "#EC NOTEXT
  3172.               c lw_fieldnum.
  3173.               c 'OF STRUCTURE s_insert TO <fs>.'.           "#EC NOTEXT
  3174.               c '<fs> = '.                                  "#EC NOTEXT
  3175.               c lw_fieldval.
  3176.               c '.'.                                        "#EC NOTEXT
  3177.               lw_started_field = space.
  3178.             ENDIF.
  3179.           ENDIF.
  3180.         ENDWHILE.
  3181.       ELSEIF fp_param(3) = 'SET'.
  3182.  
  3183.  
  3184.         lw_length = strlen( fp_param ).
  3185.         lw_pos = 3.
  3186.         lw_fieldnum = 0.
  3187.         lw_wait_name = abap_true.
  3188.         WHILE lw_pos < lw_length.
  3189.           lw_char = fp_param+lw_pos(1).
  3190.           lw_pos = lw_pos + 1.
  3191.           IF lw_wait_name = abap_true.
  3192.             TRANSLATE lw_char TO UPPER CASE.
  3193.             IF lw_char = space OR NOT sy-abcde CS lw_char.
  3194.               CONTINUE. "not a begin of fieldname
  3195.             ENDIF.
  3196.             lw_wait_name = space.
  3197.             lw_started = abap_true.
  3198.             CONCATENATE 's_insert-' lw_char
  3199.                         INTO lw_fieldname.                  "#EC NOTEXT
  3200.             CONTINUE.
  3201.           ENDIF.
  3202.  
  3203.           IF lw_started = abap_true.
  3204.             IF lw_char = space.
  3205.               CONCATENATE lw_fieldname lw_char INTO lw_fieldname
  3206.                           SEPARATED BY space.
  3207.             ELSE.
  3208.               CONCATENATE lw_fieldname lw_char INTO lw_fieldname.
  3209.             ENDIF.
  3210.             IF lw_char = '='. "end of the field name
  3211.               lw_started = space.
  3212.             ENDIF.
  3213.  
  3214.             CONTINUE.
  3215.           ENDIF.
  3216.  
  3217.           IF lw_started_field NE abap_true.
  3218.             IF lw_char NE ''''. "field value must start by '
  3219.               CONTINUE.
  3220.             ENDIF.
  3221.             lw_started_field = abap_true.
  3222.             lw_fieldval = lw_char.
  3223.             CONTINUE.
  3224.           ENDIF.
  3225.  
  3226.           IF lw_char = space.
  3227.             CONCATENATE lw_fieldval lw_char INTO lw_fieldval
  3228.                         SEPARATED BY space.
  3229.           ELSE.
  3230.             CONCATENATE lw_fieldval lw_char INTO lw_fieldval.
  3231.           ENDIF.
  3232.           IF lw_char = ''''. "end of a field ?
  3233.             IF lw_pos < lw_length.
  3234.               lw_char = fp_param+lw_pos(1).
  3235.             ELSE.
  3236.               CLEAR lw_char.
  3237.             ENDIF.
  3238.             IF lw_char = ''''. "not end !
  3239.               CONCATENATE lw_fieldval lw_char INTO lw_fieldval.
  3240.               lw_pos = lw_pos + 1.
  3241.               CONTINUE.
  3242.             ELSE. "end of a field!
  3243.               c lw_fieldname.
  3244.               c lw_fieldval.
  3245.               c '.'.
  3246.               lw_started_field = space.
  3247.               lw_wait_name = abap_true.
  3248.             ENDIF.
  3249.           ENDIF.
  3250.         ENDWHILE.
  3251.       ELSE.
  3252.         MESSAGE 'Error in INSERT syntax : VALUES / SET required'(m26)
  3253.                 TYPE c_msg_error.
  3254.       ENDIF. "if fp_param(6) = 'VALUES'.
  3255.       c fp_command.
  3256.       c 'INTO'.                                             "#EC NOTEXT
  3257.       c fp_table.
  3258.       c 'VALUES s_insert.'.                                 "#EC NOTEXT
  3259.   ENDCASE.
  3260.  
  3261. * Get query execution time & affected lines
  3262.   c 'IF sy-subrc = 0.'.                                     "#EC NOTEXT
  3263.   c '  fp_count = sy-dbcnt.'.                               "#EC NOTEXT
  3264.   c 'ENDIF.'.                                               "#EC NOTEXT
  3265.   c 'GET TIME STAMP FIELD w_timeend.'.                      "#EC NOTEXT
  3266.   c 'fp_time = w_timeend - w_timestart.'.                   "#EC NOTEXT
  3267.   c 'ENDFORM.'.                                             "#EC NOTEXT
  3268.  
  3269.   CLEAR : lw_line,
  3270.           lw_word,
  3271.           lw_mess.
  3272.   SYNTAX-CHECK FOR lt_code_string PROGRAM sy-repid
  3273.                MESSAGE lw_mess LINE lw_line WORD lw_word.
  3274.   IF sy-subrc NE 0 AND fp_display = space.
  3275.     MESSAGE lw_mess TYPE c_msg_error.
  3276.   ENDIF.
  3277.  
  3278.   IF fp_display = space.
  3279.     GENERATE SUBROUTINE POOL lt_code_string NAME fp_program.
  3280.   ELSE.
  3281.     IF lw_mess IS NOT INITIAL.
  3282.       lw_explicit = lw_line.
  3283.       CONCATENATE lw_mess '(line'(m28) lw_explicit ',word'(m29)
  3284.                   lw_word ')'(m30)
  3285.                   INTO lw_mess SEPARATED BY space.
  3286.       MESSAGE lw_mess TYPE c_msg_success DISPLAY LIKE c_msg_error.
  3287.     ENDIF.
  3288.     EDITOR-CALL FOR lt_code_string DISPLAY-MODE
  3289.                 TITLE 'Generated code for current query'(t01).
  3290.   ENDIF.
  3291. ENDFORM.                    " GENERATE_SUBROUTINE_NOSELECT
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement