From c31528604e5e9abe2d14cdf693a216ebbc349c57 Mon Sep 17 00:00:00 2001 From: oliver-huetkoeper Date: Thu, 2 Oct 2014 08:05:55 +0200 Subject: [PATCH 1/5] Add method to check if a cell is merged --- ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk b/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk index 7cd92d8..33dca93 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk @@ -4233,6 +4233,30 @@ ENDMETHOD. ENDIF. endmethod. + + + + + + + method IS_CELL_MERGED. + DATA lt_merge_range TYPE string_table. + + FIELD-SYMBOLS <lv_merge_range> LIKE LINE OF lt_merge_range. + + + lt_merge_range = me->get_merge( ). + + LOOP AT lt_merge_range ASSIGNING <lv_merge_range>. + rp_is_merged = zcl_excel_common=>is_cell_in_range( + ip_column = ip_column + ip_row = ip_row + ip_range = <lv_merge_range> ). + IF rp_is_merged = abap_true. + EXIT. + ENDIF. + ENDLOOP. +endmethod. method PRINT_TITLE_SET_RANGE. From 21a63fd96eea372cd862a8ad547aeeb2d74eabc5 Mon Sep 17 00:00:00 2001 From: oliver-huetkoeper Date: Thu, 2 Oct 2014 08:10:42 +0200 Subject: [PATCH 2/5] Ignore merged cells when calculating column width When calculating column width cells that are merged should be ignored. This is MS Excel behavior and should be handled similar in ABAP2XLSX. --- ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk b/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk index 33dca93..eabbefc 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_WORKSHEET.slnk @@ -3174,6 +3174,10 @@ ENDMETHOD. * col_alpha = zcl_excel_common=>convert_column2alpha( <auto_size>-col_index )." issue #155 - less restrictive typing for ip_column count = 1. WHILE count <= highest_row. +* Do not check merged cells + IF is_cell_merged( + ip_column = <auto_size>-col_index + ip_row = count ) = abap_false. * Start of change # issue 139 - Dateretention of cellstyles * IF cell_style IS BOUND. * CREATE OBJECT cell_style. @@ -3195,11 +3199,12 @@ ENDMETHOD. * width = cell_style->font->calculate_text_width( cell_value ). * ENDIF. * width = calculate_cell_width( ip_column = col_alpha " issue #155 - less restrictive typing for ip_column - width = calculate_cell_width( ip_column = <auto_size>-col_index " issue #155 - less restrictive typing for ip_column - ip_row = count ). + width = calculate_cell_width( ip_column = <auto_size>-col_index " issue #155 - less restrictive typing for ip_column + ip_row = count ). * End of change # issue 139 - Dateretention of cellstyles - IF width > <auto_size>-width. - <auto_size>-width = width. + IF width > <auto_size>-width. + <auto_size>-width = width. + ENDIF. ENDIF. count = count + 1. ENDWHILE. From 248ed862d444891251b3bebf5515df7266027d08 Mon Sep 17 00:00:00 2001 From: oliver-huetkoeper Date: Thu, 2 Oct 2014 08:28:47 +0200 Subject: [PATCH 3/5] Add method to check if a cell is within a range --- ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk b/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk index 3ac095e..2eac9b4 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk @@ -1886,6 +1886,46 @@ endmethod. ENDLOOP. +endmethod. + + + + + + + + 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 >= lv_column_start_i AND + lv_column_i <= lv_column_end_i AND + ip_row >= lv_row_start AND + ip_row <= lv_row_end. + rp_in_range = abap_true. + ENDIF. endmethod. From 3cfb536b021c051c0388e8d61f028fa0d8e6362c Mon Sep 17 00:00:00 2001 From: oliver-huetkoeper Date: Fri, 14 Nov 2014 09:32:08 +0100 Subject: [PATCH 4/5] Add test method for is_cell_in_range --- ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk | 109 ++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk b/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk index 2eac9b4..8c74d8a 100644 --- a/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk +++ b/ZA2X/CLAS/ZCL_EXCEL_COMMON.slnk @@ -65,6 +65,7 @@ CLASS lcl_excel_common_test DEFINITION FOR TESTING "#AU Risk_Level Harmles METHODS: describe_structure FOR TESTING. METHODS: calculate_cell_distance FOR TESTING. METHODS: shift_formula FOR TESTING. + METHODS: is_cell_in_range FOR TESTING. ENDCLASS. "lcl_Excel_Common_Test @@ -1036,9 +1037,117 @@ CLASS lcl_excel_common_test IMPLEMENTATION. 'A1+$A1+A$1+$A$1+B2' -1 -1 '#REF!+#REF!+#REF!+$A$1+A1'. " Referencing error , row and column , underflow ENDMETHOD. "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=>is_cell_in_range( + ip_column = 'B' + ip_row = 2 + ip_range = 'B2:D4' ). + zcl_excel_common=>assert_equals( + act = ep_cell_in_range + exp = abap_true + msg = 'Check cell in range failed' + level = if_aunit_constants=>critical ). + CATCH zcx_excel. + zcl_excel_common=>fail( + msg = 'Unexpected exception' + level = if_aunit_constants=>critical ). + ENDTRY. +* Test 2: lower right corner (in range) + TRY. + ep_cell_in_range = zcl_excel_common=>is_cell_in_range( + ip_column = 'D' + ip_row = 4 + ip_range = 'B2:D4' ). + + zcl_excel_common=>assert_equals( + act = ep_cell_in_range + exp = abap_true + msg = 'Check cell in range failed' + level = if_aunit_constants=>critical ). + CATCH zcx_excel. + zcl_excel_common=>fail( + msg = 'Unexpected exception' + level = if_aunit_constants=>critical ). + ENDTRY. + +* Test 3: left side (out of range) + TRY. + ep_cell_in_range = zcl_excel_common=>is_cell_in_range( + ip_column = 'A' + ip_row = 3 + ip_range = 'B2:D4' ). + + zcl_excel_common=>assert_equals( + act = ep_cell_in_range + exp = abap_false + msg = 'Check cell in range failed' + level = if_aunit_constants=>critical ). + CATCH zcx_excel. + zcl_excel_common=>fail( + msg = 'Unexpected exception' + level = if_aunit_constants=>critical ). + ENDTRY. + +* Test 4: upper side (out of range) + TRY. + ep_cell_in_range = zcl_excel_common=>is_cell_in_range( + ip_column = 'C' + ip_row = 1 + ip_range = 'B2:D4' ). + + zcl_excel_common=>assert_equals( + act = ep_cell_in_range + exp = abap_false + msg = 'Check cell in range failed' + level = if_aunit_constants=>critical ). + CATCH zcx_excel. + zcl_excel_common=>fail( + msg = 'Unexpected exception' + level = if_aunit_constants=>critical ). + ENDTRY. + +* Test 5: right side (out of range) + TRY. + ep_cell_in_range = zcl_excel_common=>is_cell_in_range( + ip_column = 'E' + ip_row = 3 + ip_range = 'B2:D4' ). + + zcl_excel_common=>assert_equals( + act = ep_cell_in_range + exp = abap_false + msg = 'Check cell in range failed' + level = if_aunit_constants=>critical ). + CATCH zcx_excel. + zcl_excel_common=>fail( + msg = 'Unexpected exception' + level = if_aunit_constants=>critical ). + ENDTRY. + +* Test 6: lower side (out of range) + TRY. + ep_cell_in_range = zcl_excel_common=>is_cell_in_range( + ip_column = 'C' + ip_row = 5 + ip_range = 'B2:D4' ). + + zcl_excel_common=>assert_equals( + act = ep_cell_in_range + exp = abap_false + msg = 'Check cell in range failed' + level = if_aunit_constants=>critical ). + CATCH zcx_excel. + zcl_excel_common=>fail( + msg = 'Unexpected exception' + level = if_aunit_constants=>critical ). + ENDTRY. + ENDMETHOD. ENDCLASS. "lcl_Excel_Common_Test From a74220e25fd4351288786454a03cd13be72238ce Mon Sep 17 00:00:00 2001 From: oliver-huetkoeper Date: Fri, 14 Nov 2014 09:35:57 +0100 Subject: [PATCH 5/5] Add sheet for merged cells I have added a new sheet to demonstrate that merged cells are ignored when using auto-size (MS Excel like behaviour). --- ZA2X/PROG/ZDEMO_EXCEL31.slnk | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ZA2X/PROG/ZDEMO_EXCEL31.slnk b/ZA2X/PROG/ZDEMO_EXCEL31.slnk index 44474dd..3852397 100644 --- a/ZA2X/PROG/ZDEMO_EXCEL31.slnk +++ b/ZA2X/PROG/ZDEMO_EXCEL31.slnk @@ -142,6 +142,23 @@ START-OF-SELECTION. column_dimension = lo_worksheet->get_column_dimension( 'C' ). column_dimension->set_auto_size( ip_auto_size = abap_true ). + " Add sheet for merged cells + lo_worksheet = lo_excel->add_new_worksheet( ). + lo_worksheet->set_title( ip_title = 'Merged cells' ). + + lo_worksheet->set_cell( ip_column = 'A' ip_row = 1 ip_value = 'This is a very long header text' ). + lo_worksheet->set_cell( ip_column = 'A' ip_row = 2 ip_value = 'Some data' ). + lo_worksheet->set_cell( ip_column = 'A' ip_row = 3 ip_value = 'Some more data' ). + + lo_worksheet->set_merge( + EXPORTING + ip_column_start = 'A' + ip_column_end = 'C' + ip_row = 1 ). + + column_dimension = lo_worksheet->get_column_dimension( 'A' ). + column_dimension->set_auto_size( ip_auto_size = abap_true ). + lo_excel->set_active_sheet_index( i_active_worksheet = 1 ). *** Create output