├── .abapgit.xml ├── LICENSE ├── README.md ├── abaplint.json ├── package.devc.xml ├── z_debugger_data_view_ext_demo.prog.abap ├── z_debugger_data_view_ext_demo.prog.xml ├── z_struc_v_build_services_menue.enho.b6b26735.abap ├── z_struc_v_build_services_menue.enho.caee08db.abap ├── z_struc_v_build_services_menue.enho.xml ├── z_table_v_build_services_menue.enho.aaad3be5.abap ├── z_table_v_build_services_menue.enho.fbf01ccc.abap ├── z_table_v_build_services_menue.enho.xml ├── zcl_max_line_length_pp.clas.abap ├── zcl_max_line_length_pp.clas.testclasses.abap ├── zcl_max_line_length_pp.clas.xml ├── zcl_op_abap_typedescr.clas.abap ├── zcl_op_abap_typedescr.clas.xml ├── zcl_op_component.clas.abap ├── zcl_op_component.clas.xml ├── zcl_op_debugger_integration.clas.abap ├── zcl_op_debugger_integration.clas.xml ├── zcl_op_pretty_printer_factory.clas.abap ├── zcl_op_pretty_printer_factory.clas.testclasses.abap ├── zcl_op_pretty_printer_factory.clas.xml ├── zcl_op_pretty_printer_injector.clas.abap ├── zcl_op_pretty_printer_injector.clas.xml ├── zcl_op_simple_field_catalog.clas.abap ├── zcl_op_simple_field_catalog.clas.testclasses.abap ├── zcl_op_simple_field_catalog.clas.xml ├── zcl_op_structure.clas.abap ├── zcl_op_structure.clas.testclasses.abap ├── zcl_op_structure.clas.xml ├── zcl_op_table.clas.abap ├── zcl_op_table.clas.testclasses.abap ├── zcl_op_table.clas.xml ├── zcl_op_value_pretty_printer.clas.abap ├── zcl_op_value_pretty_printer.clas.locals_def.abap ├── zcl_op_value_pretty_printer.clas.testclasses.abap ├── zcl_op_value_pretty_printer.clas.xml ├── zenh_table_values.enho.1b6c0c61.abap ├── zenh_table_values.enho.c5c75b12.abap ├── zenh_table_values.enho.d656a875.abap ├── zenh_table_values.enho.xml ├── zif_op_value_pretty_printer.intf.abap ├── zif_op_value_pretty_printer.intf.xml ├── zop_dve_maintena.fugr.lzop_dve_maintenaf00.abap ├── zop_dve_maintena.fugr.lzop_dve_maintenaf00.xml ├── zop_dve_maintena.fugr.lzop_dve_maintenai00.abap ├── zop_dve_maintena.fugr.lzop_dve_maintenai00.xml ├── zop_dve_maintena.fugr.lzop_dve_maintenat00.abap ├── zop_dve_maintena.fugr.lzop_dve_maintenat00.xml ├── zop_dve_maintena.fugr.lzop_dve_maintenatop.abap ├── zop_dve_maintena.fugr.lzop_dve_maintenatop.xml ├── zop_dve_maintena.fugr.saplzop_dve_maintena.abap ├── zop_dve_maintena.fugr.saplzop_dve_maintena.xml ├── zop_dve_maintena.fugr.tableframe_zop_dve_maintena.abap ├── zop_dve_maintena.fugr.tableproc_zop_dve_maintena.abap ├── zop_dve_maintena.fugr.xml ├── zop_dve_maintenance_views.fugr.lzop_dve_maintenance_viewstop.abap ├── zop_dve_maintenance_views.fugr.lzop_dve_maintenance_viewstop.xml ├── zop_dve_maintenance_views.fugr.saplzop_dve_maintenance_views.abap ├── zop_dve_maintenance_views.fugr.saplzop_dve_maintenance_views.xml ├── zop_dve_maintenance_views.fugr.xml ├── ztop_dve_cust.tabl.xml └── ztop_dve_custs.tobj.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | / 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | /zcl_aunit_struc_view.clas.testclasses.abap 15 | /zop_aunit_ext_demo.prog.abap 16 | /zop_aunit_ext_demo.prog.xml 17 | /zop_custom_event_rec.clas.testclasses.abap 18 | /abaplint.json 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 objective partner AG 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # abap debugger data view extension 2 | Extensions to abap debugger to be able to view itab and structure data in a abap-coding friendly way 3 | 4 | For details see
5 | https://blogs.sap.com/2017/12/17/abap-debugger-enhancement-or-how-to-speed-up-your-test-data-creation-process/ 6 |
and
7 | https://blogs.sap.com/2019/02/22/abap-debugger-enhancement-update/ 8 | 9 | 10 | Follow this link for a german description of this extension: 11 | https://www.objective-partner.de/abap-debugger-erweiterung/ 12 | 13 | -------------------------------------------------------------------------------- /abaplint.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "files": "/**/*.*", 4 | "skipGeneratedGatewayClasses": true, 5 | "skipGeneratedPersistentClasses": true, 6 | "skipGeneratedFunctionGroups": true 7 | }, 8 | "syntax": { 9 | "version": "v740sp02", 10 | "errorNamespace": "", 11 | "globalConstants": [], 12 | "globalMacros": [] 13 | }, 14 | "dependencies": [ 15 | { 16 | "url": "https://github.com/abaplint/deps", 17 | "folder": "/deps", 18 | "files": "/src/**/*.*" 19 | } 20 | ], 21 | "rules": { 22 | "avoid_use": false, 23 | "commented_code": false, 24 | "constructor_visibility_public": false, 25 | "description_empty": false, 26 | "empty_statement": false, 27 | "empty_structure": false, 28 | "exporting": false, 29 | "functional_writing": false, 30 | "global_class": false, 31 | "identical_form_names": false, 32 | "if_in_if": false, 33 | "inline_data_old_versions": false, 34 | "line_length": false, 35 | "max_one_statement": false, 36 | "message_exists": false, 37 | "method_length": false, 38 | "mix_returning": false, 39 | "msag_consistency": false, 40 | "nesting": false, 41 | "obsolete_statement": false, 42 | "parser_error": false, 43 | "preferred_compare_operator": false, 44 | "short_case": false, 45 | "superclass_final": false, 46 | "unreachable_code": false, 47 | "use_new": false, 48 | "when_others_last": false, 49 | "ambiguous_statement": false, 50 | "begin_end_names": false, 51 | "check_transformation_exists": false, 52 | "check_syntax": true, 53 | "form_tables_obsolete": false, 54 | "tabl_enhancement_category": false, 55 | "implement_methods": false, 56 | "main_file_contents": false, 57 | "rfc_error_handling": false, 58 | "indentation": false, 59 | "sequential_blank": false, 60 | "empty_line_in_statement": false, 61 | "check_abstract": false, 62 | "no_public_attributes": false, 63 | "abapdoc": false, 64 | "prefer_returning_to_exporting": false, 65 | "keep_single_parameter_on_one_line": false, 66 | "allowed_object_naming": false, 67 | "fully_type_constants": false, 68 | "check_comments": false, 69 | "check_text_elements": false, 70 | "newline_between_methods": false, 71 | "check_include": false, 72 | "xml_consistency": false, 73 | "prefix_is_current_class": false, 74 | "line_break_multiple_parameters": false, 75 | "prefer_inline": false, 76 | "reduce_string_templates": false, 77 | "sicf_consistency": false, 78 | "sql_escape_host_variables": false, 79 | "try_without_catch": false, 80 | "names_no_dash": false, 81 | "unknown_types": false, 82 | "unused_variables": false, 83 | "unused_types": false, 84 | "use_bool_expression": false, 85 | "use_line_exists": false, 86 | "check_subrc": false, 87 | "cyclomatic_complexity": false, 88 | "parser_missing_space": false, 89 | "identical_conditions": false, 90 | "prefer_is_not": false 91 | } 92 | } -------------------------------------------------------------------------------- /package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Z_DEBUGGER_DATA_VIEW_EXT 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /z_debugger_data_view_ext_demo.prog.abap: -------------------------------------------------------------------------------- 1 | *&---------------------------------------------------------------------* 2 | *& Report z_debugger_data_view_ext_demo 3 | *&---------------------------------------------------------------------* 4 | *& 5 | *&---------------------------------------------------------------------* 6 | REPORT z_debugger_data_view_ext_demo. 7 | 8 | DATA: 9 | lt_flights TYPE ty_flights, 10 | ls_flight TYPE sflight, 11 | BEGIN OF flights_with_header OCCURS 0, 12 | carrid TYPE sflights-carrid, " this table contains 13 | connid TYPE sflights-connid, " the key information 14 | fldate TYPE sflights-fldate, " of the hit list 15 | END OF flights_with_header, 16 | flights_hashed TYPE HASHED TABLE OF sflight WITH UNIQUE KEY mandt carrid connid fldate. 17 | 18 | " for obsolete tables with header 19 | 20 | flights_with_header[] = VALUE #( connid = '0017' 21 | ( carrid = 'AA' fldate = '20141217' ) 22 | ( carrid = 'AB' fldate = '20150225' ) 23 | ( carrid = 'AC' fldate = '20150225' ) ). 24 | 25 | " for table enhancement 26 | 27 | lt_flights = VALUE #( mandt = '100' 28 | carrid = 'AA' 29 | connid = '0017' 30 | price = '422.94 ' 31 | currency = 'USD' 32 | planetype = '747-400' 33 | seatsmax = '385 ' 34 | seatsmax_b = '31 ' 35 | seatsmax_f = '21 ' 36 | ( fldate = '20141217' 37 | seatsocc = '372 ' 38 | paymentsum = '192437.84 ' 39 | seatsocc_b = '28 ' 40 | seatsocc_f = '21 ' ) 41 | ( fldate = '20150225' 42 | seatsocc = '369 ' 43 | paymentsum = '191490.49 ' 44 | seatsocc_b = '30 ' 45 | seatsocc_f = '20 ' ) 46 | ( fldate = '20150506' 47 | seatsocc = '374 ' 48 | paymentsum = '192991.93 ' 49 | seatsocc_b = '30 ' 50 | seatsocc_f = '19 ' ) ). 51 | 52 | " for testing filtered view 53 | INSERT LINES OF lt_flights INTO TABLE flights_hashed. 54 | 55 | " for testing structure enhancement 56 | ls_flight = VALUE #( mandt = '100' 57 | carrid = 'AA' 58 | connid = '0017' 59 | fldate = '20141217' 60 | price = '422.94' 61 | currency = 'USD' 62 | planetype = '747-400' 63 | seatsmax = '385' 64 | seatsocc = '372' 65 | paymentsum = '192437.84' 66 | seatsmax_b = '31' 67 | seatsocc_b = '28' 68 | seatsmax_f = '21' 69 | seatsocc_f = '21' ). 70 | 71 | " nested examples 72 | TYPES: BEGIN OF t_col2, 73 | col1 TYPE i, 74 | col2 TYPE i, 75 | END OF t_col2. 76 | 77 | TYPES: BEGIN OF t_struct, 78 | col1 TYPE i, 79 | col2 TYPE t_col2, 80 | END OF t_struct. 81 | 82 | TYPES: my_itab_type TYPE STANDARD TABLE OF t_struct WITH DEFAULT KEY, 83 | my_nested_struc_type TYPE t_struct. 84 | 85 | TYPES: BEGIN OF nested_type, 86 | col1 TYPE i, 87 | col2 TYPE t_col2, 88 | col3 TYPE my_itab_type, 89 | END OF nested_type. 90 | 91 | TYPES my_nested_itab_type TYPE STANDARD TABLE OF nested_type WITH DEFAULT KEY. 92 | 93 | DATA: nested_itab TYPE my_nested_itab_type, 94 | nested_struc TYPE my_nested_struc_type, 95 | itab_in_struc TYPE nested_type. 96 | 97 | " build structures 98 | nested_struc = VALUE my_nested_struc_type( col1 = 1 99 | col2 = VALUE #( col1 = 1 100 | col2 = 2 ) ). 101 | itab_in_struc = VALUE nested_type( col1 = 1 102 | 103 | col2 = VALUE #( col1 = 11 104 | col2 = 22 ) 105 | col3 = VALUE #( ( col1 = 311 106 | col2 = VALUE #( col1 = 3121 107 | col2 = 3122 ) ) 108 | ( col1 = 321 109 | col2 = VALUE #( col1 = 3221 110 | col2 = 3222 ) ) ) ). 111 | 112 | " build itab 113 | nested_itab = VALUE my_nested_itab_type( ( col1 = 1 114 | col2 = VALUE #( col1 = 1 115 | col2 = 2 ) 116 | col3 = VALUE #( " start here a nested itab 117 | ( col1 = 1 ) " first row of it 118 | ( col2-col2 = 2 ) ) ) ). 119 | 120 | " do something with structure 121 | DATA(ls_col2) = nested_struc-col2. 122 | 123 | " do something with itab 124 | DATA(ls_col1) = nested_itab[ 1 ]-col1. 125 | 126 | " Use Field Symbols 127 | ASSIGN lt_flights TO FIELD-SYMBOL(). 128 | 129 | " Do something with it 130 | CHECK IS NOT INITIAL. 131 | -------------------------------------------------------------------------------- /z_debugger_data_view_ext_demo.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Z_DEBUGGER_DATA_VIEW_EXT_DEMO 7 | 1 8 | T 9 | E 10 | X 11 | X 12 | 13 | 14 | 15 | D 16 | 17 | 18 | R 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /z_struc_v_build_services_menue.enho.b6b26735.abap: -------------------------------------------------------------------------------- 1 | "Name: \TY:CL_TPDA_TOOL_STRUC_VIEW\IN:IF_TPDA_TOOL_SERVICES\ME:BUILD_SERVICES_MENUE\SE:END\EI 2 | ENHANCEMENT 0 Z_STRUC_V_BUILD_SERVICES_MENUE. 3 | CLEAR l_node. 4 | 5 | l_node-node_key = 'ZDATA_4_ABAP'. 6 | l_node-relatkey = cl_tpda_services_tools=>c_special. 7 | l_node-n_image = cl_tpda_icons=>tpda_icon_download. 8 | l_node-relatship = cl_gui_simple_tree=>relat_last_child. 9 | l_node-text = 'Data for Abap View'. 10 | 11 | APPEND l_node TO p_it_menue_tree. 12 | 13 | ENDENHANCEMENT. 14 | -------------------------------------------------------------------------------- /z_struc_v_build_services_menue.enho.caee08db.abap: -------------------------------------------------------------------------------- 1 | "Name: \TY:CL_TPDA_TOOL_STRUC_VIEW\IN:IF_TPDA_TOOL\ME:HANDLE_OK_CODE\SE:BEGIN\EI 2 | ENHANCEMENT 0 Z_STRUC_V_BUILD_SERVICES_MENUE. 3 | IF p_ok_code-ok_code EQ 'ZDATA_4_ABAP'. 4 | zcl_op_debugger_integration=>debug_debugger_if_needed( ). 5 | TRY. 6 | DATA(zz_reference_to_data) = NEW zcl_op_debugger_integration( )->get_ref_to_any_content( i_variable_name = dynp_vars-struc_name ). 7 | 8 | DATA(zz_field_catalog) = NEW zcl_op_simple_field_catalog( )->get_by_reference( zz_reference_to_data ). 9 | 10 | FIELD-SYMBOLS: TYPE any. 11 | ASSIGN zz_reference_to_data->* TO . "de-referencing 12 | 13 | NEW zcl_op_structure( )->show_popup_w_content( i_structure = 14 | i_field_catalog = zz_field_catalog 15 | i_struc_name = dynp_vars-struc_name ). 16 | CATCH cx_root into DATA(lx_root). 17 | "dont want to crash, so catch all catchable exceptions here 18 | 19 | ENDTRY. 20 | 21 | RETURN. 22 | ENDIF. 23 | ENDENHANCEMENT. 24 | -------------------------------------------------------------------------------- /z_struc_v_build_services_menue.enho.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | HOOK_IMPL 6 | AUnit - Erweiterung der Struktur View 7 | 8 | R3TR 9 | CLAS 10 | CL_TPDA_TOOL_STRUC_VIEW 11 | CLAS 12 | CL_TPDA_TOOL_STRUC_VIEW 13 | CL_TPDA_TOOL_STRUC_VIEW=======CP 14 | 15 | 16 | 17 | CL_TPDA_TOOL_STRUC_VIEW=======CP 18 | D 19 | \TY:CL_TPDA_TOOL_STRUC_VIEW\IN:IF_TPDA_TOOL_SERVICES\ME:BUILD_SERVICES_MENUE\SE:END\EI 20 | 21 | 22 | CL_TPDA_TOOL_STRUC_VIEW=======CP 23 | D 24 | \TY:CL_TPDA_TOOL_STRUC_VIEW\IN:IF_TPDA_TOOL\ME:HANDLE_OK_CODE\SE:BEGIN\EI 25 | 26 | 27 | 28 | 29 | \TY:CL_TPDA_TOOL_STRUC_VIEW\IN:IF_TPDA_TOOL_SERVICES\ME:BUILD_SERVICES_MENUE\SE:END\EI 30 | b6b26735 31 | 32 | 33 | \TY:CL_TPDA_TOOL_STRUC_VIEW\IN:IF_TPDA_TOOL\ME:HANDLE_OK_CODE\SE:BEGIN\EI 34 | caee08db 35 | 36 | 37 | 38 | 39 |
40 | 000D3A46373D1EDA9BA13BBAE94A9A1A 41 | E 42 | 1 43 | AAI= 44 |
45 | 46 | 47 | 000D3A46373D1EDA9BA13BBAE94A9A1A 48 | E 49 | 0001 50 | X 51 | R 52 | 056 53 | AUnit - Erweiterung der Struktur View 54 | 55 | 56 |
57 |
58 | 59 | 60 | R3TR 61 | ENHO 62 | Z_STRUC_V_BUILD_SERVICES_MENUE 63 | 000D3A46373D1EDA9BA13BBAE94A9A1A 64 | 0001 65 | 66 | 67 |
68 |
69 |
70 | -------------------------------------------------------------------------------- /z_table_v_build_services_menue.enho.aaad3be5.abap: -------------------------------------------------------------------------------- 1 | "Name: \TY:CL_TPDA_TOOL_TABLE_NEW\ME:HANDLE_OK_CODE\SE:BEGIN\EI 2 | ENHANCEMENT 0 Z_TABLE_V_BUILD_SERVICES_MENUE. 3 | IF i_action EQ 'ZD' AND i_subaction EQ 'ATA_4_ABAP'. 4 | FIELD-SYMBOLS: TYPE ANY TABLE. 5 | zcl_op_debugger_integration=>debug_debugger_if_needed( ). 6 | TRY. 7 | TRY. 8 | DATA(zz_reference_to_data) = NEW zcl_op_debugger_integration( )->get_ref_to_any_content( i_variable_name = dynp_vars-table_name ). 9 | DATA(zz_field_catalog) = NEW zcl_op_simple_field_catalog( )->get_by_reference( zz_reference_to_data ). 10 | ASSIGN zz_reference_to_data->* TO . "de-referencing 11 | CATCH cx_root INTO DATA(lx_root). 12 | "could be a header table, try it a different way 13 | create_real_clone( IMPORTING e_rda_table = DATA(l_zz_rda_table) 14 | e_tab_fcat = zz_field_catalog ). 15 | ASSIGN l_zz_rda_table->* TO . 16 | ENDTRY. 17 | 18 | NEW zcl_op_table( )->show_popup_w_content( 19 | EXPORTING 20 | i_table = 21 | i_fieldcatalog = zz_field_catalog 22 | i_table_title = me->dynp_vars-table_name ). 23 | 24 | RETURN. 25 | CATCH cx_root INTO lx_root. 26 | "dont want to crash, so catch all catchable exceptions here 27 | zcl_op_debugger_integration=>debug_debugger_if_needed( ). 28 | ENDTRY. 29 | ENDIF. 30 | ENDENHANCEMENT. 31 | -------------------------------------------------------------------------------- /z_table_v_build_services_menue.enho.fbf01ccc.abap: -------------------------------------------------------------------------------- 1 | "Name: \TY:CL_TPDA_TOOL_TABLE_NEW\IN:IF_TPDA_TOOL_SERVICES\ME:BUILD_SERVICES_MENUE\SE:END\EI 2 | ENHANCEMENT 0 Z_TABLE_V_BUILD_SERVICES_MENUE. 3 | DATA l_zz_node LIKE LINE OF p_it_menue_tree. 4 | CLEAR l_zz_node. 5 | 6 | l_zz_node-node_key = 'ZDATA_4_ABAP'. 7 | l_zz_node-relatkey = cl_tpda_services_tools=>c_special. 8 | l_zz_node-n_image = cl_tpda_icons=>tpda_icon_download. 9 | l_zz_node-relatship = cl_gui_simple_tree=>relat_last_child. 10 | l_zz_node-text = 'Data for Abap View'. 11 | 12 | APPEND l_zz_node TO p_it_menue_tree. 13 | ENDENHANCEMENT. 14 | -------------------------------------------------------------------------------- /z_table_v_build_services_menue.enho.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | HOOK_IMPL 6 | Debugger extension for table view 7 | 8 | R3TR 9 | CLAS 10 | CL_TPDA_TOOL_TABLE_NEW 11 | CLAS 12 | CL_TPDA_TOOL_TABLE_NEW 13 | CL_TPDA_TOOL_TABLE_NEW========CP 14 | 15 | 16 | 17 | CL_TPDA_TOOL_TABLE_NEW========CP 18 | D 19 | \TY:CL_TPDA_TOOL_TABLE_NEW\IN:IF_TPDA_TOOL_SERVICES\ME:BUILD_SERVICES_MENUE\SE:END\EI 20 | 21 | 22 | CL_TPDA_TOOL_TABLE_NEW========CP 23 | D 24 | \TY:CL_TPDA_TOOL_TABLE_NEW\ME:HANDLE_OK_CODE\SE:BEGIN\EI 25 | 26 | 27 | 28 | 29 | \TY:CL_TPDA_TOOL_TABLE_NEW\IN:IF_TPDA_TOOL_SERVICES\ME:BUILD_SERVICES_MENUE\SE:END\EI 30 | fbf01ccc 31 | 32 | 33 | \TY:CL_TPDA_TOOL_TABLE_NEW\ME:HANDLE_OK_CODE\SE:BEGIN\EI 34 | aaad3be5 35 | 36 | 37 | 38 | 39 |
40 | 000D3A46373D1EDA9BA13BFC92B95A1A 41 | E 42 | 1 43 | AAI= 44 |
45 | 46 | 47 | 000D3A46373D1EDA9BA13BFC92B95A1A 48 | E 49 | 0001 50 | X 51 | R 52 | 050 53 | Debugger extension for table view 54 | 55 | 56 |
57 |
58 | 59 | 60 | R3TR 61 | ENHO 62 | Z_TABLE_V_BUILD_SERVICES_MENUE 63 | 000D3A46373D1EDA9BA13BFC92B95A1A 64 | 0001 65 | 66 | 67 |
68 |
69 |
70 | -------------------------------------------------------------------------------- /zcl_max_line_length_pp.clas.abap: -------------------------------------------------------------------------------- 1 | "! Initially created by Andreas Kopp 2 | "! This class is a pretty printer for abap value # expression 3 | "! It consider a max line lenght of 128 chars 4 | CLASS zcl_max_line_length_pp DEFINITION 5 | PUBLIC 6 | CREATE PRIVATE 7 | GLOBAL FRIENDS zcl_op_pretty_printer_factory. "needed for instantiation 8 | 9 | PUBLIC SECTION. 10 | INTERFACES zif_op_value_pretty_printer. 11 | 12 | ALIASES: format FOR zif_op_value_pretty_printer~format. 13 | 14 | "! @parameter indent_size | Number of spaces to begin each line with 15 | "! @parameter max_line_length | Maximum number of characters for each line. Value has 16 | "! to be between 20 and 255 characters (maximum of ABAP editor). 17 | METHODS constructor 18 | IMPORTING 19 | indent_size TYPE i DEFAULT 2 20 | max_line_length TYPE i DEFAULT 128. 21 | 22 | PROTECTED SECTION. 23 | PRIVATE SECTION. 24 | TYPES: BEGIN OF ty_block, 25 | id TYPE i, 26 | group_id TYPE i, 27 | char(1) TYPE c, 28 | level_of_depth TYPE i, 29 | line_index TYPE i, 30 | "block is completed when '(' and ')' for the same group_id exists 31 | is_completed TYPE abap_bool, 32 | END OF ty_block, 33 | ty_block_table TYPE SORTED TABLE OF ty_block WITH UNIQUE KEY id, 34 | ty_lines TYPE TABLE OF string WITH DEFAULT KEY. 35 | 36 | DATA: 37 | m_indent_size TYPE i, 38 | m_max_line_length TYPE i, 39 | m_reader TYPE REF TO cl_abap_string_c_reader, 40 | m_blocks TYPE ty_block_table, 41 | m_line TYPE string, 42 | m_lines TYPE ty_lines. 43 | 44 | CONSTANTS: 45 | c_newline TYPE abap_char1 VALUE cl_abap_char_utilities=>cr_lf, 46 | c_opening_bracket TYPE c VALUE '(', 47 | c_closing_bracket TYPE c VALUE ')', 48 | c_enclosure TYPE c VALUE '''', 49 | c_enclosure_escape TYPE c VALUE '''', 50 | c_concatenate TYPE c VALUE '&'. 51 | 52 | METHODS: 53 | get_lines_as_string 54 | RETURNING 55 | VALUE(r_string) TYPE string, 56 | 57 | "! Processes next char read by reader 58 | handle_char 59 | IMPORTING 60 | i_char TYPE string, 61 | 62 | "! Reads component value that is between enclosure characters (respecting enclosure escapes). 63 | "! Example: Returns "It''s easy (isn''t it?)" from "[COL =] 'It''s easy (isn''t it?)' ". 64 | read_value_between_enclosures 65 | RETURNING 66 | VALUE(r_value) TYPE string, 67 | 68 | "! Splits value into several lines. The length of each line is less than the maximum line size. 69 | "! The remaining characters of the first line can be used to fill up the first line. 70 | "! 71 | "! @parameter i_length_of_first_line | characters already used for the first line 72 | "! @parameter i_value | value to split up 73 | "! @parameter i_indent_size | number of spaces to begin each line beginning from the second line 74 | split_value_at_max_line_length 75 | IMPORTING 76 | i_length_of_first_line TYPE i 77 | i_value TYPE string 78 | i_indent_size TYPE i OPTIONAL 79 | RETURNING 80 | VALUE(r_parts) TYPE ty_lines, 81 | 82 | add_to_block_control 83 | IMPORTING 84 | i_char TYPE string 85 | i_line_index TYPE i 86 | RETURNING 87 | VALUE(r_block) TYPE ty_block, 88 | 89 | "! Calculates number of spaces for the next line. 90 | "! Previous line has to be appended already to m_lines and block control must exist. 91 | calculate_indent 92 | RETURNING 93 | VALUE(r_spaces) TYPE string, 94 | 95 | calculate_level_of_depth 96 | IMPORTING 97 | i_char TYPE string 98 | RETURNING 99 | VALUE(r_level_of_depth) TYPE i, 100 | 101 | calculate_group_id 102 | IMPORTING 103 | i_char TYPE string 104 | RETURNING 105 | VALUE(r_group_id) TYPE i, 106 | 107 | append_line, 108 | update_indent_of_last_line, 109 | clear_members. 110 | ENDCLASS. 111 | 112 | 113 | 114 | CLASS zcl_max_line_length_pp IMPLEMENTATION. 115 | 116 | 117 | METHOD add_to_block_control. 118 | DATA block LIKE LINE OF m_blocks. 119 | 120 | "Example: Line 121 | "D = VALUE #( 1 122 | "COL1 = '(1)' 2 123 | "COL2 = VALUE #( 3 124 | "COL1 = '1' 4 125 | "COL2 = '2' 5 126 | "COL3 = 'It''s easy' 6 127 | ") 7 128 | "COL3 = '3' 8 129 | "COL4 = VALUE #( 9 130 | "COL1 = '1' 10 131 | "COL2 = '2' 11 132 | ") 12 133 | "). 13 134 | 135 | "Blocks: 136 | "|ID |GROUP|CHAR|LEVEL|LINE 137 | "|1 |1 |( |1 |1 138 | "|2 |2 |( |2 |3 139 | "|3 |2 |) |2 |7 140 | "|4 |3 |( |2 |9 141 | "|5 |3 |) |2 |12 142 | "|6 |1 |) |1 |13 143 | 144 | "Blocks that belong together have the same group id. 145 | "Each block starts with '(' and ends with ')'. 146 | CHECK i_char = c_opening_bracket 147 | OR i_char = c_closing_bracket. 148 | 149 | block-id = lines( m_blocks ) + 1. 150 | block-char = i_char. 151 | block-line_index = i_line_index. 152 | block-level_of_depth = calculate_level_of_depth( i_char ). 153 | block-group_id = calculate_group_id( i_char ). 154 | 155 | "With the closing bracket, a group of two blocks (with the same group id) is complete. 156 | IF i_char = c_closing_bracket. 157 | block-is_completed = abap_true. 158 | ASSIGN m_blocks[ group_id = block-group_id ] TO FIELD-SYMBOL(). 159 | IF sy-subrc = 0. 160 | -is_completed = abap_true. 161 | ENDIF. 162 | ENDIF. 163 | 164 | APPEND block TO m_blocks. 165 | ENDMETHOD. 166 | 167 | 168 | METHOD append_line. 169 | APPEND m_line TO m_lines. 170 | CLEAR m_line. 171 | ENDMETHOD. 172 | 173 | 174 | METHOD calculate_group_id. 175 | DATA excluded_group_ids TYPE TABLE OF ty_block-group_id. 176 | DATA(index) = lines( m_blocks ). 177 | 178 | "each opening bracket starts a new group 179 | IF i_char = c_opening_bracket. 180 | r_group_id = COND #( WHEN index > 0 181 | THEN m_blocks[ index ]-group_id + 1 182 | ELSE 1 ). 183 | RETURN. 184 | ENDIF. 185 | 186 | "find matching opening bracket for each closing bracket 187 | "and assign group id of corresponding opening bracket 188 | IF i_char = c_closing_bracket. 189 | WHILE index > 0. 190 | ASSIGN m_blocks[ index ] TO FIELD-SYMBOL(). 191 | IF -char = c_closing_bracket. 192 | "group is already closed so exclude its group_id 193 | APPEND -group_id TO excluded_group_ids. 194 | ELSEIF -char = c_opening_bracket 195 | AND NOT line_exists( excluded_group_ids[ table_line = -group_id ] ). 196 | "opening bracket found which is not closed yet 197 | r_group_id = -group_id. 198 | RETURN. 199 | ENDIF. 200 | index = index - 1. 201 | ENDWHILE. 202 | ENDIF. 203 | ENDMETHOD. 204 | 205 | 206 | METHOD calculate_indent. 207 | DATA level TYPE ty_block-level_of_depth. 208 | IF lines( m_lines ) < 1. 209 | RETURN. 210 | ENDIF. 211 | DATA(last_line) = m_lines[ lines( m_lines ) ]. 212 | DATA(last_char_of_last_line) = substring( val = last_line off = strlen( last_line ) - 1 ). 213 | 214 | CASE last_char_of_last_line. 215 | WHEN c_opening_bracket OR c_closing_bracket. 216 | level = m_blocks[ lines( m_blocks ) ]-level_of_depth - 1. 217 | WHEN c_enclosure OR c_concatenate. 218 | "find latest block that is not completed 219 | DATA(block_index) = lines( m_blocks ). 220 | WHILE block_index > 0. 221 | IF m_blocks[ block_index ]-is_completed = abap_false. 222 | level = m_blocks[ block_index ]-level_of_depth. 223 | EXIT. 224 | ENDIF. 225 | block_index = block_index - 1. 226 | ENDWHILE. 227 | ENDCASE. 228 | 229 | DATA(lv_num_spaces) = level * m_indent_size. 230 | DO lv_num_spaces TIMES. 231 | r_spaces = |{ r_spaces } |. 232 | ENDDO. 233 | ENDMETHOD. 234 | 235 | 236 | METHOD calculate_level_of_depth. 237 | DATA(index) = lines( m_blocks ). 238 | IF index = 0. "first entry 239 | r_level_of_depth = 1. 240 | RETURN. 241 | ENDIF. 242 | DATA(previous_block) = m_blocks[ index ]. 243 | r_level_of_depth = COND #( 244 | WHEN i_char = c_opening_bracket AND previous_block-char = c_closing_bracket 245 | OR i_char = c_closing_bracket AND previous_block-char = c_opening_bracket 246 | THEN previous_block-level_of_depth 247 | WHEN i_char = c_opening_bracket AND previous_block-char = c_opening_bracket 248 | THEN previous_block-level_of_depth + 1 249 | WHEN i_char = c_closing_bracket AND previous_block-char = c_closing_bracket 250 | THEN previous_block-level_of_depth - 1 251 | ). 252 | ENDMETHOD. 253 | 254 | 255 | METHOD constructor. 256 | m_indent_size = indent_size. 257 | m_max_line_length = COND #( 258 | WHEN max_line_length >= 20 AND max_line_length <= 255 259 | THEN max_line_length 260 | ELSE 128 261 | ). 262 | ENDMETHOD. 263 | 264 | 265 | METHOD get_lines_as_string. 266 | DATA(writer) = NEW cl_abap_string_c_writer( ). 267 | 268 | LOOP AT m_lines ASSIGNING FIELD-SYMBOL(). 269 | IF sy-tabix > 1. 270 | writer->write( |{ c_newline }| ). 271 | ENDIF. 272 | writer->write( ). 273 | ENDLOOP. 274 | 275 | writer->close( ). 276 | r_string = writer->get_result_string( ). 277 | ENDMETHOD. 278 | 279 | 280 | METHOD handle_char. 281 | FIELD-SYMBOLS LIKE LINE OF m_lines. 282 | 283 | "Skip blanks between brackets and components 284 | IF m_line CO space AND i_char CO space. "EQ space does not work 285 | RETURN. 286 | ENDIF. 287 | 288 | IF i_char = c_enclosure. 289 | DATA(value) = read_value_between_enclosures( ). 290 | DATA(parts) = split_value_at_max_line_length( 291 | EXPORTING 292 | i_length_of_first_line = strlen( m_line ) "to fill up current line 293 | i_value = value 294 | i_indent_size = strlen( calculate_indent( ) ) "indent size needed for split calculation 295 | ). 296 | LOOP AT parts INTO DATA(part). 297 | m_line = m_line && part. 298 | append_line( ). 299 | update_indent_of_last_line( ). 300 | ENDLOOP. 301 | RETURN. 302 | ENDIF. 303 | 304 | m_line = m_line && i_char. 305 | 306 | IF i_char = c_opening_bracket 307 | OR i_char = c_closing_bracket. 308 | append_line( ). "append line first 309 | add_to_block_control( "block control expects that line is appended 310 | i_char = i_char 311 | i_line_index = lines( m_lines ) ). 312 | update_indent_of_last_line( ). "indent calculation requires block control 313 | ENDIF. 314 | 315 | ENDMETHOD. 316 | 317 | 318 | METHOD read_value_between_enclosures. 319 | DATA char TYPE string. 320 | DATA(value) = | { c_enclosure }|. 321 | DO. 322 | char = m_reader->read( 1 ). 323 | value = value && char. 324 | "^[ ](['].*['])[ ]$ extracts value surrounded by enclosures 325 | "^[ ]['](.*)['][ ]$ extracts value only 326 | DATA(matcher) = cl_abap_matcher=>create( 327 | EXPORTING 328 | pattern = |^[ ]([{ c_enclosure }].*[{ c_enclosure }])[ ]$| 329 | text = value 330 | ). 331 | IF matcher->match( ) = abap_true. 332 | r_value = matcher->get_submatch( 1 ). 333 | RETURN. 334 | ENDIF. 335 | ENDDO. 336 | ENDMETHOD. 337 | 338 | 339 | METHOD split_value_at_max_line_length. 340 | "#TODO Don't break line between escape and enclosure. 341 | DATA part TYPE string. 342 | "if max length is not exceeded, just return input value. 343 | IF i_length_of_first_line + strlen( i_value ) <= m_max_line_length. 344 | APPEND i_value TO r_parts. 345 | RETURN. 346 | ENDIF. 347 | 348 | DATA(lo_reader) = NEW cl_abap_string_c_reader( str = i_value ). 349 | DATA(max_length) = m_max_line_length - i_length_of_first_line - i_indent_size. "first line is shorter 350 | WHILE lo_reader->data_available( ) = abap_true. 351 | IF strlen( part ) = ( max_length - 4 ). "4 chars for closing enclosure, space and && 352 | APPEND |{ part }{ c_enclosure } { c_concatenate }{ c_concatenate }| TO r_parts. 353 | part = |{ c_enclosure }|. "starting with indent and a opening enclosure 354 | DO i_indent_size TIMES. 355 | part = | { part }|. 356 | ENDDO. 357 | max_length = m_max_line_length. "full line length beginning at 2nd line 358 | ENDIF. 359 | part = part && lo_reader->read( 1 ). 360 | ENDWHILE. 361 | lo_reader->close( ). 362 | IF part IS NOT INITIAL. 363 | APPEND |{ part }| TO r_parts. 364 | ENDIF. 365 | ENDMETHOD. 366 | 367 | 368 | METHOD update_indent_of_last_line. 369 | ASSIGN m_lines[ lines( m_lines ) ] TO FIELD-SYMBOL(). 370 | SHIFT LEFT DELETING LEADING space. 371 | = |{ calculate_indent( ) }{ }|. 372 | ENDMETHOD. 373 | 374 | 375 | METHOD zif_op_value_pretty_printer~format. 376 | 377 | DATA char TYPE string. "work throughout with strings as spaces are preserved 378 | 379 | clear_members( ). 380 | 381 | m_reader = NEW cl_abap_string_c_reader( str = i_unformated_value_content ). 382 | 383 | WHILE m_reader->data_available( ) = abap_true. 384 | char = m_reader->read( 1 ). 385 | handle_char( char ). 386 | ENDWHILE. 387 | m_reader->close( ). 388 | 389 | r_formated_content = get_lines_as_string( ). 390 | ENDMETHOD. 391 | 392 | METHOD clear_members. 393 | CLEAR: m_reader, m_blocks, m_line, m_lines. 394 | ENDMETHOD. 395 | 396 | ENDCLASS. 397 | -------------------------------------------------------------------------------- /zcl_max_line_length_pp.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for your ABAP unit test classes 2 | CLASS ltcl_pretty_printer_should DEFINITION DEFERRED. 3 | CLASS zcl_max_line_length_pp DEFINITION LOCAL FRIENDS ltcl_pretty_printer_should. 4 | CLASS ltcl_pretty_printer_should DEFINITION FINAL FOR TESTING 5 | DURATION SHORT 6 | RISK LEVEL HARMLESS. 7 | 8 | PRIVATE SECTION. 9 | DATA cut TYPE REF TO zcl_max_line_length_pp. 10 | 11 | METHODS: 12 | setup, 13 | "! test escaped apostrophes in the beginning, middle and end of string. 14 | escape_apostrophes FOR TESTING RAISING cx_static_check, 15 | indent_and_add_line_breaks FOR TESTING RAISING cx_static_check, 16 | 17 | "! ABAP Editor does not support more than 255 lines. 18 | "! Issue: https://github.com/objective-partner/abap_debugger_data_view_extension/issues/9 19 | break_line_if_length_less_20 FOR TESTING RAISING cx_static_check, 20 | max_line_length_less_128 FOR TESTING RAISING cx_static_check, 21 | 22 | "!calls to pretty printer should be idempotent 23 | clear_last_result FOR TESTING RAISING cx_static_check. 24 | ENDCLASS. 25 | 26 | CLASS ltcl_pretty_printer_should IMPLEMENTATION. 27 | 28 | METHOD setup. 29 | "as we are here in a private unit test class so we don't need to use the factory or injector for instantiating 30 | cut = NEW #( indent_size = 2 max_line_length = 128 ). 31 | ENDMETHOD. 32 | 33 | 34 | METHOD escape_apostrophes. 35 | "GIVEN 36 | cut = NEW #( indent_size = 2 max_line_length = 128 ). 37 | DATA(input) = |D = VALUE #( COL_1 = 'It''s easy (isn''t it?)' COL_2 = 'keep on doin''' COL_3 = '''ne Weile' COL_4 = '''' )|. 38 | DATA(expected) = |D = VALUE #(\r COL_1 = 'It''s easy (isn''t it?)'\r COL_2 = 'keep on doin'''\r COL_3 = '''ne Weile'\r COL_4 = ''''\r)|. 39 | 40 | "WHEN 41 | DATA(formatted_string) = cut->format( input ). 42 | 43 | "THEN 44 | cl_abap_unit_assert=>assert_equals( 45 | EXPORTING 46 | act = formatted_string 47 | exp = expected 48 | msg = |Apostrophes or brackets were not handled correctly.| ). 49 | ENDMETHOD. 50 | 51 | METHOD indent_and_add_line_breaks. 52 | "GIVEN 53 | cut = NEW #( indent_size = 2 max_line_length = 128 ). 54 | DATA(input) = |D = VALUE #( COL1 = '1' COL2 = VALUE #( COL1 = '1' COL2 = '2' ) COL3 = '3' COL4 = VALUE #( COL1 = '1' COL2 = '2' ) )|. 55 | DATA(expected) = |D = VALUE #(\r COL1 = '1'\r COL2 = VALUE #(\r COL1 = '1'\r COL2 = '2'\r )\r COL3 = '3'\r COL4 = VALUE #(\r COL1 = '1'\r COL2 = '2'\r )\r)|. 56 | 57 | "D = VALUE #( 58 | " COL1 = '1' 59 | " COL2 = VALUE #( 60 | " COL1 = '1' 61 | " COL2 = '2' 62 | " ) 63 | " COL3 = '3' 64 | " COL4 = VALUE #( 65 | " COL1 = '1' 66 | " COL2 = '2' 67 | " ) 68 | "). 69 | 70 | "WHEN 71 | DATA(formatted_string) = cut->format( input ). 72 | 73 | "THEN 74 | cl_abap_unit_assert=>assert_equals( 75 | EXPORTING 76 | act = formatted_string 77 | exp = expected 78 | msg = |Indent or line breaks were not added correctly| ). 79 | 80 | ENDMETHOD. 81 | 82 | METHOD break_line_if_length_less_20. 83 | "GIVEN 84 | cut = NEW #( indent_size = 2 max_line_length = 20 ). 85 | DATA(input) = |D = VALUE #( C1 = 'A123456789B123456789C123456789D123456789E123456789' )|. 86 | DATA(expected) = |D = VALUE #(\r C1 = 'A123456789' &&\r 'B123456789C1234' &&\r '56789D123456789' &&\r 'E123456789'\r)|. 87 | 88 | "WHEN 89 | DATA(formatted_string) = cut->format( input ). 90 | 91 | "THEN 92 | cl_abap_unit_assert=>assert_equals( 93 | EXPORTING 94 | act = formatted_string 95 | exp = expected 96 | msg = |Values exceeding maximum line length are not handled correctly.| ). 97 | 98 | ENDMETHOD. 99 | 100 | METHOD max_line_length_less_128. 101 | DATA lines_actual TYPE TABLE OF string. 102 | DATA lines_expected TYPE TABLE OF string. 103 | 104 | "GIVEN 105 | cut = NEW #( indent_size = 2 max_line_length = 128 ). 106 | DATA(input) = |EDIDD = VALUE #( ( SEGNAM = 'E1EDK01' SDATA = 'EUREUR1.00000 0021 DE12345678901 DE12345678901 INVO1234561234| && 107 | | 2.000 2.000 ABCDE 1112223344 | && 108 | | ABCDEDFGHIJKLMNOPQRSTUVWXYZ AND STILL SOME MORE CHARACTERS - THERE WILL BE NO END | && 109 | | - MAYBE THERE IS AN END IN SIGHT' ) ).|. 110 | DATA(expected) = |EDIDD = VALUE #(\r| && 111 | | (\r SEGNAM = 'E1EDK01'\r| && 112 | | SDATA = 'EUREUR1.00000 0021 DE12345678901 DE12345678901 INVO1234561234 ' &&\r| && 113 | | ' 2.000 2.000 ABCDE 1112223344 ' &&\r| && 114 | | 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ AND STILL SOME MORE CHARACTERS - THERE WILL BE NO END ' &&\r| && 115 | | ' - MAYBE THERE IS AN END IN SIGHT'\r| && 116 | | )\r)|. 117 | lines_expected = VALUE #( 118 | ( |EDIDD = VALUE #(| ) 119 | ( | (| ) 120 | ( | SEGNAM = 'E1EDK01'| ) 121 | ( | SDATA = 'EUREUR1.00000 0021 DE12345678901 DE12345678901 INVO1234561234 ' &&| ) 122 | ( | ' 2.000 2.000 ABCDE 1112223344 ' &&| ) 123 | ( | 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ AND STILL SOME MORE CHARACTERS - THERE WILL BE NO END ' &&| ) 124 | ( | ' - MAYBE THERE IS AN END IN SIGHT'| ) 125 | ( | )| ) 126 | ( |)| ) 127 | ). 128 | "EDIDD = VALUE #( 129 | " ( 130 | " SEGNAM = 'E1EDK01' 131 | " SDATA = 'EUREUR1.00000 0021 DE12345678901 DE12345678901 INVO1234561234 ' && 132 | " ' 2.000 2.000 ABCDE 1112223344 ' && 133 | " 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ AND STILL SOME MORE CHARACTERS - THERE WILL BE NO END ' && 134 | " ' - MAYBE THERE IS AN END IN SIGHT' 135 | " ) 136 | ") 137 | 138 | "WHEN 139 | DATA(formated_string) = cut->format( input ). 140 | 141 | SPLIT formated_string AT zcl_max_line_length_pp=>c_newline INTO TABLE lines_actual. 142 | DATA(max_length) = 0. 143 | LOOP AT lines_actual INTO DATA(line). 144 | DATA(length) = strlen( line ). 145 | max_length = COND i( WHEN length >= max_length THEN length ELSE max_length ). 146 | ENDLOOP. 147 | 148 | "THEN 149 | cl_abap_unit_assert=>assert_number_between( lower = 2 upper = 128 number = max_length ). 150 | cl_abap_unit_assert=>assert_equals( act = lines_actual exp = lines_expected ). 151 | cl_abap_unit_assert=>assert_equals( act = formated_string exp = expected ). 152 | 153 | ENDMETHOD. 154 | 155 | 156 | METHOD clear_last_result. 157 | "GIVEN 158 | cut = NEW #( indent_size = 2 max_line_length = 20 ). 159 | DATA(input) = |D = VALUE #( C1 = 'A123456789B123456789C123456789D123456789E123456789' )|. 160 | DATA(expected) = |D = VALUE #(\r C1 = 'A123456789' &&\r 'B123456789C1234' &&\r '56789D123456789' &&\r 'E123456789'\r)|. 161 | 162 | "WHEN 163 | DATA(formatted_string) = cut->format( input ). 164 | "we need to call it twice here, to see if output is still the right one 165 | formatted_string = cut->format( input ). 166 | 167 | "THEN 168 | cl_abap_unit_assert=>assert_equals( 169 | EXPORTING 170 | act = formatted_string 171 | exp = expected 172 | msg = |Values exceeding maximum line length are not handled correctly.| ). 173 | ENDMETHOD. 174 | 175 | ENDCLASS. 176 | -------------------------------------------------------------------------------- /zcl_max_line_length_pp.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_MAX_LINE_LENGTH_PP 7 | E 8 | Pretty Printer for VALUE with compression 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zcl_op_abap_typedescr.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_op_abap_typedescr DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PUBLIC . 5 | 6 | PUBLIC SECTION. 7 | 8 | CONSTANTS typekind_int TYPE abap_typekind VALUE 'I'. "#EC NOTEXT 9 | CONSTANTS typekind_int1 TYPE abap_typekind VALUE 'b'. "#EC NOTEXT 10 | CONSTANTS typekind_int2 TYPE abap_typekind VALUE 's'. "#EC NOTEXT 11 | "in 7.40 there is no int8 but in s4hana there is one 12 | "having this constants in z-class gives little upward compatibility 13 | CONSTANTS typekind_int8 TYPE abap_typekind VALUE '8'. "#EC NOTEXT 14 | CONSTANTS typekind_struct1 TYPE abap_typekind VALUE 'u'. "#EC NOTEXT 15 | CONSTANTS typekind_struct2 TYPE abap_typekind VALUE 'v'. "#EC NOTEXT 16 | CONSTANTS typekind_table TYPE abap_typekind VALUE 'h'. "#EC NOTEXT 17 | CONSTANTS typekind_string TYPE abap_typekind VALUE 'g'. "#EC NOTEXT 18 | 19 | PROTECTED SECTION. 20 | PRIVATE SECTION. 21 | ENDCLASS. 22 | 23 | 24 | 25 | CLASS zcl_op_abap_typedescr IMPLEMENTATION. 26 | ENDCLASS. 27 | -------------------------------------------------------------------------------- /zcl_op_abap_typedescr.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_ABAP_TYPEDESCR 7 | E 8 | Custom Copy of CL_ABAP_TYPEDESCR Types 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /zcl_op_component.clas.abap: -------------------------------------------------------------------------------- 1 | "! Component representation for Abap Debugger Enhancement 2 | "! is responsible for representing components/fields 3 | "! within a -component = 'component value' statement 4 | CLASS zcl_op_component DEFINITION 5 | PUBLIC 6 | FINAL 7 | CREATE PUBLIC . 8 | 9 | PUBLIC SECTION. 10 | METHODS: 11 | 12 | "! add a single component or already formated context 13 | "! @parameter i_datatype | datatype of component 14 | "! @parameter i_current_context | current context as string 15 | "! @parameter i_component | current component 16 | "! @parameter i_component_info | field catalog info for this component 17 | "! @parameter r_current_context | changed context with added component data as string 18 | add 19 | IMPORTING 20 | i_datatype TYPE datatype_d OPTIONAL 21 | i_current_context TYPE string 22 | i_component TYPE any 23 | i_component_info TYPE lvc_s_fcat 24 | RETURNING VALUE(r_current_context) TYPE string. 25 | 26 | PROTECTED SECTION. 27 | PRIVATE SECTION. 28 | METHODS: 29 | "! prepare component name 30 | "! delete surrounding spaces 31 | component_name IMPORTING i_component_name TYPE string 32 | RETURNING VALUE(r_component_name) TYPE string. 33 | ENDCLASS. 34 | 35 | 36 | 37 | CLASS zcl_op_component IMPLEMENTATION. 38 | 39 | 40 | METHOD add. 41 | 42 | r_current_context = i_current_context. 43 | 44 | CHECK i_component IS NOT INITIAL. 45 | 46 | DATA(assign_component_value) = SWITCH #( i_component_info-inttype 47 | WHEN zcl_op_abap_typedescr=>typekind_int1 48 | OR zcl_op_abap_typedescr=>typekind_int2 49 | OR zcl_op_abap_typedescr=>typekind_int 50 | OR zcl_op_abap_typedescr=>typekind_int8 51 | THEN condense( |{ i_component }| ) 52 | WHEN zcl_op_abap_typedescr=>typekind_struct1 53 | OR zcl_op_abap_typedescr=>typekind_struct2 54 | OR zcl_op_abap_typedescr=>typekind_table 55 | THEN i_component 56 | WHEN zcl_op_abap_typedescr=>typekind_string 57 | THEN |`{ replace( val = i_component sub = |`| with = |``| occ = 0 ) }`| 58 | ELSE |'{ replace( val = i_component sub = |'| with = |''| occ = 0 ) }'| ). 59 | 60 | IF i_component_info-fieldname IS NOT INITIAL. 61 | 62 | DATA(component_name) = COND string( WHEN i_component_info-seltext <> space 63 | AND i_component_info-seltext <> i_component_info-fieldname 64 | THEN i_component_info-seltext 65 | ELSE i_component_info-fieldname ). 66 | 67 | DATA(new_column_value_combi) = | { me->component_name( component_name ) 68 | }{ COND #( WHEN i_component_info-datatype <> |STRU| THEN | = | ) 69 | }{ assign_component_value }|. 70 | 71 | r_current_context = |{ i_current_context }{ new_column_value_combi }|. 72 | 73 | ELSE. 74 | 75 | " Line type of table has NO component (like a table of integers: DATA itab TYPE TABLE OF i) 76 | r_current_context = | { assign_component_value }|. 77 | 78 | ENDIF. 79 | 80 | 81 | 82 | ENDMETHOD. 83 | 84 | 85 | METHOD component_name. 86 | r_component_name = i_component_name. 87 | CONDENSE r_component_name NO-GAPS. 88 | ENDMETHOD. 89 | ENDCLASS. 90 | -------------------------------------------------------------------------------- /zcl_op_component.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_COMPONENT 7 | E 8 | Component Representation for Abap Debugger Enhancement 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /zcl_op_debugger_integration.clas.abap: -------------------------------------------------------------------------------- 1 | "!This Class is offering an integration for debugger structure view 2 | CLASS zcl_op_debugger_integration DEFINITION 3 | PUBLIC 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | METHODS: 9 | "! Get reference to structure or table content 10 | "! we need to do this as the full structure content is hidden here 11 | "! and need to be retrieved via a kernel call 12 | "! @parameter i_variable_name | Name of the structure 13 | "! @parameter r_content_ref | Reference to structures content 14 | "! @raising cx_tpda_sys_symb | 15 | "! @raising cx_tpda_varname | 16 | "! @raising cx_tpda_internel_error | 17 | get_ref_to_any_content 18 | IMPORTING i_variable_name TYPE string 19 | RETURNING VALUE(r_content_ref) TYPE REF TO data 20 | RAISING cx_tpda_sys_symb 21 | cx_tpda_varname 22 | cx_tpda_internel_error. 23 | 24 | CLASS-METHODS: 25 | debug_debugger_if_needed. 26 | 27 | 28 | PROTECTED SECTION. 29 | PRIVATE SECTION. 30 | 31 | METHODS: 32 | 33 | get_data_as_readable_xml 34 | IMPORTING 35 | i_variable_name TYPE string 36 | RETURNING 37 | VALUE(r_readable_xml_data) TYPE string 38 | RAISING cx_tpda_sys_symb, 39 | 40 | create_empty_data_structure 41 | IMPORTING 42 | i_variable_name TYPE string 43 | RETURNING VALUE(r_empty_data_structure_ref) TYPE REF TO data 44 | RAISING cx_tpda_sys_symb 45 | cx_tpda_varname 46 | cx_tpda_internel_error, 47 | 48 | fill_empty_data_from_xml 49 | IMPORTING i_xml TYPE string 50 | i_empty_data_structure_ref TYPE REF TO data 51 | RETURNING VALUE(r_filled_data_structure_ref) TYPE REF TO data, 52 | 53 | rename_xml_node 54 | IMPORTING 55 | i_new_node_name TYPE string 56 | CHANGING 57 | c_document TYPE REF TO if_ixml_document, 58 | 59 | render_new_xml_document 60 | CHANGING 61 | c_xml TYPE string 62 | c_ixml TYPE REF TO if_ixml 63 | c_document TYPE REF TO if_ixml_document. 64 | 65 | ENDCLASS. 66 | 67 | 68 | 69 | CLASS ZCL_OP_DEBUGGER_INTEGRATION IMPLEMENTATION. 70 | 71 | 72 | METHOD create_empty_data_structure. 73 | 74 | cl_tpda_ctrl_handler=>get_quick_var( EXPORTING 75 | p_symbname = i_variable_name " symbol name 76 | IMPORTING 77 | p_symbquick_ref = DATA(symbquick_ref) ). 78 | 79 | cl_tpda_variable_services=>convert_quick_info( EXPORTING 80 | p_symbquick = symbquick_ref " TPDA: Retrieval Structure for get_Symb_Quick 81 | p_ref_flag = space 82 | p_itab_body_flag = space 83 | IMPORTING 84 | p_var_result = DATA(struc_data) ). 85 | 86 | 87 | 88 | 89 | CREATE DATA r_empty_data_structure_ref TYPE (struc_data-varabstypename). " RTTC - dynamic creation of elementary data object 90 | 91 | ENDMETHOD. 92 | 93 | 94 | METHOD debug_debugger_if_needed. 95 | 96 | IF sy-datum = '20240608' AND sy-uname = 'A.GEPPART'. 97 | BREAK-POINT ##NEEDED. 98 | ENDIF. 99 | 100 | ENDMETHOD. 101 | 102 | 103 | METHOD fill_empty_data_from_xml. 104 | 105 | DATA: content_ref TYPE REF TO data. 106 | 107 | content_ref = i_empty_data_structure_ref. 108 | 109 | 110 | DATA(xml) = i_xml. "we need a copy as we will change it locally 111 | 112 | DATA(ixml) = cl_ixml=>create( ). 113 | DATA(stream_factory) = ixml->create_stream_factory( ). 114 | DATA(document) = ixml->create_document( ). 115 | 116 | CONSTANTS: c_new_node_name TYPE string VALUE 'Here_Is_the_Data'. 117 | 118 | IF ixml->create_parser( document = document 119 | stream_factory = stream_factory 120 | istream = stream_factory->create_istream_string( xml ) 121 | )->parse( ) <> 0. 122 | RETURN. 123 | ENDIF. 124 | 125 | me->rename_xml_node( EXPORTING i_new_node_name = c_new_node_name 126 | CHANGING c_document = document ). 127 | 128 | me->render_new_xml_document( CHANGING c_xml = xml 129 | c_ixml = ixml 130 | c_document = document ). 131 | 132 | DATA: transform_result_binding TYPE abap_trans_resbind_tab. 133 | FIELD-SYMBOLS: LIKE LINE OF transform_result_binding. 134 | 135 | APPEND INITIAL LINE TO transform_result_binding ASSIGNING . 136 | -name = c_new_node_name. 137 | -value = content_ref. 138 | 139 | CALL TRANSFORMATION id 140 | SOURCE XML xml 141 | RESULT (transform_result_binding) ##no_text. 142 | 143 | r_filled_data_structure_ref = content_ref. 144 | 145 | ENDMETHOD. 146 | 147 | 148 | METHOD get_data_as_readable_xml. 149 | 150 | cl_tpda_ctrl_handler=>get_symb_asxml( EXPORTING 151 | symbname = |{ i_variable_name }| 152 | offset = -1 153 | len = -1 154 | IMPORTING 155 | xml = DATA(binary_xml_data) ). 156 | r_readable_xml_data = cl_abap_codepage=>convert_from( binary_xml_data ). 157 | ENDMETHOD. 158 | 159 | 160 | METHOD get_ref_to_any_content. 161 | DATA(readable_xml_data) = me->get_data_as_readable_xml( i_variable_name ). 162 | 163 | DATA(empty_data_structure_ref) = me->create_empty_data_structure( i_variable_name ). 164 | 165 | r_content_ref = me->fill_empty_data_from_xml( EXPORTING i_xml = readable_xml_data 166 | i_empty_data_structure_ref = empty_data_structure_ref ). 167 | ENDMETHOD. 168 | 169 | 170 | METHOD rename_xml_node. 171 | 172 | DATA last_node_name TYPE string. 173 | 174 | DATA(node_element_filter) = c_document->create_filter_node_type( node_types = if_ixml_node=>co_node_element ). 175 | 176 | DATA(iterator) = c_document->create_iterator_filtered( filter = node_element_filter ). 177 | 178 | DO. 179 | DATA(node) = iterator->get_next( ). 180 | IF node IS INITIAL. 181 | EXIT. 182 | ENDIF. 183 | DATA(current_node_name) = node->get_name( ). 184 | IF last_node_name EQ |values|. 185 | "we have to rename current node (start element), as its name can lead to unseccessfull transformation 186 | node->set_name( name = i_new_node_name ). 187 | EXIT. 188 | ENDIF. 189 | last_node_name = current_node_name. 190 | ENDDO. 191 | 192 | ENDMETHOD. 193 | 194 | 195 | METHOD render_new_xml_document. 196 | 197 | CLEAR: c_xml. "we will append new content to it now 198 | c_document->render( ostream = c_ixml->create_stream_factory( )->create_ostream_cstring( string = c_xml ) ). 199 | 200 | ENDMETHOD. 201 | ENDCLASS. 202 | -------------------------------------------------------------------------------- /zcl_op_debugger_integration.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_DEBUGGER_INTEGRATION 7 | E 8 | Abap Debugger Integration 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /zcl_op_pretty_printer_factory.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_op_pretty_printer_factory DEFINITION 2 | PUBLIC 3 | FINAL 4 | CREATE PRIVATE 5 | GLOBAL FRIENDS zcl_op_pretty_printer_injector. 6 | 7 | PUBLIC SECTION. 8 | CLASS-METHODS: 9 | create RETURNING VALUE(r_pretty_printer) 10 | TYPE REF TO zif_op_value_pretty_printer 11 | RAISING cx_class_not_existent. 12 | PROTECTED SECTION. 13 | 14 | PRIVATE SECTION. 15 | TYPES: tt_dve_cust TYPE STANDARD TABLE OF ztop_dve_cust WITH DEFAULT KEY. 16 | CLASS-DATA: pretty_printer TYPE REF TO zif_op_value_pretty_printer, 17 | class_names TYPE string_table, 18 | user_class_customizing TYPE tt_dve_cust. 19 | CLASS-METHODS: 20 | "!get active classes implementing zif_op_value_pretty_printer 21 | get_activ_implementing_classes RETURNING VALUE(r_class_names) TYPE string_table 22 | RAISING cx_class_not_existent, 23 | get_customizing_for_given_user RETURNING VALUE(r_customizing) TYPE ztop_dve_cust, 24 | read_customizing, 25 | "!check if a given class an active implementation 26 | is_given_class_an_active_impl IMPORTING i_classname_to_use TYPE ztop_dve_cust 27 | RETURNING VALUE(r_class_impl_is_active) TYPE boole_d 28 | RAISING cx_class_not_existent . 29 | ENDCLASS. 30 | 31 | 32 | 33 | CLASS zcl_op_pretty_printer_factory IMPLEMENTATION. 34 | 35 | 36 | METHOD create. 37 | 38 | IF pretty_printer IS NOT BOUND. 39 | 40 | "check which of them is customized for current user 41 | DATA(classname_to_use) = get_customizing_for_given_user( ). 42 | 43 | classname_to_use = COND #( WHEN is_given_class_an_active_impl( classname_to_use ) EQ abap_true THEN classname_to_use ELSE |ZCL_OP_VALUE_PRETTY_PRINTER| ). 44 | 45 | CREATE OBJECT pretty_printer TYPE (classname_to_use). 46 | ENDIF. 47 | 48 | r_pretty_printer = pretty_printer. 49 | ENDMETHOD. 50 | 51 | 52 | METHOD get_activ_implementing_classes. 53 | IF class_names[] IS INITIAL. 54 | DATA(oo_interface) = NEW cl_oo_interface( |ZIF_OP_VALUE_PRETTY_PRINTER| ). 55 | 56 | DATA(classes) = oo_interface->get_implementing_classes( ). 57 | 58 | class_names = VALUE #( FOR IN classes ( CONV string( -clsname ) ) ). 59 | ENDIF. 60 | 61 | 62 | r_class_names = class_names. 63 | ENDMETHOD. 64 | 65 | 66 | METHOD get_customizing_for_given_user. 67 | read_customizing( ). 68 | CHECK line_exists( user_class_customizing[ user_name = sy-uname ] ). 69 | r_customizing = user_class_customizing[ user_name = sy-uname ]-class_name. 70 | ENDMETHOD. 71 | 72 | 73 | METHOD is_given_class_an_active_impl. 74 | 75 | " get active classes implementing zif_op_value_pretty_printer 76 | class_names = get_activ_implementing_classes( ). 77 | 78 | r_class_impl_is_active = COND boole_d( WHEN line_exists( class_names[ table_line = i_classname_to_use ] ) THEN abap_true ELSE abap_false ). 79 | 80 | ENDMETHOD. 81 | 82 | 83 | METHOD read_customizing. 84 | IF user_class_customizing[] IS INITIAL. 85 | SELECT * 86 | FROM ztop_dve_cust 87 | INTO TABLE user_class_customizing. 88 | 89 | ENDIF. 90 | ENDMETHOD. 91 | ENDCLASS. 92 | -------------------------------------------------------------------------------- /zcl_op_pretty_printer_factory.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for your ABAP unit test classes 2 | CLASS ltcl_pp_factory_should DEFINITION DEFERRED. 3 | CLASS zcl_op_pretty_printer_factory DEFINITION LOCAL FRIENDS ltcl_pp_factory_should. 4 | CLASS ltcl_pp_factory_should DEFINITION FINAL FOR TESTING 5 | DURATION SHORT 6 | RISK LEVEL HARMLESS. 7 | 8 | PRIVATE SECTION. 9 | METHODS: 10 | find_standard_pretty_printer FOR TESTING RAISING cx_static_check, 11 | create_standard_pretty_printer FOR TESTING RAISING cx_static_check. 12 | ENDCLASS. 13 | 14 | 15 | CLASS ltcl_pp_factory_should IMPLEMENTATION. 16 | 17 | 18 | METHOD find_standard_pretty_printer. 19 | "GIVEN - ... 20 | 21 | "WHEN 22 | DATA(classes) = zcl_op_pretty_printer_factory=>get_activ_implementing_classes( ). 23 | 24 | "THEN 25 | cl_abap_unit_assert=>assert_table_contains( EXPORTING line = |ZCL_OP_VALUE_PRETTY_PRINTER| 26 | table = classes 27 | msg = |Main implementation of zif_op_value_pretty_printer was not found| ). 28 | 29 | ENDMETHOD. 30 | 31 | 32 | METHOD create_standard_pretty_printer. 33 | 34 | "GIVEN 35 | zcl_op_pretty_printer_factory=>user_class_customizing = VALUE #( ( user_name = |AGEPPART| class_name = |ZCL_OP_VALUE_PRETTY_PRINTER| ) ). 36 | 37 | "WHEN 38 | DATA(pretty_printer) = zcl_op_pretty_printer_factory=>create( ). 39 | 40 | 41 | "THEN 42 | TRY. 43 | DATA(must_be_pretty_printer) = CAST zcl_op_value_pretty_printer( pretty_printer ). 44 | 45 | CATCH cx_sy_move_cast_error INTO DATA(error). 46 | cl_abap_unit_assert=>fail( EXPORTING msg = |Standard class ZCL_OP_VALUE_PRETTY_PRINTER was not used in factory but should have been. Error is { error->get_longtext( ) }| ). 47 | ENDTRY. 48 | 49 | 50 | ENDMETHOD. 51 | 52 | ENDCLASS. 53 | -------------------------------------------------------------------------------- /zcl_op_pretty_printer_factory.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_PRETTY_PRINTER_FACTORY 7 | E 8 | ABAP Debugger Enhancement - Factory for Pretty Printer 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zcl_op_pretty_printer_injector.clas.abap: -------------------------------------------------------------------------------- 1 | "! need for dependency injection via lookup and unit tests 2 | "! see openSAP course Writing Testable Code for ABAP Week_5 3 | CLASS zcl_op_pretty_printer_injector DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | CLASS-METHODS: 10 | inject_pretty_printer IMPORTING i_pretty_printer TYPE REF TO zif_op_value_pretty_printer, 11 | inject_class_names IMPORTING i_class_names TYPE string_table, 12 | inject_user_class_customizing IMPORTING i_user_class_customizing TYPE zcl_op_pretty_printer_factory=>tt_dve_cust. 13 | PROTECTED SECTION. 14 | PRIVATE SECTION. 15 | ENDCLASS. 16 | 17 | 18 | 19 | CLASS zcl_op_pretty_printer_injector IMPLEMENTATION. 20 | 21 | METHOD inject_pretty_printer. 22 | zcl_op_pretty_printer_factory=>pretty_printer = i_pretty_printer. 23 | ENDMETHOD. 24 | 25 | 26 | METHOD inject_class_names. 27 | zcl_op_pretty_printer_factory=>class_names = i_class_names. 28 | ENDMETHOD. 29 | 30 | 31 | METHOD inject_user_class_customizing. 32 | zcl_op_pretty_printer_factory=>user_class_customizing = i_user_class_customizing. 33 | ENDMETHOD. 34 | 35 | ENDCLASS. 36 | -------------------------------------------------------------------------------- /zcl_op_pretty_printer_injector.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_PRETTY_PRINTER_INJECTOR 7 | E 8 | ABAP Debugger Enhancement - Injector for Pretty Printer 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /zcl_op_simple_field_catalog.clas.abap: -------------------------------------------------------------------------------- 1 | "!This Class is offering a simplified field catalog 2 | "!where only needed fields are populated for debugger extension 3 | CLASS zcl_op_simple_field_catalog DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC . 7 | 8 | PUBLIC SECTION. 9 | METHODS: 10 | "! get field_catalog by reference to data 11 | "! @parameter i_reference_to_data | reference to current data 12 | "! @parameter r_field_catalog | field catalog of current data 13 | get_by_reference 14 | IMPORTING i_reference_to_data TYPE REF TO data 15 | RETURNING VALUE(r_field_catalog) TYPE lvc_t_fcat, 16 | "! get field_catalog by given data 17 | "! @parameter i_table | any table 18 | "! @parameter i_structure | any structure 19 | "! @parameter r_field_catalog | field catalog of current data 20 | get_by_data 21 | IMPORTING i_table TYPE ANY TABLE OPTIONAL 22 | i_structure TYPE any OPTIONAL 23 | RETURNING VALUE(r_field_catalog) TYPE lvc_t_fcat. 24 | PROTECTED SECTION. 25 | PRIVATE SECTION. 26 | METHODS: 27 | get_fieldcatalog_from_ddic 28 | IMPORTING i_rtti TYPE REF TO cl_abap_typedescr 29 | RETURNING VALUE(r_field_catalog) TYPE lvc_t_fcat, 30 | get_fieldcat_from_local_type 31 | IMPORTING i_rtti TYPE REF TO cl_abap_typedescr 32 | RETURNING VALUE(r_field_catalog) TYPE lvc_t_fcat, 33 | transform 34 | CHANGING 35 | !c_ddic_fields TYPE ddfields OPTIONAL 36 | !c_ddic_field TYPE dfies OPTIONAL, 37 | map_to_field_catalog 38 | IMPORTING i_ddic_fields TYPE ddfields 39 | RETURNING VALUE(r_field_catalog) TYPE lvc_t_fcat, 40 | get_reference_to_data 41 | IMPORTING 42 | i_table TYPE ANY TABLE 43 | i_structure TYPE any 44 | RETURNING VALUE(r_data) TYPE REF TO data, 45 | get_fieldcatalog_via_reference 46 | IMPORTING i_reference_to_data TYPE REF TO data 47 | RETURNING VALUE(r_field_catalog) TYPE lvc_t_fcat. 48 | ENDCLASS. 49 | 50 | 51 | 52 | CLASS zcl_op_simple_field_catalog IMPLEMENTATION. 53 | 54 | METHOD get_by_reference. 55 | r_field_catalog = me->get_fieldcatalog_via_reference( i_reference_to_data ). 56 | ENDMETHOD. 57 | 58 | METHOD get_fieldcatalog_via_reference. 59 | 60 | DATA(rtti) = cl_abap_typedescr=>describe_by_data_ref( i_reference_to_data ). 61 | 62 | IF rtti->kind = rtti->kind_table. 63 | rtti = CAST cl_abap_tabledescr( rtti )->get_table_line_type( ). 64 | ENDIF. 65 | 66 | r_field_catalog = COND #( WHEN rtti->is_ddic_type( ) = abap_true 67 | THEN me->get_fieldcatalog_from_ddic( rtti ) 68 | ELSE me->get_fieldcat_from_local_type( rtti ) ). 69 | 70 | ENDMETHOD. 71 | 72 | METHOD get_by_data. 73 | 74 | DATA(reference_to_data) = me->get_reference_to_data( i_table = i_table i_structure = i_structure ). 75 | 76 | r_field_catalog = me->get_fieldcatalog_via_reference( reference_to_data ). 77 | ENDMETHOD. 78 | 79 | 80 | METHOD get_fieldcatalog_from_ddic. 81 | 82 | CASE i_rtti->kind. 83 | WHEN i_rtti->kind_elem. 84 | DATA(ddic_fields) = VALUE ddfields( ( CAST cl_abap_elemdescr( i_rtti )->get_ddic_field( ) ) ). 85 | WHEN i_rtti->kind_struct. 86 | ddic_fields = CAST cl_abap_structdescr( i_rtti )->get_ddic_field_list( ). 87 | ENDCASE. 88 | 89 | transform( CHANGING c_ddic_fields = ddic_fields ). 90 | 91 | r_field_catalog = map_to_field_catalog( ddic_fields ). 92 | 93 | ENDMETHOD. 94 | 95 | 96 | METHOD get_fieldcat_from_local_type. 97 | "in case it is a local itab, structure or element definition 98 | CASE i_rtti->kind. 99 | WHEN i_rtti->kind_elem. 100 | APPEND VALUE lvc_s_fcat( LET element_description2 = CAST cl_abap_elemdescr( i_rtti ) IN 101 | inttype = element_description2->type_kind 102 | decimals = element_description2->decimals 103 | convexit = element_description2->edit_mask 104 | outputlen = element_description2->output_length ) 105 | TO r_field_catalog. 106 | WHEN i_rtti->kind_struct. 107 | LOOP AT CAST cl_abap_structdescr( i_rtti )->get_components( ) INTO DATA(component). 108 | CASE component-type->kind. 109 | WHEN 'E'. 110 | DATA(element_description) = CAST cl_abap_elemdescr( component-type ). 111 | IF element_description->is_ddic_type( ) = abap_true. 112 | APPEND VALUE lvc_s_fcat( fieldname = component-name 113 | seltext = component-name 114 | inttype = element_description->type_kind 115 | decimals = element_description->decimals 116 | convexit = element_description->edit_mask 117 | outputlen = element_description->output_length ) 118 | TO r_field_catalog. 119 | 120 | ELSE. 121 | APPEND VALUE lvc_s_fcat( fieldname = component-name 122 | seltext = component-name 123 | inttype = element_description->type_kind 124 | decimals = element_description->decimals 125 | convexit = element_description->edit_mask 126 | outputlen = element_description->output_length ) 127 | TO r_field_catalog. 128 | ENDIF. 129 | WHEN 'S'. 130 | IF component-as_include = abap_true. 131 | DATA(lt_include_field_cat) = me->get_fieldcat_from_local_type( i_rtti = CAST #( component-type ) ). 132 | APPEND LINES OF lt_include_field_cat TO r_field_catalog. 133 | ELSE. 134 | DATA(structure_description) = CAST cl_abap_structdescr( component-type ). 135 | APPEND VALUE lvc_s_fcat( fieldname = component-name 136 | seltext = component-name 137 | inttype = structure_description->type_kind 138 | datatype = |STRU| ) 139 | TO r_field_catalog. 140 | ENDIF. 141 | WHEN 'T'. 142 | DATA(table_description) = CAST cl_abap_tabledescr( component-type ). 143 | APPEND VALUE #( fieldname = component-name 144 | seltext = component-name 145 | inttype = table_description->type_kind 146 | datatype = COND #( WHEN table_description->kind EQ table_description->kind_table 147 | THEN |TTYP| 148 | ELSE space ) ) 149 | TO r_field_catalog. 150 | ENDCASE. 151 | 152 | ENDLOOP. 153 | ENDCASE. 154 | ENDMETHOD. 155 | 156 | 157 | METHOD transform. 158 | "see CL_SALV_DATA_DESCR=>TRANSFORM 159 | IF c_ddic_field-tabname EQ c_ddic_field-rollname OR 160 | c_ddic_field-tabname EQ c_ddic_field-domname. 161 | CLEAR c_ddic_field-tabname. 162 | ENDIF. 163 | 164 | 165 | c_ddic_field-reftable = c_ddic_field-tabname. 166 | c_ddic_field-reffield = c_ddic_field-fieldname. 167 | CLEAR c_ddic_field-precfield. 168 | 169 | FIELD-SYMBOLS: TYPE dfies. 170 | 171 | LOOP AT c_ddic_fields ASSIGNING . 172 | 173 | CLEAR -precfield. 174 | IF -datatype = 'CURR' OR -datatype = 'QUAN'. 175 | 176 | READ TABLE c_ddic_fields WITH KEY fieldname = -reffield TRANSPORTING NO FIELDS. 177 | IF sy-subrc EQ 0. 178 | -precfield = -reffield. 179 | ENDIF. 180 | 181 | ENDIF. 182 | -reftable = -tabname. 183 | -reffield = -fieldname. 184 | 185 | ENDLOOP. 186 | ENDMETHOD. 187 | 188 | 189 | METHOD map_to_field_catalog. 190 | DATA field_catalog TYPE lvc_s_fcat. 191 | 192 | LOOP AT i_ddic_fields INTO DATA(ls_dfies). 193 | CLEAR field_catalog. 194 | MOVE-CORRESPONDING ls_dfies TO field_catalog. 195 | field_catalog-seltext = ls_dfies-fieldname. 196 | APPEND field_catalog TO r_field_catalog. 197 | ENDLOOP. 198 | ENDMETHOD. 199 | 200 | 201 | METHOD get_reference_to_data. 202 | 203 | IF i_table[] IS NOT INITIAL. 204 | CREATE DATA r_data LIKE LINE OF i_table. 205 | ELSE. 206 | CREATE DATA r_data LIKE i_structure. 207 | ENDIF. 208 | 209 | ENDMETHOD. 210 | 211 | ENDCLASS. 212 | -------------------------------------------------------------------------------- /zcl_op_simple_field_catalog.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for your ABAP unit test classes 2 | CLASS ltcl_fieldcatalog_should DEFINITION DEFERRED. 3 | CLASS zcl_op_simple_field_catalog DEFINITION LOCAL FRIENDS ltcl_fieldcatalog_should. 4 | CLASS ltcl_fieldcatalog_should DEFINITION FINAL FOR TESTING 5 | DURATION SHORT 6 | RISK LEVEL HARMLESS. 7 | 8 | PRIVATE SECTION. 9 | 10 | DATA: lo_cut TYPE REF TO zcl_op_simple_field_catalog. 11 | METHODS: 12 | setup, 13 | get_fields_in_right_order FOR TESTING RAISING cx_static_check, 14 | get_fieldcatalog_of_local_type FOR TESTING RAISING cx_static_check, 15 | get_fieldcatalog_nostruc_table FOR TESTING RAISING cx_static_check, 16 | get_fieldcat_of_local_typ_incl FOR TESTING RAISING cx_static_check. 17 | ENDCLASS. 18 | 19 | 20 | CLASS ltcl_fieldcatalog_should IMPLEMENTATION. 21 | 22 | METHOD get_fields_in_right_order. 23 | DATA: field_catalog TYPE lvc_t_fcat. 24 | 25 | 26 | TYPES: BEGIN OF t_col2, 27 | col1 TYPE i, 28 | col2 TYPE i, 29 | END OF t_col2. 30 | 31 | TYPES: BEGIN OF t_struct, 32 | col1 TYPE i, 33 | col2 TYPE t_col2, 34 | END OF t_struct. 35 | 36 | TYPES: my_itab_type TYPE STANDARD TABLE OF t_struct WITH DEFAULT KEY. 37 | TYPES: BEGIN OF nested_type, 38 | col1 TYPE i, 39 | col2 TYPE t_col2, 40 | col3 TYPE my_itab_type, 41 | END OF nested_type. 42 | 43 | DATA(itab_in_struc) = VALUE nested_type( col1 = 1 44 | 45 | col2 = VALUE #( 46 | col1 = 11 47 | col2 = 22 48 | ) 49 | col3 = VALUE #( 50 | ( col1 = 311 col2 = VALUE #( col1 = 3121 col2 = 3122 ) ) 51 | ( col1 = 321 col2 = VALUE #( col1 = 3221 col2 = 3222 ) ) 52 | ) 53 | ). 54 | 55 | field_catalog = lo_cut->get_by_data( EXPORTING i_structure = itab_in_struc ). 56 | 57 | cl_abap_unit_assert=>assert_equals( 58 | EXPORTING 59 | act = field_catalog[ 1 ]-fieldname 60 | exp = |COL1| 61 | msg = |Order of fieldcatalog fieldnames is not ok| ). 62 | cl_abap_unit_assert=>assert_equals( 63 | EXPORTING 64 | act = field_catalog[ 2 ]-fieldname 65 | exp = |COL2| 66 | msg = |Order of fieldcatalog fieldnames is not ok| ). 67 | cl_abap_unit_assert=>assert_equals( 68 | EXPORTING 69 | act = field_catalog[ 3 ]-fieldname 70 | exp = |COL3| 71 | msg = |Order of fieldcatalog fieldnames is not ok| ). 72 | ENDMETHOD. 73 | 74 | 75 | METHOD setup. 76 | lo_cut = NEW zcl_op_simple_field_catalog( ). 77 | ENDMETHOD. 78 | 79 | 80 | METHOD get_fieldcatalog_of_local_type. 81 | 82 | TYPES: BEGIN OF ts_flight_data, 83 | carrid TYPE s_carr_id, 84 | connid TYPE s_conn_id, 85 | fldate TYPE s_date, 86 | price TYPE s_price, 87 | END OF ts_flight_data, 88 | tt_flight_data TYPE STANDARD TABLE OF ts_flight_data WITH EMPTY KEY, 89 | BEGIN OF ts_flight_data_deep, 90 | col1 TYPE tt_flight_data, 91 | END OF ts_flight_data_deep, 92 | tt_flight_data_deep TYPE STANDARD TABLE OF ts_flight_data_deep WITH EMPTY KEY. 93 | 94 | 95 | DATA(flights) = VALUE tt_flight_data_deep( ( col1 = VALUE #( 96 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 97 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 98 | ) 99 | ) 100 | ( col1 = VALUE #( 101 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 102 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 103 | ) 104 | ) 105 | ). 106 | 107 | DATA(lt_field_catalog) = lo_cut->get_by_data( i_table = flights ). 108 | 109 | cl_abap_unit_assert=>assert_not_initial( EXPORTING act = lt_field_catalog[] 110 | msg = |Field catalog was not created| ). 111 | 112 | ENDMETHOD. 113 | 114 | METHOD get_fieldcatalog_nostruc_table. 115 | 116 | TYPES: tt_nostruc TYPE STANDARD TABLE OF i WITH EMPTY KEY. 117 | 118 | 119 | DATA(table) = VALUE tt_nostruc( ( 1 ) ( 2 ) ( 3 ) ). 120 | 121 | DATA(lt_field_catalog) = lo_cut->get_by_data( i_table = table ). 122 | 123 | cl_abap_unit_assert=>assert_not_initial( EXPORTING act = lt_field_catalog[] 124 | msg = |Field catalog was not created| ). 125 | 126 | ENDMETHOD. 127 | 128 | METHOD get_fieldcat_of_local_typ_incl. 129 | 130 | TYPES BEGIN OF gtyp_struct. 131 | INCLUDE TYPE t000. 132 | TYPES dummy_field_1 TYPE i. 133 | TYPES dummy_field_2 TYPE string. 134 | TYPES END OF gtyp_struct . 135 | 136 | DATA(ls_struct) 137 | = VALUE gtyp_struct( 138 | mandt = '000' 139 | logsys = 'DUMMY_1' 140 | dummy_field_1 = 666 141 | dummy_field_2 = 'Hello' 142 | ). 143 | 144 | DATA(lt_field_catalog_act) = lo_cut->get_fieldcat_from_local_type( i_rtti = CAST cl_abap_structdescr( cl_abap_structdescr=>describe_by_data( p_data = ls_struct ) ) ). 145 | 146 | 147 | DATA(lt_field_catalog_exp) = VALUE lvc_t_fcat( 148 | ( 149 | fieldname = 'MANDT' 150 | outputlen = '000003' 151 | seltext = 'MANDT' 152 | inttype = 'C' 153 | ) 154 | ( 155 | fieldname = 'MTEXT' 156 | outputlen = '000025' 157 | seltext = 'MTEXT' 158 | inttype = 'C' 159 | ) 160 | ( 161 | fieldname = 'ORT01' 162 | outputlen = '000025' 163 | seltext = 'ORT01' 164 | inttype = 'C' 165 | ) 166 | ( 167 | fieldname = 'MWAER' 168 | outputlen = '000005' 169 | seltext = 'MWAER' 170 | inttype = 'C' 171 | ) 172 | ( 173 | fieldname = 'ADRNR' 174 | outputlen = '000010' 175 | seltext = 'ADRNR' 176 | inttype = 'C' 177 | ) 178 | ( 179 | fieldname = 'CCCATEGORY' 180 | outputlen = '000001' 181 | seltext = 'CCCATEGORY' 182 | inttype = 'C' 183 | ) 184 | ( 185 | fieldname = 'CCCORACTIV' 186 | outputlen = '000001' 187 | seltext = 'CCCORACTIV' 188 | inttype = 'C' 189 | ) 190 | ( 191 | fieldname = 'CCNOCLIIND' 192 | outputlen = '000001' 193 | seltext = 'CCNOCLIIND' 194 | inttype = 'C' 195 | ) 196 | ( 197 | fieldname = 'CCCOPYLOCK' 198 | outputlen = '000001' 199 | seltext = 'CCCOPYLOCK' 200 | inttype = 'C' 201 | ) 202 | ( 203 | fieldname = 'CCNOCASCAD' 204 | outputlen = '000001' 205 | seltext = 'CCNOCASCAD' 206 | inttype = 'C' 207 | ) 208 | ( 209 | fieldname = 'CCSOFTLOCK' 210 | outputlen = '000001' 211 | seltext = 'CCSOFTLOCK' 212 | inttype = 'C' 213 | ) 214 | ( 215 | fieldname = 'CCORIGCONT' 216 | outputlen = '000001' 217 | seltext = 'CCORIGCONT' 218 | inttype = 'C' 219 | ) 220 | ( 221 | fieldname = 'CCIMAILDIS' 222 | outputlen = '000001' 223 | seltext = 'CCIMAILDIS' 224 | inttype = 'C' 225 | ) 226 | ( 227 | fieldname = 'CCTEMPLOCK' 228 | outputlen = '000001' 229 | seltext = 'CCTEMPLOCK' 230 | inttype = 'C' 231 | ) 232 | ( 233 | fieldname = 'CHANGEUSER' 234 | outputlen = '000012' 235 | seltext = 'CHANGEUSER' 236 | inttype = 'C' 237 | ) 238 | ( 239 | fieldname = 'CHANGEDATE' 240 | outputlen = '000010' 241 | seltext = 'CHANGEDATE' 242 | inttype = 'D' 243 | ) 244 | ( 245 | fieldname = 'LOGSYS' 246 | outputlen = '000010' 247 | convexit = '==ALP' 248 | seltext = 'LOGSYS' 249 | inttype = 'C' 250 | ) 251 | ( 252 | fieldname = 'DUMMY_FIELD_1' 253 | outputlen = '000011' 254 | seltext = 'DUMMY_FIELD_1' 255 | inttype = 'I' 256 | ) 257 | ( 258 | fieldname = 'DUMMY_FIELD_2' 259 | seltext = 'DUMMY_FIELD_2' 260 | inttype = 'g' 261 | ) 262 | ). 263 | 264 | 265 | cl_abap_unit_assert=>assert_equals( act = lt_field_catalog_act 266 | exp = lt_field_catalog_exp 267 | msg = |Fieldcatalogue could not be retrieverd for local type with include| ). 268 | 269 | ENDMETHOD. 270 | 271 | ENDCLASS. 272 | -------------------------------------------------------------------------------- /zcl_op_simple_field_catalog.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_SIMPLE_FIELD_CATALOG 7 | E 8 | Simplified Fieldcatalog 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zcl_op_structure.clas.abap: -------------------------------------------------------------------------------- 1 | "!This class is offering an API for represent a structure 2 | "!in its ABAP VALUE way: structure_name = VALUE #(...) 3 | CLASS zcl_op_structure DEFINITION 4 | PUBLIC 5 | FINAL 6 | CREATE PUBLIC. 7 | 8 | PUBLIC SECTION. 9 | 10 | METHODS: 11 | "! is getting called from enhancement
12 | "! will ask for max line length, format content and show it 13 | "! @parameter i_structure | given structure 14 | "! @parameter i_field_catalog | field catalog of structure 15 | "! @parameter i_struc_name | structure name for "name" = VALUE #() statement 16 | show_popup_w_content 17 | IMPORTING 18 | i_structure TYPE any 19 | i_field_catalog TYPE lvc_t_fcat 20 | i_struc_name TYPE string, 21 | "! add a structure to given formated context 22 | "! @parameter i_current_context | current context as string 23 | "! @parameter i_structure | given structure 24 | "! @parameter i_field_catalog | field catalog of structure 25 | "! @parameter r_current_context | changed context with added structure data as string 26 | add_structure 27 | IMPORTING 28 | i_current_context TYPE string 29 | i_structure TYPE any 30 | i_field_catalog TYPE lvc_t_fcat 31 | RETURNING 32 | VALUE(r_current_context) TYPE string. 33 | PROTECTED SECTION. 34 | PRIVATE SECTION. 35 | 36 | METHODS: 37 | "! prepare component name 38 | "! delete surrounding spaces 39 | component_name IMPORTING i_component_name TYPE lvc_fname 40 | RETURNING VALUE(r_component_name) TYPE lvc_fname, 41 | prepare_output 42 | IMPORTING 43 | i_structure TYPE any 44 | i_field_catalog TYPE lvc_t_fcat 45 | i_struc_name TYPE string 46 | RETURNING VALUE(r_content_4_display) TYPE string, 47 | left_hand_side 48 | IMPORTING 49 | i_struc_name TYPE string 50 | i_is_type_given TYPE boole_d DEFAULT abap_false 51 | RETURNING VALUE(rv_left_hand_side_value) TYPE string, 52 | right_hand_side 53 | IMPORTING 54 | i_is_type_given TYPE boole_d DEFAULT abap_false 55 | i_structure TYPE any 56 | i_field_catalog TYPE lvc_t_fcat 57 | RETURNING VALUE(r_right_hand_side_value) TYPE string, 58 | handle_nested_structure 59 | IMPORTING 60 | i_current_context TYPE string 61 | i_structure TYPE any 62 | i_component_info TYPE lvc_s_fcat 63 | RETURNING VALUE(r_current_context) TYPE string, 64 | add_rhs_value_prefix 65 | IMPORTING 66 | i_is_type_given TYPE boole_d 67 | RETURNING VALUE(r_right_hand_side_value) TYPE string, 68 | add_rhs_postfix 69 | IMPORTING 70 | i_right_hand_side_value TYPE string 71 | RETURNING 72 | VALUE(r_right_hand_side_value) TYPE string, 73 | add_rhs_value 74 | IMPORTING i_right_hand_side_value TYPE string 75 | i_structure TYPE any 76 | i_field_catalog TYPE lvc_t_fcat 77 | RETURNING VALUE(r_right_hand_side_value) TYPE string, 78 | add_rhs_value_and_postfix 79 | IMPORTING 80 | i_right_hand_side_value TYPE string 81 | i_structure TYPE any 82 | i_field_catalog TYPE lvc_t_fcat 83 | RETURNING VALUE(r_right_hand_side_value) TYPE string, 84 | add_itab 85 | IMPORTING 86 | i_current_context TYPE string 87 | i_table TYPE ANY TABLE 88 | i_component_name TYPE lvc_fname 89 | RETURNING VALUE(r_current_context) TYPE string. 90 | 91 | ENDCLASS. 92 | 93 | 94 | 95 | CLASS zcl_op_structure IMPLEMENTATION. 96 | 97 | 98 | METHOD component_name. 99 | r_component_name = i_component_name. 100 | CONDENSE r_component_name NO-GAPS. 101 | ENDMETHOD. 102 | 103 | 104 | 105 | METHOD add_itab. 106 | 107 | r_current_context = NEW zcl_op_table( )->add_itab( i_current_context = || 108 | i_table = i_table 109 | i_component_name = i_component_name 110 | i_dont_add_a_point = abap_true ). 111 | r_current_context = |{ i_current_context } { r_current_context }|. 112 | ENDMETHOD. 113 | 114 | 115 | METHOD add_rhs_postfix. 116 | 117 | r_right_hand_side_value = |{ i_right_hand_side_value } )|. 118 | 119 | ENDMETHOD. 120 | 121 | 122 | METHOD add_rhs_value. 123 | 124 | DATA current_context TYPE string. 125 | 126 | LOOP AT i_field_catalog INTO DATA(field_info). 127 | 128 | ASSIGN COMPONENT field_info-fieldname OF STRUCTURE i_structure TO FIELD-SYMBOL(). 129 | CHECK IS ASSIGNED AND 130 | IS NOT INITIAL. 131 | 132 | current_context = COND #( WHEN field_info-datatype EQ 'TTYP' THEN me->add_itab( i_current_context = current_context 133 | i_table = 134 | i_component_name = field_info-fieldname ) 135 | WHEN field_info-datatype EQ 'STRU' 136 | THEN me->handle_nested_structure( EXPORTING i_current_context = current_context 137 | i_structure = 138 | i_component_info = field_info ) 139 | ELSE NEW zcl_op_component( )->add( i_current_context = current_context 140 | i_component = 141 | i_component_info = field_info ) ). 142 | 143 | ENDLOOP. 144 | 145 | r_right_hand_side_value = |{ i_right_hand_side_value }{ current_context }|. 146 | 147 | ENDMETHOD. 148 | 149 | 150 | METHOD add_rhs_value_and_postfix. 151 | 152 | r_right_hand_side_value = me->add_rhs_value( EXPORTING 153 | i_right_hand_side_value = i_right_hand_side_value 154 | i_field_catalog = i_field_catalog 155 | i_structure = i_structure ). 156 | r_right_hand_side_value = me->add_rhs_postfix( r_right_hand_side_value ). 157 | 158 | ENDMETHOD. 159 | 160 | 161 | METHOD add_rhs_value_prefix. 162 | 163 | r_right_hand_side_value = COND string( WHEN i_is_type_given EQ abap_true 164 | THEN | = VALUE \{i_type\}(| "#TODO 25.10.2018 AGEPPART - implement type here 165 | ELSE | = VALUE #(| ). 166 | 167 | ENDMETHOD. 168 | 169 | 170 | METHOD add_structure. 171 | r_current_context = me->right_hand_side( 172 | i_field_catalog = i_field_catalog 173 | i_structure = i_structure ). 174 | ENDMETHOD. 175 | 176 | 177 | 178 | METHOD handle_nested_structure. 179 | r_current_context = right_hand_side( EXPORTING i_structure = i_structure 180 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = i_structure ) ). 181 | 182 | r_current_context = |{ i_current_context } { component_name( i_component_info-fieldname ) }{ r_current_context }|. 183 | ENDMETHOD. 184 | 185 | 186 | METHOD left_hand_side. 187 | rv_left_hand_side_value = COND string( WHEN i_is_type_given EQ abap_true 188 | THEN |DATA({ i_struc_name })| "#TODO 02.11.2018 AGEPPART - use type later here 189 | ELSE i_struc_name ). 190 | ENDMETHOD. 191 | 192 | 193 | METHOD prepare_output. 194 | 195 | CHECK i_structure IS NOT INITIAL. 196 | 197 | r_content_4_display = |{ me->left_hand_side( i_struc_name = i_struc_name ) }{ me->right_hand_side( i_structure = i_structure i_field_catalog = i_field_catalog ) }.|. 198 | 199 | ENDMETHOD. 200 | 201 | 202 | METHOD right_hand_side. 203 | 204 | r_right_hand_side_value = me->add_rhs_value_prefix( i_is_type_given ). 205 | 206 | r_right_hand_side_value = me->add_rhs_value_and_postfix( EXPORTING i_right_hand_side_value = r_right_hand_side_value 207 | i_structure = i_structure 208 | i_field_catalog = i_field_catalog ). 209 | 210 | ENDMETHOD. 211 | 212 | 213 | METHOD show_popup_w_content. 214 | DATA(content_4_display) = me->prepare_output( i_struc_name = i_struc_name 215 | i_structure = i_structure 216 | i_field_catalog = i_field_catalog ). 217 | TRY. 218 | DATA(formated_content) = zcl_op_pretty_printer_factory=>create( )->format( content_4_display ). 219 | CATCH cx_class_not_existent INTO DATA(cx_class_not_existent). 220 | "formating went wring, fallback using non formated text 221 | formated_content = content_4_display. 222 | ENDTRY. 223 | cl_demo_output=>set_mode( cl_demo_output=>text_mode ). "set to text mode to be more compatible with minus signs and so on 224 | cl_demo_output=>write_text( formated_content ). 225 | cl_demo_output=>display( ). 226 | ENDMETHOD. 227 | 228 | 229 | ENDCLASS. 230 | -------------------------------------------------------------------------------- /zcl_op_structure.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | CLASS ltc_struc_enh_should_process DEFINITION DEFERRED. 2 | CLASS zcl_op_structure DEFINITION LOCAL FRIENDS ltc_struc_enh_should_process. 3 | 4 | CLASS ltc_struc_enh_should_process DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. 5 | 6 | PRIVATE SECTION. 7 | METHODS: 8 | simple_structure FOR TESTING, 9 | nested_structure FOR TESTING, 10 | mixed_structure FOR TESTING, 11 | itab_in_structure FOR TESTING, 12 | include_in_structure FOR TESTING. 13 | ENDCLASS. "ltc_aunit_debugger_struc_enh 14 | 15 | 16 | CLASS ltc_struc_enh_should_process IMPLEMENTATION. 17 | 18 | METHOD simple_structure. 19 | 20 | DATA(content_expected) = |STRUCTURE = VALUE #( MANDT = '100' CARRID = 'AA' CONNID = '0017' FLDATE = '20141217' PRICE = '422.94' | && 21 | |CURRENCY = 'USD' PLANETYPE = '747-400' SEATSMAX = 385 SEATSOCC = 372 PAYMENTSUM = '192437.84' SEATSMAX_B | && 22 | |= 31 SEATSOCC_B = 28 SEATSMAX_F = 21 SEATSOCC_F = 21 ).|. 23 | TYPES: BEGIN OF test_type, 24 | mandt TYPE s_mandt, 25 | carrid TYPE s_carr_id, 26 | connid TYPE s_conn_id, 27 | fldate TYPE s_date, 28 | price TYPE s_price, 29 | currency TYPE s_currcode, 30 | planetype TYPE s_planetye, 31 | seatsmax TYPE s_seatsmax, 32 | seatsocc TYPE s_seatsocc, 33 | paymentsum TYPE s_sum, 34 | seatsmax_b TYPE s_smax_b, 35 | seatsocc_b TYPE s_socc_b, 36 | seatsmax_f TYPE s_smax_f, 37 | seatsocc_f TYPE s_socc_f, 38 | END OF test_type. 39 | 40 | DATA(structure) = VALUE test_type( mandt = '100' carrid = 'AA' 41 | connid = '0017' fldate = '20141217' 42 | price = '422.94' currency = 'USD' 43 | planetype = '747-400' seatsmax = 385 44 | seatsocc = 372 paymentsum = '192437.84' 45 | seatsmax_b = 31 seatsocc_b = 28 46 | seatsmax_f = 21 seatsocc_f = 21 ). 47 | 48 | 49 | DATA(content) = NEW zcl_op_structure( )->prepare_output( i_structure = structure 50 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = structure ) 51 | i_struc_name = |STRUCTURE| ). 52 | 53 | 54 | cl_abap_unit_assert=>assert_equals( act = content 55 | exp = content_expected 56 | msg = 'Struktur String wurde nicht richtig aufbereitet' ). 57 | ENDMETHOD. 58 | 59 | METHOD nested_structure. 60 | 61 | TYPES: BEGIN OF t_col2, 62 | col1 TYPE i, 63 | col2 TYPE i, 64 | END OF t_col2, 65 | BEGIN OF t_struct, 66 | col1 TYPE i, 67 | col2 TYPE t_col2, 68 | END OF t_struct, 69 | my_nested_struc_type TYPE t_struct. 70 | 71 | DATA(nested_structure) = VALUE my_nested_struc_type( col1 = 1 col2 = VALUE #( 72 | col1 = 1 73 | col2 = 2 74 | ) ). 75 | 76 | DATA(content_expected) = |NESTED_STRUCTURE = VALUE #( COL1 = 1 COL2 = VALUE #( COL1 = 1 COL2 = 2 ) ).|. 77 | 78 | 79 | DATA(content) = NEW zcl_op_structure( )->prepare_output( i_structure = nested_structure 80 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = nested_structure ) 81 | i_struc_name = |NESTED_STRUCTURE| ). 82 | 83 | cl_abap_unit_assert=>assert_equals( act = content 84 | exp = content_expected 85 | msg = 'Nested structure was not formated as expected' ). 86 | 87 | ENDMETHOD. 88 | 89 | METHOD mixed_structure. 90 | TYPES: BEGIN OF t_col2, 91 | col1 TYPE i, 92 | col2 TYPE i, 93 | END OF t_col2, 94 | BEGIN OF t_struct, 95 | col1 TYPE i, 96 | col2 TYPE t_col2, 97 | col3 TYPE i, 98 | col4 TYPE t_col2, 99 | END OF t_struct, 100 | my_mixed_structure_type TYPE t_struct. 101 | 102 | DATA(mixed_structure) = VALUE my_mixed_structure_type( col1 = 1 103 | col2 = VALUE #( 104 | col1 = 1 105 | col2 = 2 106 | ) 107 | col3 = 3 108 | col4 = VALUE #( 109 | col1 = 1 110 | col2 = 2 111 | ) 112 | ). 113 | 114 | DATA(content_expected) = |MIXED_STRUCTURE = VALUE #( COL1 = 1 COL2 = VALUE #( COL1 = 1 COL2 = 2 ) COL3 = 3 COL4 = VALUE #( COL1 = 1 COL2 = 2 ) ).|. 115 | 116 | DATA(content) = NEW zcl_op_structure( )->prepare_output( i_structure = mixed_structure 117 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = mixed_structure ) 118 | i_struc_name = |MIXED_STRUCTURE| ). 119 | 120 | cl_abap_unit_assert=>assert_equals( act = content 121 | exp = content_expected 122 | msg = |Mixed structure was not formated as expected| ). 123 | ENDMETHOD. 124 | 125 | 126 | METHOD itab_in_structure. 127 | 128 | TYPES: BEGIN OF t_col2, 129 | col1 TYPE i, 130 | col2 TYPE i, 131 | END OF t_col2, 132 | BEGIN OF t_struct, 133 | col1 TYPE i, 134 | col2 TYPE t_col2, 135 | END OF t_struct, 136 | my_itab_type TYPE STANDARD TABLE OF t_struct WITH DEFAULT KEY, 137 | BEGIN OF itab_in_struc_type, 138 | col1 TYPE i, 139 | col2 TYPE t_col2, 140 | col3 TYPE my_itab_type, 141 | END OF itab_in_struc_type. 142 | 143 | DATA(itab_in_struc) = VALUE itab_in_struc_type( col1 = 1 144 | 145 | col2 = VALUE #( 146 | col1 = 11 147 | col2 = 22 148 | ) 149 | col3 = VALUE #( 150 | ( col1 = 311 col2 = VALUE #( col1 = 3121 col2 = 3122 ) ) 151 | ( col1 = 321 col2 = VALUE #( col1 = 3221 col2 = 3222 ) ) 152 | ) 153 | ). 154 | 155 | 156 | DATA(content_expected) = |ITAB_IN_STRUCTURE = VALUE #( COL1 = 1 COL2 = VALUE #( COL1 = 11 COL2 = 22 ) COL3 = VALUE #(| && 157 | | ( COL1 = 311 COL2 = VALUE #( COL1 = 3121 COL2 = 3122 ) ) ( COL1 = 321 COL2 = VALUE #( COL1 = 3221 COL2 = 3222 ) ) ) ).|. 158 | 159 | DATA(content) = NEW zcl_op_structure( )->prepare_output( i_structure = itab_in_struc 160 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = itab_in_struc ) 161 | i_struc_name = |ITAB_IN_STRUCTURE| ). 162 | cl_abap_unit_assert=>assert_equals( act = content 163 | exp = content_expected 164 | msg = |itab in structure was not formated as expected| ). 165 | ENDMETHOD. 166 | 167 | 168 | METHOD include_in_structure. 169 | TYPES BEGIN OF t_struct. 170 | INCLUDE TYPE t000. 171 | TYPES dummy_field_1 TYPE i. 172 | TYPES dummy_field_2 TYPE string. 173 | TYPES END OF t_struct. 174 | 175 | DATA(include_in_structure) = VALUE t_struct( mandt = '100' mtext = 'someText' dummy_field_1 = 5 dummy_field_2 = 'someOtherText' ). 176 | 177 | DATA(content_expected) = |INCLUDE_IN_STRUCTURE = VALUE #( MANDT = '100' MTEXT = 'someText' DUMMY_FIELD_1 = 5 DUMMY_FIELD_2 = `someOtherText` ).|. 178 | 179 | DATA(content) = NEW zcl_op_structure( )->prepare_output( i_structure = include_in_structure 180 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = include_in_structure ) 181 | i_struc_name = |INCLUDE_IN_STRUCTURE| ). 182 | cl_abap_unit_assert=>assert_equals( act = content 183 | exp = content_expected 184 | msg = |include in structure was not formated as expected| ). 185 | 186 | 187 | ENDMETHOD. 188 | 189 | ENDCLASS. 190 | 191 | CLASS ltc_struc_enh_should_not DEFINITION DEFERRED. 192 | CLASS zcl_op_structure DEFINITION LOCAL FRIENDS ltc_struc_enh_should_not. 193 | CLASS ltc_struc_enh_should_not DEFINITION FOR TESTING 194 | DURATION SHORT 195 | RISK LEVEL HARMLESS. 196 | 197 | PRIVATE SECTION. 198 | METHODS: miss_value_operator FOR TESTING. 199 | 200 | ENDCLASS. 201 | 202 | CLASS ltc_struc_enh_should_not IMPLEMENTATION. 203 | 204 | METHOD miss_value_operator. 205 | 206 | TYPES: 207 | tab_type_controller_empty_itab TYPE STANDARD TABLE OF i WITH EMPTY KEY, 208 | BEGIN OF ts_base, 209 | col1 TYPE i, 210 | col2 TYPE i, 211 | END OF ts_base, 212 | BEGIN OF ts_shippment, 213 | controller TYPE tab_type_controller_empty_itab, 214 | base TYPE ts_base, 215 | client_order_id TYPE i, 216 | warehouse_id TYPE i, 217 | END OF ts_shippment, 218 | tab_type_shippment TYPE STANDARD TABLE OF ts_shippment WITH EMPTY KEY, 219 | BEGIN OF ts_client_company, 220 | controller TYPE tab_type_controller_empty_itab, 221 | base TYPE ts_base, 222 | tt_shippment TYPE tab_type_shippment, 223 | END OF ts_client_company, 224 | tab_type_client_company TYPE STANDARD TABLE OF ts_client_company WITH EMPTY KEY, 225 | BEGIN OF ts_daily_processing, 226 | controller TYPE tab_type_controller_empty_itab, 227 | base TYPE ts_base, 228 | tt_client_company TYPE tab_type_client_company, 229 | END OF ts_daily_processing, 230 | BEGIN OF itab_in_struc_type, 231 | controller TYPE tab_type_controller_empty_itab, 232 | s_daily_processing TYPE ts_daily_processing, 233 | END OF itab_in_struc_type. 234 | 235 | 236 | 237 | 238 | DATA(nested_structure) = VALUE itab_in_struc_type( controller = VALUE #( ) 239 | s_daily_processing = VALUE #( controller = VALUE #( ) 240 | base = VALUE #( col1 = 1 col2 = 2 ) 241 | tt_client_company = VALUE #( ( controller = VALUE #( ) 242 | base = VALUE #( col1 = 1 col2 = 2 ) 243 | tt_shippment = VALUE #( ( controller = VALUE #( ) 244 | base = VALUE #( col1 = 1 col2 = 2 ) 245 | client_order_id = 1 246 | warehouse_id = 2 ) 247 | ) 248 | ) 249 | 250 | ) 251 | ) 252 | ). 253 | 254 | DATA(content_expected) = |NESTED_STRUCTURE = VALUE #( S_DAILY_PROCESSING = VALUE #( BASE = VALUE #( COL1 = 1 COL2 = 2 ) | && 255 | |TT_CLIENT_COMPANY = VALUE #( ( BASE = VALUE #( COL1 = 1 COL2 = 2 ) TT_SHIPPMENT = VALUE #( ( BASE | && 256 | |= VALUE #( COL1 = 1 COL2 = 2 ) CLIENT_ORDER_ID = 1 WAREHOUSE_ID = 2 ) ) ) ) ) ).|. 257 | 258 | 259 | DATA(content) = NEW zcl_op_structure( )->prepare_output( i_structure = nested_structure 260 | i_field_catalog = NEW zcl_op_simple_field_catalog( )->get_by_data( i_structure = nested_structure ) 261 | i_struc_name = |NESTED_STRUCTURE| ). 262 | 263 | cl_abap_unit_assert=>assert_equals( act = content 264 | exp = content_expected 265 | msg = 'Nested structure was not formated as expected' ). 266 | ENDMETHOD. 267 | 268 | ENDCLASS. 269 | -------------------------------------------------------------------------------- /zcl_op_structure.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_STRUCTURE 7 | E 8 | AUnit - Struktur Darstellung 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zcl_op_table.clas.abap: -------------------------------------------------------------------------------- 1 | "!This class is offering an API for representing a table 2 | "!in its ABAP VALUE way: table_name = VALUE #( (...) ) 3 | CLASS zcl_op_table DEFINITION 4 | PUBLIC FINAL 5 | CREATE PUBLIC. 6 | 7 | PUBLIC SECTION. 8 | METHODS: 9 | handle_toolbar_set FOR EVENT toolbar OF cl_gui_alv_grid IMPORTING e_object 10 | e_interactive, 11 | show_popup_w_content IMPORTING i_table TYPE ANY TABLE 12 | i_fieldcatalog TYPE lvc_t_fcat OPTIONAL 13 | i_table_title TYPE string, 14 | add_itab IMPORTING i_table_title TYPE string OPTIONAL 15 | i_current_context TYPE string 16 | i_table TYPE ANY TABLE 17 | i_component_name TYPE lvc_fname OPTIONAL 18 | i_fieldcatalog TYPE lvc_t_fcat OPTIONAL 19 | i_dont_add_a_point TYPE boole_d OPTIONAL 20 | RETURNING VALUE(r_current_context) TYPE string, 21 | filter_table_from_alv IMPORTING i_alv TYPE REF TO cl_gui_alv_grid OPTIONAL 22 | i_table TYPE ANY TABLE 23 | RETURNING VALUE(result) TYPE REF TO data. 24 | 25 | PRIVATE SECTION. 26 | METHODS: 27 | prepare_output IMPORTING i_fieldcatalog TYPE lvc_t_fcat OPTIONAL 28 | i_table TYPE ANY TABLE 29 | i_table_title TYPE string 30 | i_dont_add_a_point TYPE boole_d OPTIONAL 31 | RETURNING VALUE(r_content_4_display) TYPE string, 32 | add_prefix IMPORTING i_tabix TYPE i 33 | i_current_context TYPE string 34 | i_table_title TYPE string OPTIONAL 35 | i_component_name TYPE lvc_fname OPTIONAL 36 | RETURNING VALUE(r_current_context) TYPE string. 37 | ENDCLASS. 38 | 39 | 40 | CLASS zcl_op_table IMPLEMENTATION. 41 | METHOD add_itab. 42 | DATA table_line_context TYPE string. 43 | 44 | TRY. 45 | 46 | DATA(simple_field_catalog) = NEW zcl_op_simple_field_catalog( ). 47 | DATA(field_catalog) = COND lvc_t_fcat( WHEN i_fieldcatalog[] IS NOT INITIAL 48 | THEN i_fieldcatalog 49 | ELSE simple_field_catalog->get_by_data( i_table = i_table ) ). 50 | 51 | DATA(structure) = NEW zcl_op_structure( ). 52 | DATA(component) = NEW zcl_op_component( ). 53 | 54 | r_current_context = COND string( WHEN i_current_context IS NOT INITIAL THEN i_current_context ELSE || ). 55 | 56 | DATA(line_num) = 0. 57 | LOOP AT i_table ASSIGNING FIELD-SYMBOL(). 58 | 59 | line_num += 1. 60 | r_current_context = add_prefix( i_current_context = r_current_context 61 | i_table_title = i_table_title 62 | i_component_name = i_component_name 63 | i_tabix = line_num ). 64 | " print columns 65 | LOOP AT field_catalog INTO DATA(field_info) 66 | WHERE no_out = abap_false. 67 | IF lines( field_catalog ) = 1 AND field_catalog[ 1 ]-fieldname IS INITIAL. 68 | ASSIGN TO FIELD-SYMBOL(). 69 | ELSE. 70 | ASSIGN COMPONENT field_info-fieldname OF STRUCTURE TO . 71 | ENDIF. 72 | CHECK IS ASSIGNED 73 | AND IS NOT INITIAL. 74 | 75 | DATA(varvalue) = COND tpda_var_value( WHEN field_info-datatype = |TTYP| THEN me->add_itab( 76 | i_current_context = space 77 | i_table = 78 | i_dont_add_a_point = abap_true ) 79 | WHEN field_info-datatype = |STRU| THEN structure->add_structure( 80 | i_structure = 81 | i_field_catalog = simple_field_catalog->get_by_data( 82 | i_structure = ) 83 | i_current_context = || ) 84 | ELSE ). " it must be a component 85 | 86 | table_line_context = component->add( i_datatype = field_info-datatype 87 | i_current_context = table_line_context 88 | i_component = varvalue " here we only pass already given value as string 89 | i_component_info = field_info ). 90 | 91 | ENDLOOP. 92 | IF table_line_context <> space. 93 | r_current_context = |{ r_current_context } ({ table_line_context } )|. 94 | ENDIF. 95 | CLEAR table_line_context. 96 | ENDLOOP. 97 | 98 | r_current_context = COND #( WHEN i_dont_add_a_point = abap_true 99 | THEN |{ r_current_context } )| 100 | ELSE |{ r_current_context } ).| ). 101 | 102 | CATCH cx_root INTO DATA(lx_root). " TODO: variable is assigned but never used (ABAP cleaner) 103 | ASSERT 1 = 1. 104 | ENDTRY. 105 | ENDMETHOD. 106 | 107 | METHOD add_prefix. 108 | r_current_context = COND string( WHEN i_current_context IS NOT INITIAL THEN i_current_context ELSE || ). 109 | 110 | IF i_tabix = 1. 111 | r_current_context = COND #( WHEN i_table_title <> space THEN |{ r_current_context }{ i_table_title } = VALUE #(| 112 | WHEN i_component_name IS NOT INITIAL THEN |{ r_current_context }{ i_component_name } = VALUE #(| 113 | ELSE |{ r_current_context }VALUE #(| ). 114 | ENDIF. 115 | ENDMETHOD. 116 | 117 | METHOD handle_toolbar_set. 118 | CHECK NOT line_exists( e_object->mt_toolbar[ function = 'ZDATA_4_ABAP_VIEW' ] ). 119 | 120 | APPEND VALUE stb_button( function = 'ZDATA_4_ABAP_VIEW' 121 | butn_type = 0 122 | text = 'Data for ABAP View' ) TO e_object->mt_toolbar. 123 | ENDMETHOD. 124 | 125 | METHOD prepare_output. 126 | r_content_4_display = add_itab( i_table_title = i_table_title 127 | i_current_context = space 128 | i_table = i_table 129 | i_fieldcatalog = i_fieldcatalog 130 | i_dont_add_a_point = i_dont_add_a_point ). 131 | ENDMETHOD. 132 | 133 | METHOD show_popup_w_content. 134 | DATA(plain_content) = prepare_output( i_fieldcatalog = i_fieldcatalog 135 | i_table = i_table 136 | i_table_title = i_table_title ). 137 | 138 | TRY. 139 | DATA(formated_content) = zcl_op_pretty_printer_factory=>create( )->format( plain_content ). 140 | CATCH cx_class_not_existent INTO DATA(cx_class_not_existent). " TODO: variable is assigned but never used (ABAP cleaner) 141 | " formatting went wrong, fallback using non formatted text 142 | formated_content = plain_content. 143 | ENDTRY. 144 | 145 | DATA(content_4_display) = COND #( WHEN formated_content IS NOT INITIAL THEN formated_content 146 | WHEN plain_content IS NOT INITIAL THEN plain_content ). 147 | 148 | cl_demo_output=>set_mode( cl_demo_output=>text_mode ). " set to text mode to be more compatible with minus signs and so on 149 | cl_demo_output=>write_text( content_4_display ). 150 | cl_demo_output=>display( ). 151 | ENDMETHOD. 152 | 153 | METHOD filter_table_from_alv. 154 | DATA filtered_entries_std TYPE TABLE OF i. 155 | 156 | FIELD-SYMBOLS TYPE table. 157 | 158 | " create local copy of table for filtering 159 | CREATE DATA result LIKE i_table. 160 | ASSIGN result->* TO . 161 | = i_table. 162 | 163 | IF i_alv IS NOT BOUND. 164 | RETURN. 165 | ENDIF. 166 | 167 | i_alv->get_filtered_entries( IMPORTING et_filtered_entries = DATA(filtered_entries) ). 168 | filtered_entries_std = filtered_entries. 169 | " sort descending so deletion of entries doesn't mess up the table indices 170 | SORT filtered_entries_std BY table_line DESCENDING. 171 | LOOP AT filtered_entries_std ASSIGNING FIELD-SYMBOL(). 172 | DELETE INDEX . 173 | ENDLOOP. 174 | ENDMETHOD. 175 | ENDCLASS. 176 | -------------------------------------------------------------------------------- /zcl_op_table.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | CLASS ltc_table_enh_should DEFINITION DEFERRED. 2 | CLASS zcl_op_table DEFINITION LOCAL FRIENDS ltc_table_enh_should. 3 | 4 | CLASS ltc_table_enh_should DEFINITION FOR TESTING 5 | DURATION SHORT RISK LEVEL HARMLESS. 6 | 7 | PRIVATE SECTION. 8 | DATA: 9 | table_view TYPE REF TO zcl_op_table. "class under test 10 | 11 | METHODS: 12 | setup, 13 | teardown, 14 | "!check of 15 | prepare_ouput_w_1_line_itab FOR TESTING, 16 | handle_structure_in_itab FOR TESTING, 17 | handle_itab_in_itab FOR TESTING, 18 | st05_main_record_table FOR TESTING RAISING cx_static_check, 19 | ris_t_metadata FOR TESTING RAISING cx_static_check. 20 | ENDCLASS. 21 | 22 | 23 | CLASS ltc_table_enh_should IMPLEMENTATION. 24 | 25 | METHOD setup. 26 | table_view = NEW zcl_op_table( ). 27 | ENDMETHOD. 28 | 29 | 30 | METHOD teardown. 31 | CLEAR table_view. 32 | ENDMETHOD. 33 | 34 | 35 | METHOD prepare_ouput_w_1_line_itab. 36 | 37 | TYPES: BEGIN OF ty_sflight_mini, 38 | carrid TYPE s_carr_id, 39 | connid TYPE s_conn_id, 40 | fldate TYPE s_date, 41 | price TYPE s_price, 42 | END OF ty_sflight_mini. 43 | DATA: output TYPE string, 44 | output_exp TYPE string, 45 | sflight_lines TYPE STANDARD TABLE OF ty_sflight_mini. 46 | 47 | 48 | sflight_lines = VALUE #( ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) ). 49 | 50 | output = table_view->prepare_output( i_table = sflight_lines 51 | i_table_title = 'SFLIGHT_LINES' ). 52 | 53 | output_exp = |SFLIGHT_LINES = VALUE #( ( CARRID = 'AA' CONNID = '0017' FLDATE = '20170810' PRICE = '422.94 ' ) ).|. 54 | cl_abap_unit_assert=>assert_equals( EXPORTING act = output 55 | exp = output_exp 56 | msg = |Character String Different| ). 57 | 58 | 59 | ENDMETHOD. 60 | 61 | METHOD handle_itab_in_itab. 62 | TYPES: BEGIN OF ts_flight_data, 63 | carrid TYPE s_carr_id, 64 | connid TYPE s_conn_id, 65 | fldate TYPE s_date, 66 | price TYPE s_price, 67 | END OF ts_flight_data, 68 | tt_flight_data TYPE STANDARD TABLE OF ts_flight_data WITH EMPTY KEY, 69 | BEGIN OF ts_flight_data_deep, 70 | col1 TYPE tt_flight_data, 71 | END OF ts_flight_data_deep, 72 | tt_flight_data_deep TYPE STANDARD TABLE OF ts_flight_data_deep WITH EMPTY KEY. 73 | 74 | DATA: output TYPE string, 75 | output_exp TYPE string, 76 | sflight_lines TYPE tt_flight_data_deep. 77 | 78 | 79 | sflight_lines = VALUE #( ( col1 = VALUE #( 80 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 81 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 82 | ) 83 | ) 84 | ( col1 = VALUE #( 85 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 86 | ( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 87 | ) 88 | ) 89 | ). 90 | 91 | 92 | output = table_view->prepare_output( i_table = sflight_lines 93 | i_table_title = 'SFLIGHT_LINES' ). 94 | 95 | output_exp = |SFLIGHT_LINES = VALUE #( ( COL1 = VALUE #( ( CARRID = 'AA' CONNID = '0017' FLDATE = '20170810' PRICE = '422.94 ' )| && 96 | | ( CARRID = 'AA' CONNID = '0017' FLDATE = '20170810' PRICE = '422.94 ' ) ) ) ( COL1 = VALUE #( ( CARRID = 'AA' CONNID| && 97 | | = '0017' FLDATE = '20170810' PRICE = '422.94 ' ) ( CARRID = 'AA' CONNID = '0017' FLDATE = '20170810' PRICE = '422.94 ' ) ) ) ).|. 98 | 99 | cl_abap_unit_assert=>assert_equals( EXPORTING act = output 100 | exp = output_exp 101 | msg = |Itab in itab formating is not as expected| 102 | quit = if_aunit_constants=>method ). 103 | 104 | ENDMETHOD. 105 | 106 | 107 | METHOD handle_structure_in_itab. 108 | 109 | TYPES: BEGIN OF ts_flight_data, 110 | carrid TYPE s_carr_id, 111 | connid TYPE s_conn_id, 112 | fldate TYPE s_date, 113 | price TYPE s_price, 114 | END OF ts_flight_data, 115 | BEGIN OF ts_flight_data_w_structure, 116 | col1 TYPE ts_flight_data, 117 | END OF ts_flight_data_w_structure, 118 | tt_flight_data_w_structure TYPE STANDARD TABLE OF ts_flight_data_w_structure WITH EMPTY KEY. 119 | 120 | 121 | DATA: output TYPE string, 122 | output_exp TYPE string, 123 | sflight_lines TYPE tt_flight_data_w_structure. "ztt_age_col1 124 | 125 | 126 | sflight_lines = VALUE #( ( col1 = VALUE #( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 127 | ) 128 | ( col1 = VALUE #( carrid = 'AA' connid = '0017' fldate = '20170810' price = '422.94 ' ) 129 | ) 130 | ). 131 | 132 | 133 | output = table_view->prepare_output( i_table = sflight_lines 134 | i_table_title = 'SFLIGHT_LINES' ). 135 | 136 | output_exp = |SFLIGHT_LINES = VALUE #( ( COL1 = VALUE #( CARRID = 'AA' CONNID = '0017' FLDATE = '20170810' PRICE = '422.94' ) )| && 137 | | ( COL1 = VALUE #( CARRID = 'AA' CONNID = '0017' FLDATE = '20170810' PRICE = '422.94' ) ) ).|. 138 | 139 | cl_abap_unit_assert=>assert_equals( EXPORTING act = output 140 | exp = output_exp 141 | msg = |Structure in itab formating is not as expected| 142 | quit = if_aunit_constants=>method ). 143 | ENDMETHOD. 144 | 145 | METHOD st05_main_record_table. 146 | 147 | DATA(lv_date) = sy-datum. 148 | DATA(lv_time) = sy-uzeit. 149 | 150 | DATA(table) = VALUE st05_main_record_table( 151 | ( date = lv_date 152 | time = lv_time 153 | duration = '10.5' 154 | number_of_rows = '11.5' 155 | object = 'OBJECT' 156 | statement_with_values = `STATEMENT_WITH_VALUES` 157 | array_size = 12 158 | transaction = 'TRANSACTION' 159 | program = 'PROGRAM' 160 | db_connection_name = 'DB_CONNECTION_NAME' 161 | db_connection_id = 'DB_CON_ID' 162 | operation = 'OPERATI' 163 | return_code = 13 164 | wp_id = '001' 165 | wp_type = 'DIA' 166 | user_name = 'USER_NAME' 167 | client = '100' 168 | trans_id = 'TRANS_ID' 169 | epp_root_id = 'EPP_ROOT_ID' 170 | epp_connection_id = 'EPP_CONNECTION_ID' 171 | epp_connection_counter = 14 172 | record_number = 15 173 | record_numbers = VALUE #( ( 16 ) ( 17 ) ) 174 | offset = 18 175 | statement_with_names = `STATEMENT_WITH_NAMES` 176 | length_of_statement_with_names = 19 177 | variables = `VARIABLES` 178 | number_of_variables = 20 179 | trace_type = 'TRAC' 180 | line_color = 'LINE' 181 | ) ). 182 | 183 | DATA(output) = table_view->prepare_output( i_table = table 184 | i_table_title = 'TABLE' ). 185 | 186 | DATA(output_exp) = |TABLE = VALUE #( ( DATE = '{ lv_date }' TIME = '{ lv_time }' DURATION = '11 ' NUMBER_OF_ROWS = 12 | 187 | && |OBJECT = `OBJECT` STATEMENT_WITH_VALUES = `STATEMENT_WITH_VALUES` | 188 | && |ARRAY_SIZE = 12 TRANSACTION = 'TRANSACTION' PROGRAM = 'PROGRAM' DB_CONNECTION_NAME = | 189 | && |'DB_CONNECTION_NAME' DB_CONNECTION_ID = 'DB_CON_ID' OPERATION = 'OPERATI' RETURN_CODE | 190 | && |= 13 WP_ID = '001' WP_TYPE = 'DIA' USER_NAME = 'USER_NAME' CLIENT = '100' TRANS_ID = | 191 | && |'TRANS_ID' EPP_ROOT_ID = 'EPP_ROOT_ID' EPP_CONNECTION_ID = 'EPP_CONNECTION_ID' | 192 | && |EPP_CONNECTION_COUNTER = 14 RECORD_NUMBER = 15 RECORD_NUMBERS = VALUE #( ( 16 ) | 193 | && |( 17 ) ) OFFSET = 18 STATEMENT_WITH_NAMES = `STATEMENT_WITH_NAMES` LENGTH_OF_STATEMENT_WITH_NAMES | 194 | && |= 19 VARIABLES = `VARIABLES` NUMBER_OF_VARIABLES = 20 TRACE_TYPE = 'TRAC' LINE_COLOR = 'LINE' ) ).|. 195 | cl_abap_unit_assert=>assert_equals( EXPORTING act = output 196 | exp = output_exp ). 197 | 198 | ENDMETHOD. 199 | 200 | 201 | METHOD ris_t_metadata. 202 | DATA(table) = VALUE ris_t_metadata( 203 | ( trobjtype = '????' 204 | subtype = '' 205 | legacy_type = 'DWY' 206 | search_groups = VALUE ris_t_md_screen_groups( 207 | ( name = 'STANDARD' 208 | parent_group = '' 209 | text_ref = 'TEXT-S01' ) 210 | ( name = 'EINSTELLUNG' 211 | parent_group = '' 212 | text_ref = '' ) ) 213 | search_elements = VALUE ris_t_md_screen_elements( 214 | ( index = 1 215 | name = 'KEY1' 216 | type = 'SO' 217 | group = 'STANDARD' 218 | line = 0 219 | for = 'SDOKMEP-PROP_NAME' 220 | rb_group = '' 221 | label_for = '' 222 | label_ref = '' ) 223 | ( index = 2 224 | name = 'XTEXT' 225 | type = 'SO' 226 | group = 'STANDARD' 227 | line = 0 228 | for = 'SDOKMET-DESCRIPT' 229 | rb_group = '' 230 | label_for = '' 231 | label_ref = '' ) ) 232 | where_used = VALUE ris_t_md_relationship( 233 | ( trobjtype = 'ECTC' 234 | subtype = '' 235 | legacy_type = 'GC' 236 | group = 1 ) 237 | ( trobjtype = 'ECTC' 238 | subtype = '' 239 | legacy_type = 'GW' 240 | group = 1 ) ) 241 | environment = VALUE ris_t_md_relationship( 242 | ( trobjtype = 'FUNC' 243 | subtype = '' 244 | legacy_type = 'FF' 245 | group = 1 ) 246 | ( trobjtype = 'DIAL' 247 | subtype = '' 248 | legacy_type = 'A' 249 | group = 1 ) ) 250 | model_implementations = VALUE ris_t_md_model_implementation( ) 251 | ) 252 | ( trobjtype = '????' 253 | subtype = '' 254 | legacy_type = 'GP' 255 | search_groups = VALUE ris_t_md_screen_groups( 256 | ( name = 'STANDARD' 257 | parent_group = '' 258 | text_ref = 'TEXT-S01' ) 259 | ( name = 'EINSTELLUNG' 260 | parent_group = '' 261 | text_ref = '' ) ) 262 | search_elements = VALUE ris_t_md_screen_elements( 263 | ( index = 1 264 | name = 'KEY1' 265 | type = 'SO' 266 | group = 'STANDARD' 267 | line = 0 268 | for = 'SDOKMEP-PROP_NAME' 269 | rb_group = '' 270 | label_for = '' 271 | label_ref = '' ) 272 | ( index = 2 273 | name = 'XTEXT' 274 | type = 'SO' 275 | group = 'STANDARD' 276 | line = 0 277 | for = 'SDOKMET-DESCRIPT' 278 | rb_group = '' 279 | label_for = '' 280 | label_ref = '' ) ) 281 | where_used = VALUE ris_t_md_relationship( 282 | ( trobjtype = 'ECTC' 283 | subtype = '' 284 | legacy_type = 'GC' 285 | group = 1 ) 286 | ( trobjtype = 'ECTC' 287 | subtype = '' 288 | legacy_type = 'GW' 289 | group = 1 ) ) 290 | environment = VALUE ris_t_md_relationship( 291 | ( trobjtype = 'FUNC' 292 | subtype = '' 293 | legacy_type = 'FF' 294 | group = 1 ) 295 | ( trobjtype = 'DIAL' 296 | subtype = '' 297 | legacy_type = 'A' 298 | group = 1 ) ) 299 | model_implementations = VALUE ris_t_md_model_implementation( ) 300 | 301 | ) ). 302 | 303 | DATA(output) = table_view->prepare_output( i_table = table 304 | i_table_title = 'TABLE' ). 305 | 306 | DATA(output_exp) = |TABLE = VALUE #( ( TROBJTYPE = '????' LEGACY_TYPE = 'DWY' SEARCH_GROUPS| 307 | && | = VALUE #( ( NAME = 'STANDARD' TEXT_REF = `TEXT-S01` ) ( NAME = 'EINSTELLUNG' ) ) | 308 | && |SEARCH_ELEMENTS = VALUE #( ( INDEX = 1 NAME = 'KEY1' TYPE = 'SO' GROUP = 'STANDARD' | 309 | && |FOR = 'SDOKMEP-PROP_NAME' ) ( INDEX = 2 NAME = 'XTEXT' TYPE = 'SO' GROUP = 'STANDARD' | 310 | && |FOR = 'SDOKMET-DESCRIPT' ) ) WHERE_USED = VALUE #( ( TROBJTYPE = 'ECTC' LEGACY_TYPE = 'GC' GROUP = 1 ) | 311 | && |( TROBJTYPE = 'ECTC' LEGACY_TYPE = 'GW' GROUP = 1 ) ) ENVIRONMENT = VALUE #( ( TROBJTYPE = 'FUNC' LEGACY_TYPE = 'FF' GROUP = 1 ) | 312 | && |( TROBJTYPE = 'DIAL' LEGACY_TYPE = 'A' GROUP = 1 ) ) ) ( TROBJTYPE = '????' LEGACY_TYPE = 'GP' | 313 | && |SEARCH_GROUPS = VALUE #( ( NAME = 'STANDARD' TEXT_REF = `TEXT-S01` ) ( NAME = 'EINSTELLUNG' ) ) | 314 | && |SEARCH_ELEMENTS = VALUE #( ( INDEX = 1 NAME = 'KEY1' TYPE = 'SO' GROUP = 'STANDARD' FOR = 'SDOKMEP-PROP_NAME' ) | 315 | && |( INDEX = 2 NAME = 'XTEXT' TYPE = 'SO' GROUP = 'STANDARD' FOR = 'SDOKMET-DESCRIPT' ) ) | 316 | && |WHERE_USED = VALUE #( ( TROBJTYPE = 'ECTC' LEGACY_TYPE = 'GC' GROUP = 1 ) | 317 | && |( TROBJTYPE = 'ECTC' LEGACY_TYPE = 'GW' GROUP = 1 ) ) ENVIRONMENT = VALUE #( | 318 | && |( TROBJTYPE = 'FUNC' LEGACY_TYPE = 'FF' GROUP = 1 ) ( TROBJTYPE = 'DIAL' LEGACY_TYPE = 'A' GROUP = 1 ) ) ) ).|. 319 | cl_abap_unit_assert=>assert_equals( EXPORTING act = output 320 | exp = output_exp ). 321 | 322 | ENDMETHOD. 323 | 324 | 325 | ENDCLASS. 326 | -------------------------------------------------------------------------------- /zcl_op_table.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_TABLE 7 | E 8 | Erweiterung des ABAP Debuggers 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | I 18 | 001 19 | Add line break at position: 20 | 70 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /zcl_op_value_pretty_printer.clas.abap: -------------------------------------------------------------------------------- 1 | "!this class is responsible for pretty printing 2 | "!VALUE # operator strings 3 | CLASS zcl_op_value_pretty_printer DEFINITION 4 | PUBLIC 5 | CREATE PRIVATE 6 | GLOBAL FRIENDS zcl_op_pretty_printer_factory. " needed for instantiation 7 | 8 | PUBLIC SECTION. 9 | INTERFACES zif_op_value_pretty_printer. 10 | 11 | ALIASES format FOR zif_op_value_pretty_printer~format. 12 | 13 | PROTECTED SECTION. 14 | 15 | PRIVATE SECTION. 16 | TYPES: BEGIN OF t_char_offset, 17 | count TYPE i, 18 | offset_no TYPE i, 19 | char TYPE c LENGTH 1, 20 | END OF t_char_offset, 21 | tt_char_offset TYPE STANDARD TABLE OF t_char_offset WITH DEFAULT KEY, 22 | BEGIN OF ENUM enum_terminal STRUCTURE c_terminal, 23 | assign, 24 | rhs, 25 | empty, 26 | struct, 27 | struct2, 28 | iteration, 29 | table, 30 | rhs2, 31 | symbolname, 32 | number, 33 | non_terminal, 34 | text_literal, 35 | string_literal, 36 | spaces, 37 | END OF ENUM enum_terminal STRUCTURE c_terminal, 38 | BEGIN OF ENUM enum_sub_terminal STRUCTURE c_sub_terminal, 39 | na, " not applicable 40 | assign_operator, " = 41 | value_operator, " VALUE #( 42 | parenthesis_open, " ( 43 | parenthesis_close, " ) 44 | empty_line, " ( ) 45 | end_of_statement, " . 46 | END OF ENUM enum_sub_terminal STRUCTURE c_sub_terminal, 47 | BEGIN OF ty_trace, 48 | parent_sync_point TYPE i, 49 | terminal TYPE enum_terminal, 50 | sub_terminal TYPE enum_sub_terminal, 51 | offset TYPE i, 52 | length TYPE i, 53 | sync_point TYPE i, 54 | text TYPE string, 55 | END OF ty_trace, 56 | BEGIN OF ty_sync_point, 57 | terminal TYPE enum_terminal, 58 | sub_terminal TYPE enum_sub_terminal, 59 | offset TYPE i, 60 | trace_index TYPE i, 61 | END OF ty_sync_point. 62 | 63 | CONSTANTS: c_newline TYPE abap_char1 VALUE cl_abap_char_utilities=>cr_lf, 64 | c_regex_lhs TYPE string VALUE `[^=\s]+(?=\s*=)` ##NO_TEXT, 65 | c_regex_number TYPE string VALUE `[0-9]+` ##NO_TEXT, 66 | c_regex_text_literal TYPE string VALUE `'(?:''|[^'])+'` ##NO_TEXT, 67 | c_regex_string_literal TYPE string VALUE '`(?:``|[^`])+`' ##NO_TEXT. 68 | 69 | DATA: steering TYPE tt_char_offset, 70 | offset TYPE i, 71 | text TYPE string, 72 | trace_tab TYPE TABLE OF ty_trace 73 | WITH NON-UNIQUE SORTED KEY k1 COMPONENTS parent_sync_point terminal offset, 74 | sync_points TYPE TABLE OF ty_sync_point. 75 | 76 | METHODS: get_spaces RETURNING VALUE(r_spaces_string) TYPE string, 77 | get_offset_in_current_line IMPORTING i_content TYPE string 78 | RETURNING VALUE(r_offset) TYPE i, 79 | get_offset_for_apostroph IMPORTING i_content TYPE string 80 | RETURNING VALUE(r_offset) TYPE i, 81 | get_offset_for_closing_bracket IMPORTING i_content TYPE string 82 | RETURNING VALUE(r_offset) TYPE i, 83 | clean_up_steering_tab IMPORTING i_last_char TYPE c, 84 | "! assign tries to build this: LHS = RHS 85 | "! 86 | "! @raising lcx_no_match | 87 | assign RAISING lcx_no_match, 88 | find_spaces, 89 | rhs RAISING lcx_no_match, 90 | add_empty_value_operator RAISING lcx_no_match, 91 | add_structure_rhs RAISING lcx_no_match, 92 | add_structure_content RAISING lcx_no_match, 93 | add_table RAISING lcx_no_match, 94 | rhs2 RAISING lcx_no_match, 95 | lhs RAISING lcx_no_match, 96 | add_number RAISING lcx_no_match, 97 | non_terminal IMPORTING i_sub_terminal TYPE enum_sub_terminal 98 | i_regex TYPE csequence 99 | RAISING lcx_no_match, 100 | 101 | add_text_literal RAISING lcx_no_match, 102 | add_string_literal RAISING lcx_no_match, 103 | set_offset_for_regex IMPORTING i_regex TYPE csequence 104 | RAISING lcx_no_match, 105 | add_to_trace, 106 | set_sync_point IMPORTING i_terminal TYPE enum_terminal 107 | i_sub_terminal TYPE enum_sub_terminal DEFAULT c_sub_terminal-na 108 | RETURNING VALUE(r_current_sync_point_index) TYPE i, 109 | reset_to_sync_point IMPORTING i_sync_point_index TYPE i, 110 | cancel_sync_point IMPORTING i_sync_point_index TYPE i, 111 | 112 | add_value_open_operator RAISING lcx_no_match, 113 | 114 | add_parenthesis_close RAISING lcx_no_match, 115 | 116 | add_assign_operator RAISING lcx_no_match, 117 | 118 | add_end_of_statement RAISING lcx_no_match, 119 | 120 | add_empty_line RAISING lcx_no_match, 121 | 122 | add_parenthesis_open RAISING lcx_no_match, 123 | set_offset_for_regex_pcre 124 | IMPORTING i_regex TYPE csequence 125 | RAISING lcx_no_match. 126 | 127 | ENDCLASS. 128 | 129 | 130 | CLASS zcl_op_value_pretty_printer IMPLEMENTATION. 131 | METHOD get_spaces. 132 | DATA(spaces_no) = steering[ lines( me->steering ) ]-offset_no. 133 | r_spaces_string = repeat( val = ` ` 134 | occ = spaces_no ). 135 | ENDMETHOD. 136 | 137 | METHOD get_offset_in_current_line. 138 | SPLIT i_content AT c_newline INTO TABLE DATA(lt_split). 139 | DATA(last_line) = lt_split[ lines( lt_split ) ]. 140 | r_offset = strlen( last_line ) + 1. 141 | ENDMETHOD. 142 | 143 | METHOD get_offset_for_apostroph. 144 | SPLIT i_content AT c_newline INTO TABLE DATA(lt_split). 145 | DATA(last_line) = lt_split[ lines( lt_split ) ]. 146 | 147 | DATA(regex_matcher) = cl_abap_matcher=>create( pattern = |\\S| 148 | text = last_line ). 149 | 150 | regex_matcher->find_next( ). 151 | r_offset = regex_matcher->get_offset( ). 152 | ENDMETHOD. 153 | 154 | METHOD get_offset_for_closing_bracket. 155 | " TODO: parameter I_CONTENT is never used (ABAP cleaner) 156 | 157 | " find offset of corresponding opening bracket 158 | " therefore we need to loop backwards in steering table 159 | 160 | DATA(x_lines) = lines( me->steering ). 161 | 162 | DO x_lines TIMES. 163 | DATA(line) = steering[ x_lines ]. 164 | IF line-char = '('. 165 | r_offset = line-offset_no. 166 | EXIT. 167 | ELSE. 168 | IF x_lines = 1. 169 | EXIT. 170 | ELSE. 171 | x_lines -= 1. 172 | ENDIF. 173 | ENDIF. 174 | ENDDO. 175 | ENDMETHOD. 176 | 177 | METHOD clean_up_steering_tab. 178 | CHECK i_last_char = |)|. 179 | " a formatting block is complete 180 | " we need to clean up our steering data and remove infos about this complete formatting block 181 | DATA(x_lines) = lines( me->steering ). 182 | 183 | DO x_lines TIMES. 184 | DATA(line) = steering[ x_lines ]. 185 | DELETE me->steering INDEX x_lines. 186 | IF line-char = |(|. 187 | EXIT. 188 | ENDIF. 189 | 190 | IF x_lines = 1. 191 | EXIT. 192 | ELSE. 193 | x_lines -= 1. 194 | ENDIF. 195 | 196 | ENDDO. 197 | ENDMETHOD. 198 | 199 | METHOD assign. 200 | " assign tries to build this: LHS = RHS 201 | TRY. 202 | find_spaces( ). 203 | DATA(current_sync_point_index) = set_sync_point( i_terminal = c_terminal-assign ). 204 | 205 | lhs( ). 206 | 207 | add_assign_operator( ). 208 | 209 | rhs( ). 210 | 211 | add_end_of_statement( ). 212 | 213 | add_to_trace( ). 214 | CLEANUP. 215 | reset_to_sync_point( current_sync_point_index ). 216 | ENDTRY. 217 | ENDMETHOD. 218 | 219 | METHOD rhs. 220 | " RHS could be : number | text | string | empty | struct | table 221 | find_spaces( ). 222 | DATA(current_sync_point_index) = set_sync_point( c_terminal-rhs ). 223 | TRY. 224 | TRY. 225 | add_number( ). 226 | CATCH lcx_no_match. 227 | TRY. 228 | add_text_literal( ). 229 | CATCH lcx_no_match. 230 | TRY. 231 | add_string_literal( ). 232 | CATCH lcx_no_match. 233 | TRY. 234 | add_empty_value_operator( ). 235 | CATCH lcx_no_match. 236 | TRY. 237 | add_structure_rhs( ). 238 | CATCH lcx_no_match. 239 | add_table( ). 240 | ENDTRY. 241 | ENDTRY. 242 | ENDTRY. 243 | ENDTRY. 244 | ENDTRY. 245 | CLEANUP. 246 | reset_to_sync_point( current_sync_point_index ). 247 | ENDTRY. 248 | add_to_trace( ). 249 | ENDMETHOD. 250 | 251 | METHOD add_empty_value_operator. 252 | " empty : 'VALUE #( )' 253 | TRY. 254 | find_spaces( ). 255 | DATA(current_sync_point_index) = set_sync_point( c_terminal-empty ). 256 | set_offset_for_regex( `VALUE #\( \)` ). 257 | add_to_trace( ). 258 | CLEANUP. 259 | reset_to_sync_point( current_sync_point_index ). 260 | ENDTRY. 261 | ENDMETHOD. 262 | 263 | METHOD add_structure_rhs. 264 | " struct : 'VALUE #(' struct2 ')' 265 | TRY. 266 | find_spaces( ). 267 | DATA(current_sync_point_index) = set_sync_point( c_terminal-struct ). 268 | add_value_open_operator( ). 269 | add_structure_content( ). 270 | add_parenthesis_close( ). 271 | add_to_trace( ). 272 | CLEANUP. 273 | reset_to_sync_point( current_sync_point_index ). 274 | ENDTRY. 275 | ENDMETHOD. 276 | 277 | METHOD add_structure_content. 278 | " struct2 : ( LHS '=' RHS )+ 279 | TRY. 280 | find_spaces( ). 281 | DATA(structure_sync_point_index) = set_sync_point( c_terminal-struct2 ). 282 | set_sync_point( c_terminal-iteration ). 283 | lhs( ). 284 | add_assign_operator( ). 285 | rhs( ). 286 | add_to_trace( ). 287 | DO. 288 | TRY. 289 | find_spaces( ). 290 | DATA(point2) = set_sync_point( c_terminal-iteration ). 291 | TRY. 292 | lhs( ). 293 | CATCH lcx_no_match. 294 | cancel_sync_point( point2 ). 295 | EXIT. 296 | ENDTRY. 297 | add_assign_operator( ). 298 | rhs( ). 299 | add_to_trace( ). 300 | CLEANUP. 301 | reset_to_sync_point( point2 ). 302 | ENDTRY. 303 | ENDDO. 304 | add_to_trace( ). 305 | CLEANUP. 306 | reset_to_sync_point( structure_sync_point_index ). 307 | ENDTRY. 308 | ENDMETHOD. 309 | 310 | METHOD add_table. 311 | * table : 'VALUE #(' ( '( )' | ( '(' RHS2 ')' )+ ) ')' 312 | TRY. 313 | find_spaces( ). 314 | DATA(point) = set_sync_point( c_terminal-table ). 315 | add_value_open_operator( ). 316 | TRY. 317 | add_empty_line( ). 318 | CATCH lcx_no_match. 319 | DO. 320 | TRY. 321 | find_spaces( ). 322 | DATA(point2) = set_sync_point( c_terminal-iteration ). 323 | TRY. 324 | add_parenthesis_open( ). 325 | CATCH lcx_no_match. 326 | cancel_sync_point( point2 ). 327 | EXIT. 328 | ENDTRY. 329 | rhs2( ). 330 | add_parenthesis_close( ). 331 | add_to_trace( ). 332 | CLEANUP. 333 | reset_to_sync_point( point2 ). 334 | ENDTRY. 335 | ENDDO. 336 | 337 | ENDTRY. 338 | add_parenthesis_close( ). 339 | add_to_trace( ). 340 | CLEANUP. 341 | reset_to_sync_point( point ). 342 | ENDTRY. 343 | ENDMETHOD. 344 | 345 | METHOD rhs2. 346 | " RHS2 : number | text | string | empty | struct2 347 | TRY. 348 | find_spaces( ). 349 | DATA(current_sync_point_index) = set_sync_point( c_terminal-rhs2 ). 350 | TRY. 351 | add_number( ). 352 | CATCH lcx_no_match. 353 | TRY. 354 | add_text_literal( ). 355 | CATCH lcx_no_match. 356 | TRY. 357 | add_string_literal( ). 358 | CATCH lcx_no_match. 359 | TRY. 360 | add_empty_value_operator( ). 361 | CATCH lcx_no_match. 362 | add_structure_content( ). 363 | ENDTRY. 364 | ENDTRY. 365 | ENDTRY. 366 | ENDTRY. 367 | add_to_trace( ). 368 | CLEANUP. 369 | reset_to_sync_point( current_sync_point_index ). 370 | ENDTRY. 371 | ENDMETHOD. 372 | 373 | METHOD lhs. 374 | TRY. 375 | find_spaces( ). 376 | DATA(current_sync_point_index) = set_sync_point( c_terminal-symbolname ). 377 | " SCALAR 378 | " STRUCTURE 379 | " TABLE 380 | " STRUCTURE-COMPONENT 381 | " TABLE[1] 382 | " TABLE[1]-COMPONENT 383 | " VAR_2 384 | " /NAMESPACE/VARIABLE 385 | " something like "CUT->ST03N_TRANSACTION_PROFILE" could also be a lhs 386 | 387 | set_offset_for_regex_pcre( c_regex_lhs ). 388 | add_to_trace( ). 389 | CLEANUP. 390 | reset_to_sync_point( current_sync_point_index ). 391 | ENDTRY. 392 | ENDMETHOD. 393 | 394 | METHOD add_number. 395 | TRY. 396 | find_spaces( ). 397 | DATA(current_sync_point_index) = set_sync_point( c_terminal-number ). 398 | set_offset_for_regex( c_regex_number ). 399 | add_to_trace( ). 400 | CLEANUP. 401 | reset_to_sync_point( current_sync_point_index ). 402 | ENDTRY. 403 | ENDMETHOD. 404 | 405 | METHOD non_terminal. 406 | TRY. 407 | find_spaces( ). 408 | DATA(current_sync_point_index) = set_sync_point( i_terminal = c_terminal-non_terminal 409 | i_sub_terminal = i_sub_terminal ). 410 | set_offset_for_regex( i_regex ). 411 | add_to_trace( ). 412 | CLEANUP. 413 | reset_to_sync_point( current_sync_point_index ). 414 | ENDTRY. 415 | ENDMETHOD. 416 | 417 | METHOD add_text_literal. 418 | TRY. 419 | find_spaces( ). 420 | DATA(current_sync_point_index) = set_sync_point( c_terminal-text_literal ). 421 | set_offset_for_regex( c_regex_text_literal ). 422 | add_to_trace( ). 423 | CLEANUP. 424 | reset_to_sync_point( current_sync_point_index ). 425 | ENDTRY. 426 | ENDMETHOD. 427 | 428 | METHOD add_string_literal. 429 | TRY. 430 | find_spaces( ). 431 | DATA(current_sync_point_index) = set_sync_point( c_terminal-string_literal ). 432 | set_offset_for_regex( c_regex_string_literal ). 433 | add_to_trace( ). 434 | CLEANUP. 435 | reset_to_sync_point( current_sync_point_index ). 436 | ENDTRY. 437 | ENDMETHOD. 438 | 439 | METHOD find_spaces. 440 | IF me->offset >= strlen( me->text ). 441 | RETURN. 442 | ENDIF. 443 | "search for leading spaces 444 | FIND FIRST OCCURRENCE OF REGEX '^\s+' IN me->text+me->offset MATCH LENGTH DATA(length). 445 | IF sy-subrc = 0. 446 | APPEND VALUE ty_trace( sync_point = 0 447 | parent_sync_point = 0 448 | terminal = c_terminal-spaces 449 | sub_terminal = c_sub_terminal-na 450 | offset = offset 451 | length = length ) 452 | TO me->trace_tab. 453 | offset += length. 454 | ENDIF. 455 | ENDMETHOD. 456 | 457 | METHOD set_offset_for_regex. 458 | IF me->offset >= strlen( me->text ). 459 | RAISE EXCEPTION NEW lcx_no_match( ). 460 | ENDIF. 461 | DATA(regex) = |^{ i_regex }|. 462 | FIND FIRST OCCURRENCE OF REGEX regex IN me->text+me->offset MATCH LENGTH DATA(length). 463 | IF sy-subrc = 0. 464 | offset += length. 465 | ELSE. 466 | RAISE EXCEPTION NEW lcx_no_match( ). 467 | ENDIF. 468 | ENDMETHOD. 469 | 470 | METHOD zif_op_value_pretty_printer~format. 471 | " start : assign 472 | " 473 | " assign : symbolname = RHS 474 | " 475 | " RHS : number | text | string | empty | struct | table 476 | " 477 | " empty : 'VALUE #( )' 478 | " 479 | " add_structure_rhs : 'VALUE #(' struct2 ')' 480 | " 481 | " add_structure_content : ( LHS (left hand side) '=' RHS (right hand side) )+ 482 | " 483 | " table : 'VALUE #(' ( '( )' | struct2 ( '(' RHS2 ')' )+ | ( '(' RHS ')' )+ ')' 484 | " 485 | " RHS2 : number | text | string | empty | struct2 486 | " 487 | " LHS : ^[A-Z][A-Z0-9_\-]+ 488 | " 489 | " number : ^[0-9]+ 490 | " 491 | " text : ^'(?:''|[^'])+' 492 | 493 | me->text = i_unformated_value_content. 494 | me->offset = 0. 495 | me->trace_tab = VALUE #( ). 496 | me->sync_points = VALUE #( ). 497 | TRY. 498 | assign( ). 499 | CATCH: 500 | lcx_parser_interrupt, 501 | lcx_no_match INTO DATA(lx_error). 502 | DATA(error_text) = lx_error->get_longtext( ). 503 | zcl_op_debugger_integration=>debug_debugger_if_needed( ). 504 | ENDTRY. 505 | 506 | DATA(indent) = 0. 507 | DATA(indent_step) = 8. 508 | DATA(indent_spaces) = repeat( val = ` ` 509 | occ = indent ). 510 | 511 | LOOP AT me->trace_tab REFERENCE INTO DATA(trace_line). 512 | 513 | CASE trace_line->terminal. 514 | WHEN c_terminal-symbolname 515 | OR c_terminal-non_terminal 516 | OR c_terminal-number 517 | OR c_terminal-text_literal 518 | OR c_terminal-string_literal 519 | OR c_terminal-empty 520 | OR c_terminal-spaces. 521 | r_formated_content = r_formated_content && substring( val = i_unformated_value_content 522 | off = trace_line->offset 523 | len = trace_line->length ). 524 | ENDCASE. 525 | 526 | IF trace_line->terminal = c_terminal-iteration. 527 | r_formated_content = |{ r_formated_content }\n{ indent_spaces }|. 528 | ELSEIF trace_line->sub_terminal = c_sub_terminal-value_operator 529 | OR trace_line->sub_terminal = c_sub_terminal-parenthesis_open. 530 | indent += indent_step. 531 | indent_spaces = indent_spaces && repeat( val = ` ` 532 | occ = indent_step ). 533 | r_formated_content = |{ r_formated_content }\n{ indent_spaces }|. 534 | ELSEIF trace_line->sub_terminal = c_sub_terminal-parenthesis_close. 535 | indent -= indent_step. 536 | SHIFT indent_spaces LEFT BY indent_step PLACES. 537 | ENDIF. 538 | 539 | ENDLOOP. 540 | ENDMETHOD. 541 | 542 | METHOD add_to_trace. 543 | ASSIGN me->sync_points[ lines( me->sync_points ) ] TO FIELD-SYMBOL(). 544 | 545 | APPEND VALUE ty_trace( LET length = offset - -offset IN 546 | sync_point = lines( me->sync_points ) 547 | parent_sync_point = lines( me->sync_points ) - 1 548 | terminal = -terminal 549 | sub_terminal = -sub_terminal 550 | offset = -offset 551 | length = length ) 552 | TO me->trace_tab. 553 | 554 | DELETE me->sync_points INDEX lines( me->sync_points ). 555 | 556 | IF 0 = 1. 557 | RAISE EXCEPTION NEW lcx_parser_interrupt( ). 558 | ENDIF. 559 | ENDMETHOD. 560 | 561 | METHOD set_sync_point. 562 | APPEND VALUE ty_sync_point( terminal = i_terminal 563 | sub_terminal = i_sub_terminal 564 | offset = offset 565 | trace_index = lines( me->trace_tab ) ) 566 | TO me->sync_points. 567 | 568 | r_current_sync_point_index = lines( me->sync_points ). 569 | ENDMETHOD. 570 | 571 | METHOD reset_to_sync_point. 572 | DELETE me->trace_tab FROM me->sync_points[ i_sync_point_index ]-trace_index + 1. 573 | offset = sync_points[ i_sync_point_index ]-offset. 574 | DELETE me->sync_points FROM i_sync_point_index. 575 | 576 | IF 0 = 1. 577 | RAISE EXCEPTION NEW lcx_parser_interrupt( ). 578 | ENDIF. 579 | ENDMETHOD. 580 | 581 | METHOD cancel_sync_point. 582 | DELETE me->trace_tab FROM me->sync_points[ i_sync_point_index ]-trace_index + 1. 583 | DELETE me->sync_points FROM i_sync_point_index. 584 | 585 | IF 0 = 1. 586 | RAISE EXCEPTION NEW lcx_parser_interrupt( ). 587 | ENDIF. 588 | ENDMETHOD. 589 | 590 | METHOD add_value_open_operator. 591 | non_terminal( i_sub_terminal = c_sub_terminal-value_operator 592 | i_regex = `VALUE #\(` ). 593 | ENDMETHOD. 594 | 595 | METHOD add_parenthesis_close. 596 | non_terminal( i_sub_terminal = c_sub_terminal-parenthesis_close 597 | i_regex = `\)` ). 598 | ENDMETHOD. 599 | 600 | METHOD add_assign_operator. 601 | non_terminal( i_sub_terminal = c_sub_terminal-assign_operator 602 | i_regex = '=' ). 603 | ENDMETHOD. 604 | 605 | METHOD add_end_of_statement. 606 | non_terminal( i_sub_terminal = c_sub_terminal-end_of_statement 607 | i_regex = '\.' ). 608 | ENDMETHOD. 609 | 610 | METHOD add_empty_line. 611 | non_terminal( i_sub_terminal = c_sub_terminal-empty_line 612 | i_regex = '\( \)' ). 613 | ENDMETHOD. 614 | 615 | METHOD add_parenthesis_open. 616 | non_terminal( i_sub_terminal = c_sub_terminal-parenthesis_open 617 | i_regex = '\(' ). 618 | ENDMETHOD. 619 | 620 | METHOD set_offset_for_regex_pcre. 621 | IF me->offset >= strlen( me->text ). 622 | RAISE EXCEPTION NEW lcx_no_match( ). 623 | ENDIF. 624 | DATA(regex) = |^{ i_regex }|. 625 | FIND FIRST OCCURRENCE OF PCRE regex in me->text+me->offset MATCH LENGTH DATA(length). 626 | IF sy-subrc = 0. 627 | offset += length. 628 | ELSE. 629 | RAISE EXCEPTION NEW lcx_no_match( ). 630 | ENDIF. 631 | ENDMETHOD. 632 | 633 | ENDCLASS. 634 | -------------------------------------------------------------------------------- /zcl_op_value_pretty_printer.clas.locals_def.abap: -------------------------------------------------------------------------------- 1 | *"* use this source file for any type of declarations (class 2 | *"* definitions, interfaces or type declarations) you need for 3 | *"* components in the private section 4 | 5 | class lcx_no_match definition INHERITING FROM cx_static_check. 6 | endclass. 7 | 8 | class lcx_parser_interrupt definition INHERITING FROM cx_no_check. 9 | endclass. 10 | -------------------------------------------------------------------------------- /zcl_op_value_pretty_printer.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_OP_VALUE_PRETTY_PRINTER 7 | E 8 | Pretty Printer for ABAP Debugger Enhancement 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zenh_table_values.enho.1b6c0c61.abap: -------------------------------------------------------------------------------- 1 | "Name: \PR:SAPLSTPDA_TABLE_VALUES\TY:LCL_TAB\ME:INIT_ALV\SE:END\EI 2 | ENHANCEMENT 0 ZENH_TABLE_VALUES. 3 | "instantiate custom event reciever 4 | mo_cust_rec = NEW zcl_op_table( ). 5 | 6 | "set reciever as handler for Debugger Table ALV 7 | SET HANDLER mo_cust_rec->handle_toolbar_set FOR me->ref_alv. 8 | 9 | " need to refresh alv here 10 | refresh_alv( ). 11 | ENDENHANCEMENT. 12 | -------------------------------------------------------------------------------- /zenh_table_values.enho.c5c75b12.abap: -------------------------------------------------------------------------------- 1 | "Name: \PR:SAPLSTPDA_TABLE_VALUES\TY:LCL_TAB\ME:HANDLE_USER_COMMAND\SE:BEGIN\EI 2 | ENHANCEMENT 0 ZENH_TABLE_VALUES. 3 | CASE e_ucomm. 4 | WHEN 'ZDATA_4_ABAP_VIEW'. "user klicked on Button to display ABAP friendly table data 5 | FIELD-SYMBOLS: TYPE ANY TABLE. 6 | zcl_op_debugger_integration=>debug_debugger_if_needed( ). 7 | TRY. 8 | ref_alv->get_frontend_fieldcatalog( IMPORTING et_fieldcatalog = DATA(zz_field_catalog) ). 9 | " field INDEX does not actually exist in table and is not useful in VALUE statement 10 | DELETE zz_field_catalog WHERE fieldname = 'INDEX'. 11 | ASSIGN me->rda_table->* TO . "get current table content 12 | DATA(zz_filtered_table) = mo_cust_rec->filter_table_from_alv( i_alv = ref_alv 13 | i_table = ). 14 | ASSIGN zz_filtered_table->* TO . 15 | 16 | mo_cust_rec->show_popup_w_content( 17 | EXPORTING 18 | i_table = 19 | i_table_title = me->table 20 | i_fieldcatalog = zz_field_catalog ). 21 | CATCH cx_root INTO DATA(zzlx_root). 22 | "dont want to crash, so catch all catchable exceptions here 23 | ENDTRY. 24 | ENDCASE. 25 | ENDENHANCEMENT. 26 | -------------------------------------------------------------------------------- /zenh_table_values.enho.d656a875.abap: -------------------------------------------------------------------------------- 1 | "Name: \PR:SAPLSTPDA_TABLE_VALUES\IC:LSTPDA_TABLE_VALUESTOP\SE:END\EI 2 | ENHANCEMENT 0 ZENH_TABLE_VALUES. 3 | DATA: mo_cust_rec TYPE REF TO zcl_op_table. 4 | ENDENHANCEMENT. 5 | -------------------------------------------------------------------------------- /zenh_table_values.enho.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | HOOK_IMPL 6 | Erweiterung des ALVs im ABAP Debugger 7 | 8 | R3TR 9 | FUGR 10 | STPDA_TABLE_VALUES 11 | FUGR 12 | STPDA_TABLE_VALUES 13 | SAPLSTPDA_TABLE_VALUES 14 | 15 | 16 | 17 | SAPLSTPDA_TABLE_VALUES 18 | D 19 | \PR:SAPLSTPDA_TABLE_VALUES\TY:LCL_TAB\ME:INIT_ALV\SE:END\EI 20 | 21 | 22 | SAPLSTPDA_TABLE_VALUES 23 | D 24 | \PR:SAPLSTPDA_TABLE_VALUES\TY:LCL_TAB\ME:HANDLE_USER_COMMAND\SE:BEGIN\EI 25 | 26 | 27 | SAPLSTPDA_TABLE_VALUES 28 | S 29 | \PR:SAPLSTPDA_TABLE_VALUES\IC:LSTPDA_TABLE_VALUESTOP\SE:END\EI 30 | 31 | 32 | 33 | 34 | \PR:SAPLSTPDA_TABLE_VALUES\TY:LCL_TAB\ME:INIT_ALV\SE:END\EI 35 | 1b6c0c61 36 | 37 | 38 | \PR:SAPLSTPDA_TABLE_VALUES\TY:LCL_TAB\ME:HANDLE_USER_COMMAND\SE:BEGIN\EI 39 | c5c75b12 40 | 41 | 42 | \PR:SAPLSTPDA_TABLE_VALUES\IC:LSTPDA_TABLE_VALUESTOP\SE:END\EI 43 | d656a875 44 | 45 | 46 | 47 | 48 |
49 | 000D3A46373D1EDA9BA13BBAE94A5A1A 50 | E 51 | 1 52 | AAI= 53 |
54 | 55 | 56 | 000D3A46373D1EDA9BA13BBAE94A5A1A 57 | E 58 | 0001 59 | X 60 | R 61 | 056 62 | Erweiterung des ALVs im ABAP Debugger 63 | 64 | 65 |
66 |
67 | 68 | 69 | R3TR 70 | ENHO 71 | ZENH_TABLE_VALUES 72 | 000D3A46373D1EDA9BA13BBAE94A5A1A 73 | 0001 74 | 75 | 76 |
77 |
78 |
79 | -------------------------------------------------------------------------------- /zif_op_value_pretty_printer.intf.abap: -------------------------------------------------------------------------------- 1 | "! Interface for pretty printing a value #() construct 2 | INTERFACE zif_op_value_pretty_printer 3 | PUBLIC . 4 | 5 | METHODS: 6 | "! Method for formating given string value,
7 | "! which should already be a syntax correct representation of an value #() construct
8 | "! See unit test of zcl_op_value_pretty_printer class for usage scenarios
9 | "! @parameter i_unformated_value_content | syntax correct representation of an value #() construct 10 | "! @parameter r_formated_content | formated value #() construct containing line breaks, spaces and so on 11 | format 12 | IMPORTING i_unformated_value_content TYPE string 13 | RETURNING VALUE(r_formated_content) TYPE string. 14 | 15 | ENDINTERFACE. 16 | -------------------------------------------------------------------------------- /zif_op_value_pretty_printer.intf.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZIF_OP_VALUE_PRETTY_PRINTER 7 | E 8 | Interface Value Contructor Pretty Printer 9 | 2 10 | 1 11 | X 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenaf00.abap: -------------------------------------------------------------------------------- 1 | *---------------------------------------------------------------------* 2 | * view related FORM routines 3 | *---------------------------------------------------------------------* 4 | 5 | * base table related FORM-routines............. 6 | INCLUDE LSVIMFTX . 7 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenaf00.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | LZOP_DVE_MAINTENAF00 7 | I 8 | E 9 | X 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenai00.abap: -------------------------------------------------------------------------------- 1 | *---------------------------------------------------------------------* 2 | * view related PAI modules 3 | *---------------------------------------------------------------------* 4 | 5 | INCLUDE LSVIMITX . "base table related PAI modules 6 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenai00.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | LZOP_DVE_MAINTENAI00 7 | I 8 | E 9 | X 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenat00.abap: -------------------------------------------------------------------------------- 1 | *---------------------------------------------------------------------* 2 | * view related data declarations 3 | *---------------------------------------------------------------------* 4 | *...processing: ZTOP_DVE_CUST...................................* 5 | DATA: BEGIN OF STATUS_ZTOP_DVE_CUST . "state vector 6 | INCLUDE STRUCTURE VIMSTATUS. 7 | DATA: END OF STATUS_ZTOP_DVE_CUST . 8 | CONTROLS: TCTRL_ZTOP_DVE_CUST 9 | TYPE TABLEVIEW USING SCREEN '0001'. 10 | *.........table declarations:.................................* 11 | TABLES: *ZTOP_DVE_CUST . 12 | TABLES: ZTOP_DVE_CUST . 13 | 14 | * general table data declarations.............. 15 | INCLUDE LSVIMTDT . 16 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenat00.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | LZOP_DVE_MAINTENAT00 7 | I 8 | E 9 | X 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenatop.abap: -------------------------------------------------------------------------------- 1 | FUNCTION-POOL ZOP_DVE_MAINTENA MESSAGE-ID SV. 2 | 3 | * INCLUDE LZOP_DVE_MAINTENAD... " Local class definition 4 | INCLUDE LSVIMDAT . "general data decl. 5 | INCLUDE LZOP_DVE_MAINTENAT00 . "view rel. data dcl. 6 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.lzop_dve_maintenatop.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | LZOP_DVE_MAINTENATOP 7 | S 8 | D$ 9 | I 10 | S 11 | X 12 | D$S 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.saplzop_dve_maintena.abap: -------------------------------------------------------------------------------- 1 | ******************************************************************* 2 | * System-defined Include-files. * 3 | ******************************************************************* 4 | INCLUDE LZOP_DVE_MAINTENATOP. " Global Data 5 | INCLUDE LZOP_DVE_MAINTENAUXX. " Function Modules 6 | 7 | ******************************************************************* 8 | * User-defined Include-files (if necessary). * 9 | ******************************************************************* 10 | * INCLUDE LZOP_DVE_MAINTENAF... " Subroutines 11 | * INCLUDE LZOP_DVE_MAINTENAO... " PBO-Modules 12 | * INCLUDE LZOP_DVE_MAINTENAI... " PAI-Modules 13 | * INCLUDE LZOP_DVE_MAINTENAE... " Events 14 | * INCLUDE LZOP_DVE_MAINTENAP... " Local class implement. 15 | * INCLUDE LZOP_DVE_MAINTENAT99. " ABAP Unit tests 16 | INCLUDE LZOP_DVE_MAINTENAF00 . " subprograms 17 | INCLUDE LZOP_DVE_MAINTENAI00 . " PAI modules 18 | INCLUDE LSVIMFXX . " subprograms 19 | INCLUDE LSVIMOXX . " PBO modules 20 | INCLUDE LSVIMIXX . " PAI modules 21 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.saplzop_dve_maintena.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | SAPLZOP_DVE_MAINTENA 7 | S 8 | D$ 9 | F 10 | S 11 | E 12 | X 13 | D$S 14 | X 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.tableframe_zop_dve_maintena.abap: -------------------------------------------------------------------------------- 1 | *---------------------------------------------------------------------* 2 | * program for: TABLEFRAME_ZOP_DVE_MAINTENA 3 | *---------------------------------------------------------------------* 4 | FUNCTION TABLEFRAME_ZOP_DVE_MAINTENA . 5 | 6 | PERFORM TABLEFRAME TABLES X_HEADER X_NAMTAB DBA_SELLIST DPL_SELLIST 7 | EXCL_CUA_FUNCT 8 | USING CORR_NUMBER VIEW_ACTION VIEW_NAME. 9 | 10 | ENDFUNCTION. 11 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.tableproc_zop_dve_maintena.abap: -------------------------------------------------------------------------------- 1 | *---------------------------------------------------------------------* 2 | * program for: TABLEPROC_ZOP_DVE_MAINTENA 3 | *---------------------------------------------------------------------* 4 | FUNCTION TABLEPROC_ZOP_DVE_MAINTENA . 5 | 6 | PERFORM TABLEPROC. 7 | 8 | ENDFUNCTION. 9 | -------------------------------------------------------------------------------- /zop_dve_maintena.fugr.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Extended Table Maintenance (Generated) 6 | 7 | LZOP_DVE_MAINTENAF00 8 | LZOP_DVE_MAINTENAI00 9 | LZOP_DVE_MAINTENAT00 10 | LZOP_DVE_MAINTENATOP 11 | SAPLZOP_DVE_MAINTENA 12 | 13 | 14 | 15 | TABLEFRAME_ZOP_DVE_MAINTENA 16 | Extended Table Maintenance: Upper Level 17 | 18 | 19 | VIEW_ACTION 20 | 'S' 21 | 22 | 23 | VIEW_NAME 24 | DD02V-TABNAME 25 | 26 | 27 | CORR_NUMBER 28 | E070-TRKORR 29 | ' ' 30 | 31 | 32 | 33 | 34 | DBA_SELLIST 35 | VIMSELLIST 36 | 37 | 38 | DPL_SELLIST 39 | VIMSELLIST 40 | 41 | 42 | EXCL_CUA_FUNCT 43 | VIMEXCLFUN 44 | 45 | 46 | X_HEADER 47 | VIMDESC 48 | 49 | 50 | X_NAMTAB 51 | VIMNAMTAB 52 | 53 | 54 | 55 | 56 | MISSING_CORR_NUMBER 57 | 58 | 59 | 60 | 61 | VIEW_ACTION 62 | P 63 | Aktion mit Tabelle: anz./änd./transp. (S/U/T) 64 | 65 | 66 | VIEW_NAME 67 | P 68 | Name der Tabelle 69 | 70 | 71 | CORR_NUMBER 72 | P 73 | Korrekturnummer für durchgeführte Änderungen 74 | 75 | 76 | DBA_SELLIST 77 | P 78 | Selektionsbedingungen für den DB-Zugriff 79 | 80 | 81 | DPL_SELLIST 82 | P 83 | Selektionsbedingungen für die Anzeige 84 | 85 | 86 | EXCL_CUA_FUNCT 87 | P 88 | Tabelle mit dynam. zu deaktivierenden CUA-Funkt. 89 | 90 | 91 | X_HEADER 92 | P 93 | Kontrollblocktabelle für die Tabelle 94 | 95 | 96 | X_NAMTAB 97 | P 98 | Kontrollblocktabelle für die Tabellen-Felder 99 | 100 | 101 | MISSING_CORR_NUMBER 102 | X 103 | Korrekturnummer fehlt 104 | 105 | 106 | 107 | 108 | TABLEPROC_ZOP_DVE_MAINTENA 109 | X 110 | Lower-level extended table maintenance 111 | 112 | 113 | FCODE 114 | 'RDED' 115 | 116 | 117 | VIEW_ACTION 118 | 'S' 119 | 120 | 121 | VIEW_NAME 122 | DD02V-TABNAME 123 | 124 | 125 | CORR_NUMBER 126 | E070-TRKORR 127 | ' ' 128 | 129 | 130 | 131 | 132 | LAST_ACT_ENTRY 133 | 134 | 135 | UCOMM 136 | 137 | 138 | UPDATE_REQUIRED 139 | 140 | 141 | 142 | 143 | CORR_KEYTAB 144 | E071K 145 | 146 | 147 | DBA_SELLIST 148 | VIMSELLIST 149 | 150 | 151 | DPL_SELLIST 152 | VIMSELLIST 153 | 154 | 155 | EXCL_CUA_FUNCT 156 | VIMEXCLFUN 157 | 158 | 159 | EXTRACT 160 | 161 | 162 | TOTAL 163 | 164 | 165 | X_HEADER 166 | VIMDESC 167 | 168 | 169 | X_NAMTAB 170 | VIMNAMTAB 171 | 172 | 173 | 174 | 175 | MISSING_CORR_NUMBER 176 | 177 | 178 | SAVING_CORRECTION_FAILED 179 | 180 | 181 | 182 | 183 | FCODE 184 | P 185 | gewünschte Funktion des Bausteins 186 | 187 | 188 | VIEW_ACTION 189 | P 190 | Aktion mit Tabelle: anz./änd./transp. (S/U/T) 191 | 192 | 193 | VIEW_NAME 194 | P 195 | Name der Tabelle 196 | 197 | 198 | CORR_NUMBER 199 | P 200 | Korrekturnummer für durchgeführte Änderungen 201 | 202 | 203 | LAST_ACT_ENTRY 204 | P 205 | Index der Cursorposition in der Anzeigetabelle 206 | 207 | 208 | UCOMM 209 | P 210 | letztes User-command innerhalb der Viewpflege 211 | 212 | 213 | UPDATE_REQUIRED 214 | P 215 | Flag: Einträge verändert, Sichern erforderlich 216 | 217 | 218 | CORR_KEYTAB 219 | P 220 | Tabelle mit den Keys der zu transport. Einträge 221 | 222 | 223 | DBA_SELLIST 224 | P 225 | Selektionsbedingungen für den DB-Zugriff 226 | 227 | 228 | DPL_SELLIST 229 | P 230 | Selektionsbedingungen für die Anzeige 231 | 232 | 233 | EXCL_CUA_FUNCT 234 | P 235 | Tab. der nicht zu aktivierenden CUA-Funktionen 236 | 237 | 238 | EXTRACT 239 | P 240 | Tab. der gerade sichtbaren Daten (Anzeigetabelle 241 | 242 | 243 | TOTAL 244 | P 245 | Tabelle, mit allen von der DB gelesenen Daten 246 | 247 | 248 | X_HEADER 249 | P 250 | Kontrollblocktabelle für die Tabelle 251 | 252 | 253 | X_NAMTAB 254 | P 255 | Kontrollblocktabelle für die Tabellen-Felder 256 | 257 | 258 | MISSING_CORR_NUMBER 259 | X 260 | Korrekturnummer fehlt 261 | 262 | 263 | SAVING_CORRECTION_FAILED 264 | X 265 | Fehler beim Sichern der Korrektureinträge 266 | 267 | 268 | 269 | 270 | 271 | 272 |
273 | SAPLZOP_DVE_MAINTENA 274 | 0001 275 | E 276 | View maint: Overview screen ZTOP_DVE_CUST 277 | N 278 | 0001 279 | 061 280 | 083 281 |
282 | 283 | 284 | SCREEN 285 | SCREEN 286 | 287 | 288 | TABLE_CTRL 289 | TCTRL_ZTOP_DVE_CUST 290 | SCREEN 291 | 001 292 | 001 293 | 050 294 | 059 295 | X 296 | X 297 | X 298 | X 299 | ENTRY 300 | X 301 | X 302 | X 303 | X 304 | X 305 | MULTIPLE 306 | NONE 307 | X 308 | 001 309 | 310 | 311 | 312 | 313 | SCREEN 314 | SCREEN 315 | PUSH_TMPL 316 | VIM_POSI_PUSH 317 | ____________________ 318 | 061 319 | 019 320 | 020 321 | 020 322 | 001 323 | POSI 324 | CHAR 325 | X 326 | N 327 | 328 | 329 | SCREEN 330 | SCREEN 331 | TEMPLATE 332 | VIM_POSITION_INFO 333 | ______________________________ 334 | 061 335 | 040 336 | 030 337 | 030 338 | 001 339 | CHAR 340 | X 341 | X 342 | X 343 | N 344 | <_--32_DIMENS>X 345 | 346 | 347 | SCREEN 348 | SCREEN 349 | OKCODE 350 | OK_CODE 351 | ____________________ 352 | 020 353 | 020 354 | 001 355 | CHAR 356 | X 357 | 358 | 359 | TABLE_CTRL 360 | TCTRL_ZTOP_DVE_CUST 361 | TEMPLATE 362 | VIM_FRAME_FIELD 363 | ____________________________________________________________ 364 | 001 365 | 060 366 | 060 367 | 001 368 | CHAR 369 | X 370 | X 371 | N 372 | X 373 | 374 | 375 | TABLE_CTRL 376 | TCTRL_ZTOP_DVE_CUST 377 | TEXT 378 | *ZTOP_DVE_CUST-USER_NAME 379 | 001 380 | 001 381 | 040 382 | 012 383 | 001 384 | CHAR 385 | X 386 | V 387 | N 388 | X 389 | 390 | 391 | TABLE_CTRL 392 | TCTRL_ZTOP_DVE_CUST 393 | TEXT 394 | *ZTOP_DVE_CUST-CLASS_NAME 395 | 001 396 | 002 397 | 040 398 | 030 399 | 001 400 | CHAR 401 | X 402 | V 403 | N 404 | X 405 | 406 | 407 | TABLE_CTRL 408 | TCTRL_ZTOP_DVE_CUST 409 | CHECK 410 | VIM_MARKED 411 | 001 412 | 001 413 | 001 414 | 001 415 | CHAR 416 | X 417 | X 418 | X 419 | 420 | 421 | TABLE_CTRL 422 | TCTRL_ZTOP_DVE_CUST 423 | TEMPLATE 424 | ZTOP_DVE_CUST-USER_NAME 425 | ____________ 426 | 001 427 | 001 428 | 012 429 | 012 430 | 001 431 | KEY 432 | CHAR 433 | X 434 | X 435 | X 436 | N 437 | 438 | 439 | TABLE_CTRL 440 | TCTRL_ZTOP_DVE_CUST 441 | TEMPLATE 442 | ZTOP_DVE_CUST-CLASS_NAME 443 | ______________________________ 444 | 001 445 | 002 446 | 030 447 | 030 448 | 001 449 | CHAR 450 | X 451 | X 452 | CLASS 453 | X 454 | X 455 | 456 | 457 | 458 | 459 | PROCESS BEFORE OUTPUT. 460 | 461 | 462 | MODULE LISTE_INITIALISIEREN. 463 | 464 | 465 | LOOP AT EXTRACT WITH CONTROL 466 | 467 | 468 | TCTRL_ZTOP_DVE_CUST CURSOR NEXTLINE. 469 | 470 | 471 | MODULE LISTE_SHOW_LISTE. 472 | 473 | 474 | ENDLOOP. 475 | 476 | 477 | * 478 | 479 | 480 | PROCESS AFTER INPUT. 481 | 482 | 483 | MODULE LISTE_EXIT_COMMAND AT EXIT-COMMAND. 484 | 485 | 486 | MODULE LISTE_BEFORE_LOOP. 487 | 488 | 489 | LOOP AT EXTRACT. 490 | 491 | 492 | MODULE LISTE_INIT_WORKAREA. 493 | 494 | 495 | CHAIN. 496 | 497 | 498 | FIELD ZTOP_DVE_CUST-USER_NAME . 499 | 500 | 501 | FIELD ZTOP_DVE_CUST-CLASS_NAME . 502 | 503 | 504 | MODULE SET_UPDATE_FLAG ON CHAIN-REQUEST. 505 | 506 | 507 | ENDCHAIN. 508 | 509 | 510 | FIELD VIM_MARKED MODULE LISTE_MARK_CHECKBOX. 511 | 512 | 513 | CHAIN. 514 | 515 | 516 | FIELD ZTOP_DVE_CUST-USER_NAME . 517 | 518 | 519 | MODULE LISTE_UPDATE_LISTE. 520 | 521 | 522 | ENDCHAIN. 523 | 524 | 525 | ENDLOOP. 526 | 527 | 528 | MODULE LISTE_AFTER_LOOP. 529 | 530 | 531 |
532 |
533 |
534 |
535 |
536 | -------------------------------------------------------------------------------- /zop_dve_maintenance_views.fugr.lzop_dve_maintenance_viewstop.abap: -------------------------------------------------------------------------------- 1 | FUNCTION-POOL ZOP_DVE_MAINTENANCE_VIEWS. "MESSAGE-ID .. 2 | 3 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWSD... " Local class definition 4 | -------------------------------------------------------------------------------- /zop_dve_maintenance_views.fugr.lzop_dve_maintenance_viewstop.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | LZOP_DVE_MAINTENANCE_VIEWSTOP 7 | S 8 | D$ 9 | I 10 | S 11 | X 12 | D$S 13 | X 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /zop_dve_maintenance_views.fugr.saplzop_dve_maintenance_views.abap: -------------------------------------------------------------------------------- 1 | ******************************************************************* 2 | * System-defined Include-files. * 3 | ******************************************************************* 4 | INCLUDE LZOP_DVE_MAINTENANCE_VIEWSTOP. " Global Data 5 | INCLUDE LZOP_DVE_MAINTENANCE_VIEWSUXX. " Function Modules 6 | 7 | ******************************************************************* 8 | * User-defined Include-files (if necessary). * 9 | ******************************************************************* 10 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWSF... " Subroutines 11 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWSO... " PBO-Modules 12 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWSI... " PAI-Modules 13 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWSE... " Events 14 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWSP... " Local class implement. 15 | * INCLUDE LZOP_DVE_MAINTENANCE_VIEWST99. " ABAP Unit tests 16 | -------------------------------------------------------------------------------- /zop_dve_maintenance_views.fugr.saplzop_dve_maintenance_views.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | SAPLZOP_DVE_MAINTENANCE_VIEWS 7 | S 8 | D$ 9 | F 10 | S 11 | E 12 | X 13 | D$S 14 | X 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /zop_dve_maintenance_views.fugr.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debugger extension - maintenance views 6 | 7 | LZOP_DVE_MAINTENANCE_VIEWSTOP 8 | SAPLZOP_DVE_MAINTENANCE_VIEWS 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ztop_dve_cust.tabl.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTOP_DVE_CUST 7 | E 8 | TRANSP 9 | ABAP Debugger Extension - Customizing for Pretty Printer 10 | X 11 | C 12 | 1 13 | 14 | 15 | ZTOP_DVE_CUST 16 | A 17 | 0 18 | APPL0 19 | N 20 | 21 | 22 | 23 | USER_NAME 24 | X 25 | UNAME 26 | 0 27 | X 28 | X 29 | E 30 | 31 | 32 | CLASS_NAME 33 | SEOCLSNAME 34 | 0 35 | X 36 | E 37 | 38 | 39 | 40 | 41 | CLASS_NAME 42 | FEH_CLASSES 43 | 44 | 45 | USER_NAME 46 | USER_ADDR 47 | 48 | 49 | 50 | 51 | CLASS_NAME 52 | FEH_CLASSES 53 | CLSNAME 54 | 0001 55 | ZTOP_DVE_CUST 56 | CLASS_NAME 57 | X 58 | X 59 | SEOCLSNAME 60 | SEOCLSNAME 61 | CHAR 62 | 000030 63 | 64 | 65 | CLASS_NAME 66 | FEH_CLASSES 67 | DESCRIPT 68 | 0003 69 | G 70 | X 71 | X 72 | SEODESCR 73 | AS4TEXT 74 | CHAR 75 | 000060 76 | 77 | 78 | USER_NAME 79 | USER_ADDR 80 | BNAME 81 | 0001 82 | ZTOP_DVE_CUST 83 | USER_NAME 84 | X 85 | X 86 | XUBNAME 87 | XUBNAME 88 | CHAR 89 | 000012 90 | 91 | 92 | USER_NAME 93 | USER_ADDR 94 | BUILDING 95 | 0005 96 | G 97 | X 98 | X 99 | AD_BLDNG_P 100 | TEXT10 101 | CHAR 102 | 000010 103 | 104 | 105 | USER_NAME 106 | USER_ADDR 107 | COMPANY 108 | 0012 109 | G 110 | X 111 | X 112 | USCOMP 113 | USCOMP 114 | CHAR 115 | 000042 116 | 117 | 118 | USER_NAME 119 | USER_ADDR 120 | DEPARTMENT 121 | 0004 122 | G 123 | X 124 | X 125 | AD_DPRTMNT 126 | TEXT40 127 | CHAR 128 | 000040 129 | 130 | 131 | USER_NAME 132 | USER_ADDR 133 | IDADTYPE 134 | 0013 135 | G 136 | X 137 | X 138 | SUIDADTYPE 139 | SUIDADTYPE 140 | NUMC 141 | 000002 142 | 143 | 144 | USER_NAME 145 | USER_ADDR 146 | INHOUSE_ML 147 | 0009 148 | G 149 | X 150 | X 151 | AD_IH_MAIL 152 | TEXT10 153 | CHAR 154 | 000010 155 | 156 | 157 | USER_NAME 158 | USER_ADDR 159 | KOSTL 160 | 0008 161 | G 162 | X 163 | X 164 | XUKOSTL 165 | CHAR8 166 | CHAR 167 | 000008 168 | 169 | 170 | USER_NAME 171 | USER_ADDR 172 | MC_CITY1 173 | 0011 174 | G 175 | X 176 | X 177 | AD_MC_CITY 178 | CHAR25 179 | CHAR 180 | 000025 181 | 182 | 183 | USER_NAME 184 | USER_ADDR 185 | MC_NAME1 186 | 0010 187 | G 188 | X 189 | X 190 | AD_MC_NAME 191 | CHAR25 192 | CHAR 193 | 000025 194 | 195 | 196 | USER_NAME 197 | USER_ADDR 198 | MC_NAMEFIR 199 | 0003 200 | G 201 | X 202 | X 203 | AD_MC_NMFI 204 | CHAR25 205 | CHAR 206 | 000025 207 | 208 | 209 | USER_NAME 210 | USER_ADDR 211 | MC_NAMELAS 212 | 0002 213 | G 214 | X 215 | X 216 | AD_MC_NMLA 217 | CHAR25 218 | CHAR 219 | 000025 220 | 221 | 222 | USER_NAME 223 | USER_ADDR 224 | ROOMNUMBER 225 | 0006 226 | G 227 | X 228 | X 229 | AD_ROOMNUM 230 | TEXT10 231 | CHAR 232 | 000010 233 | 234 | 235 | USER_NAME 236 | USER_ADDR 237 | TEL_EXTENS 238 | 0007 239 | G 240 | X 241 | X 242 | AD_TLXTNS1 243 | CHAR10 244 | CHAR 245 | 000010 246 | 247 | 248 | 249 | 250 | ZTOP_DVE_CUST 251 | &NC& 252 | 253 | 254 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /ztop_dve_custs.tobj.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZTOP_DVE_CUST 7 | S 8 | CUSY 9 | 2 10 | 3 11 | 12 | 13 | E 14 | ZTOP_DVE_CUST 15 | S 16 | 17 | 18 | 19 | ZTOP_DVE_CUST 20 | S 21 | ZTOP_DVE_CUST 22 | X 23 | X 24 | 25 | 26 | 27 | 28 | ZTOP_DVE_CUST 29 | &NC& 30 | 31 | 32 | ZTOP_DVE_CUST 33 | ZOP_DVE_MAINTENA 34 | 1 35 | 0001 36 | X 37 | X 38 | 39 | 40 | 41 | 42 | 43 | --------------------------------------------------------------------------------