这个报表实现的效果是子选择界面中选择要显示的列(此程序为月份),内表会动态的形成需要的结构并输出在ALV中。
REPORT ysun_fs_001.
*&---------------------------------------------------------------------*
*& ysun_fs_001_top
*&---------------------------------------------------------------------*
"ZSUN_ICOME_01
DATA: gt_income TYPE TABLE OF zsun_icome_01,
gs_income TYPE zsun_icome_01.
"FIELDCAT
DATA:gt_fieldcat TYPE lvc_t_fcat,
gs_fieldcat TYPE lvc_s_fcat.
RANGES r_month FOR gs_income-zmonth .
DATA gv_fieldname TYPE c LENGTH 20 .
DATA gv_description TYPE c LENGTH 20 .
DATA gv_number TYPE i .
DATA gv_low TYPE c LENGTH 2 .
"动态内表字段符号
FIELD-SYMBOLS :<ft_vb> TYPE STANDARD TABLE, "内表
<fs_vb> TYPE any, "结构
<dyn_field> TYPE any. "字段
" ADD FIELDCAT
DATA gv_pos TYPE i .
DEFINE %%add_fieldcat .
CLEAR gs_fieldcat.
gv_pos = gv_pos + 1.
gs_fieldcat-col_pos = gv_pos .
gs_fieldcat-fieldname = &1 .
gs_fieldcat-scrtext_m = &2 .
gs_fieldcat-cfieldname = &3 .
gs_fieldcat-outputlen = 15 .
APPEND gs_fieldcat TO gt_fieldcat .
END-OF-DEFINITION.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001.
PARAMETERS :p_year TYPE zsun_icome_01-zyear OBLIGATORY . "公司代码 1
SELECT-OPTIONS:s_comp FOR gs_income-company OBLIGATORY . "利润中心 1
SELECT-OPTIONS:s_month FOR gs_income-zmonth OBLIGATORY . "利润中心 1
SELECTION-SCREEN END OF BLOCK b1.
*&---------------------------------------------------------------------*
*& ysun_fs_001_form
*&---------------------------------------------------------------------*
FORM field_symbol_basic .
"一般类型
FIELD-SYMBOLS : <fs_field> TYPE any , "任意变量/结构
<fs_field_02> ,
<fs_table> TYPE ANY TABLE . "任意表
"完整类型
TYPES gty_makt TYPE TABLE OF makt.
FIELD-SYMBOLS : <fs_char> TYPE c,
<fs_makt> TYPE makt,
"<FS_MAKT01> like line of MAKT,
<ft_makt> TYPE gty_makt . "makt类型的内表
DATA gv_char TYPE c LENGTH 13 VALUE '北京'.
DATA gv_numc TYPE n LENGTH 10 VALUE '123456'.
DATA gs_makt TYPE makt.
"分配变量
ASSIGN gv_char TO <fs_field>.
WRITE:/ gv_char,
/ <fs_field>.
ASSIGN gv_numc TO <fs_field>.
"分配结构体
SELECT SINGLE *
FROM makt
INTO CORRESPONDING FIELDS OF gs_makt.
IF sy-subrc = 0 .
ASSIGN gs_makt TO <fs_field>.
ELSE.
ENDIF.
WRITE: / <fs_field>.
"分配变量
ASSIGN gv_char TO <fs_char> .
WRITE: / <fs_char>.
"ASSIGN GV_NUMC to <FS_CHAR>. "类型不匹配
"分配结构
ASSIGN gs_makt TO <fs_makt> .
WRITE: / <fs_makt>-matnr , <fs_makt>-maktx .
"动态指定
DATA: gv_char01 TYPE c LENGTH 10 VALUE 'A',
gv_char02 TYPE c LENGTH 10 VALUE 'B',
gv_char03 TYPE c LENGTH 10 VALUE 'C',
gv_char04 TYPE c LENGTH 10 VALUE 'D',
gv_char05 TYPE c LENGTH 10 VALUE 'E',
gv_char06 TYPE c LENGTH 10 VALUE 'F',
gv_char07 TYPE c LENGTH 10 VALUE 'G',
gv_char08 TYPE c LENGTH 10 VALUE 'H',
gv_char09 TYPE c LENGTH 10 VALUE 'I'.
DATA gv_index TYPE n LENGTH 2.
DATA gv_fieldname TYPE c LENGTH 30. "放置变量的名称
gv_fieldname = 'GV_CHAR' .
ASSIGN (gv_fieldname) TO <fs_field> . "动态指定,用小括号表示变量的值
WRITE : / <fs_field>.
DO 9 TIMES.
gv_index = sy-index .
CONCATENATE 'GV_CHAR' gv_index INTO gv_fieldname.
ASSIGN (gv_fieldname) TO <fs_field> .
WRITE : / gv_index, ':',<fs_field>.
ENDDO.
"结构体GS_MAKT通过FS进行输出
"ASSIGN GS_MAKT to <FS_FIELD>.
ASSIGN COMPONENT 'MATNR' OF STRUCTURE gs_makt TO <fs_field>."通过字段名分配
WRITE : / <fs_field>.
ASSIGN COMPONENT 1 OF STRUCTURE gs_makt TO <fs_field>."通过字段号分配
WRITE : / <fs_field>.
DO 5 TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE gs_makt TO <fs_field>."通过字段号分配
WRITE :/ sy-index,':', <fs_field>.
ENDDO.
"结构体GS_MAKT字段 动态分配
gv_fieldname = 'MATNR'.
ASSIGN COMPONENT gv_fieldname OF STRUCTURE gs_makt TO <fs_field>.
IF <fs_field> IS ASSIGNED.
WRITE:/ <fs_field>.
ENDIF.
"fs_field 一般类型
"fs_field makt类型
ASSIGN gs_makt TO <fs_makt> .
WRITE:/ <fs_makt>-matnr.
"一般定义的 field symbois 不能够直接使用组件
"ASSIGN gs_makt to <FS_FIELD> .
"WRITE:/ <FS_FIELD>-MATNR.
ASSIGN COMPONENT 'MATNR'OF STRUCTURE <fs_field> TO <fs_field_02>.
WRITE:/ <fs_field_02>.
gv_fieldname = 'MATNR'.
ASSIGN COMPONENT gv_fieldname OF STRUCTURE <fs_field> TO <fs_field_02>.
WRITE:/ <fs_field_02>.
"强制类型转换
ASSIGN gv_numc TO <fs_char> CASTING .
"ASSIGN GV_NUMC TO <FS_FIELD> CASTING TYPE GTY_MAKT.
TYPES: BEGIN OF gty_score,
name TYPE c LENGTH 4,
score TYPE n LENGTH 3,
END OF gty_score.
gv_char = 'ABCD100'.
ASSIGN gv_char TO <fs_field_02> CASTING TYPE gty_score .
DO 2 TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_field_02> TO <fs_field>.
WRITE:/ <fs_field>.
ENDDO.
TYPES :BEGIN OF gty_col,
col1 TYPE c LENGTH 5,
col2 TYPE c LENGTH 10,
col3 TYPE c LENGTH 15,
END OF gty_col.
DATA gs_col TYPE gty_col.
gs_col-col1 = 'CHINA' .
gs_col-col2 = 'BEIJING' .
gs_col-col3 = 'GREAT WALL'.
ASSIGN gs_col TO <fs_field_02> CASTING TYPE gty_col.
"方法1 使用行编号分配
WRITE:/ '使用行编号分配'.
DO 3 TIMES.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_field_02> TO <fs_field> .
WRITE:/ <fs_field>.
ENDDO.
"方法2 使用字段名分配
DATA gv_index01 TYPE n LENGTH 1.
WRITE:/ '使用字段名分配'.
DO 3 TIMES.
CLEAR :gv_index01,gv_fieldname.
gv_index01 = sy-index .
CONCATENATE 'COL' gv_index01 INTO gv_fieldname.
ASSIGN COMPONENT gv_fieldname OF STRUCTURE <fs_field_02> TO <fs_field> .
WRITE:/ <fs_field>.
ENDDO.
"分配-内表
DATA gt_makt TYPE TABLE OF makt .
SELECT *
FROM makt
INTO CORRESPONDING FIELDS OF TABLE gt_makt
UP TO 10 ROWS
WHERE spras = sy-langu.
FIELD-SYMBOLS <fs_wa> TYPE any .
"向一般类型的字段符号分配
ASSIGN gt_makt TO <fs_table>.
"ASSIGN GT_MAKT TO <FS_FIELD>.类型都要参照 any table
LOOP AT <fs_table> ASSIGNING <fs_field_02>.
ENDLOOP.
"向特定类型
ASSIGN gt_makt TO <ft_makt>.
"内表的读取
READ TABLE <ft_makt> ASSIGNING <fs_wa> INDEX 1. "使用索引
IF sy-subrc = 0.
ASSIGN COMPONENT 'MATNR' OF STRUCTURE <fs_wa> TO <fs_field>.
WRITE:/ <fs_field>.
ENDIF.
READ TABLE <ft_makt> ASSIGNING <fs_wa> WITH KEY mandt = '400'. "使用索引
IF sy-subrc = 0.
ASSIGN COMPONENT 'MANDT' OF STRUCTURE <fs_wa> TO <fs_field>.
WRITE:/ <fs_field> ,/.
ENDIF.
"内表读取 一般类型
"READ TABLE <FS_TABLE> ASSIGNING <FS_WA> INDEX 1. "any table 不能使用索引
"READ TABLE <FS_FIELD> ASSIGNING <FS_WA> WITH KEY MANDT = '400'. "any table 不能直接指明某一个字段
gv_fieldname = 'MANDT'.
READ TABLE <fs_table> ASSIGNING <fs_wa> WITH KEY (gv_fieldname) = '400'. "any table 可动态指明某一个字段
LOOP AT gt_makt INTO gs_makt.
IF gs_makt-mandt = '400'.
gs_makt-mandt = 'X'.
MODIFY gt_makt FROM gs_makt.
CLEAR: gs_makt.
ENDIF.
ENDLOOP.
"FIELD-SYMBOLS : <FS_MAKT> TYPE MAKT.
LOOP AT gt_makt ASSIGNING <fs_makt>.
IF <fs_makt>-mandt = '400'.
<fs_makt>-mandt = 'X'.
"MODIFY GT_MAKT FROM GS_MAKT. LOOP ASSIGNING,不需要FODIFY
"CLEAR: GS_MAKT.
ENDIF.
ENDLOOP.
DATA: gv_alpha TYPE c VALUE 'A',
gv_num TYPE i VALUE 256.
FIELD-SYMBOLS: <f_s> TYPE x ."定义为十六进制字段符号
DO 26 TIMES.
ASSIGN gv_alpha TO <f_s> CASTING. "强制类型转换
WRITE:gv_alpha.
<f_s> = <f_s> + gv_num .
ENDDO.
ENDFORM. " FIELD_SYMBOL_BASIC
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 数据获取
FORM get_data .
SELECT *
FROM zsun_icome
INTO CORRESPONDING FIELDS OF TABLE gt_income
WHERE zyear = p_year
AND company IN s_comp
AND zmonth IN s_month .
ENDFORM. " GET_DATA
*&---------------------------------------------------------------------*
*& Form BUILD_RANGE
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 获取月份数据
FORM build_range .
r_month[] = s_month[] .
READ TABLE r_month INDEX 1 . "读取第一行
IF sy-subrc = 0.
IF r_month-option = 'BT'.
IF r_month-low IS INITIAL . "只输入高值
gv_number = r_month-high .
gv_low = '01' .
ELSE. "高值低值均输入
gv_number = r_month-high - r_month-low + 1. "循环次数
gv_low = r_month-low . "03
ENDIF.
ELSEIF r_month-option = 'EQ'. "只输入单一值
gv_number = 1 .
gv_low = r_month-low .
ENDIF.
ELSEIF r_month[] IS INITIAL. "从一月份开始
gv_number = 12 .
gv_low = '01'.
ENDIF.
ENDFORM. " BUILD_RANGE
*&---------------------------------------------------------------------*
*& Form BUILD_FIELDCAT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 创建 fieldcat
FORM build_fieldcat .
"1. 公司
%%add_fieldcat 'COMPANY' '公司' space .
"2. 年份
%%add_fieldcat 'ZYEAR' '年份' space .
"3. 月份
DO gv_number TIMES .
CONCATENATE 'MONTH_' gv_low INTO gv_fieldname .
CONCATENATE gv_low '月份' INTO gv_description .
%%add_fieldcat gv_fieldname gv_description 'WAERS' .
gv_low = gv_low + 1 .
" IF LV_INDEX = R_MONTH-HIGH.
" EXIT .
" ENDIF.
ENDDO.
"4. 货币单位
%%add_fieldcat 'WAERS' '货币单位' space .
ENDFORM. " BUILD_FIELDCAT
*&---------------------------------------------------------------------*
*& Form BUILD_FIELDCAT_02
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 创建 fieldcat_02
FORM build_fieldcat_02 .
DATA lv_month TYPE c LENGTH 2 .
"1. 公司
%%add_fieldcat 'COMPANY' '公司' space .
"2. 年份
%%add_fieldcat 'ZYEAR' '年份' space .
"3. 月份
DO 12 TIMES .
lv_month = sy-index .
IF lv_month IN s_month .
CONCATENATE 'MONTH_' lv_month INTO gv_fieldname .
CONCATENATE lv_month '月份' INTO gv_description .
%%add_fieldcat gv_fieldname gv_description 'WAERS' .
ENDIF.
ENDDO.
"4. 货币单位
%%add_fieldcat 'WAERS' '货币单位' space .
ENDFORM. " BUILD_FIELDCAT_02
*&---------------------------------------------------------------------*
*& Form BUILD_DYNMIC_TABLE
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 创建动态内表
FORM build_dynamic_table . "调用静态方法 :CREATE_DYNAMIC_TABLE
DATA lt_new_table TYPE REF TO data .
DATA ls_new_line TYPE REF TO data .
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
* I_STYLE_TABLE =
it_fieldcatalog = gt_fieldcat "输入FIELDCATALOG 将返回一个动态内表
* I_LENGTH_IN_BYTE =
IMPORTING
ep_table = lt_new_table "获取返回的动态内表 (类)
* E_STYLE_FNAME =
EXCEPTIONS
generate_subpool_dir_full = 1
OTHERS = 2.
IF sy-subrc <> 0.
EXIT.
* Implement suitable error handling here
ENDIF.
ASSIGN lt_new_table->* TO <ft_vb> . "LT_NEW_TABLE 中的所有都被指向<FT_VB>(动态内表)
CREATE DATA ls_new_line LIKE LINE OF <ft_vb> .
ASSIGN ls_new_line->* TO <fs_vb> . "LS_NEW_LINE 中的所有都被指向<FS_VB> (动态内表结构)
ENDFORM. " BUILD_DYNMIC_TABLE
*&---------------------------------------------------------------------*
*& Form ADD_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* 向动态内表增加数据
FORM add_data .
DATA ls_income TYPE zsun_icome_01 .
" 首先根据年份,公司 排序
SORT gt_income BY zyear company .
LOOP AT gt_income INTO ls_income .
MOVE-CORRESPONDING ls_income TO gs_income . "AT事件后字段为*需要从 LS_INCOME 转存到 GS_INCOME
AT NEW company . " 当公司变更时 先录入 公司 ,年份 ,货币
"<FS_VB>-COMPANY = GS_INCOME-COMPANY
ASSIGN COMPONENT 'COMPANY' OF STRUCTURE <fs_vb> TO <dyn_field> .
IF sy-subrc = 0 .
<dyn_field> = gs_income-company .
ENDIF .
"<FS_VB>-ZYEAR = GS_INCOME-ZYEAR
ASSIGN COMPONENT 'ZYEAR' OF STRUCTURE <fs_vb> TO <dyn_field> .
IF sy-subrc = 0 .
<dyn_field> = gs_income-zyear .
ENDIF.
"<FS_VB>-WAERS = GS_INCOME-WAERS
ASSIGN COMPONENT 'WAERS' OF STRUCTURE <fs_vb> TO <dyn_field> .
IF sy-subrc = 0 .
<dyn_field> = gs_income-waers .
ENDIF .
ENDAT .
" 再根据月份的值,把收入写入对应字段(每一行都执行)
" <FS_VB>-MONTH_XX = GS_INCOME-INCOME
CONCATENATE 'MONTH_'gs_income-zmonth INTO gv_fieldname .
ASSIGN COMPONENT gv_fieldname OF STRUCTURE <fs_vb> TO <dyn_field> .
IF sy-subrc = 0 .
<dyn_field> = gs_income-income .
ENDIF .
AT END OF company .
" 当公司的值到达最后一行时
APPEND <fs_vb> TO <ft_vb> .
CLEAR <fs_vb> .
ENDAT .
ENDLOOP .
ENDFORM. " ADD_DATA
*&---------------------------------------------------------------------*
*& Form DISPLAY_DATA
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
* DISPLAY
FORM display_data .
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
EXPORTING
* I_INTERFACE_CHECK = ' '
* I_BYPASSING_BUFFER =
* I_BUFFER_ACTIVE =
* I_CALLBACK_PROGRAM = ' '
* I_CALLBACK_PF_STATUS_SET = ' '
* I_CALLBACK_USER_COMMAND = ' '
* I_CALLBACK_TOP_OF_PAGE = ' '
* I_CALLBACK_HTML_TOP_OF_PAGE = ' '
* I_CALLBACK_HTML_END_OF_LIST = ' '
* I_STRUCTURE_NAME =
* I_BACKGROUND_ID = ' '
* I_GRID_TITLE =
* I_GRID_SETTINGS =
* IS_LAYOUT_LVC =
it_fieldcat_lvc = gt_fieldcat
* IT_EXCLUDING =
* IT_SPECIAL_GROUPS_LVC =
* IT_SORT_LVC =
* IT_FILTER_LVC =
* IT_HYPERLINK =
* IS_SEL_HIDE =
* I_DEFAULT = 'X'
* I_SAVE = ' '
* IS_VARIANT =
* IT_EVENTS =
* IT_EVENT_EXIT =
* IS_PRINT_LVC =
* IS_REPREP_ID_LVC =
* I_SCREEN_START_COLUMN = 0
* I_SCREEN_START_LINE = 0
* I_SCREEN_END_COLUMN = 0
* I_SCREEN_END_LINE = 0
* I_HTML_HEIGHT_TOP =
* I_HTML_HEIGHT_END =
* IT_ALV_GRAPHICS =
* IT_EXCEPT_QINFO_LVC =
* IR_SALV_FULLSCREEN_ADAPTER =
* IMPORTING
* E_EXIT_CAUSED_BY_CALLER =
* ES_EXIT_CAUSED_BY_USER =
TABLES
t_outtab = <ft_vb>
EXCEPTIONS
program_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
EXIT .
* Implement suitable error handling here
ENDIF.
ENDFORM. " DISPLAY_DATA
INITIALIZATION.
START-OF-SELECTION.
PERFORM get_data. "数据获取
PERFORM build_range. "获取月份数据
PERFORM build_fieldcat_02. "创建 fieldcat_02
PERFORM build_dynamic_table. "创建动态内表
PERFORM add_data. "向动态内表增加数据
END-OF-SELECTION.
PERFORM display_data. "DISPLAY
实现的效果为:
前台选择1~7月
ALV输出对应的1-7月的数据(表数据是乱建的)