class ZCL_BC_TABLE_INTROSPECTOR definition
public
final
create private .
public section.
*"* public components of class ZCL_BC_TABLE_INTROSPECTOR
*"* do not include other source files here!!!
types:
ty_color type n length 2 .
types:
ty_xml(1024) type x .
types:
ty_xml_t type standard table of ty_xml with non-unique default key .
types:
ty_delimiter type c length 1 .
constants:
begin of e_color,
none type ty_color value '00',
standard type ty_color value '01',
end of e_color .
type-pools ABAP .
class-methods FACTORY_USING_SQL
importing
!IM_DBTAB type CSEQUENCE
!IM_COLUMNS type CSEQUENCE optional
!IM_WHERE_CLAUSE type CSEQUENCE optional
!IM_MAX_ROWS type I optional
!IM_DELIMITER type TY_DELIMITER default ','
!IM_USE_HEADER_RECORD type ABAP_BOOL default ABAP_TRUE
!IM_USE_COLUMN_ALIGNMENT type ABAP_BOOL default ABAP_TRUE
!IM_POINT_HEADER_TO_DDIC type ABAP_BOOL default ABAP_TRUE
!IM_ENCLOSE_STRINGS type ABAP_BOOL default ABAP_FALSE
!IM_FORMAT_TIME type ABAP_BOOL default ABAP_TRUE
!IM_FORMAT_DATE type ABAP_BOOL default ABAP_TRUE
!IM_AUTHOR type STRING optional
!IM_SHEET_NAME type STRING optional
!IM_FREEZE_HEADER type ABAP_BOOL default ABAP_TRUE
!IM_HEADER_COLOR type TY_COLOR default E_COLOR-STANDARD
!IM_HEADER_HEIGHT type I default 5
!IM_STRING_CELL_WIDTH type I default 80
!IM_POINTS_FACTOR type I default 8
exporting
value(EX_TABLE_INTROSPECTOR) type ref to ZCL_BC_TABLE_INTROSPECTOR
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods FACTORY_USING_TABLE
importing
!IM_TABLE type ANY TABLE
!IM_COLUMNS type CSEQUENCE optional
!IM_DELIMITER type TY_DELIMITER default ','
!IM_USE_HEADER_RECORD type ABAP_BOOL default ABAP_TRUE
!IM_USE_COLUMN_ALIGNMENT type ABAP_BOOL default ABAP_TRUE
!IM_POINT_HEADER_TO_DDIC type ABAP_BOOL default ABAP_TRUE
!IM_ENCLOSE_STRINGS type ABAP_BOOL default ABAP_FALSE
!IM_FORMAT_TIME type ABAP_BOOL default ABAP_TRUE
!IM_FORMAT_DATE type ABAP_BOOL default ABAP_TRUE
!IM_AUTHOR type STRING optional
!IM_SHEET_NAME type STRING optional
!IM_FREEZE_HEADER type ABAP_BOOL default ABAP_TRUE
!IM_HEADER_COLOR type TY_COLOR default E_COLOR-STANDARD
!IM_HEADER_HEIGHT type I default 5
!IM_STRING_CELL_WIDTH type I default 80
!IM_POINTS_FACTOR type I default 8
exporting
value(EX_TABLE_INTROSPECTOR) type ref to ZCL_BC_TABLE_INTROSPECTOR
raising
ZCX_BC_TABLE_INTROSPECTOR .
methods GET_ALV_RENDITION
exporting
value(EX_ALV_TABLE) type ref to CL_SALV_TABLE
raising
ZCX_BC_TABLE_INTROSPECTOR .
methods GET_SOLI_RENDITION
exporting
value(EX_SOLI_TABLE) type SOLI_TAB
raising
ZCX_BC_TABLE_INTROSPECTOR .
methods GET_SOLIX_RENDITION
exporting
value(EX_SOLIX_TABLE) type SOLIX_TAB
raising
ZCX_BC_TABLE_INTROSPECTOR .
methods GET_XML_SOLIX_RENDITION
exporting
value(EX_XML_SOLIX_TABLE) type SOLIX_TAB
raising
ZCX_BC_TABLE_INTROSPECTOR .
methods GET_FILE_RENDITION
exporting
value(EX_FILE_TABLE) type STRING_TABLE
raising
ZCX_BC_TABLE_INTROSPECTOR .
methods GET_XML_RENDITION
exporting
value(EX_XML_TABLE) type TY_XML_T
raising
ZCX_BC_TABLE_INTROSPECTOR .
protected section.
*"* protected components of class ZCL_BC_TABLE_INTROSPECTOR
*"* do not include other source files here!!!
private section.
*"* private components of class ZCL_BC_TABLE_INTROSPECTOR
*"* do not include other source files here!!!
type-pools ABAP .
data USE_HEADER_RECORD type ABAP_BOOL .
data USE_COLUMN_ALIGNMENT type ABAP_BOOL .
data HEADER_DATA_REF type ref to DATA .
data TABLE_DATA_REF type ref to DATA .
data RAW_TABLE_DATA_REF type ref to DATA .
data XML_DOCUMENT_REF type ref to IF_IXML_DOCUMENT .
methods CONSTRUCTOR
importing
!IM_USE_HEADER_RECORD type ABAP_BOOL
!IM_USE_COLUMN_ALIGNMENT type ABAP_BOOL
!IM_HEADER_DATA_REF type ref to DATA
!IM_TABLE_DATA_REF type ref to DATA
!IM_RAW_TABLE_DATA_REF type ref to DATA
!IM_XML_DOCUMENT_REF type ref to IF_IXML_DOCUMENT .
class-methods GET_INTERNAL_TABLE_METADATA
importing
!IM_TABLE type ANY TABLE
!IM_COLUMNS type CSEQUENCE optional
exporting
value(EX_STRUCT_DESCR) type ref to CL_ABAP_STRUCTDESCR
value(EX_XML_STRUCT_DESCR) type ref to CL_ABAP_STRUCTDESCR
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods GET_TABLE_METADATA
importing
!IM_DBTAB type CSEQUENCE
!IM_COLUMNS type CSEQUENCE
exporting
value(EX_STRUCT_DESCR) type ref to CL_ABAP_STRUCTDESCR
raising
ZCX_BC_TABLE_INTROSPECTOR .
class CL_ABAP_STRUCTDESCR definition load .
class-methods RECURSIVE_FILTER_COLUMNS
importing
!IM_COLUMNS type CSEQUENCE
!IM_COMPONENTS type CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE
exporting
value(EX_COMPONENTS) type CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods POPULATE_HEADER
importing
!IM_USE_COLUMN_ALIGNMENT type ABAP_BOOL
!IM_POINT_HEADER_TO_DDIC type ABAP_BOOL
!IM_STRUCT_DESCR type ref to CL_ABAP_STRUCTDESCR
exporting
value(EX_STRUCT_REF) type ref to DATA
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods EXECUTE_SQL
importing
!IM_DBTAB type CSEQUENCE
!IM_WHERE_CLAUSE type CSEQUENCE
!IM_MAX_ROWS type I
!IM_STRUCT_DESCR type ref to CL_ABAP_STRUCTDESCR
exporting
value(EX_TABLE_REF) type ref to DATA
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods POPULATE_TABLE
importing
!IM_TABLE type ANY TABLE
!IM_STRUCT_DESCR type ref to CL_ABAP_STRUCTDESCR
exporting
value(EX_TABLE_REF) type ref to DATA
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods BUILD_FORMATTED_COMPONENTS
importing
!IM_USE_COLUMN_ALIGNMENT type ABAP_BOOL
!IM_ENCLOSE_STRINGS type ABAP_BOOL
!IM_STRUCT_DESCR type ref to CL_ABAP_STRUCTDESCR
exporting
value(EX_FORMATTED_STRUCT_DESCR) type ref to CL_ABAP_STRUCTDESCR
value(EX_FORMATTED_TABLE_DESCR) type ref to CL_ABAP_STRUCTDESCR
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods POPULATE_FORMATTED_HEADER
importing
!IM_DELIMITER type TY_DELIMITER optional
!IM_ENCLOSE_STRINGS type ABAP_BOOL
!IM_FORMATTED_STRUCT_DESCR type ref to CL_ABAP_STRUCTDESCR
!IM_STRUCT_REF type ref to DATA
exporting
value(EX_FORMATTED_STRUCT_REF) type ref to DATA
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods POPULATE_FORMATTED_TABLE
importing
!IM_DELIMITER type TY_DELIMITER optional
!IM_ENCLOSE_STRINGS type ABAP_BOOL
!IM_FORMAT_TIME type ABAP_BOOL optional
!IM_FORMAT_DATE type ABAP_BOOL optional
!IM_FORMATTED_TABLE_DESCR type ref to CL_ABAP_STRUCTDESCR
!IM_TABLE_REF type ref to DATA
exporting
value(EX_FORMATTED_TABLE_REF) type ref to DATA
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods NORMALIZE_LINE_FORMAT
importing
!IM_USE_COLUMN_ALIGNMENT type ABAP_BOOL
!IM_DATA type ANY
exporting
value(EX_TABLE) type STRING_TABLE
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods POPULATE_XML_TABLE
importing
!IM_TABLE type ANY TABLE
!IM_XML_STRUCT_DESCR type ref to CL_ABAP_STRUCTDESCR
exporting
value(EX_XML_TABLE_REF) type ref to DATA
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods GET_DDIC_NAME
importing
!IM_COMPONENT type CL_ABAP_STRUCTDESCR=>COMPONENT
!IM_POINT_HEADER_TO_DDIC type ABAP_BOOL
exporting
value(EX_NAME) type STRING
raising
ZCX_BC_TABLE_INTROSPECTOR .
class-methods POPULATE_XML_DOCUMENT
importing
!IM_USE_HEADER_RECORD type ABAP_BOOL optional
!IM_POINT_HEADER_TO_DDIC type ABAP_BOOL optional
!IM_FORMAT_TIME type ABAP_BOOL optional
!IM_FORMAT_DATE type ABAP_BOOL optional
!IM_AUTHOR type STRING optional
!IM_SHEET_NAME type STRING optional
!IM_FREEZE_HEADER type ABAP_BOOL optional
!IM_HEADER_COLOR type TY_COLOR optional
!IM_HEADER_HEIGHT type I optional
!IM_STRING_CELL_WIDTH type I optional
!IM_POINTS_FACTOR type I optional
!IM_XML_TABLE_REF type ref to DATA
exporting
value(EX_XML_DOCUMENT_REF) type ref to IF_IXML_DOCUMENT
raising
ZCX_BC_TABLE_INTROSPECTOR .
ENDCLASS.
CLASS ZCL_BC_TABLE_INTROSPECTOR IMPLEMENTATION.
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>BUILD_FORMATTED_COMPONENTS
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_USE_COLUMN_ALIGNMENT TYPE ABAP_BOOL
* | [--->] IM_ENCLOSE_STRINGS TYPE ABAP_BOOL
* | [--->] IM_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_FORMATTED_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_FORMATTED_TABLE_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method build_formatted_components.
*-- object references
data: lo_elemdescr type ref to cl_abap_elemdescr,
lo_header_struct_descr type ref to cl_abap_structdescr,
lo_table_struct_descr type ref to cl_abap_structdescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_components type cl_abap_structdescr=>component_table,
lt_hdr_components_interleaved type cl_abap_structdescr=>component_table,
lt_rec_components_interleaved type cl_abap_structdescr=>component_table.
*-- structure defintion
data: ls_component type abap_componentdescr,
ls_component_temp type abap_componentdescr.
*-- local variables
data: lv_output_length type i,
lv_delimiter_name type char5,
lv_counter type n length 4,
lv_error_msg type string.
lt_components = im_struct_descr->get_components( ).
*-- loop thru all components and convert to flat, character-based, delimited collection suitable for output in flat file
loop at lt_components into ls_component.
try.
*-- create new character-based component based on length of ddic description (for header)
clear: ls_component_temp.
lo_elemdescr ?= ls_component-type.
if im_use_column_alignment eq abap_true.
*-- account for string elements which have no defined length
if lo_elemdescr->output_length eq 0.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = 255 ).
else.
lv_output_length = lo_elemdescr->output_length.
if im_enclose_strings eq abap_true and
( lo_elemdescr->type_kind eq cl_abap_typedescr=>typekind_char or
lo_elemdescr->type_kind eq cl_abap_typedescr=>typekind_string ).
add 2 to lv_output_length.
endif.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = lv_output_length ).
endif.
else.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = 40 ).
endif.
ls_component_temp-name = ls_component-name.
append ls_component_temp to lt_hdr_components_interleaved.
*-- cast to cl_abap_elemdescr, retrieve output length, and create new character-based component based on this length (for record)
clear: ls_component_temp.
lo_elemdescr ?= ls_component-type.
if lo_elemdescr->output_length eq 0.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = 255 ).
else.
lv_output_length = lo_elemdescr->output_length.
if im_enclose_strings eq abap_true and
( lo_elemdescr->type_kind eq cl_abap_typedescr=>typekind_char or
lo_elemdescr->type_kind eq cl_abap_typedescr=>typekind_string ).
add 2 to lv_output_length.
endif.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = lv_output_length ).
endif.
ls_component_temp-name = ls_component-name.
append ls_component_temp to lt_rec_components_interleaved.
*-- create dynamically named delimiter component
clear: ls_component_temp.
add 1 to lv_counter.
concatenate 'd' lv_counter into lv_delimiter_name.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = 1 ).
ls_component_temp-name = lv_delimiter_name.
append ls_component_temp to lt_hdr_components_interleaved.
append ls_component_temp to lt_rec_components_interleaved.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
endloop.
try.
lo_header_struct_descr =
cl_abap_structdescr=>create( lt_hdr_components_interleaved ).
lo_table_struct_descr =
cl_abap_structdescr=>create( lt_rec_components_interleaved ).
catch cx_sy_struct_creation
cx_sy_table_creation into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
*-- return new delimited component structure
ex_formatted_struct_descr = lo_header_struct_descr.
ex_formatted_table_descr = lo_table_struct_descr.
endmethod. "build_formatted_components
* ---------------------------------------------------------------------------------------+
* | Instance Private Method ZCL_BC_TABLE_INTROSPECTOR->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_USE_HEADER_RECORD TYPE ABAP_BOOL
* | [--->] IM_USE_COLUMN_ALIGNMENT TYPE ABAP_BOOL
* | [--->] IM_HEADER_DATA_REF TYPE REF TO DATA
* | [--->] IM_TABLE_DATA_REF TYPE REF TO DATA
* | [--->] IM_RAW_TABLE_DATA_REF TYPE REF TO DATA
* | [--->] IM_XML_DOCUMENT_REF TYPE REF TO IF_IXML_DOCUMENT
* +--------------------------------------------------------------------------------------
method constructor.
use_header_record = im_use_header_record.
use_column_alignment = im_use_column_alignment.
header_data_ref = im_header_data_ref.
table_data_ref = im_table_data_ref.
raw_table_data_ref = im_raw_table_data_ref.
xml_document_ref = im_xml_document_ref.
endmethod. "constructor
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>EXECUTE_SQL
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_DBTAB TYPE CSEQUENCE
* | [--->] IM_WHERE_CLAUSE TYPE CSEQUENCE
* | [--->] IM_MAX_ROWS TYPE I
* | [--->] IM_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_TABLE_REF TYPE REF TO DATA
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method execute_sql.
*-- object references
data: lo_table_descr type ref to cl_abap_tabledescr,
lo_root_exc type ref to cx_root.
*-- local variables
data: lv_structdata_ref type ref to data,
lv_error_msg type string,
lv_error_msg_temp type string.
*-- field symbols
field-symbols: type standard table,
type any.
try.
lo_table_descr = cl_abap_tabledescr=>create( im_struct_descr ).
create data ex_table_ref type handle lo_table_descr.
assign ex_table_ref->* to .
create data lv_structdata_ref type handle im_struct_descr.
assign lv_structdata_ref->* to .
catch cx_sy_create_data_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
if im_max_rows lt 0.
lv_error_msg = 'With "UP TO n ROWS", specify only positive values'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
try.
select *
from (im_dbtab)
into corresponding fields of table
up to im_max_rows rows
where (im_where_clause).
catch cx_sy_sql_error into lo_root_exc.
clear: lv_error_msg_temp.
lv_error_msg = 'Error in SQL execution'.
lv_error_msg_temp = lo_root_exc->get_text( ).
if lv_error_msg_temp is not initial.
concatenate lv_error_msg ': ' lv_error_msg_temp into lv_error_msg respecting blanks.
endif.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
endmethod. "execute_sql
* ---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_BC_TABLE_INTROSPECTOR=>FACTORY_USING_SQL
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_DBTAB TYPE CSEQUENCE
* | [--->] IM_COLUMNS TYPE CSEQUENCE(optional)
* | [--->] IM_WHERE_CLAUSE TYPE CSEQUENCE(optional)
* | [--->] IM_MAX_ROWS TYPE I(optional)
* | [--->] IM_DELIMITER TYPE TY_DELIMITER (default =',')
* | [--->] IM_USE_HEADER_RECORD TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_USE_COLUMN_ALIGNMENT TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_POINT_HEADER_TO_DDIC TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_ENCLOSE_STRINGS TYPE ABAP_BOOL (default =ABAP_FALSE)
* | [--->] IM_FORMAT_TIME TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_FORMAT_DATE TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_AUTHOR TYPE STRING(optional)
* | [--->] IM_SHEET_NAME TYPE STRING(optional)
* | [--->] IM_FREEZE_HEADER TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_HEADER_COLOR TYPE TY_COLOR (default =E_COLOR-STANDARD)
* | [--->] IM_HEADER_HEIGHT TYPE I (default =5)
* | [--->] IM_STRING_CELL_WIDTH TYPE I (default =80)
* | [--->] IM_POINTS_FACTOR TYPE I (default =8)
* | [<---] EX_TABLE_INTROSPECTOR TYPE REF TO ZCL_BC_TABLE_INTROSPECTOR
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method factory_using_sql.
*-- object references
data: lo_struct_descr type ref to cl_abap_structdescr,
lo_formatted_struct_descr type ref to cl_abap_structdescr,
lo_formatted_table_descr type ref to cl_abap_structdescr,
lo_table_ref type ref to data,
lo_xml_table_ref type ref to data,
lo_formatted_table_ref type ref to data,
lo_struct_ref type ref to data,
lo_formatted_struct_ref type ref to data,
lo_xml_document_ref type ref to if_ixml_document.
*-- get flattened components according to columns
call method get_table_metadata(
exporting
im_dbtab = im_dbtab
im_columns = im_columns
importing
ex_struct_descr = lo_struct_descr ).
*-- populate header structure
call method populate_header(
exporting
im_use_column_alignment = im_use_column_alignment
im_point_header_to_ddic = im_point_header_to_ddic
im_struct_descr = lo_struct_descr
importing
ex_struct_ref = lo_struct_ref ).
*-- execute SQL query and populate table structure
call method execute_sql(
exporting
im_dbtab = im_dbtab
im_where_clause = im_where_clause
im_max_rows = im_max_rows
im_struct_descr = lo_struct_descr
importing
ex_table_ref = lo_table_ref ).
*-- populate xml table structure - no long text considered
lo_xml_table_ref = lo_table_ref.
*-- create new header and table structures with delimiters inserted
call method build_formatted_components(
exporting
im_use_column_alignment = im_use_column_alignment
im_enclose_strings = im_enclose_strings
im_struct_descr = lo_struct_descr
importing
ex_formatted_struct_descr = lo_formatted_struct_descr
ex_formatted_table_descr = lo_formatted_table_descr ).
*-- populate formatted header
call method populate_formatted_header(
exporting
im_delimiter = im_delimiter
im_enclose_strings = im_enclose_strings
im_formatted_struct_descr = lo_formatted_struct_descr
im_struct_ref = lo_struct_ref
importing
ex_formatted_struct_ref = lo_formatted_struct_ref ).
*-- populate formatted table
call method populate_formatted_table(
exporting
im_delimiter = im_delimiter
im_enclose_strings = im_enclose_strings
im_format_time = im_format_time
im_format_date = im_format_date
im_formatted_table_descr = lo_formatted_table_descr
im_table_ref = lo_table_ref
importing
ex_formatted_table_ref = lo_formatted_table_ref ).
*-- populate xml document
call method populate_xml_document(
exporting
im_use_header_record = im_use_header_record
im_point_header_to_ddic = im_point_header_to_ddic
im_format_time = im_format_time
im_format_date = im_format_date
im_author = im_author
im_sheet_name = im_sheet_name
im_freeze_header = im_freeze_header
im_header_color = im_header_color
im_header_height = im_header_height
im_string_cell_width = im_string_cell_width
im_points_factor = im_points_factor
im_xml_table_ref = lo_xml_table_ref
importing
ex_xml_document_ref = lo_xml_document_ref ).
*-- finally we instantiate the class
create object ex_table_introspector
exporting
im_use_header_record = im_use_header_record
im_use_column_alignment = im_use_column_alignment
im_header_data_ref = lo_formatted_struct_ref
im_table_data_ref = lo_formatted_table_ref
im_raw_table_data_ref = lo_table_ref
im_xml_document_ref = lo_xml_document_ref.
endmethod. "factory_using_sql
* ---------------------------------------------------------------------------------------+
* | Static Public Method ZCL_BC_TABLE_INTROSPECTOR=>FACTORY_USING_TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_TABLE TYPE ANY TABLE
* | [--->] IM_COLUMNS TYPE CSEQUENCE(optional)
* | [--->] IM_DELIMITER TYPE TY_DELIMITER (default =',')
* | [--->] IM_USE_HEADER_RECORD TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_USE_COLUMN_ALIGNMENT TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_POINT_HEADER_TO_DDIC TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_ENCLOSE_STRINGS TYPE ABAP_BOOL (default =ABAP_FALSE)
* | [--->] IM_FORMAT_TIME TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_FORMAT_DATE TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_AUTHOR TYPE STRING(optional)
* | [--->] IM_SHEET_NAME TYPE STRING(optional)
* | [--->] IM_FREEZE_HEADER TYPE ABAP_BOOL (default =ABAP_TRUE)
* | [--->] IM_HEADER_COLOR TYPE TY_COLOR (default =E_COLOR-STANDARD)
* | [--->] IM_HEADER_HEIGHT TYPE I (default =5)
* | [--->] IM_STRING_CELL_WIDTH TYPE I (default =80)
* | [--->] IM_POINTS_FACTOR TYPE I (default =8)
* | [<---] EX_TABLE_INTROSPECTOR TYPE REF TO ZCL_BC_TABLE_INTROSPECTOR
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method factory_using_table.
*-- object references
data: lo_struct_descr type ref to cl_abap_structdescr,
lo_xml_struct_descr type ref to cl_abap_structdescr,
lo_formatted_struct_descr type ref to cl_abap_structdescr,
lo_formatted_table_descr type ref to cl_abap_structdescr,
lo_table_ref type ref to data,
lo_xml_table_ref type ref to data,
lo_formatted_table_ref type ref to data,
lo_struct_ref type ref to data,
lo_formatted_struct_ref type ref to data,
lo_xml_document_ref type ref to if_ixml_document.
*-- get flattened components according to columns
call method get_internal_table_metadata(
exporting
im_table = im_table
im_columns = im_columns
importing
ex_struct_descr = lo_struct_descr
ex_xml_struct_descr = lo_xml_struct_descr ).
*-- populate header structure
call method populate_header(
exporting
im_use_column_alignment = im_use_column_alignment
im_point_header_to_ddic = im_point_header_to_ddic
im_struct_descr = lo_struct_descr
importing
ex_struct_ref = lo_struct_ref ).
*-- populate table structure
call method populate_table(
exporting
im_table = im_table
im_struct_descr = lo_struct_descr
importing
ex_table_ref = lo_table_ref ).
*-- populate xml table structure
call method populate_xml_table(
exporting
im_table = im_table
im_xml_struct_descr = lo_xml_struct_descr
importing
ex_xml_table_ref = lo_xml_table_ref ).
*-- create new header and table structures with delimiters interleaved
call method build_formatted_components(
exporting
im_use_column_alignment = im_use_column_alignment
im_enclose_strings = im_enclose_strings
im_struct_descr = lo_struct_descr
importing
ex_formatted_struct_descr = lo_formatted_struct_descr
ex_formatted_table_descr = lo_formatted_table_descr ).
*-- populate formatted header
call method populate_formatted_header(
exporting
im_delimiter = im_delimiter
im_enclose_strings = im_enclose_strings
im_formatted_struct_descr = lo_formatted_struct_descr
im_struct_ref = lo_struct_ref
importing
ex_formatted_struct_ref = lo_formatted_struct_ref ).
*-- populate formatted table
call method populate_formatted_table(
exporting
im_delimiter = im_delimiter
im_enclose_strings = im_enclose_strings
im_format_time = im_format_time
im_format_date = im_format_date
im_formatted_table_descr = lo_formatted_table_descr
im_table_ref = lo_table_ref
importing
ex_formatted_table_ref = lo_formatted_table_ref ).
*-- populate xml document
call method populate_xml_document(
exporting
im_use_header_record = im_use_header_record
im_point_header_to_ddic = im_point_header_to_ddic
im_format_time = im_format_time
im_format_date = im_format_date
im_author = im_author
im_sheet_name = im_sheet_name
im_freeze_header = im_freeze_header
im_header_color = im_header_color
im_header_height = im_header_height
im_string_cell_width = im_string_cell_width
im_points_factor = im_points_factor
im_xml_table_ref = lo_xml_table_ref
importing
ex_xml_document_ref = lo_xml_document_ref ).
*-- finally we instantiate the class
create object ex_table_introspector
exporting
im_use_header_record = im_use_header_record
im_use_column_alignment = im_use_column_alignment
im_header_data_ref = lo_formatted_struct_ref
im_table_data_ref = lo_formatted_table_ref
im_raw_table_data_ref = lo_table_ref
im_xml_document_ref = lo_xml_document_ref.
endmethod. "factory_using_table
* ---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_BC_TABLE_INTROSPECTOR->GET_ALV_RENDITION
* +-------------------------------------------------------------------------------------------------+
* | [<---] EX_ALV_TABLE TYPE REF TO CL_SALV_TABLE
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_alv_rendition.
*-- object references
data: lo_root_exc type ref to cx_root.
*-- local variables
data: lv_error_msg type string.
*-- field symbols
field-symbols: type standard table.
if raw_table_data_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
try.
assign raw_table_data_ref->* to .
cl_salv_table=>factory(
importing r_salv_table = ex_alv_table
changing t_table = ).
catch cx_salv_msg into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
endmethod. "get_alv_rendition
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>GET_DDIC_NAME
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_COMPONENT TYPE CL_ABAP_STRUCTDESCR=>COMPONENT
* | [--->] IM_POINT_HEADER_TO_DDIC TYPE ABAP_BOOL
* | [<---] EX_NAME TYPE STRING
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_ddic_name.
*-- object references
data: lo_elemdescr type ref to cl_abap_elemdescr,
lo_root_exc type ref to cx_root.
*-- structure defintion
data: ls_dfies type dfies.
*-- local variables
data: lv_normalized_name type c length 255,
lv_error_msg type string.
try.
lo_elemdescr ?= im_component-type.
*-- retrieve ddic description where relevant
if im_point_header_to_ddic eq abap_false.
lv_normalized_name = im_component-name.
translate lv_normalized_name to lower case.
else.
*-- if ddic element, retrieve field label
if lo_elemdescr->is_ddic_type( ) eq abap_true.
ls_dfies = lo_elemdescr->get_ddic_field( ).
lv_normalized_name = ls_dfies-scrtext_l.
endif.
*-- if not ddic element (or ddic description empty), set field label to pretty printed name of element
if lv_normalized_name is initial.
lv_normalized_name = im_component-name.
replace all occurrences of '_' in lv_normalized_name with ` `.
translate lv_normalized_name to lower case.
translate lv_normalized_name+0(1) to upper case.
endif.
endif.
ex_name = lv_normalized_name.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
endmethod. "get_ddic_name
* ---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_BC_TABLE_INTROSPECTOR->GET_FILE_RENDITION
* +-------------------------------------------------------------------------------------------------+
* | [<---] EX_FILE_TABLE TYPE STRING_TABLE
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_file_rendition.
*-- internal table defintion
data: lt_header_table type string_table,
lt_body_table type string_table,
lt_file_table type string_table.
*-- local variables
data: lv_error_msg type string.
*-- field symbols
field-symbols: type any,
type standard table.
if table_data_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
assign header_data_ref->* to .
assign table_data_ref->* to .
*-- normalize header and body
call method normalize_line_format
exporting
im_use_column_alignment = use_column_alignment
im_data =
importing
ex_table = lt_header_table.
call method normalize_line_format
exporting
im_use_column_alignment = use_column_alignment
im_data =
importing
ex_table = lt_body_table.
if use_header_record eq abap_true.
append lines of lt_header_table to lt_file_table.
endif.
append lines of lt_body_table to lt_file_table.
ex_file_table[] = lt_file_table[].
endmethod. "get_file_rendition
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>GET_INTERNAL_TABLE_METADATA
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_TABLE TYPE ANY TABLE
* | [--->] IM_COLUMNS TYPE CSEQUENCE(optional)
* | [<---] EX_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_XML_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_internal_table_metadata.
*-- object references
data: lo_struct_descr type ref to cl_abap_structdescr,
lo_table_descr type ref to cl_abap_tabledescr,
lo_elem_objectdescr type ref to cl_abap_objectdescr,
lo_xml_struct_descr type ref to cl_abap_structdescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_original_components type cl_abap_structdescr=>component_table,
lt_components_filtered type cl_abap_structdescr=>component_table,
lt_components type cl_abap_structdescr=>component_table,
lt_xml_components type cl_abap_structdescr=>component_table.
*-- structure defintion
data: ls_component_filtered like line of lt_components_filtered.
*-- local variables
data: lv_error_msg type string.
try.
lo_table_descr ?= cl_abap_tabledescr=>describe_by_data( im_table ).
lo_struct_descr ?= lo_table_descr->get_table_line_type( ).
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
lt_original_components = lo_struct_descr->get_components( ).
*-- recursive call - as side effect, components are flattened
call method recursive_filter_columns(
exporting
im_columns = im_columns
im_components = lt_original_components
importing
ex_components = lt_components_filtered ).
if lt_components_filtered[] is initial.
lv_error_msg = 'No columns found according to search criteria'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
*-- standard component set includes elements only
lo_elem_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_elemdescr' ).
loop at lt_components_filtered into ls_component_filtered.
if lo_elem_objectdescr->applies_to( ls_component_filtered-type ) eq 'X'.
append ls_component_filtered to lt_components.
endif.
endloop.
*-- xml component set includes elements and tables
lt_xml_components[] = lt_components_filtered[].
try.
lo_struct_descr =
cl_abap_structdescr=>create( lt_components ).
lo_xml_struct_descr =
cl_abap_structdescr=>create( lt_xml_components ).
catch cx_sy_struct_creation into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
ex_struct_descr = lo_struct_descr.
ex_xml_struct_descr = lo_xml_struct_descr.
endmethod. "get_internal_table_metadata
* ---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_BC_TABLE_INTROSPECTOR->GET_SOLIX_RENDITION
* +-------------------------------------------------------------------------------------------------+
* | [<---] EX_SOLIX_TABLE TYPE SOLIX_TAB
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_solix_rendition.
*-- object references
data: lo_root_exc type ref to cx_bcs.
*-- internal table defintion
data: lt_solix type solix_tab,
lt_file_table type string_table.
*-- structure defintion
data: ls_file_table like line of lt_file_table.
*-- local variables
data: lv_string type string,
lv_error_msg type string.
if table_data_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
call method me->get_file_rendition
importing
ex_file_table = lt_file_table.
loop at lt_file_table into ls_file_table.
concatenate
lv_string
ls_file_table
cl_abap_char_utilities=>cr_lf
into lv_string respecting blanks.
endloop.
try.
cl_bcs_convert=>string_to_solix(
exporting
iv_string = lv_string
importing
et_solix = lt_solix ).
catch cx_bcs into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
ex_solix_table[] = lt_solix[].
endmethod. "get_solix_rendition
* ---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_BC_TABLE_INTROSPECTOR->GET_SOLI_RENDITION
* +-------------------------------------------------------------------------------------------------+
* | [<---] EX_SOLI_TABLE TYPE SOLI_TAB
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_soli_rendition.
*-- object references
data: lo_root_exc type ref to cx_bcs.
*-- internal table defintion
data: lt_soli type soli_tab,
lt_file_table type string_table.
*-- structure defintion
data: ls_file_table like line of lt_file_table.
*-- local variables
data: lv_string type string,
lv_error_msg type string.
if table_data_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
call method me->get_file_rendition
importing
ex_file_table = lt_file_table.
loop at lt_file_table into ls_file_table.
concatenate
lv_string
ls_file_table
cl_abap_char_utilities=>cr_lf
into lv_string respecting blanks.
endloop.
try.
cl_bcs_convert=>string_to_soli(
exporting
iv_string = lv_string
receiving
et_soli = lt_soli ).
catch cx_bcs into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
ex_soli_table[] = lt_soli[].
endmethod. "get_soli_rendition
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>GET_TABLE_METADATA
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_DBTAB TYPE CSEQUENCE
* | [--->] IM_COLUMNS TYPE CSEQUENCE
* | [<---] EX_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_table_metadata.
*-- object references
data: lo_type_descr type ref to cl_abap_typedescr,
lo_struct_descr type ref to cl_abap_structdescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_components type cl_abap_structdescr=>component_table,
lt_components_filtered type cl_abap_structdescr=>component_table.
*-- local variables
data: lv_error_msg type string.
cl_abap_typedescr=>describe_by_name(
exporting p_name = im_dbtab
receiving p_descr_ref = lo_type_descr
exceptions type_not_found = 4 ).
if sy-subrc = 4.
if im_dbtab is initial.
lv_error_msg = 'No table specified'.
else.
concatenate 'Table ' im_dbtab ' not found' into lv_error_msg respecting blanks.
condense lv_error_msg.
endif.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
try.
lo_struct_descr ?= lo_type_descr.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
lt_components = lo_struct_descr->get_components( ).
*-- recursive call - as side effect, components are flattened
call method recursive_filter_columns(
exporting
im_columns = im_columns
im_components = lt_components
importing
ex_components = lt_components_filtered ).
if lt_components_filtered[] is initial.
lv_error_msg = 'No columns found according to search criteria'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
try.
lo_struct_descr =
cl_abap_structdescr=>create( lt_components_filtered ).
catch cx_sy_struct_creation
cx_sy_table_creation into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
ex_struct_descr = lo_struct_descr.
endmethod. "get_table_metadata
* ---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_BC_TABLE_INTROSPECTOR->GET_XML_RENDITION
* +-------------------------------------------------------------------------------------------------+
* | [<---] EX_XML_TABLE TYPE TY_XML_T
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_xml_rendition.
*-- object references
data: lo_ixml_factory type ref to if_ixml,
lo_stream_factory type ref to if_ixml_stream_factory,
lo_ostream type ref to if_ixml_ostream,
lo_renderer type ref to if_ixml_renderer.
*-- local variables
data: lv_error_msg type string.
*-- constants
data: lc_ampersand type string value '&'.
if xml_document_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
*-- get reference to iXML factory object
lo_ixml_factory = cl_ixml=>create( ).
*-- get stream factory
lo_stream_factory = lo_ixml_factory->create_stream_factory( ).
*-- create table-based output stream
lo_ostream = lo_stream_factory->create_ostream_itable( ex_xml_table ).
*-- create renderer and set options
lo_renderer = lo_ixml_factory->create_renderer(
ostream = lo_ostream
document = xml_document_ref ).
call method lo_renderer->set_no_escaping
exporting
no_escaping = lc_ampersand.
call method lo_renderer->set_normalizing( ).
*-- render document
lo_renderer->render( ).
endmethod. "get_xml_rendition
* ---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_BC_TABLE_INTROSPECTOR->GET_XML_SOLIX_RENDITION
* +-------------------------------------------------------------------------------------------------+
* | [<---] EX_XML_SOLIX_TABLE TYPE SOLIX_TAB
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method get_xml_solix_rendition.
*-- object references
data: lo_ixml_factory type ref to if_ixml,
lo_stream_factory type ref to if_ixml_stream_factory,
lo_ostream type ref to if_ixml_ostream,
lo_renderer type ref to if_ixml_renderer,
lo_root_exc type ref to cx_bcs.
*-- internal table defintion
data: lt_solix type solix_tab.
*-- local variables
data: lv_xml_xstring type xstring,
lv_string type string,
lv_error_msg type string.
*-- constants
data: lc_ampersand type string value '&'.
if xml_document_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
*-- get reference to iXML factory object
lo_ixml_factory = cl_ixml=>create( ).
*-- get stream factory
lo_stream_factory = lo_ixml_factory->create_stream_factory( ).
*-- create xstring-based output stream
lo_ostream = lo_stream_factory->create_ostream_xstring( lv_xml_xstring ).
*-- create renderer and set options
lo_renderer = lo_ixml_factory->create_renderer(
ostream = lo_ostream
document = xml_document_ref ).
call method lo_renderer->set_no_escaping
exporting
no_escaping = lc_ampersand.
call method lo_renderer->set_normalizing( ).
*-- render document
lo_renderer->render( ).
*-- convert to solix tab
try.
cl_bcs_convert=>xstring_to_solix(
exporting
iv_xstring = lv_xml_xstring
receiving
et_solix = lt_solix ).
catch cx_bcs into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
ex_xml_solix_table[] = lt_solix[].
endmethod. "get_solix_rendition
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>NORMALIZE_LINE_FORMAT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_USE_COLUMN_ALIGNMENT TYPE ABAP_BOOL
* | [--->] IM_DATA TYPE ANY
* | [<---] EX_TABLE TYPE STRING_TABLE
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method normalize_line_format.
*-- object references
data: lo_struct_ref type ref to data,
lo_table_ref type ref to data,
lo_struct_objectdescr type ref to cl_abap_objectdescr,
lo_table_objectdescr type ref to cl_abap_objectdescr,
lo_type_descr type ref to cl_abap_typedescr.
*-- local variables
data: lv_len type i,
lv_counter type i,
lv_line type string.
*-- field symbols
field-symbols: type any,
type standard table,
type any,
type any.
cl_abap_typedescr=>describe_by_data(
exporting p_data = im_data
receiving p_descr_ref = lo_type_descr ).
lo_struct_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_structdescr' ).
lo_table_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_tabledescr' ).
if lo_struct_objectdescr->applies_to( lo_type_descr ) eq 'X'.
*-- process structure
create data lo_struct_ref like im_data.
assign lo_struct_ref->* to .
= im_data.
lv_counter = 0.
lv_line = ''.
if im_use_column_alignment eq abap_false.
*-- build up line with condensed fields
do.
add 1 to lv_counter.
assign component lv_counter of structure to .
if sy-subrc is not initial.
exit.
endif.
shift right deleting trailing space.
shift left deleting leading space.
*-- add field to line
lv_len = strlen( ).
if lv_len ge 1.
concatenate lv_line (lv_len) into lv_line respecting blanks.
endif.
enddo.
else.
lv_len = strlen( ).
lv_line = (lv_len).
endif.
append lv_line to ex_table.
elseif lo_table_objectdescr->applies_to( lo_type_descr ) eq 'X'.
*-- process table
create data lo_table_ref like im_data.
assign lo_table_ref->* to .
= im_data.
loop at assigning .
lv_counter = 0.
lv_line = ''.
if im_use_column_alignment eq abap_false.
*-- build up line with condensed fields
do.
add 1 to lv_counter.
assign component lv_counter of structure to .
if sy-subrc is not initial.
exit.
endif.
shift right deleting trailing space.
shift left deleting leading space.
lv_len = strlen( ).
if lv_len ge 1.
concatenate lv_line (lv_len) into lv_line respecting blanks.
endif.
enddo.
else.
lv_len = strlen( ).
lv_line = (lv_len).
endif.
append lv_line to ex_table.
endloop.
endif.
endmethod. "normalize_line_format
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>POPULATE_FORMATTED_HEADER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_DELIMITER TYPE TY_DELIMITER(optional)
* | [--->] IM_ENCLOSE_STRINGS TYPE ABAP_BOOL
* | [--->] IM_FORMATTED_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [--->] IM_STRUCT_REF TYPE REF TO DATA
* | [<---] EX_FORMATTED_STRUCT_REF TYPE REF TO DATA
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method populate_formatted_header.
*-- object references
data: lo_elemdescr type ref to cl_abap_elemdescr,
lo_root_exc type ref to cx_root.
*-- local variables
data: lv_counter type i value 0,
lv_mod_result type i,
lv_string_length type i,
lv_output_length type i,
lv_repetitions type string,
lv_regex type string,
lv_error_msg type string.
*-- field symbols
field-symbols: type any,
type any,
type any.
try.
create data ex_formatted_struct_ref type handle im_formatted_struct_descr.
assign ex_formatted_struct_ref->* to . " point to results for later export
catch cx_sy_create_data_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
*-- move data to , and inject delimiters
assign im_struct_ref->* to .
move-corresponding to .
*-- iterate thru each component of interleaved structure
lv_counter = 0.
do.
add 1 to lv_counter.
assign component lv_counter of structure to .
if sy-subrc is not initial.
exit.
endif.
lv_mod_result = lv_counter mod 2.
*-- populate field
if lv_mod_result ne 0.
shift right deleting trailing space.
shift left deleting leading space.
*-- header fields are always treated as a string
if im_enclose_strings eq abap_true.
*-- build regular expression to correctly insert quotes
lo_elemdescr ?= cl_abap_elemdescr=>describe_by_data( ).
lv_output_length = lo_elemdescr->output_length - 2.
lv_string_length = strlen( ).
if lv_output_length lt lv_string_length.
lv_repetitions = lv_output_length.
else.
lv_repetitions = lv_string_length.
endif.
condense lv_repetitions.
concatenate '(^.{' lv_repetitions '})(.*$)' into lv_regex.
*-- interpolate quotes in field
replace regex lv_regex in with '"$1"'.
endif.
else.
*-- populate delimiter
= im_delimiter.
endif.
enddo.
endmethod. "populate_formatted_header
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>POPULATE_FORMATTED_TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_DELIMITER TYPE TY_DELIMITER(optional)
* | [--->] IM_ENCLOSE_STRINGS TYPE ABAP_BOOL
* | [--->] IM_FORMAT_TIME TYPE ABAP_BOOL(optional)
* | [--->] IM_FORMAT_DATE TYPE ABAP_BOOL(optional)
* | [--->] IM_FORMATTED_TABLE_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [--->] IM_TABLE_REF TYPE REF TO DATA
* | [<---] EX_FORMATTED_TABLE_REF TYPE REF TO DATA
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method populate_formatted_table.
*-- object references
data: lo_tabledescr_interleaved type ref to cl_abap_tabledescr,
lo_table_line_ref type ref to data,
lo_table_interleaved_ref type ref to data,
lo_root_exc type ref to cx_root.
*-- local variables
data: lv_error_msg type string,
lv_counter type i value 0,
lv_typekind type abap_typekind,
lv_mod_result type i,
lv_date_internal type sydatum,
lv_date_external type string,
lv_time_internal type syuzeit,
lv_time_external type string.
*-- field symbols
field-symbols: type standard table,
type standard table,
type any,
type any,
like line of cl_abap_structdescr=>components,
type any,
type any.
*-- create new (empty) table based on previously built interleaved components
try.
lo_tabledescr_interleaved =
cl_abap_tabledescr=>create( im_formatted_table_descr ).
catch cx_sy_struct_creation
cx_sy_table_creation into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
try.
create data ex_formatted_table_ref type handle lo_tabledescr_interleaved.
assign ex_formatted_table_ref->* to . " point to results for later export
catch cx_sy_create_data_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
try.
*-- create table work area
assign im_table_ref->* to .
create data lo_table_line_ref like line of .
assign lo_table_line_ref->* to .
*-- create interleaved table work area
create data lo_table_interleaved_ref like line of .
assign lo_table_interleaved_ref->* to .
catch cx_sy_create_data_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
*-- move data to , and inject delimiters
loop at into .
*-- iterate thru each component of interleaved structure
lv_counter = 0.
loop at im_formatted_table_descr->components assigning .
add 1 to lv_counter.
assign component -name of structure to .
lv_mod_result = lv_counter mod 2.
*-- populate field
if lv_mod_result ne 0.
*-- lookup original field to get type kind
assign component -name of structure to .
lv_typekind = cl_abap_elemdescr=>get_data_type_kind( ).
= .
*-- apply formatting to field
check is not initial.
case lv_typekind.
when cl_abap_typedescr=>typekind_time.
if im_format_time eq abap_true.
lv_time_internal = .
try.
call method cl_abap_timefm=>conv_time_int_to_ext
exporting
time_int = lv_time_internal
importing
time_ext = lv_time_external.
= lv_time_external.
catch cx_parameter_invalid_range.
clear .
endtry.
endif.
when cl_abap_typedescr=>typekind_date.
if im_format_date eq abap_true.
lv_date_internal = .
try.
call method cl_abap_datfm=>conv_date_int_to_ext
exporting
im_datint = lv_date_internal
importing
ex_datext = lv_date_external.
= lv_date_external.
catch cx_abap_datfm_format_unknown.
clear .
endtry.
endif.
when cl_abap_typedescr=>typekind_string
or cl_abap_typedescr=>typekind_char.
if im_enclose_strings eq abap_true.
replace all occurrences of '"' in with ''''.
concatenate '"' '"' into .
else.
*-- remove delimiter when not escaped with quotes
replace all occurrences of im_delimiter in with ` `.
endif.
when cl_abap_typedescr=>typekind_num
or cl_abap_typedescr=>typekind_packed
or cl_abap_typedescr=>typekind_int
or cl_abap_typedescr=>typekind_float.
call function 'CLOI_PUT_SIGN_IN_FRONT'
changing
value = .
endcase.
shift right deleting trailing space.
shift left deleting leading space.
else.
*-- populate delimiter
= im_delimiter.
endif.
endloop.
append to .
endloop.
endmethod. "populate_formatted_table
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>POPULATE_HEADER
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_USE_COLUMN_ALIGNMENT TYPE ABAP_BOOL
* | [--->] IM_POINT_HEADER_TO_DDIC TYPE ABAP_BOOL
* | [--->] IM_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_STRUCT_REF TYPE REF TO DATA
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method populate_header.
*-- object references
data: lo_elemdescr type ref to cl_abap_elemdescr,
lo_struct_descr type ref to cl_abap_structdescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_components type cl_abap_structdescr=>component_table,
lt_hdr_components type cl_abap_structdescr=>component_table.
*-- structure defintion
data: ls_component type abap_componentdescr,
ls_hdr_component type abap_componentdescr,
ls_component_temp type abap_componentdescr,
ls_dfies type dfies.
*-- local variables
data: lv_ddic_name type string,
lv_error_msg type string.
*-- field symbols
field-symbols: type any,
type any.
*-- call get_components to populate components from structure
lt_components = im_struct_descr->get_components( ).
loop at lt_components into ls_component.
*-- create new structure based on structure passed thru
try.
clear: ls_component_temp.
lo_elemdescr ?= ls_component-type.
if im_use_column_alignment eq abap_true.
*-- account for string elements which have no defined length
if lo_elemdescr->output_length eq 0.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = 255 ).
else.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = lo_elemdescr->output_length ).
endif.
else.
ls_component_temp-type = cl_abap_elemdescr=>get_c( p_length = 40 ).
endif.
ls_component_temp-name = ls_component-name.
append ls_component_temp to lt_hdr_components.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
endloop.
*-- get structure description from newly created component table
try.
lo_struct_descr =
cl_abap_structdescr=>create( lt_hdr_components ).
catch cx_sy_struct_creation into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
*-- now populate each field from previous ddic lookup
try.
create data ex_struct_ref type handle lo_struct_descr.
assign ex_struct_ref->* to .
catch cx_sy_create_data_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
loop at lt_hdr_components into ls_hdr_component.
assign component ls_hdr_component-name of structure to .
*-- lookup original component and read element description
read table lt_components with key name = ls_hdr_component-name into ls_component.
call method get_ddic_name
exporting
im_component = ls_component
im_point_header_to_ddic = im_point_header_to_ddic
importing
ex_name = lv_ddic_name.
= lv_ddic_name.
endloop.
endmethod. "populate_header
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>POPULATE_TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_TABLE TYPE ANY TABLE
* | [--->] IM_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_TABLE_REF TYPE REF TO DATA
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method populate_table.
*-- object references
data: lo_src_table_descr type ref to cl_abap_tabledescr,
lo_src_table_ref type ref to data,
lo_src_struct_descr type ref to cl_abap_structdescr,
lo_src_struct_ref type ref to data,
lo_dst_table_ref type ref to data,
lo_dst_struct_ref type ref to data,
lo_table_descr type ref to cl_abap_tabledescr,
lo_root_exc type ref to cx_root.
*-- local variables
data: lv_error_msg type string.
*-- field symbols
field-symbols: type standard table,
type any,
type standard table,
type any.
*-- prepare source table structures
try.
lo_src_table_descr ?= cl_abap_tabledescr=>describe_by_data( im_table ).
lo_src_struct_descr ?= lo_src_table_descr->get_table_line_type( ).
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
create data lo_src_table_ref type handle lo_src_table_descr.
assign lo_src_table_ref->* to .
create data lo_src_struct_ref type handle lo_src_struct_descr.
assign lo_src_struct_ref->* to .
= im_table.
*-- prepare destination table structures (descriptions passed represent destination)
lo_table_descr = cl_abap_tabledescr=>create( im_struct_descr ).
create data lo_dst_table_ref type handle lo_table_descr.
assign lo_dst_table_ref->* to .
create data lo_dst_struct_ref type handle im_struct_descr.
assign lo_dst_struct_ref->* to .
*-- copy data between tables
loop at into .
move-corresponding to .
append to .
endloop.
ex_table_ref = lo_dst_table_ref.
endmethod. "populate_table
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>POPULATE_XML_DOCUMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_USE_HEADER_RECORD TYPE ABAP_BOOL(optional)
* | [--->] IM_POINT_HEADER_TO_DDIC TYPE ABAP_BOOL(optional)
* | [--->] IM_FORMAT_TIME TYPE ABAP_BOOL(optional)
* | [--->] IM_FORMAT_DATE TYPE ABAP_BOOL(optional)
* | [--->] IM_AUTHOR TYPE STRING(optional)
* | [--->] IM_SHEET_NAME TYPE STRING(optional)
* | [--->] IM_FREEZE_HEADER TYPE ABAP_BOOL(optional)
* | [--->] IM_HEADER_COLOR TYPE TY_COLOR(optional)
* | [--->] IM_HEADER_HEIGHT TYPE I(optional)
* | [--->] IM_STRING_CELL_WIDTH TYPE I(optional)
* | [--->] IM_POINTS_FACTOR TYPE I(optional)
* | [--->] IM_XML_TABLE_REF TYPE REF TO DATA
* | [<---] EX_XML_DOCUMENT_REF TYPE REF TO IF_IXML_DOCUMENT
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method populate_xml_document.
*-- type pools
type-pools: ixml.
*-- object references
data: lo_ixml_factory type ref to if_ixml,
lo_excel_pi type ref to if_ixml_pi_parsed,
lo_document type ref to if_ixml_document,
lo_element_root type ref to if_ixml_element,
lo_element_worksheet type ref to if_ixml_element,
lo_element_properties type ref to if_ixml_element,
lo_element_options type ref to if_ixml_element,
lo_element_selected type ref to if_ixml_element,
lo_element_freezepanes type ref to if_ixml_element,
lo_element_frozennosplit type ref to if_ixml_element,
lo_element_splithorizontal type ref to if_ixml_element,
lo_element_toprowbottompane type ref to if_ixml_element,
lo_element_activepane type ref to if_ixml_element,
lo_ns_attribute type ref to if_ixml_attribute,
lo_styles type ref to if_ixml_element,
lo_style type ref to if_ixml_element,
lo_format type ref to if_ixml_element,
lo_table type ref to if_ixml_element,
lo_column type ref to if_ixml_element,
lo_row type ref to if_ixml_element,
lo_cell type ref to if_ixml_element,
lo_data type ref to if_ixml_element,
lo_struct_descr type ref to cl_abap_structdescr,
lo_table_descr type ref to cl_abap_tabledescr,
lo_elemdescr type ref to cl_abap_elemdescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_components type cl_abap_structdescr=>component_table.
*-- structure defintion
data: ls_component type abap_componentdescr.
*-- local variables
data: lv_field_type type string,
lv_field_value type string,
lv_time_internal type syuzeit,
lv_time_external type string,
lv_date_internal type sydatum,
lv_date_external type string,
lv_color type string,
lv_header_height type string,
lv_author type string,
lv_typekind type abap_typekind,
lv_style_id type string,
lv_format_code type string,
lv_error_msg type string,
lv_sheet_name type string,
lv_column_width type string,
lv_output_length type i,
lv_ddic_length type i,
lv_actual_length type i,
lv_ddic_name type string.
*-- constants
constants: lc_max_column_width type i value 500.
*-- field symbols
field-symbols: type standard table,
type any,
type any.
if im_xml_table_ref is not bound.
lv_error_msg = 'No table data found - make sure you have instantiated the class first.'.
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endif.
*-- get reference to iXML factory object
lo_ixml_factory = cl_ixml=>create( ).
*-- create DOM-based XML document
lo_document = lo_ixml_factory->create_document( ).
*-- create processing instruction
lo_excel_pi = lo_document->create_pi_parsed( name = 'mso-application' ).
lo_excel_pi->set_attribute(
name = 'progid'
value = 'Excel.Sheet' ).
lo_document->append_child( lo_excel_pi ).
*-- create workbook root element
lo_element_root = lo_document->create_simple_element(
name = 'Workbook'
parent = lo_document ).
lo_element_root->set_attribute(
name = 'xmlns'
value = 'urn:schemas-microsoft-com:office:spreadsheet' ).
lo_ns_attribute = lo_document->create_namespace_decl(
name = 'ss'
prefix = 'xmlns'
uri = 'urn:schemas-microsoft-com:office:spreadsheet' ).
lo_element_root->set_attribute_node( lo_ns_attribute ).
lo_ns_attribute = lo_document->create_namespace_decl(
name = 'x'
prefix = 'xmlns'
uri = 'urn:schemas-microsoft-com:office:excel' ).
lo_element_root->set_attribute_node( lo_ns_attribute ).
*-- create document properties element
lo_element_properties = lo_document->create_simple_element(
name = 'DocumentProperties'
parent = lo_element_root ).
lo_element_properties->set_attribute(
name = 'xmlns'
value = 'urn:schemas-microsoft-com:office:office' ).
lv_author = im_author.
if lv_author is initial.
lv_author = sy-uname.
endif.
lo_document->create_simple_element(
name = 'Author'
value = lv_author
parent = lo_element_properties ).
*-- create styles element
lo_styles = lo_document->create_simple_element(
name = 'Styles'
parent = lo_element_root ).
*-- header style
if im_use_header_record eq abap_true.
lo_style = lo_document->create_simple_element(
name = 'Style'
parent = lo_styles ).
lo_style->set_attribute_ns(
name = 'ID'
prefix = 'ss'
value = 'Header' ).
lo_format = lo_document->create_simple_element(
name = 'Font'
parent = lo_style ).
lo_format->set_attribute_ns(
name = 'Bold'
prefix = 'ss'
value = '1' ).
case im_header_color.
when zcl_bc_table_introspector=>e_color-standard.
lv_color = '#C5D9F1'.
when zcl_bc_table_introspector=>e_color-none.
lv_color = ''.
when others.
lv_color = ''.
endcase.
if lv_color is not initial.
lo_format = lo_document->create_simple_element(
name = 'Interior'
parent = lo_style ).
lo_format->set_attribute_ns(
name = 'Color'
prefix = 'ss'
value = lv_color ).
lo_format->set_attribute_ns(
name = 'Pattern'
prefix = 'ss'
value = 'Solid' ).
endif.
lo_format = lo_document->create_simple_element(
name = 'Alignment'
parent = lo_style ).
lo_format->set_attribute_ns(
name = 'Vertical'
prefix = 'ss'
value = 'Bottom' ).
lo_format->set_attribute_ns(
name = 'WrapText'
prefix = 'ss'
value = '1' ).
endif.
*-- body style
lo_style = lo_document->create_simple_element(
name = 'Style'
parent = lo_styles ).
lo_style->set_attribute_ns(
name = 'ID'
prefix = 'ss'
value = 'Body' ).
lo_format = lo_document->create_simple_element(
name = 'Alignment'
parent = lo_style ).
lo_format->set_attribute_ns(
name = 'Vertical'
prefix = 'ss'
value = 'Bottom' ).
lo_format->set_attribute_ns(
name = 'WrapText'
prefix = 'ss'
value = '1' ).
*-- begin table analysis
assign im_xml_table_ref->* to .
try.
lo_table_descr ?= cl_abap_tabledescr=>describe_by_data_ref( im_xml_table_ref ).
lo_struct_descr ?= lo_table_descr->get_table_line_type( ).
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
lt_components = lo_struct_descr->get_components( ).
*-- create style ids for each column, setting the appropriate format
loop at lt_components into ls_component.
*-- create style id based on component type
lv_style_id = ls_component-name.
try.
lo_elemdescr ?= ls_component-type.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
*-- create new style element
lo_style = lo_document->create_simple_element(
name = 'Style'
parent = lo_styles ).
*-- set style attributes ss:ID
lo_style->set_attribute_ns(
name = 'ID'
prefix = 'ss'
value = lv_style_id ).
*-- create new number format element
lo_format = lo_document->create_simple_element(
name = 'NumberFormat'
parent = lo_style ).
lv_format_code = '@'.
*-- set number format attribute ss:format
lo_format->set_attribute_ns(
name = 'Format'
prefix = 'ss'
value = lv_format_code ).
endloop.
*-- create worksheet element
lo_element_worksheet = lo_document->create_simple_element(
name = 'Worksheet'
parent = lo_element_root ).
lv_sheet_name = im_sheet_name.
if lv_sheet_name is initial.
lv_sheet_name = 'Sheet1'.
endif.
lo_element_worksheet->set_attribute_ns(
name = 'Name'
prefix = 'ss'
value = lv_sheet_name ).
lo_table = lo_document->create_simple_element(
name = 'Table'
parent = lo_element_worksheet ).
lo_table->set_attribute_ns(
name = 'FullColumns'
prefix = 'x'
value = '1' ).
lo_table->set_attribute_ns(
name = 'FullRows'
prefix = 'x'
value = '1' ).
*-- loop thru components to build set of column elements
loop at lt_components into ls_component.
lo_column = lo_document->create_simple_element(
name = 'Column'
parent = lo_table ).
lv_style_id = ls_component-name.
*-- set style id to name of field
lo_column->set_attribute_ns(
name = 'StyleID'
prefix = 'ss'
value = lv_style_id ).
call method get_ddic_name
exporting
im_component = ls_component
im_point_header_to_ddic = im_point_header_to_ddic
importing
ex_name = lv_ddic_name.
try.
lo_elemdescr ?= ls_component-type.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
*-- get output length
if lo_elemdescr->output_length = 0.
lv_output_length = im_string_cell_width.
else.
lv_output_length = lo_elemdescr->output_length.
endif.
*-- get ddic length
lv_ddic_length = strlen( lv_ddic_name ).
*-- get actual length
if im_use_header_record eq abap_true and
lv_ddic_length gt lv_output_length.
lv_actual_length = lv_ddic_length.
else.
lv_actual_length = lv_output_length.
endif.
lv_column_width = lv_actual_length * im_points_factor.
if lv_column_width gt lc_max_column_width.
lv_column_width = lc_max_column_width.
endif.
condense lv_column_width no-gaps.
lo_column->set_attribute_ns(
name = 'Width'
prefix = 'ss'
value = lv_column_width ).
endloop.
*-- create header record
if im_use_header_record = abap_true.
lo_row = lo_document->create_simple_element(
name = 'Row'
parent = lo_table ).
*-- set header record height
if im_header_height is not initial.
lv_header_height = im_header_height * im_points_factor.
condense lv_header_height.
lo_row->set_attribute_ns(
name = 'Height'
prefix = 'ss'
value = lv_header_height ).
else.
lo_row->set_attribute_ns(
name = 'AutoFitHeight'
prefix = 'ss'
value = '1' ).
endif.
*-- iterate thru components to build header
loop at lt_components into ls_component.
*-- create header cell element
lo_cell = lo_document->create_simple_element(
name = 'Cell'
parent = lo_row ).
*-- set style
lo_cell->set_attribute_ns(
name = 'StyleID'
prefix = 'ss'
value = 'Header' ).
*-- get ddic name
call method get_ddic_name
exporting
im_component = ls_component
im_point_header_to_ddic = im_point_header_to_ddic
importing
ex_name = lv_ddic_name.
*-- set header cell value
lo_data = lo_document->create_simple_element(
name = 'Data'
value = lv_ddic_name
parent = lo_cell ).
lo_data->set_attribute_ns(
name = 'Type'
prefix = 'ss'
value = 'String' ).
endloop.
endif.
*-- iterate thru table records
loop at assigning .
lo_row = lo_document->create_simple_element(
name = 'Row'
parent = lo_table ).
*-- autofit height
lo_row->set_attribute_ns(
name = 'AutoFitHeight'
prefix = 'ss'
value = '1' ).
lt_components = lo_struct_descr->get_components( ).
*-- for each record, iterate thru components and build cell elements
loop at lt_components into ls_component.
lo_cell = lo_document->create_simple_element(
name = 'Cell'
parent = lo_row ).
lo_cell->set_attribute_ns(
name = 'StyleID'
prefix = 'ss'
value = 'Body' ).
assign component ls_component-name of structure to .
lv_typekind = cl_abap_elemdescr=>get_data_type_kind( ).
case lv_typekind.
when cl_abap_typedescr=>typekind_time.
lv_field_type = 'String'.
lv_field_value = .
if im_format_time eq abap_true.
lv_time_internal = lv_field_value.
try.
call method cl_abap_timefm=>conv_time_int_to_ext
exporting
time_int = lv_time_internal
importing
time_ext = lv_time_external.
lv_field_value = lv_time_external.
catch cx_parameter_invalid_range.
clear lv_field_value.
endtry.
endif.
when cl_abap_typedescr=>typekind_date.
lv_field_type = 'String'.
lv_field_value = .
if im_format_date eq abap_true.
lv_date_internal = lv_field_value.
try.
call method cl_abap_datfm=>conv_date_int_to_ext
exporting
im_datint = lv_date_internal
importing
ex_datext = lv_date_external.
lv_field_value = lv_date_external.
catch cx_abap_datfm_format_unknown.
clear lv_field_value.
endtry.
endif.
when cl_abap_typedescr=>typekind_string
or cl_abap_typedescr=>typekind_char.
lv_field_type = 'String'.
lv_field_value = .
when cl_abap_typedescr=>typekind_num
or cl_abap_typedescr=>typekind_packed
or cl_abap_typedescr=>typekind_int
or cl_abap_typedescr=>typekind_float.
lv_field_type = 'Number'.
lv_field_value = .
call function 'CLOI_PUT_SIGN_IN_FRONT'
changing
value = lv_field_value.
when others.
lv_field_type = 'String'.
lv_field_value = .
endcase.
shift lv_field_value right deleting trailing space.
shift lv_field_value left deleting leading space.
*-- set field data
lo_data = lo_document->create_simple_element(
name = 'Data'
value = lv_field_value
parent = lo_cell ).
*-- set field type
lo_data->set_attribute_ns(
name = 'Type'
prefix = 'ss'
value = lv_field_type ).
endloop.
endloop.
*-- create worksheet option element
if im_use_header_record eq abap_true and im_freeze_header eq abap_true.
lo_element_options = lo_document->create_simple_element(
name = 'WorksheetOptions'
parent = lo_element_worksheet ).
lo_element_options->set_attribute(
name = 'xmlns'
value = 'urn:schemas-microsoft-com:office:excel' ).
lo_element_selected = lo_document->create_simple_element(
name = 'Selected'
parent = lo_element_options ).
lo_element_freezepanes = lo_document->create_simple_element(
name = 'FreezePanes'
parent = lo_element_options ).
lo_element_frozennosplit = lo_document->create_simple_element(
name = 'FrozenNoSplit'
parent = lo_element_options ).
lo_element_splithorizontal = lo_document->create_simple_element(
name = 'SplitHorizontal'
value = '1'
parent = lo_element_options ).
lo_element_toprowbottompane = lo_document->create_simple_element(
name = 'TopRowBottomPane'
value = '1'
parent = lo_element_options ).
lo_element_activepane = lo_document->create_simple_element(
name = 'ActivePane'
value = '2'
parent = lo_element_options ).
endif.
ex_xml_document_ref = lo_document.
endmethod. "POPULATE_RENDERED_XML_TABLE
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>POPULATE_XML_TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_TABLE TYPE ANY TABLE
* | [--->] IM_XML_STRUCT_DESCR TYPE REF TO CL_ABAP_STRUCTDESCR
* | [<---] EX_XML_TABLE_REF TYPE REF TO DATA
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method populate_xml_table.
*-- object references
data: lo_src_table_descr type ref to cl_abap_tabledescr,
lo_src_table_ref type ref to data,
lo_src_struct_descr type ref to cl_abap_structdescr,
lo_src_struct_ref type ref to data,
lo_dst_table_ref type ref to data,
lo_dst_struct_ref type ref to data,
lo_struct_descr type ref to cl_abap_structdescr,
lo_table_descr type ref to cl_abap_tabledescr,
lo_elem_objectdescr type ref to cl_abap_objectdescr,
lo_table_objectdescr type ref to cl_abap_objectdescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_components type cl_abap_structdescr=>component_table,
lt_xml_components type cl_abap_structdescr=>component_table,
lt_tlines type tline_t,
lt_text type string_table.
*-- structure defintion
data: ls_component_temp like line of lt_components,
ls_component like line of lt_components,
ls_tline type tline.
*-- local variables
data: lv_text type string,
lv_num_lines type i,
lv_index type i,
lv_error_msg type string.
*-- constants
data: lc_xml_newline type string value '
'.
*-- field symbols
field-symbols: type standard table,
type any,
type standard table,
type any,
type standard table,
like line of lt_components,
type any,
type any.
*-- prepare source table structure
try.
lo_src_table_descr ?= cl_abap_tabledescr=>describe_by_data( im_table ).
lo_src_struct_descr ?= lo_src_table_descr->get_table_line_type( ).
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
create data lo_src_table_ref type handle lo_src_table_descr.
assign lo_src_table_ref->* to .
create data lo_src_struct_ref type handle lo_src_struct_descr.
assign lo_src_struct_ref->* to .
= im_table.
*-- prepare destination table structure (where long text modelled as string)
lt_components = im_xml_struct_descr->get_components( ).
lo_elem_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_elemdescr' ).
lo_table_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_tabledescr' ).
loop at lt_components into ls_component.
if lo_elem_objectdescr->applies_to( ls_component-type ) eq 'X'.
append ls_component to lt_xml_components.
elseif lo_table_objectdescr->applies_to( ls_component-type ) eq 'X'.
ls_component_temp-type = cl_abap_elemdescr=>get_string( ).
ls_component_temp-name = ls_component-name.
append ls_component_temp to lt_xml_components.
endif.
endloop.
try.
lo_struct_descr = cl_abap_structdescr=>create( lt_xml_components ).
lo_table_descr = cl_abap_tabledescr=>create( lo_struct_descr ).
catch cx_sy_struct_creation
cx_sy_table_creation into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
create data lo_dst_table_ref type handle lo_table_descr.
assign lo_dst_table_ref->* to .
create data lo_dst_struct_ref type handle lo_struct_descr.
assign lo_dst_struct_ref->* to .
*-- copy data between tables
loop at into .
clear: .
loop at lt_components assigning .
if lo_elem_objectdescr->applies_to( -type ) eq 'X'.
*-- if type kind is element, do direct copy
assign component -name of structure to .
assign component -name of structure to .
= .
elseif lo_table_objectdescr->applies_to( -type ) eq 'X'.
*-- if type kind is table, map long text to string and then copy
assign component -name of structure to .
assign component -name of structure to .
lt_tlines[] = .
check lt_tlines[] is not initial.
clear lv_text.
lv_num_lines = lines( lt_tlines ).
lv_index = 1.
while lv_index lt lv_num_lines.
read table lt_tlines index lv_index into ls_tline.
concatenate lv_text ls_tline-tdline lc_xml_newline into lv_text.
add 1 to lv_index.
endwhile.
read table lt_tlines index lv_index into ls_tline.
concatenate lv_text ls_tline-tdline into lv_text.
= lv_text.
endif.
endloop.
append to .
endloop.
ex_xml_table_ref = lo_dst_table_ref.
endmethod. "populate_xml_table
* ---------------------------------------------------------------------------------------+
* | Static Private Method ZCL_BC_TABLE_INTROSPECTOR=>RECURSIVE_FILTER_COLUMNS
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_COLUMNS TYPE CSEQUENCE
* | [--->] IM_COMPONENTS TYPE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE
* | [<---] EX_COMPONENTS TYPE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE
* | [!CX!] ZCX_BC_TABLE_INTROSPECTOR
* +--------------------------------------------------------------------------------------
method recursive_filter_columns.
*-- object references
data: lo_elem_objectdescr type ref to cl_abap_objectdescr,
lo_struct_objectdescr type ref to cl_abap_objectdescr,
lo_table_objectdescr type ref to cl_abap_objectdescr,
lo_structdescr type ref to cl_abap_structdescr,
lo_tabledescr type ref to cl_abap_tabledescr,
lo_root_exc type ref to cx_root.
*-- internal table defintion
data: lt_components type cl_abap_structdescr=>component_table,
lt_components_filtered type cl_abap_structdescr=>component_table,
lt_inner_components type cl_abap_structdescr=>component_table,
lt_components_temp type cl_abap_structdescr=>component_table,
lt_tline type tline_t.
*-- structure defintion
data: ls_component type abap_componentdescr,
ls_component_temp type abap_componentdescr.
*-- local variables
data: lv_error_msg type string.
lt_components[] = im_components[].
*-- loop thru all components and convert to flat, filtered collection
loop at lt_components into ls_component.
*-- set up descriptors to test what subclass of cl_abap_typedescr is being processed (ABAP lacks instance of operator)
lo_elem_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_elemdescr' ).
lo_struct_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_structdescr' ).
lo_table_objectdescr ?= cl_abap_typedescr=>describe_by_name( 'cl_abap_tabledescr' ).
*-- adjust component collection based on selected columns (* or space defaults to all columns)
clear: ls_component_temp.
if ls_component-as_include ne 'X' and im_columns ns '*' and im_columns is not initial.
move ls_component to ls_component_temp.
concatenate '(\W|^)' ls_component_temp-name '(\W|$)'
into ls_component_temp-name.
find regex ls_component_temp-name in im_columns ignoring case.
check sy-subrc eq 0.
endif.
*-- iterate thru each component: if component is an element, process directly; if component is a structure, process recursively
if lo_elem_objectdescr->applies_to( ls_component-type ) eq 'X'.
*-- skip MANDT column here
if ls_component-name eq 'MANDT'.
continue.
endif.
append ls_component to lt_components_filtered.
elseif lo_struct_objectdescr->applies_to( ls_component-type ) eq 'X'.
try.
*-- cast to cl_abap_structdescr, get each component related to the structure, and process
lo_structdescr ?= ls_component-type.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
lt_inner_components = lo_structdescr->get_components( ).
*-- recursive call
call method recursive_filter_columns(
exporting
im_columns = im_columns
im_components = lt_inner_components
importing
ex_components = lt_components_temp ).
append lines of lt_components_temp to lt_components_filtered.
elseif lo_table_objectdescr->applies_to( ls_component-type ) eq 'X'.
try.
*-- cast to cl_abap_tabledescr, discard if table is not long text (tline = tdformat, tdline)
lo_tabledescr ?= ls_component-type.
catch cx_sy_move_cast_error into lo_root_exc.
lv_error_msg = lo_root_exc->get_text( ).
raise exception type zcx_bc_table_introspector
exporting
error_text = lv_error_msg.
endtry.
if lo_tabledescr->applies_to_data( lt_tline ) eq 'X'.
append ls_component to lt_components_filtered.
endif.
endif.
endloop.
*-- return new flat filtered component structure
ex_components[] = lt_components_filtered[].
endmethod. "recursive_filter_columns
ENDCLASS.