class ZCL_EXCEL_COMMON definition
public
final
create public .
public section.
*"* public components of class ZCL_EXCEL_COMMON
*"* do not include other source files here!!!
constants C_EXCEL_BASELINE_DATE type D value '19000101'. "#EC NOTEXT
class-data C_EXCEL_NUMFMT_OFFSET type INT1 value 164. "#EC NOTEXT .
constants C_EXCEL_SHEET_MAX_COL type INT4 value 16384. "#EC NOTEXT
constants C_EXCEL_SHEET_MIN_COL type INT4 value 1. "#EC NOTEXT
class-data C_SPRAS_EN type SPRAS value 'E'. "#EC NOTEXT .
class-data O_CONV type ref to CL_ABAP_CONV_OUT_CE .
constants C_EXCEL_1900_LEAP_YEAR type D value '19000228'. "#EC NOTEXT
class-methods DESCRIBE_STRUCTURE
importing
!IO_STRUCT type ref to CL_ABAP_STRUCTDESCR
returning
value(RT_DFIES) type DDFIELDS .
class-methods DESCRIBE_TABLE .
class-methods CONVERT_COLUMN2ALPHA
importing
!IP_COLUMN type SIMPLE
returning
value(EP_COLUMN) type ZEXCEL_CELL_COLUMN_ALPHA
raising
ZCX_EXCEL .
class-methods CONVERT_COLUMN2INT
importing
!IP_COLUMN type SIMPLE
returning
value(EP_COLUMN) type ZEXCEL_CELL_COLUMN
raising
ZCX_EXCEL .
class-methods CONVERT_COLUMNROW2COLUMN_A_ROW
importing
!I_COLUMNROW type STRING
exporting
!E_COLUMN type ZEXCEL_CELL_COLUMN_ALPHA
!E_ROW type ZEXCEL_CELL_ROW .
class-methods CONVERT_RANGE2COLUMN_A_ROW
importing
!I_RANGE type STRING
exporting
!E_COLUMN_START type ZEXCEL_CELL_COLUMN_ALPHA
!E_COLUMN_END type ZEXCEL_CELL_COLUMN_ALPHA
!E_ROW_START type ZEXCEL_CELL_ROW
!E_ROW_END type ZEXCEL_CELL_ROW
!E_SHEET type ZEXCEL_SHEET_TITLE .
class-methods DATE_TO_EXCEL_STRING
importing
!IP_VALUE type D
returning
value(EP_VALUE) type ZEXCEL_CELL_VALUE .
class-methods ENCRYPT_PASSWORD
importing
!I_PWD type ZEXCEL_AES_PASSWORD
returning
value(R_ENCRYPTED_PWD) type ZEXCEL_AES_PASSWORD .
class-methods ESCAPE_STRING
importing
!IP_VALUE type STRING
returning
value(EP_ESCAPED_VALUE) type STRING .
class-methods EXCEL_STRING_TO_DATE
importing
!IP_VALUE type ZEXCEL_CELL_VALUE
returning
value(EP_VALUE) type D
raising
ZCX_EXCEL .
class-methods EXCEL_STRING_TO_TIME
importing
!IP_VALUE type ZEXCEL_CELL_VALUE
returning
value(EP_VALUE) type T
raising
ZCX_EXCEL .
class-methods GET_FIELDCATALOG
importing
!IP_TABLE type STANDARD TABLE
returning
value(EP_FIELDCATALOG) type ZEXCEL_T_FIELDCATALOG .
class-methods NUMBER_TO_EXCEL_STRING
importing
value(IP_VALUE) type NUMERIC
returning
value(EP_VALUE) type ZEXCEL_CELL_VALUE .
class-methods RECURSIVE_CLASS_TO_STRUCT
importing
!I_SOURCE type ANY
changing
!E_TARGET type DATA
!E_TARGETX type DATA .
class-methods RECURSIVE_STRUCT_TO_CLASS
importing
!I_SOURCE type DATA
!I_SOURCEX type DATA
changing
!E_TARGET type ANY .
class-methods TIME_TO_EXCEL_STRING
importing
!IP_VALUE type T
returning
value(EP_VALUE) type ZEXCEL_CELL_VALUE .
type-pools ABAP .
class-methods ASSERT_EQUALS
importing
!EXP type ANY
!ACT type ANY
!MSG type CSEQUENCE optional
!LEVEL type AUNIT_LEVEL default IF_AUNIT_CONSTANTS=>CRITICAL
!TOL type F optional
!QUIT type AUNIT_FLOWCTRL default IF_AUNIT_CONSTANTS=>METHOD
!IGNORE_HASH_SEQUENCE type ABAP_BOOL default ABAP_FALSE
returning
value(ASSERTION_FAILED) type ABAP_BOOL .
class-methods FAIL
importing
!MSG type CSEQUENCE optional
!LEVEL type AUNIT_LEVEL default IF_AUNIT_CONSTANTS=>CRITICAL
!QUIT type AUNIT_FLOWCTRL default IF_AUNIT_CONSTANTS=>METHOD
!DETAIL type CSEQUENCE optional .
class-methods ASSERT_DIFFERS
importing
!EXP type SIMPLE
!ACT type SIMPLE
!MSG type CSEQUENCE optional
!LEVEL type AUNIT_LEVEL default IF_AUNIT_CONSTANTS=>CRITICAL
!TOL type F optional
!QUIT type AUNIT_FLOWCTRL default IF_AUNIT_CONSTANTS=>METHOD
returning
value(ASSERTION_FAILED) type ABAP_BOOL .
class-methods SPLIT_FILE
importing
!IP_FILE type TEXT255
exporting
!EP_FILE type TEXT255
!EP_EXTENSION type CHAR10
!EP_DOTEXTENSION type CHAR10 .*"* protected components of class ZCL_EXCEL_COMMON
*"* do not include other source files here!!!
protected section.private section.
*"* private components of class ZCL_EXCEL_COMMON
*"* do not include other source files here!!!
class-data C_EXCEL_COL_MODULE type INT2 value 64. "#EC NOTEXT .
class-methods STRUCTURE_CASE
importing
!IS_COMPONENT type ABAP_COMPONENTDESCR
changing
!XT_COMPONENTS type ABAP_COMPONENT_TAB .
class-methods STRUCTURE_RECURSIVE
importing
!IS_COMPONENT type ABAP_COMPONENTDESCR
returning
value(RT_COMPONENTS) type ABAP_COMPONENT_TAB .
class-methods CHAR2HEX
importing
!I_CHAR type CHAR1
returning
value(R_HEX) type ZEXCEL_PWD_HASH .
class-methods SHL01
importing
!I_PWD_HASH type ZEXCEL_PWD_HASH
returning
value(R_PWD_HASH) type ZEXCEL_PWD_HASH .
class-methods SHR14
importing
!I_PWD_HASH type ZEXCEL_PWD_HASH
returning
value(R_PWD_HASH) type ZEXCEL_PWD_HASH .*"* local class implementation for public class
*"* use this source file for the implementation part of
*"* local helper classes*"* use this source file for any type declarations (class
*"* definitions, interfaces or data types) you need for method
*"* implementation or private method's signature*"* use this source file for any macro definitions you need
*"* in the implementation part of the classCLASS 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 "#AU Risk_Level Harmless
. "#AU Duration Short
*?<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
*?<asx:values>
*?<TESTCLASS_OPTIONS>
*?<TEST_CLASS>lcl_Excel_Common_Test
*?</TEST_CLASS>
*?<TEST_MEMBER>f_Cut
*?</TEST_MEMBER>
*?<OBJECT_UNDER_TEST>ZCL_EXCEL_COMMON
*?</OBJECT_UNDER_TEST>
*?<OBJECT_IS_LOCAL/>
*?<GENERATE_FIXTURE>X
*?</GENERATE_FIXTURE>
*?<GENERATE_CLASS_FIXTURE>X
*?</GENERATE_CLASS_FIXTURE>
*?<GENERATE_INVOCATION>X
*?</GENERATE_INVOCATION>
*?<GENERATE_ASSERT_EQUAL>X
*?</GENERATE_ASSERT_EQUAL>
*?</TESTCLASS_OPTIONS>
*?</asx:values>
*?</asx:abap>
PRIVATE SECTION.
* ================
DATA:
lx_excel TYPE REF TO zcx_excel,
f_cut TYPE REF TO zcl_excel_common. "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.
ENDCLASS. "lcl_Excel_Common_Test
*----------------------------------------------------------------------*
* CLASS lcl_Excel_Common_Test IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_excel_common_test IMPLEMENTATION.
* ===========================================
METHOD class_setup.
* ===================
ENDMETHOD. "class_Setup
METHOD class_teardown.
* ======================
ENDMETHOD. "class_Teardown
METHOD setup.
* =============
CREATE OBJECT f_cut.
ENDMETHOD. "setup
METHOD teardown.
* ================
ENDMETHOD. "teardown
METHOD convert_column2alpha.
* ============================
DATA ep_column TYPE zexcel_cell_column_alpha.
* Test 1. Simple test
TRY.
ep_column = zcl_excel_common=>convert_column2alpha( 1 ).
zcl_excel_common=>assert_equals(
act = ep_column
exp = 'A'
msg = 'Wrong column conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Max column for OXML #16,384 = XFD
TRY.
ep_column = zcl_excel_common=>convert_column2alpha( 16384 ).
zcl_excel_common=>assert_equals(
act = ep_column
exp = 'XFD'
msg = 'Wrong column conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 3. Index 0 is out of bounds
TRY.
ep_column = zcl_excel_common=>convert_column2alpha( 0 ).
zcl_excel_common=>assert_equals(
act = ep_column
exp = 'A'
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Index out of bounds'
msg = 'Colum index 0 is out of bounds, min column index is 1'
level = if_aunit_constants=>fatal
).
ENDTRY.
* Test 4. Exception should be thrown index out of bounds
TRY.
ep_column = zcl_excel_common=>convert_column2alpha( 16385 ).
zcl_excel_common=>assert_differs(
act = ep_column
exp = 'XFE'
msg = 'Colum index 16385 is out of bounds, max column index is 16384'
level = if_aunit_constants=>fatal
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Index out of bounds'
msg = 'Wrong exception is thrown'
level = if_aunit_constants=>tolerable
).
ENDTRY.
ENDMETHOD. "convert_Column2alpha
METHOD convert_column2int.
* ==========================
DATA ep_column TYPE zexcel_cell_column.
* Test 1. Basic test
TRY.
ep_column = zcl_excel_common=>convert_column2int( 'A' ).
zcl_excel_common=>assert_equals(
act = ep_column
exp = 1
msg = 'Wrong column conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Max column
TRY.
ep_column = zcl_excel_common=>convert_column2int( 'XFD' ).
zcl_excel_common=>assert_equals(
act = ep_column
exp = 16384
msg = 'Wrong column conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 3. Out of bounds
TRY.
ep_column = zcl_excel_common=>convert_column2int( '' ).
zcl_excel_common=>assert_differs(
act = ep_column
exp = '0'
msg = 'Wrong column conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Unable to interpret column'
msg = 'Colum name should be a valid string'
level = if_aunit_constants=>fatal
).
ENDTRY.
* Test 4. Out of bounds
TRY.
ep_column = zcl_excel_common=>convert_column2int( 'XFE' ).
zcl_excel_common=>assert_differs(
act = ep_column
exp = 16385
msg = 'Wrong column conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Index out of bounds'
msg = 'Colum XFE is out of range'
level = if_aunit_constants=>fatal
).
ENDTRY.
ENDMETHOD. "convert_Column2int
METHOD date_to_excel_string.
* ============================
DATA ep_value TYPE zexcel_cell_value.
* Test 1. Basic conversion
TRY.
ep_value = zcl_excel_common=>date_to_excel_string( '19000101' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = 1
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Check around the "Excel Leap Year" 1900
TRY.
ep_value = zcl_excel_common=>date_to_excel_string( '19000228' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = 59
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
TRY.
ep_value = zcl_excel_common=>date_to_excel_string( '19000301' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = 61
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
ep_value = zcl_excel_common=>date_to_excel_string( '99991212' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = 2958446
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 3. Initial date
TRY.
DATA: lv_date TYPE d.
ep_value = zcl_excel_common=>date_to_excel_string( lv_date ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = ''
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
DATA exp_value TYPE zexcel_cell_value VALUE 0.
ep_value = zcl_excel_common=>date_to_excel_string( '18991231' ).
zcl_excel_common=>assert_differs(
act = ep_value
exp = exp_value
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Index out of bounds'
msg = 'Dates prior of 1900 are not available in excel'
level = if_aunit_constants=>critical
).
ENDTRY.
ENDMETHOD. "date_To_Excel_String
METHOD encrypt_password.
* ========================
DATA lv_encrypted_pwd TYPE zexcel_aes_password.
TRY.
lv_encrypted_pwd = zcl_excel_common=>encrypt_password( 'test' ).
zcl_excel_common=>assert_equals(
act = lv_encrypted_pwd
exp = 'CBEB'
msg = 'Wrong password encryption'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
ENDMETHOD. "encrypt_Password
METHOD excel_string_to_date.
* ============================
DATA ep_value TYPE d.
* Test 1. Simple test -> ABAP Manage also date prior of 1900
TRY.
ep_value = zcl_excel_common=>excel_string_to_date( '0' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '18991231'
msg = 'Wrong date conversion'
level = if_aunit_constants=>tolerable
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Check around the "Excel Leap Year" 1900
TRY.
ep_value = zcl_excel_common=>excel_string_to_date( '59' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '19000228'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
TRY.
ep_value = zcl_excel_common=>excel_string_to_date( '61' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '19000301'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Simple test
TRY.
ep_value = zcl_excel_common=>excel_string_to_date( '1' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '19000101'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 3. Index 0 is out of bounds
TRY.
ep_value = zcl_excel_common=>excel_string_to_date( '2958446' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '99991212'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 4. Exception should be thrown index out of bounds
TRY.
ep_value = zcl_excel_common=>excel_string_to_date( '2958447' ).
zcl_excel_common=>assert_differs(
act = ep_value
exp = '99991212'
msg = 'Wrong date conversion'
level = if_aunit_constants=>fatal
).
zcl_excel_common=>assert_differs(
act = ep_value
exp = '00000000'
msg = 'Wrong date conversion'
level = if_aunit_constants=>fatal
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Index out of bounds'
msg = 'Wrong exception is thrown'
level = if_aunit_constants=>tolerable
).
ENDTRY.
ENDMETHOD. "excel_String_To_Date
METHOD excel_string_to_time.
* ============================
DATA ep_value TYPE t.
* Test 1. Simple test
TRY.
ep_value = zcl_excel_common=>excel_string_to_time( '0' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '000000'
msg = 'Wrong date conversion'
level = if_aunit_constants=>tolerable
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Simple test
TRY.
ep_value = zcl_excel_common=>excel_string_to_time( '1' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '000000'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 3. Simple test
TRY.
ep_value = zcl_excel_common=>excel_string_to_time( '0.99999' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '235959'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 4. Also string greater than 1 should be managed
TRY.
ep_value = zcl_excel_common=>excel_string_to_time( '4.1' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '022400'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 4. string is not a number
TRY.
ep_value = zcl_excel_common=>excel_string_to_time( 'NaN' ).
zcl_excel_common=>assert_differs(
act = ep_value
exp = '000000'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>assert_equals(
act = lx_excel->error
exp = 'Unable to interpret time'
msg = 'Time should be a valid string'
level = if_aunit_constants=>fatal
).
ENDTRY.
ENDMETHOD. "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=>time_to_excel_string( '000001' ).
" A test directly in Excel returns the value 0.0000115740740740741000
zcl_excel_common=>assert_equals(
act = ep_value
exp = '0.0000115740740741'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
ep_value = zcl_excel_common=>time_to_excel_string( '235959' ).
" A test directly in Excel returns the value 0.9999884259259260000000
zcl_excel_common=>assert_equals(
act = ep_value
exp = '0.9999884259259260'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 3. Initial date
TRY.
ep_value = zcl_excel_common=>time_to_excel_string( '000000' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '0'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
* Test 2. Basic conversion
TRY.
ep_value = zcl_excel_common=>time_to_excel_string( '022400' ).
zcl_excel_common=>assert_equals(
act = ep_value
exp = '0.1000000000000000'
msg = 'Wrong date conversion'
level = if_aunit_constants=>critical
).
CATCH zcx_excel INTO lx_excel.
zcl_excel_common=>fail(
msg = 'unexpected exception'
level = if_aunit_constants=>critical " Error Severity
).
ENDTRY.
ENDMETHOD. "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=>split_file( EXPORTING ip_file = 'filename.xml'
IMPORTING ep_file = ep_file
ep_extension = ep_extension
ep_dotextension = ep_dotextension ).
zcl_excel_common=>assert_equals(
act = ep_file
exp = 'filename'
msg = 'Split filename failed'
level = if_aunit_constants=>critical ).
zcl_excel_common=>assert_equals(
act = ep_extension
exp = 'xml'
msg = 'Split extension failed'
level = if_aunit_constants=>critical ).
zcl_excel_common=>assert_equals(
act = ep_dotextension
exp = '.xml'
msg = 'Split extension failed'
level = if_aunit_constants=>critical ).
* Test 2. no extension
zcl_excel_common=>split_file( EXPORTING ip_file = 'filename'
IMPORTING ep_file = ep_file
ep_extension = ep_extension
ep_dotextension = ep_dotextension ).
zcl_excel_common=>assert_equals(
act = ep_file
exp = 'filename'
msg = 'Split filename failed'
level = if_aunit_constants=>critical ).
zcl_excel_common=>assert_equals(
act = ep_extension
exp = ''
msg = 'Split extension failed'
level = if_aunit_constants=>critical ).
zcl_excel_common=>assert_equals(
act = ep_dotextension
exp = ''
msg = 'Split extension failed'
level = if_aunit_constants=>critical ).
ENDMETHOD. "split_file
ENDCLASS. "lcl_Excel_Common_TestABAPmethod ASSERT_DIFFERS.
DATA: ls_seoclass TYPE seoclass.
" Let see >=7.02
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = 'CL_ABAP_UNIT_ASSERT'.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=>assert_differs
EXPORTING
exp = exp
act = act
msg = msg
level = level
tol = tol
quit = quit
RECEIVING
assertion_failed = assertion_failed.
ELSE.
" Let see >=7.00 or even lower
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = 'CL_AUNIT_ASSERT'.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=>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.method ASSERT_EQUALS.
DATA: ls_seoclass TYPE seoclass.
" Let see >=7.02
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = 'CL_ABAP_UNIT_ASSERT'.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=>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.
" Let see >=7.00 or even lower
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = 'CL_AUNIT_ASSERT'.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=>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.method CHAR2HEX.
IF o_conv IS NOT BOUND.
o_conv = cl_abap_conv_out_ce=>create( endian = 'L'
ignore_cerr = abap_true
replacement = '#' ).
ENDIF.
CALL METHOD o_conv->reset( ).
CALL METHOD o_conv->write( data = i_char ).
r_hex+1 = o_conv->get_buffer( ). " x'65' must be x'0065'
endmethod.method CONVERT_COLUMN2ALPHA.
DATA: lo_conv TYPE REF TO cl_abap_conv_in_ce,
lv_uccpi TYPE i,
lv_text TYPE sychar02,
lv_module TYPE int4,
lv_column TYPE zexcel_cell_column.
* Propagate zcx_excel if error occurs " issue #155 - less restrictive typing for ip_column
lv_column = convert_column2int( ip_column ). " issue #155 - less restrictive typing for ip_column
IF lv_column GT 16384 OR lv_column LT 1.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Index out of bounds'.
ENDIF.
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=>uccpi( lv_uccpi ).
CONCATENATE lv_text ep_column INTO ep_column.
ENDWHILE.
endmethod.method CONVERT_COLUMN2INT.
DATA: lv_uccpi TYPE i,
lv_factor TYPE i,
lv_offset TYPE i,
lv_char TYPE c,
lv_column TYPE zexcel_cell_column_alpha,
lv_column_c TYPE char10,
mod TYPE i.
* If a number gets passed, just convert it to an integer,
* Otherwise try to interpret it as if ZEXCEL_CELL_COLUMN_ALPHA was passed
* if both fails raise exception
lv_column_c = ip_column.
TRANSLATE lv_column TO UPPER CASE.
CONDENSE lv_column_c NO-GAPS.
IF lv_column_c EQ ''.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Unable to interpret column'.
ENDIF.
* First try - convert to number
TRY.
IF lv_column_c CO '1234567890 '. " Fix #164
ep_column = lv_column_c. " Fix #164
EXIT.
ENDIF.
CATCH cx_sy_conversion_no_number.
" Too bad - try the character-approach
ENDTRY.
* Upper case
lv_column = lv_column_c.
** Get string lenght and align to right
* lv_offset = 3 - STRLEN( lv_column ).
*
* SHIFT lv_column RIGHT BY lv_offset PLACES.
*
** Calculate column position
* DO 3 TIMES.
* lv_offset = sy-index - 1.
* lv_char = lv_column+lv_offset(1).
* if lv_char IS INITIAL.
* CONTINUE.
* ENDIF.
* lv_uccpi = cl_abap_conv_out_ce=>uccpi( lv_char ).
* lv_factor = 26 ** ( 3 - sy-index ).
* ep_column = ep_column + ( lv_uccpi MOD zcl_excel_common=>c_excel_col_module ) * lv_factor.
* ENDDO.
* Raise error if unexpected character turns up
mod = cl_abap_conv_out_ce=>uccpi( lv_column+0(1) ) MOD zcl_excel_common=>c_excel_col_module.
IF mod < 1 OR mod > 26.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Unable to interpret column'.
ENDIF.
ep_column = mod.
CHECK lv_column+1(1) IS NOT INITIAL. " No need to continue if string ended
mod = cl_abap_conv_out_ce=>uccpi( lv_column+1(1) ) MOD zcl_excel_common=>c_excel_col_module.
IF mod < 1 OR mod > 26.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Unable to interpret column'.
ENDIF.
ep_column = 26 * ep_column + mod.
CHECK lv_column+2(1) IS NOT INITIAL. " No need to continue if string ended
mod = cl_abap_conv_out_ce=>uccpi( lv_column+2(1) ) MOD zcl_excel_common=>c_excel_col_module.
IF mod < 1 OR mod > 26.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Unable to interpret column'.
ENDIF.
ep_column = 26 * ep_column + mod.
IF ep_column GT 16384 OR ep_column LT 1.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Index out of bounds'.
ENDIF.
endmethod.method CONVERT_COLUMNROW2COLUMN_A_ROW.
DATA: width TYPE i,
col_width TYPE i,
row_str TYPE string,
col_str TYPE string.
width = strlen( i_columnrow ).
col_width = width.
col_str = i_columnrow.
WHILE col_str CA '0123456789'.
col_width = col_width - 1.
col_str = i_columnrow(col_width).
ENDWHILE.
e_column = col_str.
width = width - col_width.
row_str = i_columnrow+col_width(width).
e_row = row_str.
endmethod.method CONVERT_RANGE2COLUMN_A_ROW.
DATA:
sheet TYPE string,
range TYPE string,
columnrow_start TYPE string,
columnrow_end TYPE string.
IF i_range IS INITIAL
OR NOT i_range CS ':'.
RETURN.
ENDIF.
IF i_range CS '!'.
SPLIT i_range AT '!' INTO sheet range.
e_sheet = sheet.
ELSE.
range = i_range.
ENDIF.
REPLACE ALL OCCURRENCES OF '$' IN range WITH ''.
SPLIT range AT ':' INTO columnrow_start columnrow_end.
convert_columnrow2column_a_row(
EXPORTING
i_columnrow = columnrow_start
IMPORTING
e_column = e_column_start
e_row = e_row_start
).
convert_columnrow2column_a_row(
EXPORTING
i_columnrow = columnrow_end
IMPORTING
e_column = e_column_end
e_row = e_row_end
).
endmethod.method DATE_TO_EXCEL_STRING.
DATA: lv_date_diff TYPE i.
CHECK ip_value IS NOT INITIAL.
" Needed hack caused by the problem that:
" Excel 2000 incorrectly assumes that the year 1900 is a leap year
" http://support.microsoft.com/kb/214326/en-us
IF ip_value > 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=>number_to_excel_string( ip_value = lv_date_diff ).
endmethod.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.
"for DDIC structure get the info directly
IF io_struct->is_ddic_type( ) = abap_true.
rt_dfies = io_struct->get_ddic_field_list( ).
ELSE.
lt_components = io_struct->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->kind = cl_abap_typedescr=>kind_elem. "E Elementary Type
ADD 1 TO l_position.
lo_elemdescr ?= ls_component-type.
IF lo_elemdescr->is_ddic_type( ) = abap_true.
ls_dfies = lo_elemdescr->get_ddic_field( ).
ls_dfies-position = l_position.
ELSE.
ls_dfies-fieldname = ls_component-name.
ls_dfies-position = l_position.
ls_dfies-inttype = lo_elemdescr->type_kind.
ls_dfies-leng = lo_elemdescr->length.
ls_dfies-outputlen = lo_elemdescr->length.
ls_dfies-decimals = lo_elemdescr->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.method DESCRIBE_TABLE.
endmethod.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 '7FFF',
lv_0x0001 TYPE zexcel_pwd_hash VALUE '0001',
lv_0xce4b TYPE zexcel_pwd_hash VALUE 'CE4B'.
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.method ESCAPE_STRING.
DATA lv_value TYPE string.
lv_value = ip_value.
REPLACE ALL OCCURRENCES OF `'` IN lv_value WITH `''`.
IF lv_value CP '* *'.
CONCATENATE `'` lv_value `'` INTO lv_value .
ENDIF.
ep_escaped_value = lv_value.
endmethod.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.
" Needed hack caused by the problem that:
" Excel 2000 incorrectly assumes that the year 1900 is a leap year
" http://support.microsoft.com/kb/214326/en-us
IF ep_value < c_excel_1900_leap_year.
ep_value = ep_value + 1.
ENDIF.
CATCH cx_sy_conversion_error.
RAISE EXCEPTION TYPE zcx_excel
EXPORTING
error = 'Index out of bounds'.
ENDTRY.
endmethod.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 = 'Unable to interpret time'.
ENDTRY.
endmethod.method FAIL.
DATA: ls_seoclass TYPE seoclass.
" Let see >=7.02
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = 'CL_ABAP_UNIT_ASSERT'.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=>fail
EXPORTING
msg = msg
level = level
quit = quit
detail = detail.
ELSE.
" Let see >=7.00 or even lower
SELECT SINGLE * INTO ls_seoclass
FROM seoclass
WHERE clsname = 'CL_AUNIT_ASSERT'.
IF sy-subrc = 0.
CALL METHOD (ls_seoclass-clsname)=>fail
EXPORTING
msg = msg
level = level
quit = quit
detail = detail.
ELSE.
* We do nothing for now not supported
ENDIF.
ENDIF.
endmethod.method GET_FIELDCATALOG.
data: lr_data type ref to data,
lo_structdescr type ref to cl_abap_structdescr,
lt_dfies type ddfields,
ls_dfies type dfies,
ls_fieldcatalog type zexcel_s_fieldcatalog.
create data lr_data like line of ip_table.
lo_structdescr ?= cl_abap_structdescr=>describe_by_data_ref( lr_data ).
lt_dfies = describe_structure( io_struct = lo_structdescr ).
loop at lt_dfies into ls_dfies.
clear ls_fieldcatalog.
move-corresponding ls_dfies to ls_fieldcatalog.
append ls_fieldcatalog to ep_fieldcatalog.
endloop.
endmethod.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 ',' IN lv_value_c WITH '.'.
ep_value = lv_value_c.
CONDENSE ep_value.
IF ip_value < 0.
CONCATENATE '-' ep_value INTO ep_value.
ELSEIF ip_value EQ 0.
ep_value = '0'.
ENDIF.
endmethod.method RECURSIVE_CLASS_TO_STRUCT.
" # issue 139
* is working for me - but after looking through this coding I guess
* I'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->components,
attribute_name TYPE fieldname,
flag_class TYPE flag,
o_border TYPE REF TO zcl_excel_style_border.
FIELD-SYMBOLS: <field> TYPE any,
<fieldx> TYPE any,
<class> TYPE REF TO object,
<attribute> TYPE any.
descr ?= cl_abap_structdescr=>describe_by_data( e_target ).
LOOP AT descr->components INTO wa_component.
* Assign structure and X-structure
ASSIGN COMPONENT wa_component-name OF STRUCTURE e_target TO <field>.
ASSIGN COMPONENT wa_component-name OF STRUCTURE e_targetx TO <fieldx>.
* 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 <attribute>.
IF sy-subrc <> 0.
* not - then it is an attribute of the class - use different assign then
CONCATENATE 'i_source->' wa_component-name INTO attribute_name.
ASSIGN (attribute_name) TO <attribute>.
IF sy-subrc <> 0.
EXIT.
ENDIF. " 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=>typekind_struct1. " Structure --> 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=>recursive_class_to_struct( EXPORTING i_source = <attribute>
CHANGING e_target = <field>
e_targetx = <fieldx> ).
WHEN OTHERS.
<field> = <attribute>.
<fieldx> = abap_true.
ENDCASE.
ENDLOOP.
endmethod.method RECURSIVE_STRUCT_TO_CLASS.
" # issue 139
* is working for me - but after looking through this coding I guess
* I'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->components,
attribute_name TYPE fieldname,
flag_class TYPE flag,
o_border TYPE REF TO zcl_excel_style_border.
FIELD-SYMBOLS: <field> TYPE any,
<fieldx> TYPE any,
<class> TYPE REF TO object,
<attribute> TYPE any.
descr ?= cl_abap_structdescr=>describe_by_data( i_source ).
LOOP AT descr->components INTO wa_component.
* Assign structure and X-structure
ASSIGN COMPONENT wa_component-name OF STRUCTURE i_source TO <field>.
ASSIGN COMPONENT wa_component-name OF STRUCTURE i_sourcex TO <fieldx>.
* At least one field in the structure should be marked - otherwise continue with next field
CHECK <fieldx> 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 <attribute>.
IF sy-subrc <> 0.
* not - then it is an attribute of the class - use different assign then
CONCATENATE 'E_TARGET->' wa_component-name INTO attribute_name.
ASSIGN (attribute_name) TO <attribute>.
IF sy-subrc <> 0.EXIT.ENDIF. " 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=>typekind_struct1. " Structure --> use recursion
IF flag_class = abap_true AND <attribute> 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.
<attribute> = o_border.
ENDIF.
zcl_excel_common=>recursive_struct_to_class( EXPORTING i_source = <field>
i_sourcex = <fieldx>
CHANGING e_target = <attribute> ).
WHEN OTHERS.
CHECK <fieldx> = abap_true. " Marked for change
<attribute> = <field>.
ENDCASE.
ENDLOOP.
endmethod.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.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.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 '.'
SPLIT ip_file AT '.' INTO TABLE lt_hlp.
** get the extenstion from the last line of table
DESCRIBE TABLE lt_hlp LINES lf_anz.
IF lf_anz <= 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 '.' 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 > 0.
ep_file = ip_file(lf_len).
ENDIF.
ENDMETHOD.method STRUCTURE_CASE.
DATA: lt_comp_str TYPE abap_component_tab.
CASE is_component-type->kind.
WHEN cl_abap_typedescr=>kind_elem. "E Elementary Type
INSERT is_component INTO TABLE xt_components.
WHEN cl_abap_typedescr=>kind_table. "T Table
INSERT is_component INTO TABLE xt_components.
WHEN cl_abap_typedescr=>kind_struct. "S Structure
lt_comp_str = structure_recursive( is_component = is_component ).
INSERT LINES OF lt_comp_str INTO TABLE xt_components.
WHEN OTHERS. "cl_abap_typedescr=>kind_ref or cl_abap_typedescr=>kind_class or cl_abap_typedescr=>kind_intf.
* We skip it. for now.
ENDCASE.
endmethod.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->get_components( ).
LOOP AT lt_components INTO ls_components.
structure_case( EXPORTING is_component = ls_components
CHANGING xt_components = rt_components ) .
ENDLOOP.
endmethod.method TIME_TO_EXCEL_STRING.
DATA: lv_seconds_in_day TYPE i,
lv_day_fraction TYPE f,
lc_time_baseline TYPE t VALUE '000000',
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=>number_to_excel_string( ip_value = lv_day_fraction ).
endmethod.