abap2xlsx/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk
Ivan 24515b3a0a fix issue #361 #363 #357 by Stefan Schmöcker""
I commit the changes due to an inconsistency in Stefan's repository
2015-03-02 09:46:24 -06:00

2754 lines
140 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<CLAS CLSNAME="ZCL_EXCEL_COMMON" VERSION="1" LANGU="E" DESCRIPT="Static common methods" CATEGORY="00" EXPOSURE="2" STATE="1" RELEASE="0" CLSFINAL="X" CLSCCINCL="X" FIXPT="X" UNICODE="X" CLSBCCAT="00" WITH_UNIT_TESTS="X" DURATION_TYPE="0 " RISK_LEVEL="0 ">
<localImplementation>*&quot;* local class implementation for public class
*&quot;* use this source file for the implementation part of
*&quot;* local helper classes</localImplementation>
<localTypes>*&quot;* use this source file for any type declarations (class
*&quot;* definitions, interfaces or data types) you need for method
*&quot;* implementation or private method&apos;s signature</localTypes>
<localMacros>*&quot;* use this source file for any macro definitions you need
*&quot;* in the implementation part of the class</localMacros>
<localTestClasses>CLASS lcl_excel_common_test DEFINITION DEFERRED.
CLASS zcl_excel_common DEFINITION LOCAL FRIENDS lcl_excel_common_test.
*----------------------------------------------------------------------*
* CLASS lcl_Excel_Common_Test DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_excel_common_test DEFINITION FOR TESTING &quot;#AU Risk_Level Harmless
. &quot;#AU Duration Short
*?&lt;asx:abap xmlns:asx=&quot;http://www.sap.com/abapxml&quot; version=&quot;1.0&quot;&gt;
*?&lt;asx:values&gt;
*?&lt;TESTCLASS_OPTIONS&gt;
*?&lt;TEST_CLASS&gt;lcl_Excel_Common_Test
*?&lt;/TEST_CLASS&gt;
*?&lt;TEST_MEMBER&gt;f_Cut
*?&lt;/TEST_MEMBER&gt;
*?&lt;OBJECT_UNDER_TEST&gt;ZCL_EXCEL_COMMON
*?&lt;/OBJECT_UNDER_TEST&gt;
*?&lt;OBJECT_IS_LOCAL/&gt;
*?&lt;GENERATE_FIXTURE&gt;X
*?&lt;/GENERATE_FIXTURE&gt;
*?&lt;GENERATE_CLASS_FIXTURE&gt;X
*?&lt;/GENERATE_CLASS_FIXTURE&gt;
*?&lt;GENERATE_INVOCATION&gt;X
*?&lt;/GENERATE_INVOCATION&gt;
*?&lt;GENERATE_ASSERT_EQUAL&gt;X
*?&lt;/GENERATE_ASSERT_EQUAL&gt;
*?&lt;/TESTCLASS_OPTIONS&gt;
*?&lt;/asx:values&gt;
*?&lt;/asx:abap&gt;
PRIVATE SECTION.
* ================
DATA:
lx_excel TYPE REF TO zcx_excel,
ls_symsg_act TYPE symsg, &quot; actual messageinformation of exception
ls_symsg_exp TYPE symsg, &quot; expected messageinformation of exception
f_cut TYPE REF TO zcl_excel_common. &quot;class under test
CLASS-METHODS: class_setup.
CLASS-METHODS: class_teardown.
METHODS: setup.
METHODS: teardown.
* METHODS: char2hex FOR TESTING.
METHODS: convert_column2alpha FOR TESTING.
METHODS: convert_column2int FOR TESTING.
METHODS: date_to_excel_string FOR TESTING.
METHODS: encrypt_password FOR TESTING.
METHODS: excel_string_to_date FOR TESTING.
METHODS: excel_string_to_time FOR TESTING.
* METHODS: number_to_excel_string FOR TESTING.
METHODS: time_to_excel_string FOR TESTING.
METHODS: split_file FOR TESTING.
METHODS: convert_range2column_a_row FOR TESTING.
METHODS: describe_structure FOR TESTING.
METHODS: calculate_cell_distance FOR TESTING.
METHODS: shift_formula FOR TESTING.
METHODS: is_cell_in_range FOR TESTING.
ENDCLASS. &quot;lcl_Excel_Common_Test
*----------------------------------------------------------------------*
* CLASS lcl_Excel_Common_Test IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_excel_common_test IMPLEMENTATION.
* ===========================================
METHOD class_setup.
* ===================
ENDMETHOD. &quot;class_Setup
METHOD class_teardown.
* ======================
ENDMETHOD. &quot;class_Teardown
METHOD setup.
* =============
CREATE OBJECT f_cut.
ENDMETHOD. &quot;setup
METHOD teardown.
* ================
ENDMETHOD. &quot;teardown
METHOD convert_column2alpha.
* ============================
DATA ep_column TYPE zexcel_cell_column_alpha.
* Test 1. Simple test
TRY.
ep_column = zcl_excel_common=&gt;convert_column2alpha( 1 ).
zcl_excel_common=&gt;assert_equals(
act = ep_column
exp = &apos;A&apos;
msg = &apos;Wrong column conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Max column for OXML #16,384 = XFD
TRY.
ep_column = zcl_excel_common=&gt;convert_column2alpha( 16384 ).
zcl_excel_common=&gt;assert_equals(
act = ep_column
exp = &apos;XFD&apos;
msg = &apos;Wrong column conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 3. Index 0 is out of bounds
TRY.
ep_column = zcl_excel_common=&gt;convert_column2alpha( 0 ).
zcl_excel_common=&gt;assert_equals(
act = ep_column
exp = &apos;A&apos;
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;assert_equals(
act = lx_excel-&gt;error
exp = &apos;Index out of bounds&apos;
msg = &apos;Colum index 0 is out of bounds, min column index is 1&apos;
level = if_aunit_constants=&gt;fatal
).
ENDTRY.
* Test 4. Exception should be thrown index out of bounds
TRY.
ep_column = zcl_excel_common=&gt;convert_column2alpha( 16385 ).
zcl_excel_common=&gt;assert_differs(
act = ep_column
exp = &apos;XFE&apos;
msg = &apos;Colum index 16385 is out of bounds, max column index is 16384&apos;
level = if_aunit_constants=&gt;fatal
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;assert_equals(
act = lx_excel-&gt;error
exp = &apos;Index out of bounds&apos;
msg = &apos;Wrong exception is thrown&apos;
level = if_aunit_constants=&gt;tolerable
).
ENDTRY.
ENDMETHOD. &quot;convert_Column2alpha
METHOD convert_column2int.
* ==========================
DATA ep_column TYPE zexcel_cell_column.
* Test 1. Basic test
TRY.
ep_column = zcl_excel_common=&gt;convert_column2int( &apos;A&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_column
exp = 1
msg = &apos;Wrong column conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Max column
TRY.
ep_column = zcl_excel_common=&gt;convert_column2int( &apos;XFD&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_column
exp = 16384
msg = &apos;Wrong column conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 3. Out of bounds
TRY.
ep_column = zcl_excel_common=&gt;convert_column2int( &apos;&apos; ).
zcl_excel_common=&gt;assert_differs( act = ep_column
exp = &apos;0&apos;
msg = &apos;Wrong column conversion&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel INTO lx_excel.
CLEAR: ls_symsg_act,
ls_symsg_exp.
ls_symsg_exp-msgid = &apos;ZABAP2XLSX&apos;.
ls_symsg_exp-msgno = &apos;800&apos;.
ls_symsg_act-msgid = lx_excel-&gt;syst_at_raise-msgid.
ls_symsg_act-msgno = lx_excel-&gt;syst_at_raise-msgno.
zcl_excel_common=&gt;assert_equals( act = ls_symsg_act
exp = ls_symsg_exp
msg = &apos;Colum name should be a valid string&apos;
level = if_aunit_constants=&gt;fatal ).
ENDTRY.
* Test 4. Out of bounds
TRY.
ep_column = zcl_excel_common=&gt;convert_column2int( &apos;XFE&apos; ).
zcl_excel_common=&gt;assert_differs( act = ep_column
exp = 16385
msg = &apos;Wrong column conversion&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;assert_equals( act = lx_excel-&gt;error
exp = &apos;Index out of bounds&apos;
msg = &apos;Colum XFE is out of range&apos;
level = if_aunit_constants=&gt;fatal ).
ENDTRY.
ENDMETHOD. &quot;convert_Column2int
METHOD date_to_excel_string.
* ============================
DATA ep_value TYPE zexcel_cell_value.
* Test 1. Basic conversion
TRY.
ep_value = zcl_excel_common=&gt;date_to_excel_string( &apos;19000101&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = 1
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Check around the &quot;Excel Leap Year&quot; 1900
TRY.
ep_value = zcl_excel_common=&gt;date_to_excel_string( &apos;19000228&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = 59
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
TRY.
ep_value = zcl_excel_common=&gt;date_to_excel_string( &apos;19000301&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = 61
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
ep_value = zcl_excel_common=&gt;date_to_excel_string( &apos;99991212&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = 2958446
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 3. Initial date
TRY.
DATA: lv_date TYPE d.
ep_value = zcl_excel_common=&gt;date_to_excel_string( lv_date ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
DATA exp_value TYPE zexcel_cell_value VALUE 0.
ep_value = zcl_excel_common=&gt;date_to_excel_string( &apos;18991231&apos; ).
zcl_excel_common=&gt;assert_differs(
act = ep_value
exp = exp_value
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;assert_equals(
act = lx_excel-&gt;error
exp = &apos;Index out of bounds&apos;
msg = &apos;Dates prior of 1900 are not available in excel&apos;
level = if_aunit_constants=&gt;critical
).
ENDTRY.
ENDMETHOD. &quot;date_To_Excel_String
METHOD encrypt_password.
* ========================
DATA lv_encrypted_pwd TYPE zexcel_aes_password.
TRY.
lv_encrypted_pwd = zcl_excel_common=&gt;encrypt_password( &apos;test&apos; ).
zcl_excel_common=&gt;assert_equals(
act = lv_encrypted_pwd
exp = &apos;CBEB&apos;
msg = &apos;Wrong password encryption&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
ENDMETHOD. &quot;encrypt_Password
METHOD excel_string_to_date.
* ============================
DATA ep_value TYPE d.
* Test 1. Simple test -&gt; ABAP Manage also date prior of 1900
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_date( &apos;0&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;18991231&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;tolerable
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Check around the &quot;Excel Leap Year&quot; 1900
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_date( &apos;59&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;19000228&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_date( &apos;61&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;19000301&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Simple test
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_date( &apos;1&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;19000101&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 3. Index 0 is out of bounds
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_date( &apos;2958446&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;99991212&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 4. Exception should be thrown index out of bounds
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_date( &apos;2958447&apos; ).
zcl_excel_common=&gt;assert_differs(
act = ep_value
exp = &apos;99991212&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;fatal
).
zcl_excel_common=&gt;assert_differs(
act = ep_value
exp = &apos;00000000&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;fatal
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;assert_equals(
act = lx_excel-&gt;error
exp = &apos;Index out of bounds&apos;
msg = &apos;Wrong exception is thrown&apos;
level = if_aunit_constants=&gt;tolerable
).
ENDTRY.
ENDMETHOD. &quot;excel_String_To_Date
METHOD excel_string_to_time.
* ============================
DATA ep_value TYPE t.
* Test 1. Simple test
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_time( &apos;0&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;000000&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;tolerable
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Simple test
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_time( &apos;1&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;000000&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 3. Simple test
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_time( &apos;0.99999&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;235959&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 4. Also string greater than 1 should be managed
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_time( &apos;4.1&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;022400&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 4. string is not a number
TRY.
ep_value = zcl_excel_common=&gt;excel_string_to_time( &apos;NaN&apos; ).
zcl_excel_common=&gt;assert_differs(
act = ep_value
exp = &apos;000000&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;assert_equals(
act = lx_excel-&gt;error
exp = &apos;Unable to interpret time&apos;
msg = &apos;Time should be a valid string&apos;
level = if_aunit_constants=&gt;fatal
).
ENDTRY.
ENDMETHOD. &quot;excel_String_To_Time
METHOD time_to_excel_string.
* ============================
DATA ep_value TYPE zexcel_cell_value.
* Test 1. Basic conversion
TRY.
ep_value = zcl_excel_common=&gt;time_to_excel_string( &apos;000001&apos; ).
&quot; A test directly in Excel returns the value 0.0000115740740740741000
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;0.0000115740740741&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
ep_value = zcl_excel_common=&gt;time_to_excel_string( &apos;235959&apos; ).
&quot; A test directly in Excel returns the value 0.9999884259259260000000
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;0.9999884259259260&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 3. Initial date
TRY.
ep_value = zcl_excel_common=&gt;time_to_excel_string( &apos;000000&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;0&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
ep_value = zcl_excel_common=&gt;time_to_excel_string( &apos;022400&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_value
exp = &apos;0.1000000000000000&apos;
msg = &apos;Wrong date conversion&apos;
level = if_aunit_constants=&gt;critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;unexpected exception&apos;
level = if_aunit_constants=&gt;critical &quot; Error Severity
).
ENDTRY.
ENDMETHOD. &quot;time_To_Excel_String
METHOD split_file.
* ============================
DATA: ep_file TYPE text255,
ep_extension TYPE char10,
ep_dotextension TYPE char10.
* Test 1. Basic conversion
zcl_excel_common=&gt;split_file( EXPORTING ip_file = &apos;filename.xml&apos;
IMPORTING ep_file = ep_file
ep_extension = ep_extension
ep_dotextension = ep_dotextension ).
zcl_excel_common=&gt;assert_equals(
act = ep_file
exp = &apos;filename&apos;
msg = &apos;Split filename failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = ep_extension
exp = &apos;xml&apos;
msg = &apos;Split extension failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = ep_dotextension
exp = &apos;.xml&apos;
msg = &apos;Split extension failed&apos;
level = if_aunit_constants=&gt;critical ).
* Test 2. no extension
zcl_excel_common=&gt;split_file( EXPORTING ip_file = &apos;filename&apos;
IMPORTING ep_file = ep_file
ep_extension = ep_extension
ep_dotextension = ep_dotextension ).
zcl_excel_common=&gt;assert_equals(
act = ep_file
exp = &apos;filename&apos;
msg = &apos;Split filename failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = ep_extension
exp = &apos;&apos;
msg = &apos;Split extension failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = ep_dotextension
exp = &apos;&apos;
msg = &apos;Split extension failed&apos;
level = if_aunit_constants=&gt;critical ).
ENDMETHOD. &quot;split_file
METHOD convert_range2column_a_row.
DATA: lv_range TYPE string.
DATA: lv_column_start TYPE zexcel_cell_column_alpha,
lv_column_end TYPE zexcel_cell_column_alpha,
lv_row_start TYPE zexcel_cell_row,
lv_row_end TYPE zexcel_cell_row,
lv_sheet TYPE string.
* a) input empty --&gt; nothing to do
zcl_excel_common=&gt;convert_range2column_a_row(
EXPORTING
i_range = lv_range
IMPORTING
e_column_start = lv_column_start &quot; Cell Column Start
e_column_end = lv_column_end &quot; Cell Column End
e_row_start = lv_row_start &quot; Cell Row
e_row_end = lv_row_end &quot; Cell Row
e_sheet = lv_sheet &quot; Title
).
zcl_excel_common=&gt;assert_equals(
act = lv_column_start
exp = &apos;&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_column_end
exp = &apos;&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_start
exp = &apos;&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_end
exp = &apos;&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_sheet
exp = &apos;&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
* b) sheetname existing - starts with &apos; example &apos;Sheet 1&apos;!$B$6:$D$13
lv_range = `&apos;Sheet 1&apos;!$B$6:$D$13`.
zcl_excel_common=&gt;convert_range2column_a_row(
EXPORTING
i_range = lv_range
IMPORTING
e_column_start = lv_column_start &quot; Cell Column Start
e_column_end = lv_column_end &quot; Cell Column End
e_row_start = lv_row_start &quot; Cell Row
e_row_end = lv_row_end &quot; Cell Row
e_sheet = lv_sheet &quot; Title
).
zcl_excel_common=&gt;assert_equals(
act = lv_column_start
exp = &apos;B&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_column_end
exp = &apos;D&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_start
exp = &apos;6&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_end
exp = &apos;13&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_sheet
exp = &apos;Sheet 1&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
* c) sheetname existing - does not start with &apos; example Sheet1!$B$6:$D$13
lv_range = `Sheet1!B6:$D$13`.
zcl_excel_common=&gt;convert_range2column_a_row(
EXPORTING
i_range = lv_range
IMPORTING
e_column_start = lv_column_start &quot; Cell Column Start
e_column_end = lv_column_end &quot; Cell Column End
e_row_start = lv_row_start &quot; Cell Row
e_row_end = lv_row_end &quot; Cell Row
e_sheet = lv_sheet &quot; Title
).
zcl_excel_common=&gt;assert_equals(
act = lv_column_start
exp = &apos;B&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_column_end
exp = &apos;D&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_start
exp = &apos;6&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_end
exp = &apos;13&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_sheet
exp = &apos;Sheet1&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
* d) no sheetname - just area example $B$6:$D$13
lv_range = `$B$6:D13`.
zcl_excel_common=&gt;convert_range2column_a_row(
EXPORTING
i_range = lv_range
IMPORTING
e_column_start = lv_column_start &quot; Cell Column Start
e_column_end = lv_column_end &quot; Cell Column End
e_row_start = lv_row_start &quot; Cell Row
e_row_end = lv_row_end &quot; Cell Row
e_sheet = lv_sheet &quot; Title
).
zcl_excel_common=&gt;assert_equals(
act = lv_column_start
exp = &apos;B&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_column_end
exp = &apos;D&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_start
exp = &apos;6&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_row_end
exp = &apos;13&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
zcl_excel_common=&gt;assert_equals(
act = lv_sheet
exp = &apos;&apos;
msg = &apos;Conversion of range failed&apos;
level = if_aunit_constants=&gt;critical ).
ENDMETHOD. &quot;convert_range2column_a_row
METHOD describe_structure.
DATA: ls_test TYPE scarr.
DATA: lo_structdescr TYPE REF TO cl_abap_structdescr.
DATA: lt_structure TYPE ddfields.
FIELD-SYMBOLS: &lt;line&gt; LIKE LINE OF lt_structure.
&quot; Test with DDIC Type
lo_structdescr ?= cl_abap_structdescr=&gt;describe_by_data( p_data = ls_test ).
lt_structure = zcl_excel_common=&gt;describe_structure( io_struct = lo_structdescr ).
READ TABLE lt_structure ASSIGNING &lt;line&gt; INDEX 1.
zcl_excel_common=&gt;assert_equals(
act = &lt;line&gt;-fieldname
exp = &apos;MANDT&apos;
msg = &apos;Describe structure failed&apos;
level = if_aunit_constants=&gt;critical ).
&quot; Test with local defined structure having DDIC and non DDIC elements
TYPES:
BEGIN OF t_test,
carrid TYPE s_carr_id,
carrname TYPE s_carrname,
carrdesc TYPE string,
END OF t_test.
DATA: ls_ttest TYPE t_test.
lo_structdescr ?= cl_abap_structdescr=&gt;describe_by_data( p_data = ls_ttest ).
lt_structure = zcl_excel_common=&gt;describe_structure( io_struct = lo_structdescr ).
READ TABLE lt_structure ASSIGNING &lt;line&gt; INDEX 1.
zcl_excel_common=&gt;assert_equals(
act = &lt;line&gt;-fieldname
exp = &apos;CARRID&apos;
msg = &apos;Describe structure failed&apos;
level = if_aunit_constants=&gt;critical ).
ENDMETHOD. &quot;describe_structure
METHOD calculate_cell_distance.
DATA: lv_offset_rows TYPE i,
lv_offset_cols TYPE i,
lv_message TYPE string.
DEFINE macro_calculate_cell_distance.
zcl_excel_common=&gt;calculate_cell_distance( exporting iv_reference_cell = &amp;1
iv_current_cell = &amp;2
importing ev_row_difference = lv_offset_rows
ev_col_difference = lv_offset_cols ).
* Check delta columns
concatenate &apos;Error calculating column difference in test:&apos;
&amp;1
&apos;-&gt;&apos;
&amp;2
into lv_message separated by space.
zcl_excel_common=&gt;assert_equals( act = lv_offset_cols
exp = &amp;3
msg = lv_message
quit = 0 &quot; continue tests
level = if_aunit_constants=&gt;critical ).
* Check delta rows
concatenate &apos;Error calculating row difference in test:&apos;
&amp;1
&apos;-&gt;&apos;
&amp;2
into lv_message separated by space.
zcl_excel_common=&gt;assert_equals( act = lv_offset_rows
exp = &amp;4
msg = lv_message
quit = 0 &quot; continue tests
level = if_aunit_constants=&gt;critical ).
END-OF-DEFINITION.
macro_calculate_cell_distance:
&apos;C12&apos; &apos;C12&apos; 0 0 , &quot; Same cell
&apos;C12&apos; &apos;C13&apos; 0 1 , &quot; Shift down 1 place
&apos;C12&apos; &apos;C25&apos; 0 13 , &quot; Shift down some places
&apos;C12&apos; &apos;C11&apos; 0 -1 , &quot; Shift up 1 place
&apos;C12&apos; &apos;C1&apos; 0 -11 , &quot; Shift up some place
&apos;C12&apos; &apos;D12&apos; 1 0 , &quot; Shift right 1 place
&apos;C12&apos; &apos;AA12&apos; 24 0 , &quot; Shift right some places
&apos;C12&apos; &apos;B12&apos; -1 0 , &quot; Shift left 1 place
&apos;AA12&apos; &apos;C12&apos; -24 0 , &quot; Shift left some place
&apos;AA121&apos; &apos;C12&apos; -24 -109 . &quot; The full package.
ENDMETHOD. &quot;CALCULATE_CELL_DISTANCE
METHOD shift_formula.
DATA: lv_resulting_formula TYPE string,
lv_message TYPE string,
lv_counter TYPE num8.
DEFINE macro_shift_formula.
add 1 to lv_counter.
clear lv_resulting_formula.
try.
lv_resulting_formula = zcl_excel_common=&gt;shift_formula( iv_reference_formula = &amp;1
iv_shift_cols = &amp;2
iv_shift_rows = &amp;3 ).
concatenate &apos;Wrong result in test&apos;
lv_counter
&apos;shifting formula &apos;
&amp;1
into lv_message separated by space.
zcl_excel_common=&gt;assert_equals( act = lv_resulting_formula
exp = &amp;4
msg = lv_message
quit = 0 &quot; continue tests
level = if_aunit_constants=&gt;critical ).
catch zcx_excel.
concatenate &apos;Unexpected exception occurred in test&apos;
lv_counter
&apos;shifting formula &apos;
&amp;1
into lv_message separated by space.
zcl_excel_common=&gt;assert_equals( act = lv_resulting_formula
exp = &amp;4
msg = lv_message
quit = 0 &quot; continue tests
level = if_aunit_constants=&gt;critical ).
endtry.
END-OF-DEFINITION.
* Test shifts that should result in a valid output
macro_shift_formula:
&apos;C17&apos; 0 0 &apos;C17&apos;, &quot; Very basic check
&apos;C17&apos; 2 3 &apos;E20&apos;, &quot; Check shift right and down
&apos;C17&apos; -2 -3 &apos;A14&apos;, &quot; Check shift left and up
&apos;$C$17&apos; 1 1 &apos;$C$17&apos;, &quot; Fixed columns/rows
&apos;SUM($C17:C$23)+C30&apos; 1 11 &apos;SUM($C28:D$23)+D41&apos;, &quot; Operators and Ranges, mixed fixed rows or columns
&apos;RNGNAME1+C7&apos; -1 -4 &apos;RNGNAME1+B3&apos;, &quot; Operators and Rangename
&apos;&quot;Date:&quot;&amp;TEXT(B2)&apos; 1 1 &apos;&quot;Date:&quot;&amp;TEXT(C3)&apos;, &quot; String literals and string concatenation
&apos;[TEST6.XLSX]SHEET1!A1&apos; 1 11 &apos;[TEST6.XLSX]SHEET1!B12&apos;, &quot; External sheet reference
`X(B13, &quot;KK&quot; ) ` 1 1 `X(C14,&quot;KK&quot;)`, &quot; superflous blanks, multi-argument functions, literals in function, unknown functions
* &apos;SIN((((((B2))))))&apos; 1 1 &apos;SIN((((((C3))))))&apos;, &quot; Deep nesting
* &apos;SIN(SIN(SIN(SIN(E22))))&apos; 0 1 &apos;SIN(SIN(SIN(SIN(E23))))&apos;, &quot; Different type of deep nesting
`SIN(SIN(SIN(SIN(E22))))` 0 1 &apos;SIN(SIN(SIN(SIN(E23))))&apos;, &quot; same as above - but with string input instead of Char-input
&apos;HEUTE()&apos; 2 5 &apos;HEUTE()&apos;, &quot; Functions w/o arguments, No cellreferences
&apos;&quot;B2&quot;&apos; 2 5 &apos;&quot;B2&quot;&apos;, &quot; No cellreferences
&apos;&apos; 2 5 &apos;&apos;, &quot; Empty
&apos;A1+$A1+A$1+$A$1+B2&apos; -1 0 &apos;#REF!+$A1+#REF!+$A$1+A2&apos;, &quot; Referencing error , column only , underflow
&apos;A1+$A1+A$1+$A$1+B2&apos; 0 -1 &apos;#REF!+#REF!+A$1+$A$1+B1&apos;, &quot; Referencing error , row only , underflow
&apos;A1+$A1+A$1+$A$1+B2&apos; -1 -1 &apos;#REF!+#REF!+#REF!+$A$1+A1&apos;. &quot; Referencing error , row and column , underflow
ENDMETHOD. &quot;SHIFT_FORMULA
METHOD is_cell_in_range.
DATA ep_cell_in_range TYPE abap_bool.
* Test 1: upper left corner (in range)
TRY.
ep_cell_in_range = zcl_excel_common=&gt;is_cell_in_range(
ip_column = &apos;B&apos;
ip_row = 2
ip_range = &apos;B2:D4&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_cell_in_range
exp = abap_true
msg = &apos;Check cell in range failed&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;Unexpected exception&apos;
level = if_aunit_constants=&gt;critical ).
ENDTRY.
* Test 2: lower right corner (in range)
TRY.
ep_cell_in_range = zcl_excel_common=&gt;is_cell_in_range(
ip_column = &apos;D&apos;
ip_row = 4
ip_range = &apos;B2:D4&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_cell_in_range
exp = abap_true
msg = &apos;Check cell in range failed&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;Unexpected exception&apos;
level = if_aunit_constants=&gt;critical ).
ENDTRY.
* Test 3: left side (out of range)
TRY.
ep_cell_in_range = zcl_excel_common=&gt;is_cell_in_range(
ip_column = &apos;A&apos;
ip_row = 3
ip_range = &apos;B2:D4&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_cell_in_range
exp = abap_false
msg = &apos;Check cell in range failed&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;Unexpected exception&apos;
level = if_aunit_constants=&gt;critical ).
ENDTRY.
* Test 4: upper side (out of range)
TRY.
ep_cell_in_range = zcl_excel_common=&gt;is_cell_in_range(
ip_column = &apos;C&apos;
ip_row = 1
ip_range = &apos;B2:D4&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_cell_in_range
exp = abap_false
msg = &apos;Check cell in range failed&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;Unexpected exception&apos;
level = if_aunit_constants=&gt;critical ).
ENDTRY.
* Test 5: right side (out of range)
TRY.
ep_cell_in_range = zcl_excel_common=&gt;is_cell_in_range(
ip_column = &apos;E&apos;
ip_row = 3
ip_range = &apos;B2:D4&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_cell_in_range
exp = abap_false
msg = &apos;Check cell in range failed&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;Unexpected exception&apos;
level = if_aunit_constants=&gt;critical ).
ENDTRY.
* Test 6: lower side (out of range)
TRY.
ep_cell_in_range = zcl_excel_common=&gt;is_cell_in_range(
ip_column = &apos;C&apos;
ip_row = 5
ip_range = &apos;B2:D4&apos; ).
zcl_excel_common=&gt;assert_equals(
act = ep_cell_in_range
exp = abap_false
msg = &apos;Check cell in range failed&apos;
level = if_aunit_constants=&gt;critical ).
CATCH zcx_excel.
zcl_excel_common=&gt;fail(
msg = &apos;Unexpected exception&apos;
level = if_aunit_constants=&gt;critical ).
ENDTRY.
ENDMETHOD.
ENDCLASS. &quot;lcl_Excel_Common_Test</localTestClasses>
<textPool>
<language SPRAS="D">
<textElement ID="I" KEY="001" ENTRY="Unerlaubter Bereich" LENGTH="60 "/>
<textElement ID="I" KEY="002" ENTRY="Eingabe nicht korrekt ?escaped? - &amp; Wie zum Geier heißt das" LENGTH="60 "/>
<textElement ID="I" KEY="003" ENTRY="Eingabe konnte nicht als Spaltenname interpretiert werden" LENGTH="60 "/>
<textElement ID="I" KEY="004" ENTRY="Index nicht im erlaubten Bereich" LENGTH="60 "/>
</language>
<language SPRAS="E">
<textElement ID="I" KEY="001" ENTRY="Invalid range" LENGTH="60 "/>
<textElement ID="I" KEY="002" ENTRY="Input not properly escaped - &amp;" LENGTH="60 "/>
<textElement ID="I" KEY="003" ENTRY="Unable to interpret input as column" LENGTH="60 "/>
<textElement ID="I" KEY="004" ENTRY="Index out of bounds" LENGTH="60 "/>
</language>
</textPool>
<typeUsage CLSNAME="ZCL_EXCEL_COMMON" TYPEGROUP="ABAP" VERSION="1" TPUTYPE="0" IMPLICIT="X"/>
<forwardDeclaration>ABAP</forwardDeclaration>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_1900_LEAP_YEAR" VERSION="1" LANGU="E" DESCRIPT="Excel baseline date" EXPOSURE="2" STATE="1" EDITORDER="10 " ATTDECLTYP="2" ATTVALUE="&apos;19000228&apos;" ATTEXPVIRT="0" TYPTYPE="1" TYPE="D" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_BASELINE_DATE" VERSION="1" LANGU="E" DESCRIPT="Excel baseline date" EXPOSURE="2" STATE="1" EDITORDER="1 " ATTDECLTYP="2" ATTVALUE="&apos;19000101&apos;" ATTEXPVIRT="0" TYPTYPE="1" TYPE="D" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_COL_MODULE" VERSION="1" LANGU="E" DESCRIPT="2 byte integer (signed)" EXPOSURE="0" STATE="1" EDITORDER="2 " ATTDECLTYP="1" ATTVALUE="64" ATTEXPVIRT="0" TYPTYPE="1" TYPE="INT2" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_NUMFMT_OFFSET" VERSION="1" LANGU="E" DESCRIPT="2 byte integer (signed)" EXPOSURE="2" STATE="1" EDITORDER="3 " ATTDECLTYP="1" ATTVALUE="164" ATTEXPVIRT="0" TYPTYPE="1" TYPE="INT1" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_SHEET_MAX_COL" VERSION="1" LANGU="E" DESCRIPT="2 byte integer (signed)" EXPOSURE="2" STATE="1" EDITORDER="4 " ATTDECLTYP="2" ATTVALUE="16384" ATTEXPVIRT="0" TYPTYPE="1" TYPE="INT4" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_SHEET_MAX_ROW" VERSION="1" LANGU="E" DESCRIPT="2 byte integer (signed)" EXPOSURE="2" STATE="1" EDITORDER="6 " ATTDECLTYP="2" ATTVALUE="1048576" ATTEXPVIRT="0" TYPTYPE="1" TYPE="INT4" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_SHEET_MIN_COL" VERSION="1" LANGU="E" DESCRIPT="2 byte integer (signed)" EXPOSURE="2" STATE="1" EDITORDER="5 " ATTDECLTYP="2" ATTVALUE="1" ATTEXPVIRT="0" TYPTYPE="1" TYPE="INT4" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_EXCEL_SHEET_MIN_ROW" VERSION="1" LANGU="E" DESCRIPT="2 byte integer (signed)" EXPOSURE="2" STATE="1" EDITORDER="7 " ATTDECLTYP="2" ATTVALUE="1" ATTEXPVIRT="0" TYPTYPE="1" TYPE="INT4" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_SPRAS_EN" VERSION="1" LANGU="E" DESCRIPT="Language Key" EXPOSURE="2" STATE="1" EDITORDER="8 " ATTDECLTYP="1" ATTVALUE="&apos;E&apos;" ATTEXPVIRT="0" TYPTYPE="1" TYPE="SPRAS" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="C_XLSX_FILE_FILTER" VERSION="1" LANGU="E" DESCRIPT="File filter" EXPOSURE="2" STATE="1" EDITORDER="11 " ATTDECLTYP="2" ATTVALUE="&apos;Excel Workbook (*.xlsx)|*.xlsx|&apos;" ATTEXPVIRT="0" TYPTYPE="1" TYPE="STRING" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<attribute CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="O_CONV" VERSION="1" LANGU="E" DESCRIPT="Code Page and Endian Conversion (System Format -&gt; External)" EXPOSURE="2" STATE="1" EDITORDER="9 " ATTDECLTYP="1" ATTEXPVIRT="0" TYPTYPE="3" TYPE="CL_ABAP_CONV_OUT_CE" SRCROW1="0 " SRCCOLUMN1="0 " SRCROW2="0 " SRCCOLUMN2="0 " TYPESRC_LENG="0 "/>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" VERSION="1" LANGU="E" DESCRIPT="Ensure Difference Between 2 (Elementary) data Objects" EXPOSURE="2" STATE="1" EDITORDER="20 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="EXP" VERSION="1" LANGU="E" DESCRIPT="Compare Object with Unexpected Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="SIMPLE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="ACT" VERSION="1" LANGU="E" DESCRIPT="Data Object with Current Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="SIMPLE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="MSG" VERSION="1" LANGU="E" DESCRIPT="Message in Case of Error" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CSEQUENCE" PAROPTIONL="X"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="LEVEL" VERSION="1" LANGU="E" DESCRIPT="Error Severity" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="AUNIT_LEVEL" PARVALUE="IF_AUNIT_CONSTANTS=&gt;CRITICAL"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="TOL" VERSION="1" LANGU="E" DESCRIPT="Tolerance Range for Floating Point Numbers" CMPTYPE="1" MTDTYPE="0" EDITORDER="5 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="F" PAROPTIONL="X"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="QUIT" VERSION="1" LANGU="E" DESCRIPT="Flow Control in Case of Error" CMPTYPE="1" MTDTYPE="0" EDITORDER="6 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="AUNIT_FLOWCTRL" PARVALUE="IF_AUNIT_CONSTANTS=&gt;METHOD"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_DIFFERS" SCONAME="ASSERTION_FAILED" VERSION="1" LANGU="E" DESCRIPT="Condition not met" CMPTYPE="1" MTDTYPE="0" EDITORDER="7 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ABAP_BOOL"/>
<source>method ASSERT_DIFFERS.
DATA: ls_seoclass TYPE seoclass.
&quot; Let see &gt;=7.02
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = &apos;CL_ABAP_UNIT_ASSERT&apos;.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=&gt;assert_differs
EXPORTING
exp = exp
act = act
msg = msg
level = level
tol = tol
quit = quit
RECEIVING
assertion_failed = assertion_failed.
ELSE.
&quot; Let see &gt;=7.00 or even lower
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = &apos;CL_AUNIT_ASSERT&apos;.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=&gt;assert_differs
EXPORTING
exp = exp
act = act
msg = msg
level = level
tol = tol
quit = quit
RECEIVING
assertion_failed = assertion_failed.
ELSE.
* We do nothing for now not supported
ENDIF.
ENDIF.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" VERSION="1" LANGU="E" DESCRIPT="Ensure Equality of Two Data Objects" EXPOSURE="2" STATE="1" EDITORDER="18 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="EXP" VERSION="1" LANGU="E" DESCRIPT="Data Object with Expected Type" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ANY"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="ACT" VERSION="1" LANGU="E" DESCRIPT="Data Object with Current Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ANY"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="MSG" VERSION="1" LANGU="E" DESCRIPT="Message in Case of Error" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CSEQUENCE" PAROPTIONL="X"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="LEVEL" VERSION="1" LANGU="E" DESCRIPT="Error Severity" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="AUNIT_LEVEL" PARVALUE="IF_AUNIT_CONSTANTS=&gt;CRITICAL"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="TOL" VERSION="1" LANGU="E" DESCRIPT="Tolerance Range for Floating Point Numbers" CMPTYPE="1" MTDTYPE="0" EDITORDER="5 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="F" PAROPTIONL="X"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="QUIT" VERSION="1" LANGU="E" DESCRIPT="Flow Control in Case of Error" CMPTYPE="1" MTDTYPE="0" EDITORDER="6 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="AUNIT_FLOWCTRL" PARVALUE="IF_AUNIT_CONSTANTS=&gt;METHOD"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="IGNORE_HASH_SEQUENCE" VERSION="1" LANGU="E" DESCRIPT="Ignore change sequence in hash tables" CMPTYPE="1" MTDTYPE="0" EDITORDER="7 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ABAP_BOOL" PARVALUE="ABAP_FALSE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ASSERT_EQUALS" SCONAME="ASSERTION_FAILED" VERSION="1" LANGU="E" DESCRIPT="Condition not met" CMPTYPE="1" MTDTYPE="0" EDITORDER="8 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ABAP_BOOL"/>
<source>METHOD assert_equals.
DATA: ls_seoclass TYPE seoclass.
&quot; Let see &gt;=7.02
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = &apos;CL_ABAP_UNIT_ASSERT&apos;.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=&gt;assert_equals
EXPORTING
exp = exp
act = act
msg = msg
level = level
tol = tol
quit = quit
ignore_hash_sequence = ignore_hash_sequence
RECEIVING
assertion_failed = assertion_failed.
ELSE.
&quot; Let see &gt;=7.00 or even lower
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = &apos;CL_AUNIT_ASSERT&apos;.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=&gt;assert_equals
EXPORTING
exp = exp
act = act
msg = msg
level = level
tol = tol
quit = quit
ignore_hash_sequence = ignore_hash_sequence
RECEIVING
assertion_failed = assertion_failed.
ELSE.
* We do nothing for now not supported
ENDIF.
ENDIF.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CALCULATE_CELL_DISTANCE" VERSION="1" LANGU="E" DESCRIPT="Give distance between two cells" EXPOSURE="2" STATE="1" EDITORDER="22 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CALCULATE_CELL_DISTANCE" SCONAME="IV_REFERENCE_CELL" VERSION="1" LANGU="E" DESCRIPT="Reference Cell" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CALCULATE_CELL_DISTANCE" SCONAME="IV_CURRENT_CELL" VERSION="1" LANGU="E" DESCRIPT="Current Cell" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CALCULATE_CELL_DISTANCE" SCONAME="EV_ROW_DIFFERENCE" VERSION="1" LANGU="E" DESCRIPT="Number of rows current cell is below reference cell" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="I"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CALCULATE_CELL_DISTANCE" SCONAME="EV_COL_DIFFERENCE" VERSION="1" LANGU="E" DESCRIPT="Number of columns current cell is right of reference cell" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="I"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CALCULATE_CELL_DISTANCE" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>METHOD calculate_cell_distance.
DATA: lv_reference_row TYPE i,
lv_reference_col_alpha TYPE zexcel_cell_column_alpha,
lv_reference_col TYPE i,
lv_current_row TYPE i,
lv_current_col_alpha TYPE zexcel_cell_column_alpha,
lv_current_col TYPE i.
*--------------------------------------------------------------------*
* Split reference cell into numerical row/column representation
*--------------------------------------------------------------------*
convert_columnrow2column_a_row( EXPORTING
i_columnrow = iv_reference_cell
IMPORTING
e_column = lv_reference_col_alpha
e_row = lv_reference_row ).
lv_reference_col = convert_column2int( lv_reference_col_alpha ).
*--------------------------------------------------------------------*
* Split current cell into numerical row/column representation
*--------------------------------------------------------------------*
convert_columnrow2column_a_row( EXPORTING
i_columnrow = iv_current_cell
IMPORTING
e_column = lv_current_col_alpha
e_row = lv_current_row ).
lv_current_col = convert_column2int( lv_current_col_alpha ).
*--------------------------------------------------------------------*
* Calculate row and column difference
* Positive: Current cell below reference cell
* or Current cell right of reference cell
* Negative: Current cell above reference cell
* or Current cell left of reference cell
*--------------------------------------------------------------------*
ev_row_difference = lv_current_row - lv_reference_row.
ev_col_difference = lv_current_col - lv_reference_col.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CHAR2HEX" VERSION="1" LANGU="E" DESCRIPT="Character to Hexadecimal" EXPOSURE="0" STATE="1" EDITORDER="3 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CHAR2HEX" SCONAME="I_CHAR" VERSION="1" LANGU="E" DESCRIPT="Single-Character Indicator" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CHAR1"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CHAR2HEX" SCONAME="R_HEX" VERSION="1" LANGU="E" DESCRIPT="Password hash" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_PWD_HASH"/>
<source>method CHAR2HEX.
IF o_conv IS NOT BOUND.
o_conv = cl_abap_conv_out_ce=&gt;create( endian = &apos;L&apos;
ignore_cerr = abap_true
replacement = &apos;#&apos; ).
ENDIF.
CALL METHOD o_conv-&gt;reset( ).
CALL METHOD o_conv-&gt;write( data = i_char ).
r_hex+1 = o_conv-&gt;get_buffer( ). &quot; x&apos;65&apos; must be x&apos;0065&apos;
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2ALPHA" VERSION="1" LANGU="E" DESCRIPT="Convert column indicator to Alpha" EXPOSURE="2" STATE="1" EDITORDER="2 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2ALPHA" SCONAME="IP_COLUMN" VERSION="1" LANGU="E" DESCRIPT="Cell Column" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="SIMPLE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2ALPHA" SCONAME="EP_COLUMN" VERSION="1" LANGU="E" DESCRIPT="Cell Column" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_CELL_COLUMN_ALPHA"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2ALPHA" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>METHOD convert_column2alpha.
DATA: lv_uccpi TYPE i,
lv_text TYPE sychar02,
lv_module TYPE int4,
lv_column TYPE zexcel_cell_column.
* Propagate zcx_excel if error occurs &quot; issue #155 - less restrictive typing for ip_column
lv_column = convert_column2int( ip_column ). &quot; issue #155 - less restrictive typing for ip_column
*--------------------------------------------------------------------*
* Check whether column is in allowed range for EXCEL to handle ( 1-16384 )
*--------------------------------------------------------------------*
IF lv_column &gt; 16384
OR lv_column &lt; 1.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = &apos;Index out of bounds&apos;.
ENDIF.
*--------------------------------------------------------------------*
* Build alpha representation of column
*--------------------------------------------------------------------*
WHILE lv_column GT 0.
lv_module = ( lv_column - 1 ) MOD 26.
lv_uccpi = 65 + lv_module.
lv_column = ( lv_column - lv_module ) / 26.
lv_text = cl_abap_conv_in_ce=&gt;uccpi( lv_uccpi ).
CONCATENATE lv_text ep_column INTO ep_column.
ENDWHILE.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2INT" VERSION="1" LANGU="E" DESCRIPT="Convert column indicator to Integer" EXPOSURE="2" STATE="1" EDITORDER="3 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2INT" SCONAME="IP_COLUMN" VERSION="1" LANGU="E" DESCRIPT="Cell Column" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="SIMPLE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2INT" SCONAME="EP_COLUMN" VERSION="1" LANGU="E" DESCRIPT="Cell Column" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_CELL_COLUMN"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMN2INT" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>METHOD convert_column2int.
*--------------------------------------------------------------------*
* issue #230 - Pimp my Code
* - Stefan Schmöcker, (done) 2012-12-29
* - ...
* changes: renaming variables to naming conventions
* removing unused variables
* removing commented out code that is inactive for more then half a year
* message made to support multilinguality
* adding comments to explain what we are trying to achieve
*--------------------------------------------------------------------*
* issue#246 - error converting lower case column names
* - Stefan Schmöcker, 2012-12-29
* changes: translating the correct variable to upper dase
* adding missing exception if input is a number
* that is out of bounds
* adding missing exception if input contains
* illegal characters like german umlauts
*--------------------------------------------------------------------*
DATA: lv_column TYPE zexcel_cell_column_alpha,
lv_column_c TYPE char10,
lv_column_s TYPE string,
lv_errormessage TYPE string, &quot; Can&apos;t pass &apos;...&apos;(abc) to exception-class
lv_modulo TYPE i.
*--------------------------------------------------------------------*
* This module tries to identify which column a user wants to access
* Numbers as input are just passed back, anything else will be converted
* using EXCEL nomenclatura A = 1, AA = 27, ..., XFD = 16384
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* Normalize input ( upper case , no gaps )
*--------------------------------------------------------------------*
lv_column_c = ip_column.
* TRANSLATE lv_column TO UPPER CASE. &quot; Fix #246
TRANSLATE lv_column_c TO UPPER CASE. &quot; Fix #246
CONDENSE lv_column_c NO-GAPS.
IF lv_column_c EQ &apos;&apos;.
* lv_errormessage = &apos;Unable to interpret input as column&apos;(003).
* RAISE EXCEPTION TYPE zcx_excel
* EXPORTING
* error = lv_errormessage.
MESSAGE e800(zabap2xlsx) INTO lv_errormessage.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
syst_at_raise = syst.
ENDIF.
*--------------------------------------------------------------------*
* If a number gets passed, just convert it to an integer and return
* the converted value
*--------------------------------------------------------------------*
TRY.
IF lv_column_c CO &apos;1234567890 &apos;. &quot; Fix #164
ep_column = lv_column_c. &quot; Fix #164
*--------------------------------------------------------------------*
* Maximum column for EXCEL: XFD = 16384 &quot; if anyone has a reference for this information - please add here instead of this comment
*--------------------------------------------------------------------*
IF ep_column &gt; 16384 OR ep_column &lt; 1.
lv_errormessage = &apos;Index out of bounds&apos;(004).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
EXIT.
ENDIF.
CATCH cx_sy_conversion_no_number. &quot;#EC NO_HANDLER
&quot; Try the character-approach if approach via number has failed
ENDTRY.
*--------------------------------------------------------------------*
* Raise error if unexpected characters turns up
*--------------------------------------------------------------------*
lv_column_s = lv_column_c.
IF lv_column_s CN sy-abcde.
* lv_errormessage = &apos;Unable to interpret input as column&apos;(003).
* RAISE EXCEPTION TYPE zcx_excel
* EXPORTING
* error = lv_errormessage.
MESSAGE e800(zabap2xlsx) INTO lv_errormessage.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
syst_at_raise = syst.
ENDIF.
*--------------------------------------------------------------------*
* Interpret input as number to base 26 with A=1, ... Z=26
* Raise error if unexpected character turns up
*--------------------------------------------------------------------*
* 1st character
*--------------------------------------------------------------------*
lv_column = lv_column_c.
lv_modulo = cl_abap_conv_out_ce=&gt;uccpi( lv_column+0(1) ) MOD zcl_excel_common=&gt;c_excel_col_module.
IF lv_modulo &lt; 1 OR lv_modulo &gt; 26.
* lv_errormessage = &apos;Unable to interpret input as column&apos;(003).
* RAISE EXCEPTION TYPE zcx_excel
* EXPORTING
* error = lv_errormessage.
MESSAGE e800(zabap2xlsx) INTO lv_errormessage.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
syst_at_raise = syst.
ENDIF.
ep_column = lv_modulo. &quot; Leftmost digit
*--------------------------------------------------------------------*
* 2nd character if present
*--------------------------------------------------------------------*
CHECK lv_column+1(1) IS NOT INITIAL. &quot; No need to continue if string ended
lv_modulo = cl_abap_conv_out_ce=&gt;uccpi( lv_column+1(1) ) MOD zcl_excel_common=&gt;c_excel_col_module.
IF lv_modulo &lt; 1 OR lv_modulo &gt; 26.
* lv_errormessage = &apos;Unable to interpret input as column&apos;(003).
* RAISE EXCEPTION TYPE zcx_excel
* EXPORTING
* error = lv_errormessage.
MESSAGE e800(zabap2xlsx) INTO lv_errormessage.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
syst_at_raise = syst.
ENDIF.
ep_column = 26 * ep_column + lv_modulo. &quot; if second digit is present first digit is for 26^1
*--------------------------------------------------------------------*
* 3rd character if present
*--------------------------------------------------------------------*
CHECK lv_column+2(1) IS NOT INITIAL. &quot; No need to continue if string ended
lv_modulo = cl_abap_conv_out_ce=&gt;uccpi( lv_column+2(1) ) MOD zcl_excel_common=&gt;c_excel_col_module.
IF lv_modulo &lt; 1 OR lv_modulo &gt; 26.
* lv_errormessage = &apos;Unable to interpret input as column&apos;(003).
* RAISE EXCEPTION TYPE zcx_excel
* EXPORTING
* error = lv_errormessage.
MESSAGE e800(zabap2xlsx) INTO lv_errormessage.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
syst_at_raise = syst.
ENDIF.
ep_column = 26 * ep_column + lv_modulo. &quot; if third digit is present first digit is for 26^2 and second digit for 26^1
*--------------------------------------------------------------------*
* Maximum column for EXCEL: XFD = 16384 &quot; if anyone has a reference for this information - please add here instead of this comment
*--------------------------------------------------------------------*
IF ep_column &gt; 16384 OR ep_column &lt; 1.
lv_errormessage = &apos;Index out of bounds&apos;(004).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMNROW2COLUMN_A_ROW" VERSION="1" LANGU="E" DESCRIPT="Convert ColumnRow i.e. AB34 to AB and 34" EXPOSURE="2" STATE="1" EDITORDER="4 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMNROW2COLUMN_A_ROW" SCONAME="I_COLUMNROW" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMNROW2COLUMN_A_ROW" SCONAME="E_COLUMN" VERSION="1" LANGU="E" DESCRIPT="Cell Column" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_COLUMN_ALPHA"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_COLUMNROW2COLUMN_A_ROW" SCONAME="E_ROW" VERSION="1" LANGU="E" DESCRIPT="Natural number" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_ROW"/>
<source>method CONVERT_COLUMNROW2COLUMN_A_ROW.
*--------------------------------------------------------------------*
&quot;issue #256 - replacing char processing with regex
*--------------------------------------------------------------------*
* Stefan Schmöcker, 2013-08-11
* Allow input to be CLIKE instead of STRING
*--------------------------------------------------------------------*
DATA: pane_cell_row_a TYPE string,
lv_columnrow type string.
lv_columnrow = i_columnrow. &quot; Get rid of trailing blanks
FIND REGEX &apos;^(\D+)(\d+)$&apos; IN lv_columnrow SUBMATCHES e_column
pane_cell_row_a.
e_row = pane_cell_row_a.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" VERSION="1" LANGU="E" DESCRIPT="Converts Sheet1!AB34:CD56 to Sheet1, AB, 34, CD, 56" EXPOSURE="2" STATE="1" EDITORDER="5 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="I_RANGE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="E_COLUMN_START" VERSION="1" LANGU="E" DESCRIPT="Cell Column Start" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_COLUMN_ALPHA"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="E_COLUMN_END" VERSION="1" LANGU="E" DESCRIPT="Cell Column End" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_COLUMN_ALPHA"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="E_ROW_START" VERSION="1" LANGU="E" DESCRIPT="Cell Row" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_ROW"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="E_ROW_END" VERSION="1" LANGU="E" DESCRIPT="Cell Row" CMPTYPE="1" MTDTYPE="0" EDITORDER="5 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_ROW"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="E_SHEET" VERSION="1" LANGU="E" DESCRIPT="Title" CMPTYPE="1" MTDTYPE="0" EDITORDER="6 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="CONVERT_RANGE2COLUMN_A_ROW" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>method CONVERT_RANGE2COLUMN_A_ROW.
*--------------------------------------------------------------------*
* issue #230 - Pimp my Code
* - Stefan Schmöcker, (done) 2012-12-07
* - ...
* changes: renaming variables to naming conventions
* aligning code
* added exceptionclass
* added errorhandling for invalid range
* adding comments to explain what we are trying to achieve
*--------------------------------------------------------------------*
* issue#241 - error when sheetname contains &quot;!&quot;
* - sheetname should be returned unescaped
* - Stefan Schmöcker, 2012-12-07
* changes: changed coding to support sheetnames with &quot;!&quot;
* unescaping sheetname
*--------------------------------------------------------------------*
* issue#155 - lessening restrictions of input parameters
* - Stefan Schmöcker, 2012-12-07
* changes: i_range changed to clike
* e_sheet changed to clike
*--------------------------------------------------------------------*
DATA: lv_sheet TYPE string,
lv_range TYPE string,
lv_columnrow_start TYPE string,
lv_columnrow_end TYPE string,
lv_errormessage TYPE string. &quot; Can&apos;t pass &apos;...&apos;(abc) to exception-class
*--------------------------------------------------------------------*
* Split input range into sheetname and Area
* 4 cases - a) input empty --&gt; nothing to do
* - b) sheetname existing - starts with &apos; example &apos;Sheet 1&apos;!$B$6:$D$13
* - c) sheetname existing - does not start with &apos; example Sheet1!$B$6:$D$13
* - d) no sheetname - just area example $B$6:$D$13
*--------------------------------------------------------------------*
* Initialize output parameters
CLEAR: e_column_start,
e_column_end,
e_row_start,
e_row_end,
e_sheet.
IF i_range IS INITIAL. &quot; a) input empty --&gt; nothing to do
EXIT.
ELSEIF i_range(1) = `&apos;`. &quot; b) sheetname existing - starts with &apos;
FIND REGEX &apos;\![^\!]*$&apos; IN i_range MATCH OFFSET sy-fdpos. &quot; Find last !
IF sy-subrc = 0.
lv_sheet = i_range(sy-fdpos).
ADD 1 TO sy-fdpos.
lv_range = i_range.
SHIFT lv_range LEFT BY sy-fdpos PLACES.
ELSE.
lv_errormessage = &apos;Invalid range&apos;(001).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
ELSEIF i_range CS &apos;!&apos;. &quot; c) sheetname existing - does not start with &apos;
SPLIT i_range AT &apos;!&apos; INTO lv_sheet lv_range.
ELSE. &quot; d) no sheetname - just area
lv_range = i_range.
ENDIF.
REPLACE ALL OCCURRENCES OF &apos;$&apos; IN lv_range WITH &apos;&apos;.
SPLIT lv_range AT &apos;:&apos; INTO lv_columnrow_start lv_columnrow_end.
convert_columnrow2column_a_row( EXPORTING
i_columnrow = lv_columnrow_start
IMPORTING
e_column = e_column_start
e_row = e_row_start ).
convert_columnrow2column_a_row( EXPORTING
i_columnrow = lv_columnrow_end
IMPORTING
e_column = e_column_end
e_row = e_row_end ).
e_sheet = unescape_string( lv_sheet ). &quot; Return in unescaped form
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DATE_TO_EXCEL_STRING" VERSION="1" LANGU="E" DESCRIPT="Convert date from SAP format to Excel" EXPOSURE="2" STATE="1" EDITORDER="6 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DATE_TO_EXCEL_STRING" SCONAME="IP_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="D"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DATE_TO_EXCEL_STRING" SCONAME="EP_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_CELL_VALUE"/>
<source>method DATE_TO_EXCEL_STRING.
DATA: lv_date_diff TYPE i.
CHECK ip_value IS NOT INITIAL.
&quot; Needed hack caused by the problem that:
&quot; Excel 2000 incorrectly assumes that the year 1900 is a leap year
&quot; http://support.microsoft.com/kb/214326/en-us
IF ip_value &gt; c_excel_1900_leap_year.
lv_date_diff = ip_value - c_excel_baseline_date + 2.
ELSE.
lv_date_diff = ip_value - c_excel_baseline_date + 1.
ENDIF.
ep_value = zcl_excel_common=&gt;number_to_excel_string( ip_value = lv_date_diff ).
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DESCRIBE_STRUCTURE" VERSION="1" LANGU="E" DESCRIPT="Describe database info of structure" EXPOSURE="2" STATE="1" EDITORDER="1 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DESCRIBE_STRUCTURE" SCONAME="IO_STRUCT" VERSION="1" LANGU="E" DESCRIPT="Runtime Type Services" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="3" TYPE="CL_ABAP_STRUCTDESCR"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DESCRIBE_STRUCTURE" SCONAME="RT_DFIES" VERSION="1" LANGU="E" DESCRIPT="DD Interface: Table Fields for DDIF_FIELDINFO_GET" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="DDFIELDS"/>
<source>method DESCRIBE_STRUCTURE.
DATA: lt_components TYPE abap_component_tab,
lt_comps TYPE abap_component_tab,
lo_struct TYPE REF TO cl_abap_structdescr,
ls_component TYPE abap_componentdescr,
lo_elemdescr TYPE REF TO cl_abap_elemdescr,
ls_dfies TYPE dfies,
l_position TYPE tabfdpos.
&quot;for DDIC structure get the info directly
IF io_struct-&gt;is_ddic_type( ) = abap_true.
rt_dfies = io_struct-&gt;get_ddic_field_list( ).
ELSE.
lt_components = io_struct-&gt;get_components( ).
LOOP AT lt_components INTO ls_component.
structure_case( EXPORTING is_component = ls_component
CHANGING xt_components = lt_comps ) .
ENDLOOP.
LOOP AT lt_comps INTO ls_component.
CLEAR ls_dfies.
IF ls_component-type-&gt;kind = cl_abap_typedescr=&gt;kind_elem. &quot;E Elementary Type
ADD 1 TO l_position.
lo_elemdescr ?= ls_component-type.
IF lo_elemdescr-&gt;is_ddic_type( ) = abap_true.
ls_dfies = lo_elemdescr-&gt;get_ddic_field( ).
ls_dfies-fieldname = ls_component-name.
ls_dfies-position = l_position.
ELSE.
ls_dfies-fieldname = ls_component-name.
ls_dfies-position = l_position.
ls_dfies-inttype = lo_elemdescr-&gt;type_kind.
ls_dfies-leng = lo_elemdescr-&gt;length.
ls_dfies-outputlen = lo_elemdescr-&gt;length.
ls_dfies-decimals = lo_elemdescr-&gt;decimals.
ls_dfies-fieldtext = ls_component-name.
ls_dfies-reptext = ls_component-name.
ls_dfies-scrtext_s = ls_component-name.
ls_dfies-scrtext_m = ls_component-name.
ls_dfies-scrtext_l = ls_component-name.
ls_dfies-dynpfld = abap_true.
ENDIF.
INSERT ls_dfies INTO TABLE rt_dfies.
ENDIF.
ENDLOOP.
ENDIF.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DETERMINE_RESULTING_FORMULA" VERSION="1" LANGU="E" DESCRIPT="Determine formula if copied to another cell" EXPOSURE="2" STATE="1" EDITORDER="23 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DETERMINE_RESULTING_FORMULA" SCONAME="IV_REFERENCE_CELL" VERSION="1" LANGU="E" DESCRIPT="Reference cell" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DETERMINE_RESULTING_FORMULA" SCONAME="IV_REFERENCE_FORMULA" VERSION="1" LANGU="E" DESCRIPT="Reference formula" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DETERMINE_RESULTING_FORMULA" SCONAME="IV_CURRENT_CELL" VERSION="1" LANGU="E" DESCRIPT="Current cell" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DETERMINE_RESULTING_FORMULA" SCONAME="EV_RESULTING_FORMULA" VERSION="1" LANGU="E" DESCRIPT="Resulting formula" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="STRING"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="DETERMINE_RESULTING_FORMULA" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>METHOD determine_resulting_formula.
DATA: lv_row_difference TYPE i,
lv_col_difference TYPE i.
*--------------------------------------------------------------------*
* Calculate distance of reference and current cell
*--------------------------------------------------------------------*
calculate_cell_distance( EXPORTING
iv_reference_cell = iv_reference_cell
iv_current_cell = iv_current_cell
IMPORTING
ev_row_difference = lv_row_difference
ev_col_difference = lv_col_difference ).
*--------------------------------------------------------------------*
* and shift formula by using the row- and columndistance
*--------------------------------------------------------------------*
ev_resulting_formula = shift_formula( iv_reference_formula = iv_reference_formula
iv_shift_rows = lv_row_difference
iv_shift_cols = lv_col_difference ).
ENDMETHOD. &quot;determine_resulting_formula</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ENCRYPT_PASSWORD" VERSION="1" LANGU="E" DESCRIPT="Encrypt password" EXPOSURE="2" STATE="1" EDITORDER="7 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ENCRYPT_PASSWORD" SCONAME="I_PWD" VERSION="1" LANGU="E" DESCRIPT="AES Password" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_AES_PASSWORD"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ENCRYPT_PASSWORD" SCONAME="R_ENCRYPTED_PWD" VERSION="1" LANGU="E" DESCRIPT="AES Password" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_AES_PASSWORD"/>
<source>method ENCRYPT_PASSWORD.
DATA lv_curr_offset TYPE i.
DATA lv_curr_char TYPE c LENGTH 1.
DATA lv_curr_hex TYPE zexcel_pwd_hash.
DATA lv_pwd_len TYPE zexcel_pwd_hash.
DATA lv_pwd_hash TYPE zexcel_pwd_hash.
CONSTANTS:
lv_0x7fff TYPE zexcel_pwd_hash VALUE &apos;7FFF&apos;,
lv_0x0001 TYPE zexcel_pwd_hash VALUE &apos;0001&apos;,
lv_0xce4b TYPE zexcel_pwd_hash VALUE &apos;CE4B&apos;.
DATA lv_pwd TYPE zexcel_aes_password.
lv_pwd = i_pwd(15).
lv_pwd_len = STRLEN( lv_pwd ).
lv_curr_offset = lv_pwd_len - 1.
WHILE lv_curr_offset GE 0.
lv_curr_char = lv_pwd+lv_curr_offset(1).
lv_curr_hex = char2hex( lv_curr_char ).
lv_pwd_hash = ( shr14( lv_pwd_hash ) BIT-AND lv_0x0001 ) BIT-OR ( shl01( lv_pwd_hash ) BIT-AND lv_0x7fff ).
lv_pwd_hash = lv_pwd_hash BIT-XOR lv_curr_hex.
SUBTRACT 1 FROM lv_curr_offset.
ENDWHILE.
lv_pwd_hash = ( shr14( lv_pwd_hash ) BIT-AND lv_0x0001 ) BIT-OR ( shl01( lv_pwd_hash ) BIT-AND lv_0x7fff ).
lv_pwd_hash = lv_pwd_hash BIT-XOR lv_0xce4b.
lv_pwd_hash = lv_pwd_hash BIT-XOR lv_pwd_len.
WRITE lv_pwd_hash TO r_encrypted_pwd.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ESCAPE_STRING" VERSION="1" LANGU="E" DESCRIPT="Escape a string" EXPOSURE="2" STATE="1" EDITORDER="8 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ESCAPE_STRING" SCONAME="IP_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="ESCAPE_STRING" SCONAME="EP_ESCAPED_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="STRING"/>
<source>method ESCAPE_STRING.
*--------------------------------------------------------------------*
* issue #230 - Pimp my Code
* - Stefan Schmöcker, (done) 2012-12-08
* - ...
* changes: aligning code
* adding comments to explain what we are trying to achieve
*--------------------------------------------------------------------*
* issue#242 - Support escaping for white-spaces
* - Escaping also necessary when &apos; encountered in input
* - Stefan Schmöcker, 2012-12-08
* changes: switched check if escaping is necessary to regular expression
* and moved the &quot;REPLACE&quot;
*--------------------------------------------------------------------*
* issue#155 - lessening restrictions of input parameters
* - Stefan Schmöcker, 2012-12-08
* changes: ip_value changed to clike
*--------------------------------------------------------------------*
DATA: lv_value TYPE string.
*--------------------------------------------------------------------*
* There exist various situations when a space will be used to separate
* different parts of a string. When we have a string consisting spaces
* that will cause errors unless we &quot;escape&quot; the string by putting &apos; at
* the beginning and at the end of the string.
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* When allowing clike-input parameters we might encounter trailing
* &quot;real&quot; blanks . These are automatically eliminated when moving
* the input parameter to a string.
* Now any remaining spaces ( white-spaces or normal spaces ) should
* trigger the escaping as well as any &apos;
*--------------------------------------------------------------------*
lv_value = ip_value.
FIND REGEX `\s|&apos;` IN lv_value. &quot; \s finds regular and white spaces
IF sy-subrc = 0.
REPLACE ALL OCCURRENCES OF `&apos;` IN lv_value WITH `&apos;&apos;`.
CONCATENATE `&apos;` lv_value `&apos;` INTO lv_value .
ENDIF.
ep_escaped_value = lv_value.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_DATE" VERSION="1" LANGU="E" DESCRIPT="Convert date from Excel format to SAP" EXPOSURE="2" STATE="1" EDITORDER="10 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_DATE" SCONAME="IP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Cell Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_VALUE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_DATE" SCONAME="EP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Date" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="D"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_DATE" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>method EXCEL_STRING_TO_DATE.
DATA: lv_date_int TYPE i.
TRY.
lv_date_int = ip_value.
ep_value = lv_date_int + c_excel_baseline_date - 2.
&quot; Needed hack caused by the problem that:
&quot; Excel 2000 incorrectly assumes that the year 1900 is a leap year
&quot; http://support.microsoft.com/kb/214326/en-us
IF ep_value &lt; c_excel_1900_leap_year.
ep_value = ep_value + 1.
ENDIF.
CATCH cx_sy_conversion_error.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = &apos;Index out of bounds&apos;.
ENDTRY.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_NUMBER" VERSION="1" LANGU="E" DESCRIPT="Convert number from Excel format to SAP" EXPOSURE="2" STATE="1" EDITORDER="12 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_NUMBER" SCONAME="IP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Cell Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_VALUE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_NUMBER" SCONAME="EP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Float will do for most situations" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="F"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_NUMBER" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>method EXCEL_STRING_TO_NUMBER.
* If we encounter anything more complicated in EXCEL we might have to extend this
* But currently this works fine - even for numbers in scientific notation
ep_value = ip_value.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_TIME" VERSION="1" LANGU="E" DESCRIPT="Convert time from Excel format to SAP" EXPOSURE="2" STATE="1" EDITORDER="11 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_TIME" SCONAME="IP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Cell Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_VALUE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_TIME" SCONAME="EP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Time" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="T"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="EXCEL_STRING_TO_TIME" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>method EXCEL_STRING_TO_TIME.
DATA: lv_seconds_in_day TYPE i,
lv_day_fraction TYPE f,
lc_seconds_in_day TYPE i VALUE 86400.
TRY.
lv_day_fraction = ip_value.
lv_seconds_in_day = lv_day_fraction * lc_seconds_in_day.
ep_value = lv_seconds_in_day.
CATCH cx_sy_conversion_error.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = &apos;Unable to interpret time&apos;.
ENDTRY.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="FAIL" VERSION="1" LANGU="E" DESCRIPT="Report Unconditional Error" EXPOSURE="2" STATE="1" EDITORDER="19 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="FAIL" SCONAME="MSG" VERSION="1" LANGU="E" DESCRIPT="Error Message" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CSEQUENCE" PAROPTIONL="X"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="FAIL" SCONAME="LEVEL" VERSION="1" LANGU="E" DESCRIPT="Error Severity" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="AUNIT_LEVEL" PARVALUE="IF_AUNIT_CONSTANTS=&gt;CRITICAL"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="FAIL" SCONAME="QUIT" VERSION="1" LANGU="E" DESCRIPT="Flow Control in Case of Error" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="AUNIT_FLOWCTRL" PARVALUE="IF_AUNIT_CONSTANTS=&gt;METHOD"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="FAIL" SCONAME="DETAIL" VERSION="1" LANGU="E" DESCRIPT="Detailed Message" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CSEQUENCE" PAROPTIONL="X"/>
<source>method FAIL.
DATA: ls_seoclass TYPE seoclass.
&quot; Let see &gt;=7.02
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = &apos;CL_ABAP_UNIT_ASSERT&apos;.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=&gt;fail
EXPORTING
msg = msg
level = level
quit = quit
detail = detail.
ELSE.
&quot; Let see &gt;=7.00 or even lower
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = &apos;CL_AUNIT_ASSERT&apos;.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=&gt;fail
EXPORTING
msg = msg
level = level
quit = quit
detail = detail.
ELSE.
* We do nothing for now not supported
ENDIF.
ENDIF.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="GET_FIELDCATALOG" VERSION="1" LANGU="E" DESCRIPT="Creates field catalog for BIND_TABLE based on internal table" EXPOSURE="2" STATE="1" EDITORDER="13 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="GET_FIELDCATALOG" SCONAME="IP_TABLE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="STANDARD TABLE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="GET_FIELDCATALOG" SCONAME="EP_FIELDCATALOG" VERSION="1" LANGU="E" DESCRIPT="Table binding field catalog" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_T_FIELDCATALOG"/>
<source>method GET_FIELDCATALOG.
DATA: lr_dref_tab TYPE REF TO data,
lo_salv_table TYPE REF TO cl_salv_table,
lo_salv_columns_table TYPE REF TO cl_salv_columns_table,
lt_salv_t_column_ref TYPE salv_t_column_ref,
ls_salv_t_column_ref LIKE LINE OF lt_salv_t_column_ref,
lo_salv_column_table TYPE REF TO cl_salv_column_table.
FIELD-SYMBOLS: &lt;tab&gt; TYPE STANDARD TABLE.
FIELD-SYMBOLS: &lt;fcat&gt; LIKE LINE OF ep_fieldcatalog.
* Get copy of IP_TABLE-structure &lt;-- must be changeable to create salv
CREATE DATA lr_dref_tab LIKE ip_table.
ASSIGN lr_dref_tab-&gt;* TO &lt;tab&gt;.
* Create salv --&gt; implicitly create fieldcat
TRY.
cl_salv_table=&gt;factory( IMPORTING
r_salv_table = lo_salv_table
CHANGING
t_table = &lt;tab&gt; ).
lo_salv_columns_table = lo_salv_table-&gt;get_columns( ).
lt_salv_t_column_ref = lo_salv_columns_table-&gt;get( ).
CATCH cx_root.
* maybe some errorhandling here - just haven&apos;t made up my mind yet
ENDTRY.
* Loop through columns and set relevant fields ( fieldname, texts )
LOOP AT lt_salv_t_column_ref INTO ls_salv_t_column_ref.
lo_salv_column_table ?= ls_salv_t_column_ref-r_column.
APPEND INITIAL LINE TO ep_fieldcatalog ASSIGNING &lt;fcat&gt;.
&lt;fcat&gt;-position = sy-tabix.
&lt;fcat&gt;-fieldname = ls_salv_t_column_ref-columnname.
&lt;fcat&gt;-scrtext_s = ls_salv_t_column_ref-r_column-&gt;get_short_text( ).
&lt;fcat&gt;-scrtext_m = ls_salv_t_column_ref-r_column-&gt;get_medium_text( ).
&lt;fcat&gt;-scrtext_l = ls_salv_t_column_ref-r_column-&gt;get_long_text( ).
&lt;fcat&gt;-dynpfld = &apos;X&apos;. &quot; What in the world would we exclude here?
IF &lt;fcat&gt;-position = 1. &quot; except for the MANDT-field of most tables ( 1st column that is )
IF lo_salv_column_table-&gt;get_ddic_datatype( ) = &apos;CLNT&apos;.
CLEAR &lt;fcat&gt;-dynpfld.
ENDIF.
ENDIF.
* For fields that don&apos;t a description ( i.e. defined by &quot;field type i,&quot; )
* just use the fieldname as description - that is better than nothing
IF &lt;fcat&gt;-scrtext_s IS INITIAL
AND &lt;fcat&gt;-scrtext_m IS INITIAL
AND &lt;fcat&gt;-scrtext_l IS INITIAL.
CONCATENATE &apos;Col:&apos; &lt;fcat&gt;-fieldname INTO &lt;fcat&gt;-scrtext_l SEPARATED BY space.
&lt;fcat&gt;-scrtext_m = &lt;fcat&gt;-scrtext_l.
&lt;fcat&gt;-scrtext_s = &lt;fcat&gt;-scrtext_l.
ENDIF.
ENDLOOP.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="IS_CELL_IN_RANGE" VERSION="1" LANGU="E" DESCRIPT="Check if cell is part of a range" EXPOSURE="2" STATE="1" EDITORDER="25 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="IS_CELL_IN_RANGE" SCONAME="IP_COLUMN" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="SIMPLE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="IS_CELL_IN_RANGE" SCONAME="IP_ROW" VERSION="1" LANGU="E" DESCRIPT="Cell Row" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_CELL_ROW"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="IS_CELL_IN_RANGE" SCONAME="IP_RANGE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="IS_CELL_IN_RANGE" SCONAME="RP_IN_RANGE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ABAP_BOOL"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="IS_CELL_IN_RANGE" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>method IS_CELL_IN_RANGE.
DATA lv_column_start TYPE zexcel_cell_column_alpha.
DATA lv_column_end TYPE zexcel_cell_column_alpha.
DATA lv_row_start TYPE zexcel_cell_row.
DATA lv_row_end TYPE zexcel_cell_row.
DATA lv_column_start_i TYPE zexcel_cell_column.
DATA lv_column_end_i TYPE zexcel_cell_column.
DATA lv_column_i TYPE zexcel_cell_column.
* Split range and convert columns
convert_range2column_a_row(
exporting
i_range = ip_range
IMPORTING
e_column_start = lv_column_start
e_column_end = lv_column_end
e_row_start = lv_row_start
e_row_end = lv_row_end ).
lv_column_start_i = convert_column2int( ip_column = lv_column_start ).
lv_column_end_i = convert_column2int( ip_column = lv_column_end ).
lv_column_i = convert_column2int( ip_column = ip_column ).
* Check if cell is in range
IF lv_column_i &gt;= lv_column_start_i AND
lv_column_i &lt;= lv_column_end_i AND
ip_row &gt;= lv_row_start AND
ip_row &lt;= lv_row_end.
rp_in_range = abap_true.
ENDIF.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="NUMBER_TO_EXCEL_STRING" VERSION="1" LANGU="E" DESCRIPT="Converts number to string representation in Excel format" EXPOSURE="2" STATE="1" EDITORDER="14 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="NUMBER_TO_EXCEL_STRING" SCONAME="IP_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="0" TYPTYPE="1" TYPE="NUMERIC"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="NUMBER_TO_EXCEL_STRING" SCONAME="EP_VALUE" VERSION="1" LANGU="E" DESCRIPT="Cell Value" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_CELL_VALUE"/>
<source>method NUMBER_TO_EXCEL_STRING.
DATA: lv_value_c TYPE c LENGTH 100.
WRITE ip_value TO lv_value_c EXPONENT 0 NO-GROUPING NO-SIGN.
REPLACE ALL OCCURRENCES OF &apos;,&apos; IN lv_value_c WITH &apos;.&apos;.
ep_value = lv_value_c.
CONDENSE ep_value.
IF ip_value &lt; 0.
CONCATENATE &apos;-&apos; ep_value INTO ep_value.
ELSEIF ip_value EQ 0.
ep_value = &apos;0&apos;.
ENDIF.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_CLASS_TO_STRUCT" VERSION="1" LANGU="E" DESCRIPT="Move class to structure" EXPOSURE="2" STATE="1" EDITORDER="15 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_CLASS_TO_STRUCT" SCONAME="I_SOURCE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ANY"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_CLASS_TO_STRUCT" SCONAME="E_TARGET" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="2" PARPASSTYP="1" TYPTYPE="1" TYPE="DATA"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_CLASS_TO_STRUCT" SCONAME="E_TARGETX" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="2" PARPASSTYP="1" TYPTYPE="1" TYPE="DATA"/>
<source>method RECURSIVE_CLASS_TO_STRUCT.
&quot; # issue 139
* is working for me - but after looking through this coding I guess
* I&apos;ll rewrite this to a version w/o recursion
* This is private an no one using it so far except me, so no need to hurry
DATA: descr TYPE REF TO cl_abap_structdescr,
wa_component LIKE LINE OF descr-&gt;components,
attribute_name TYPE fieldname,
flag_class TYPE flag,
o_border TYPE REF TO zcl_excel_style_border.
FIELD-SYMBOLS: &lt;field&gt; TYPE any,
&lt;fieldx&gt; TYPE any,
&lt;class&gt; TYPE REF TO object,
&lt;attribute&gt; TYPE any.
descr ?= cl_abap_structdescr=&gt;describe_by_data( e_target ).
LOOP AT descr-&gt;components INTO wa_component.
* Assign structure and X-structure
ASSIGN COMPONENT wa_component-name OF STRUCTURE e_target TO &lt;field&gt;.
ASSIGN COMPONENT wa_component-name OF STRUCTURE e_targetx TO &lt;fieldx&gt;.
* At least one field in the structure should be marked - otherwise continue with next field
CLEAR flag_class.
* maybe source is just a structure - try assign component...
ASSIGN COMPONENT wa_component-name OF STRUCTURE i_source TO &lt;attribute&gt;.
IF sy-subrc &lt;&gt; 0.
* not - then it is an attribute of the class - use different assign then
CONCATENATE &apos;i_source-&gt;&apos; wa_component-name INTO attribute_name.
ASSIGN (attribute_name) TO &lt;attribute&gt;.
IF sy-subrc &lt;&gt; 0.
EXIT.
ENDIF. &quot; Should not happen if structure is built properly - otherwise just exit to create no dumps
flag_class = abap_true.
ENDIF.
CASE wa_component-type_kind.
WHEN cl_abap_structdescr=&gt;typekind_struct1 OR cl_abap_structdescr=&gt;typekind_struct2. &quot; Structure --&gt; use recursio
* IF flag_class = abap_true.
** Only borders will be passed as unbound references. But since we want to set a value we have to create an instance
* ENDIF.
zcl_excel_common=&gt;recursive_class_to_struct( EXPORTING i_source = &lt;attribute&gt;
CHANGING e_target = &lt;field&gt;
e_targetx = &lt;fieldx&gt; ).
WHEN OTHERS.
&lt;field&gt; = &lt;attribute&gt;.
&lt;fieldx&gt; = abap_true.
ENDCASE.
ENDLOOP.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_STRUCT_TO_CLASS" VERSION="1" LANGU="E" DESCRIPT="Move structure to class" EXPOSURE="2" STATE="1" EDITORDER="16 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_STRUCT_TO_CLASS" SCONAME="I_SOURCE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="DATA"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_STRUCT_TO_CLASS" SCONAME="I_SOURCEX" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="DATA"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="RECURSIVE_STRUCT_TO_CLASS" SCONAME="E_TARGET" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="2" PARPASSTYP="1" TYPTYPE="1" TYPE="ANY"/>
<source>METHOD recursive_struct_to_class.
&quot; # issue 139
* is working for me - but after looking through this coding I guess
* I&apos;ll rewrite this to a version w/o recursion
* This is private an no one using it so far except me, so no need to hurry
DATA: descr TYPE REF TO cl_abap_structdescr,
wa_component LIKE LINE OF descr-&gt;components,
attribute_name TYPE fieldname,
flag_class TYPE flag,
o_border TYPE REF TO zcl_excel_style_border.
FIELD-SYMBOLS: &lt;field&gt; TYPE any,
&lt;fieldx&gt; TYPE any,
&lt;class&gt; TYPE REF TO object,
&lt;attribute&gt; TYPE any,
&lt;attribute_s&gt; TYPE ANY TABLE.
descr ?= cl_abap_structdescr=&gt;describe_by_data( i_source ).
LOOP AT descr-&gt;components INTO wa_component.
* Assign structure and X-structure
ASSIGN COMPONENT wa_component-name OF STRUCTURE i_source TO &lt;field&gt;.
ASSIGN COMPONENT wa_component-name OF STRUCTURE i_sourcex TO &lt;fieldx&gt;.
* At least one field in the structure should be marked - otherwise continue with next field
CHECK &lt;fieldx&gt; CA abap_true.
CLEAR flag_class.
* maybe target is just a structure - try assign component...
ASSIGN COMPONENT wa_component-name OF STRUCTURE e_target TO &lt;attribute&gt;.
IF sy-subrc &lt;&gt; 0.
* not - then it is an attribute of the class - use different assign then
CONCATENATE &apos;E_TARGET-&gt;&apos; wa_component-name INTO attribute_name.
ASSIGN (attribute_name) TO &lt;attribute&gt;.
IF sy-subrc &lt;&gt; 0.EXIT.ENDIF. &quot; Should not happen if structure is built properly - otherwise just exit to create no dumps
flag_class = abap_true.
ENDIF.
CASE wa_component-type_kind.
WHEN cl_abap_structdescr=&gt;typekind_struct1 OR cl_abap_structdescr=&gt;typekind_struct2. &quot; Structure --&gt; use recursion
&quot; To avoid dump with attribute GRADTYPE of class ZCL_EXCEL_STYLE_FILL
&quot; quick and really dirty fix -&gt; check the attribute name
&quot; Border has to be initialized somewhere else
IF wa_component-name EQ &apos;GRADTYPE&apos;.
flag_class = abap_false.
ENDIF.
IF flag_class = abap_true AND &lt;attribute&gt; IS INITIAL.
* Only borders will be passed as unbound references. But since we want to set a value we have to create an instance
CREATE OBJECT o_border.
&lt;attribute&gt; = o_border.
ENDIF.
zcl_excel_common=&gt;recursive_struct_to_class( EXPORTING i_source = &lt;field&gt;
i_sourcex = &lt;fieldx&gt;
CHANGING e_target = &lt;attribute&gt; ).
* WHEN cl_abap_structdescr=&gt;typekind_struct2. &quot; String
* CHECK &lt;fieldx&gt; = abap_true. &quot; Marked for change
* &lt;attribute_s&gt; = &lt;field&gt;.
WHEN OTHERS.
CHECK &lt;fieldx&gt; = abap_true. &quot; Marked for change
&lt;attribute&gt; = &lt;field&gt;.
ENDCASE.
ENDLOOP.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHIFT_FORMULA" VERSION="1" LANGU="E" DESCRIPT="Shift formula from one cell to another" EXPOSURE="2" STATE="1" EDITORDER="24 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHIFT_FORMULA" SCONAME="IV_REFERENCE_FORMULA" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHIFT_FORMULA" SCONAME="IV_SHIFT_COLS" VERSION="1" LANGU="E" DESCRIPT="Shift formula right by this many columns" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="0" TYPTYPE="1" TYPE="I"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHIFT_FORMULA" SCONAME="IV_SHIFT_ROWS" VERSION="1" LANGU="E" DESCRIPT="Shift formula down by this many rows" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="0" TYPTYPE="1" TYPE="I"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHIFT_FORMULA" SCONAME="EV_RESULTING_FORMULA" VERSION="1" LANGU="E" DESCRIPT="Resulting formula" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="STRING"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHIFT_FORMULA" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>METHOD shift_formula.
CONSTANTS: lcv_operators TYPE string VALUE &apos;+-/*^%=&lt;&gt;&amp;, !&apos;,
lcv_letters TYPE string VALUE &apos;ABCDEFGHIJKLMNOPQRSTUVWXYZ$&apos;,
lcv_digits TYPE string VALUE &apos;0123456789&apos;,
lcv_cell_reference_error TYPE string VALUE &apos;#REF!&apos;.
DATA: lv_tcnt TYPE i, &quot; Counter variable
lv_tlen TYPE i, &quot; Temp variable length
lv_cnt TYPE i, &quot; Counter variable
lv_cnt2 TYPE i, &quot; Counter variable
lv_offset1 TYPE i, &quot; Character offset
lv_numchars TYPE i, &quot; Number of characters counter
lv_tchar(1) TYPE c, &quot; Temp character
lv_tchar2(1) TYPE c, &quot; Temp character
lv_cur_form(2000) TYPE c, &quot; Formula for current cell
lv_ref_cell_addr TYPE string, &quot; Reference cell address
lv_tcol1 TYPE string, &quot; Temp column letter
lv_tcol2 TYPE string, &quot; Temp column letter
lv_tcoln TYPE i, &quot; Temp column number
lv_trow1 TYPE string, &quot; Temp row number
lv_trow2 TYPE string, &quot; Temp row number
lv_flen TYPE i, &quot; Length of reference formula
lv_tlen2 TYPE i, &quot; Temp variable length
lv_substr1 TYPE string, &quot; Substring variable
lv_abscol TYPE string, &quot; Absolute column symbol
lv_absrow TYPE string, &quot; Absolute row symbol
lv_errormessage TYPE string.
FIELD-SYMBOLS: &lt;find_my_include&gt; TYPE ANY.
*--------------------------------------------------------------------*
* When copying a cell in EXCEL to another cell any inherent formulas
* are copied as well. Cell-references in the formula are being adjusted
* by the distance of the new cell to the original one
*--------------------------------------------------------------------*
* §1 Parse reference formula character by character
* §2 Identify Cell-references
* §3 Shift cell-reference
* §4 Build resulting formula
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* No distance --&gt; Reference = resulting cell/formula
*--------------------------------------------------------------------*
IF iv_shift_cols = 0
AND iv_shift_rows = 0.
ev_resulting_formula = iv_reference_formula.
EXIT. &quot; done
ENDIF.
lv_flen = STRLEN( iv_reference_formula ).
lv_numchars = 1.
*--------------------------------------------------------------------*
* §1 Parse reference formula character by character
*--------------------------------------------------------------------*
DO lv_flen TIMES.
CLEAR: lv_tchar,
lv_substr1,
lv_ref_cell_addr.
lv_cnt2 = lv_cnt + 1.
IF lv_cnt2 &gt; lv_flen.
EXIT. &quot; Done
ENDIF.
*--------------------------------------------------------------------*
* Here we have the current character in the formula
*--------------------------------------------------------------------*
lv_tchar = iv_reference_formula+lv_cnt(1).
*--------------------------------------------------------------------*
* Operators or opening parenthesis will separate possible cellreferences
*--------------------------------------------------------------------*
IF ( lv_tchar CA lcv_operators
OR lv_tchar CA &apos;(&apos; )
AND lv_cnt2 = 1.
lv_substr1 = iv_reference_formula+lv_offset1(1).
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_numchars = 1.
CONTINUE. &quot; --&gt; next character in formula can be analyzed
ENDIF.
*--------------------------------------------------------------------*
* Quoted literal text holds no cell reference --&gt; advance to end of text
*--------------------------------------------------------------------*
IF lv_tchar EQ &apos;&quot;&apos;.
lv_cnt = lv_cnt + 1.
lv_numchars = lv_numchars + 1.
lv_tchar = iv_reference_formula+lv_cnt(1).
WHILE lv_tchar NE &apos;&quot;&apos;.
lv_cnt = lv_cnt + 1.
lv_numchars = lv_numchars + 1.
lv_tchar = iv_reference_formula+lv_cnt(1).
ENDWHILE.
lv_cnt2 = lv_cnt + 1.
lv_substr1 = iv_reference_formula+lv_offset1(lv_numchars).
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
IF lv_cnt = lv_flen.
EXIT.
ENDIF.
lv_offset1 = lv_cnt.
lv_numchars = 1.
lv_tchar = iv_reference_formula+lv_cnt(1).
lv_cnt2 = lv_cnt + 1.
CONTINUE. &quot; --&gt; next character in formula can be analyzed
ENDIF.
*--------------------------------------------------------------------*
* Operators or parenthesis or last character in formula will separate possible cellreferences
*--------------------------------------------------------------------*
IF lv_tchar CA lcv_operators
OR lv_tchar CA &apos;():&apos;
OR lv_cnt2 = lv_flen.
IF lv_cnt &gt; 0.
lv_substr1 = iv_reference_formula+lv_offset1(lv_numchars).
*--------------------------------------------------------------------*
* Check for text concatenation and functions
*--------------------------------------------------------------------*
IF ( lv_tchar CA lcv_operators AND lv_tchar EQ lv_substr1 ) OR lv_tchar EQ &apos;(&apos;.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE. &quot; --&gt; next character in formula can be analyzed
ENDIF.
lv_tlen = lv_cnt2 - lv_offset1.
*--------------------------------------------------------------------*
* Exclude mathematical operators and closing parentheses
*--------------------------------------------------------------------*
IF lv_tchar CA lcv_operators
OR lv_tchar CA &apos;:)&apos;.
IF lv_cnt2 = lv_flen
AND lv_numchars = 1.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE. &quot; --&gt; next character in formula can be analyzed
ELSE.
lv_tlen = lv_tlen - 1.
ENDIF.
ENDIF.
*--------------------------------------------------------------------*
* Capture reference cell address
*--------------------------------------------------------------------*
TRY.
MOVE: iv_reference_formula+lv_offset1(lv_tlen) TO lv_ref_cell_addr. &quot;Ref cell address
CATCH cx_root.
lv_errormessage = &apos;Internal error in Class ZCL_EXCEL_COMMON Method SHIFT_FORMULA Spot 1 &apos;. &quot; Change to messageclass if possible
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDTRY.
*--------------------------------------------------------------------*
* Split cell address into characters and numbers
*--------------------------------------------------------------------*
CLEAR: lv_tlen,
lv_tcnt,
lv_tcol1,
lv_trow1.
lv_tlen = STRLEN( lv_ref_cell_addr ).
IF lv_tlen &lt;&gt; 0.
CLEAR: lv_tcnt.
DO lv_tlen TIMES.
CLEAR: lv_tchar2.
lv_tchar2 = lv_ref_cell_addr+lv_tcnt(1).
IF lv_tchar2 CA lcv_letters.
CONCATENATE lv_tcol1 lv_tchar2 INTO lv_tcol1.
ELSEIF lv_tchar2 CA lcv_digits.
CONCATENATE lv_trow1 lv_tchar2 INTO lv_trow1.
ENDIF.
lv_tcnt = lv_tcnt + 1.
ENDDO.
ENDIF.
*--------------------------------------------------------------------*
* Check for invalid cell address
*--------------------------------------------------------------------*
IF lv_tcol1 IS INITIAL OR lv_trow1 IS INITIAL.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE.
ENDIF.
*--------------------------------------------------------------------*
* Check for range names
*--------------------------------------------------------------------*
CLEAR: lv_tlen.
lv_tlen = STRLEN( lv_tcol1 ).
IF lv_tlen GT 3.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE.
ENDIF.
*--------------------------------------------------------------------*
* Check for valid row
*--------------------------------------------------------------------*
IF lv_trow1 GT 1048576.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE.
ENDIF.
*--------------------------------------------------------------------*
* Check for absolute column or row reference
*--------------------------------------------------------------------*
CLEAR: lv_tcol2,
lv_trow2,
lv_abscol,
lv_absrow.
lv_tlen2 = STRLEN( lv_tcol1 ) - 1.
IF lv_tcol1 IS NOT INITIAL.
lv_abscol = lv_tcol1(1).
ENDIF.
IF lv_tlen2 GE 0.
lv_absrow = lv_tcol1+lv_tlen2(1).
ENDIF.
IF lv_abscol EQ &apos;$&apos; AND lv_absrow EQ &apos;$&apos;.
lv_tlen2 = lv_tlen2 - 1.
IF lv_tlen2 &gt; 0.
lv_tcol1 = lv_tcol1+1(lv_tlen2).
ENDIF.
lv_tlen2 = lv_tlen2 + 1.
ELSEIF lv_abscol EQ &apos;$&apos;.
lv_tcol1 = lv_tcol1+1(lv_tlen2).
ELSEIF lv_absrow EQ &apos;$&apos;.
lv_tcol1 = lv_tcol1(lv_tlen2).
ENDIF.
*--------------------------------------------------------------------*
* Check for valid column
*--------------------------------------------------------------------*
TRY.
lv_tcoln = zcl_excel_common=&gt;convert_column2int( lv_tcol1 ) + iv_shift_cols.
CATCH zcx_excel.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE.
ENDTRY.
*--------------------------------------------------------------------*
* Check whether there is a referencing problem
*--------------------------------------------------------------------*
lv_trow2 = lv_trow1 + iv_shift_rows.
IF ( lv_tcoln &lt; 1 AND lv_abscol &lt;&gt; &apos;$&apos; ) &quot; Maybe we should add here max-column and max row-tests as well.
OR ( lv_trow2 &lt; 1 AND lv_absrow &lt;&gt; &apos;$&apos; ). &quot; Check how EXCEL behaves in this case
*--------------------------------------------------------------------*
* Referencing problem encountered --&gt; set error
*--------------------------------------------------------------------*
CONCATENATE lv_cur_form lcv_cell_reference_error INTO lv_cur_form.
ELSE.
*--------------------------------------------------------------------*
* No referencing problems --&gt; adjust row and column
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* Adjust column
*--------------------------------------------------------------------*
IF lv_abscol EQ &apos;$&apos;.
CONCATENATE lv_cur_form lv_abscol lv_tcol1 INTO lv_cur_form.
ELSEIF iv_shift_cols EQ 0.
CONCATENATE lv_cur_form lv_tcol1 INTO lv_cur_form.
ELSE.
TRY.
lv_tcol2 = zcl_excel_common=&gt;convert_column2alpha( lv_tcoln ).
CONCATENATE lv_cur_form lv_tcol2 INTO lv_cur_form.
CATCH zcx_excel.
CONCATENATE lv_cur_form lv_substr1 INTO lv_cur_form.
lv_cnt = lv_cnt + 1.
lv_offset1 = lv_cnt.
lv_cnt2 = lv_cnt + 1.
lv_numchars = 1.
CONTINUE.
ENDTRY.
ENDIF.
*--------------------------------------------------------------------*
* Adjust row
*--------------------------------------------------------------------*
IF lv_absrow EQ &apos;$&apos;.
CONCATENATE lv_cur_form lv_absrow lv_trow1 INTO lv_cur_form.
ELSEIF iv_shift_rows = 0.
CONCATENATE lv_cur_form lv_trow1 INTO lv_cur_form.
* elseif lv_trow2 &lt; 1.
* CONCATENATE lv_cur_form lc_cell_reference_error INTO lv_cur_form.
ELSE.
CONCATENATE lv_cur_form lv_trow2 INTO lv_cur_form.
ENDIF.
ENDIF.
lv_numchars = 0.
IF lv_tchar CA lcv_operators
OR lv_tchar CA &apos;:)&apos;.
CONCATENATE lv_cur_form lv_tchar INTO lv_cur_form.
ENDIF.
lv_offset1 = lv_cnt2.
ENDIF.
ENDIF.
lv_numchars = lv_numchars + 1.
lv_cnt = lv_cnt + 1.
lv_cnt2 = lv_cnt + 1.
ENDDO.
*--------------------------------------------------------------------*
* Return resulting formula
*--------------------------------------------------------------------*
IF lv_cur_form IS NOT INITIAL.
MOVE lv_cur_form TO ev_resulting_formula.
ENDIF.
ENDMETHOD.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHL01" VERSION="1" LANGU="E" DESCRIPT="Secret function" EXPOSURE="0" STATE="1" EDITORDER="4 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHL01" SCONAME="I_PWD_HASH" VERSION="1" LANGU="E" DESCRIPT="Password hash" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_PWD_HASH"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHL01" SCONAME="R_PWD_HASH" VERSION="1" LANGU="E" DESCRIPT="Password hash" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_PWD_HASH"/>
<source>method SHL01.
DATA:
lv_bit TYPE i,
lv_curr_pos TYPE i VALUE 2,
lv_prev_pos TYPE i VALUE 1.
DO 15 TIMES.
GET BIT lv_curr_pos OF i_pwd_hash INTO lv_bit.
SET BIT lv_prev_pos OF r_pwd_hash TO lv_bit.
ADD 1 TO lv_curr_pos.
ADD 1 TO lv_prev_pos.
ENDDO.
SET BIT 16 OF r_pwd_hash TO 0.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHR14" VERSION="1" LANGU="E" DESCRIPT="Secret function" EXPOSURE="0" STATE="1" EDITORDER="5 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHR14" SCONAME="I_PWD_HASH" VERSION="1" LANGU="E" DESCRIPT="Password hash" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ZEXCEL_PWD_HASH"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SHR14" SCONAME="R_PWD_HASH" VERSION="1" LANGU="E" DESCRIPT="Password hash" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_PWD_HASH"/>
<source>method SHR14.
DATA:
lv_bit TYPE i,
lv_curr_pos TYPE i,
lv_next_pos TYPE i.
r_pwd_hash = i_pwd_hash.
DO 14 TIMES.
lv_curr_pos = 15.
lv_next_pos = 16.
DO 15 TIMES.
GET BIT lv_curr_pos OF r_pwd_hash INTO lv_bit.
SET BIT lv_next_pos OF r_pwd_hash TO lv_bit.
SUBTRACT 1 FROM lv_curr_pos.
SUBTRACT 1 FROM lv_next_pos.
ENDDO.
SET BIT 1 OF r_pwd_hash TO 0.
ENDDO.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SPLIT_FILE" VERSION="1" LANGU="E" DESCRIPT="File &amp; Extension disconnect (clone of FM CV120_SPLIT_FILE)" EXPOSURE="2" STATE="1" EDITORDER="21 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SPLIT_FILE" SCONAME="IP_FILE" VERSION="1" LANGU="E" DESCRIPT="Original of document" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="TEXT255"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SPLIT_FILE" SCONAME="EP_FILE" VERSION="1" LANGU="E" DESCRIPT="Dateiname ohne Extension" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="TEXT255"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SPLIT_FILE" SCONAME="EP_EXTENSION" VERSION="1" LANGU="E" DESCRIPT="Dateiextension (ohne .)" CMPTYPE="1" MTDTYPE="0" EDITORDER="3 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="CHAR10"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="SPLIT_FILE" SCONAME="EP_DOTEXTENSION" VERSION="1" LANGU="E" DESCRIPT="Dateiextension (mit .)" CMPTYPE="1" MTDTYPE="0" EDITORDER="4 " DISPID="0 " PARDECLTYP="1" PARPASSTYP="1" TYPTYPE="1" TYPE="CHAR10"/>
<source>method SPLIT_FILE.
DATA: lt_hlp TYPE TABLE OF text255,
ls_hlp TYPE text255.
DATA: lf_ext(10) TYPE c,
lf_dot_ext(10) TYPE c.
DATA: lf_str TYPE text255,
lf_anz TYPE i,
lf_len TYPE i.
** ---------------------------------------------------------------------
CLEAR: lt_hlp,
ep_file,
ep_extension,
ep_dotextension.
** Split the whole file at &apos;.&apos;
SPLIT ip_file AT &apos;.&apos; INTO TABLE lt_hlp.
** get the extenstion from the last line of table
DESCRIBE TABLE lt_hlp LINES lf_anz.
IF lf_anz &lt;= 1.
ep_file = ip_file.
EXIT.
ENDIF.
READ TABLE lt_hlp INTO ls_hlp INDEX lf_anz.
ep_extension = ls_hlp.
lf_ext = ls_hlp.
IF NOT lf_ext IS INITIAL.
CONCATENATE &apos;.&apos; lf_ext INTO lf_dot_ext.
ENDIF.
ep_dotextension = lf_dot_ext.
** get only the filename
lf_len = strlen( ip_file ) - strlen( lf_dot_ext ).
IF lf_len &gt; 0.
ep_file = ip_file(lf_len).
ENDIF.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="STRUCTURE_CASE" VERSION="1" LANGU="E" DESCRIPT="Case stement for recursive" EXPOSURE="0" STATE="1" EDITORDER="1 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="STRUCTURE_CASE" SCONAME="IS_COMPONENT" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ABAP_COMPONENTDESCR"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="STRUCTURE_CASE" SCONAME="XT_COMPONENTS" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="2" PARPASSTYP="1" TYPTYPE="1" TYPE="ABAP_COMPONENT_TAB"/>
<source>method STRUCTURE_CASE.
DATA: lt_comp_str TYPE abap_component_tab.
CASE is_component-type-&gt;kind.
WHEN cl_abap_typedescr=&gt;kind_elem. &quot;E Elementary Type
INSERT is_component INTO TABLE xt_components.
WHEN cl_abap_typedescr=&gt;kind_table. &quot;T Table
INSERT is_component INTO TABLE xt_components.
WHEN cl_abap_typedescr=&gt;kind_struct. &quot;S Structure
lt_comp_str = structure_recursive( is_component = is_component ).
INSERT LINES OF lt_comp_str INTO TABLE xt_components.
WHEN OTHERS. &quot;cl_abap_typedescr=&gt;kind_ref or cl_abap_typedescr=&gt;kind_class or cl_abap_typedescr=&gt;kind_intf.
* We skip it. for now.
ENDCASE.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="STRUCTURE_RECURSIVE" VERSION="1" LANGU="E" DESCRIPT="Get structure details" EXPOSURE="0" STATE="1" EDITORDER="2 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="STRUCTURE_RECURSIVE" SCONAME="IS_COMPONENT" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="ABAP_COMPONENTDESCR"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="STRUCTURE_RECURSIVE" SCONAME="RT_COMPONENTS" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ABAP_COMPONENT_TAB"/>
<source>method STRUCTURE_RECURSIVE.
DATA: lo_struct TYPE REF TO cl_abap_structdescr,
lt_components TYPE abap_component_tab,
ls_components TYPE abap_componentdescr.
REFRESH rt_components.
lo_struct ?= is_component-type.
lt_components = lo_struct-&gt;get_components( ).
LOOP AT lt_components INTO ls_components.
structure_case( EXPORTING is_component = ls_components
CHANGING xt_components = rt_components ) .
ENDLOOP.
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="TIME_TO_EXCEL_STRING" VERSION="1" LANGU="E" DESCRIPT="Convert time from SAP format to Excel" EXPOSURE="2" STATE="1" EDITORDER="17 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="TIME_TO_EXCEL_STRING" SCONAME="IP_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="T"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="TIME_TO_EXCEL_STRING" SCONAME="EP_VALUE" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="ZEXCEL_CELL_VALUE"/>
<source>method TIME_TO_EXCEL_STRING.
DATA: lv_seconds_in_day TYPE i,
lv_day_fraction TYPE f,
lc_time_baseline TYPE t VALUE &apos;000000&apos;,
lc_seconds_in_day TYPE i VALUE 86400.
lv_seconds_in_day = ip_value - lc_time_baseline.
lv_day_fraction = lv_seconds_in_day / lc_seconds_in_day.
ep_value = zcl_excel_common=&gt;number_to_excel_string( ip_value = lv_day_fraction ).
endmethod.</source>
</method>
<method CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="UNESCAPE_STRING" VERSION="1" LANGU="E" DESCRIPT="Unescape" EXPOSURE="2" STATE="1" EDITORDER="9 " DISPID="0 " MTDTYPE="0" MTDDECLTYP="1" MTDNEWEXC="X" BCMTDCAT="00" BCMTDSYN="0">
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="UNESCAPE_STRING" SCONAME="IV_ESCAPED" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="1 " DISPID="0 " PARDECLTYP="0" PARPASSTYP="1" TYPTYPE="1" TYPE="CLIKE"/>
<parameter CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="UNESCAPE_STRING" SCONAME="EV_UNESCAPED_STRING" VERSION="1" LANGU="E" CMPTYPE="1" MTDTYPE="0" EDITORDER="2 " DISPID="0 " PARDECLTYP="3" PARPASSTYP="0" TYPTYPE="1" TYPE="STRING"/>
<exception CLSNAME="ZCL_EXCEL_COMMON" CMPNAME="UNESCAPE_STRING" SCONAME="ZCX_EXCEL" VERSION="1" LANGU="E" DESCRIPT="Exceptions for ABAP2XLSX" MTDTYPE="0" EDITORDER="1 "/>
<source>method UNESCAPE_STRING.
CONSTANTS lcv_regex TYPE string VALUE `^&apos;[^&apos;]` &amp; `|` &amp; &quot; Beginning single &apos; OR
`[^&apos;]&apos;$` &amp; `|` &amp; &quot; Trailing single &apos; OR
`[^&apos;]&apos;[^&apos;]`. &quot; Single &apos; somewhere in between
DATA: lv_errormessage TYPE string. &quot; Can&apos;t pass &apos;...&apos;(abc) to exception-class
*--------------------------------------------------------------------*
* This method is used to extract the &quot;real&quot; string from an escaped string.
* An escaped string can be identified by a beginning &apos; which must be
* accompanied by a trailing &apos;
* All &apos;&apos; in between beginning and trailing &apos; are treated as single &apos;
*--------------------------------------------------------------------*
*--------------------------------------------------------------------*
* When allowing clike-input parameters we might encounter trailing
* &quot;real&quot; blanks . These are automatically eliminated when moving
* the input parameter to a string.
*--------------------------------------------------------------------*
ev_unescaped_string = iv_escaped. &quot; Pass through if not escaped
CHECK ev_unescaped_string IS NOT INITIAL. &quot; Nothing to do if empty
CHECK ev_unescaped_string(1) = `&apos;`. &quot; Nothing to do if not escaped
*--------------------------------------------------------------------*
* Remove leading and trailing &apos;
*--------------------------------------------------------------------*
REPLACE REGEX `^&apos;(.*)&apos;$` IN ev_unescaped_string WITH &apos;$1&apos;.
IF sy-subrc &lt;&gt; 0.
lv_errormessage = &apos;Input not properly escaped - &amp;&apos;(002).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
*--------------------------------------------------------------------*
* Any remaining single &apos; should not be here
*--------------------------------------------------------------------*
FIND REGEX lcv_regex IN ev_unescaped_string.
IF sy-subrc = 0.
lv_errormessage = &apos;Input not properly escaped - &amp;&apos;(002).
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = lv_errormessage.
ENDIF.
*--------------------------------------------------------------------*
* Replace &apos;&apos; with &apos;
*--------------------------------------------------------------------*
REPLACE ALL OCCURRENCES OF `&apos;&apos;` IN ev_unescaped_string WITH `&apos;`.
endmethod.</source>
</method>
</CLAS>