ABAP--如何在ALV Grid打印页上加入页号

本文介绍如何正确处理ABAP ALVGrid报告打印时的页码问题,特别是当选择包含ALV统计数据时,确保页码计算准确无误。通过使用ALV事件TopOfPage、TopOfList和EndOfList,可以实现对总页数的精确控制。
  ALV Grid - Page Numbering Problem

Problem: When you prints an ALV report, you want the pagenumber and the total number of pages in the heading (E.g. Page xxx of yyy).
The total number of pages are usually calculated from the number of lines in the report table, number of lines in the report header and the number of lines
on each report page, and should not cause any problems.
However, the standard print dialog screen for the ALV grid has an option "ALV statistics". When this option ís chosen, a page with ALV statistics will be printed before the ALV report and the total number of pages will be wrong as an extra page has been added to the report.
The solution is to use the ALV events Top Of Page, Top Of List and End Of List as demonstrated in the enclosed example.
REPORT zhfnk_alvtest.
*--------------------------------------------------------------------
* This example demonstrates a solution to a problem
* that arises when you want to include the number of pages in
* an ALV report (E.g. Pageno xxx of yyy), and choses to include
* ALV statistics when you print the report.
* When you count the total number of pages it is usually
* calculated from the number of lines in the report table,
* number of lines in the report header and the number of lines
* on each report page. However, if you include the ALV statistics when
* you print the report, this page will not be included in the total
* number of pages.
*The solution demonstrated below, is to use the ALV events
* Top Of Page, Top Of List and End Of List.
*--------------------------------------------------------------------

TYPE-POOLS: slis.
TYPES:
 BEGIN OF t_makt,
    matnr LIKE makt-matnr,
    maktx LIKE makt-maktx,
 END OF t_makt.
DATA:
 it_makt TYPE STANDARD TABLE OF t_makt,
 wa_makt TYPE t_makt.
******************************************************************'
* Data declarations for the ALV grid
******************************************************************
'

DATA:
   r_grid            TYPE REF TO cl_gui_alv_grid,
   alv_fieldcat      TYPE slis_t_fieldcat_alv,
   wa_alv_fieldcat   TYPE slis_fieldcat_alv,
   alv_layout        TYPE slis_layout_alv,
   gt_events         TYPE slis_t_event.
******************************************************************'
* Other data declarations
******************************************************************'

DATA:
    gd_repid               LIKE sy-repid,
    g_first_top_of_page(1) TYPE c, "Flag for first top of page event
    g_totpages(3)          TYPE n,
    g_pageno(3)            TYPE n,
    g_start_of_list(1)     TYPE c.
START-OF-SELECTION.
 g_first_top_of_page = 'X'.
 CLEAR g_start_of_list.
 PERFORM alv_setup.
 PERFORM build_events.
 PERFORM read_data.
END-OF-SELECTION.
 PERFORM display_alv.
*&---------------------------------------------------------------------*
*&      Form read_data
*&---------------------------------------------------------------------*

FORM read_data.
 SELECT matnr maktx
    FROM makt
    INTO TABLE it_makt
    WHERE spras = 'E'.
ENDFORM.                    " read_data
*&---------------------------------------------------------------------*
*&      Form alv_setup
*&---------------------------------------------------------------------*
* Setup of the columns in the ALV grid
*----------------------------------------------------------------------*

FORM alv_setup.
 CLEAR wa_alv_fieldcat.
 REFRESH alv_fieldcat.
* Matnr field
 wa_alv_fieldcat-key = 'X'.                     "This is a key column
 wa_alv_fieldcat-fieldname = 'MATNR'.           "Name of the table eld
 wa_alv_fieldcat-seltext_s = 'Matnr'.           "Short column heading
 wa_alv_fieldcat-seltext_m = 'Material nr.'.    "Medium column heading
 wa_alv_fieldcat-seltext_l = 'Material number'. "Long column heading
 APPEND wa_alv_fieldcat TO alv_fieldcat.
* Mat text field
 wa_alv_fieldcat-key = ''.                   "This is not a key column
 wa_alv_fieldcat-fieldname = 'MAKTX'.
 wa_alv_fieldcat-seltext_s = 'Mat. txt'.
 wa_alv_fieldcat-seltext_m = 'Material txt'.
 wa_alv_fieldcat-seltext_l = 'Material text'.
 APPEND wa_alv_fieldcat TO alv_fieldcat.
ENDFORM.                    " alv_setup
*&------------------------------------------------------------------*
*& Form BUILD_EVENTS
*&------------------------------------------------------------------*
*   Build events tabel for function module
*   REUSE_ALV_GRID_DISPLAY. The events that we are interested in are:
*   Note that each event is assigned to a sub routine that is
*   executed when the event is triggered
*   - Top Of List - Subroutine TOP_OF_LIST
*   - End Of List - END_OF_LIST
*-------------------------------------------------------------------*

FORM build_events.
 DATA: ls_event TYPE slis_alv_event.
 CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
    EXPORTING
     i_list_type = 0
    IMPORTING
      et_events   = gt_events[].
 READ TABLE gt_events WITH KEY name = slis_ev_top_of_list
                           INTO ls_event.
 IF sy-subrc = 0.
    MOVE 'TOP_OF_LIST' TO ls_event-form.
    MODIFY gt_events INDEX sy-tabix FROM ls_event.
 ENDIF.
 READ TABLE gt_events WITH KEY name = slis_ev_end_of_list
                           INTO ls_event.
 IF sy-subrc = 0.
    MOVE 'END_OF_LIST' TO ls_event-form.
    MODIFY gt_events INDEX sy-tabix FROM ls_event.
 ENDIF.
ENDFORM.                    " BUILD_EVENTS
*&---------------------------------------------------------------------*
*&      Form display_alv
*&---------------------------------------------------------------------*
* Display data in the ALV grid using function module
*----------------------------------------------------------------------*

FORM display_alv.
 gd_repid = sy-repid.
* Configure layout of screen
 alv_layout-colwidth_optimize = 'X'.
 alv_layout-zebra             = 'X'.
 alv_layout-no_min_linesize   = 'X'.
* Call ALV function module
 CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
           i_callback_program       = gd_repid
           i_callback_top_of_page   = 'TOP_OF_PAGE' "Ref to form
           is_layout                = alv_layout
           it_fieldcat              = alv_fieldcat
           it_events               = gt_events
*          is_print                = gd_prntparams
      TABLES
            t_outtab               = it_makt
     EXCEPTIONS
         program_error            = 1
         OTHERS                   = 2.
 IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
           WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
 ENDIF.
ENDFORM.                    " display_alv
*------------------------------------------------------------------*
* Form TOP_OF_LIST
*------------------------------------------------------------------*
* This event is triggerede once at top of the actual list,
* BUT NOT at the top of the ALV Statistics page
*------------------------------------------------------------------*

FORM top_of_list.
* Set flag that indicates that print of the ALV list has begun
 g_start_of_list = 'X'.
ENDFORM.                    "TOP_OF_LIST
*---------------------------------------------------------------------*
* Form TOP_OF_PAGE
*---------------------------------------------------------------------*
* This event is triggered at every top of page including top of
* page inclduing the top of the ALV statistics page
*----------------------------------------------------------------------*

FORM top_of_page.
 DATA: t_header TYPE slis_t_listheader,
        wa_header TYPE slis_listheader,
        pagno(3) TYPE n.
*---------------------------------------------------------------------
* If the list is being printed (Not didslayed) and this is the first
* time the Top Of Page event is triggered, then caculate number
* of pages for the ALV list
*---------------------------------------------------------------------

 IF sy-ucomm EQ 'PRIN' AND g_first_top_of_page = 'X'.
    PERFORM get_total_number_of_pages CHANGING g_totpages.
    CLEAR g_first_top_of_page.
 ENDIF.
* If this is a printed list
 IF sy-ucomm EQ 'PRIN'.
*---------------------------------------------------------------------
*   The Start Of List event has not yet been triggered. Thsi means that
*   we are at the top of an ALV statistics page. Add the
*   ALV statistics page to total number of pages
*---------------------------------------------------------------------

    IF g_start_of_list = ' '.
      g_totpages = g_totpages + 1.
    ENDIF.
*   Create ALV header
    wa_header-typ = 'H'.
    g_pageno = sy-pagno.
    CONCATENATE 'Mylist page' g_pageno 'of' g_totpages
        space INTO wa_header-info SEPARATED BY space.
    APPEND wa_header TO t_header.
    CLEAR wa_header.
    CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
      EXPORTING
        it_list_commentary = t_header.
 ENDIF.
ENDFORM.                    " top_of_page_setup
*-------------------------------------------------------------------
* Form END_OF_LIST
* Clear flags in case the user choses to reprint the report
*-------------------------------------------------------------------

FORM end_of_list.
 g_first_top_of_page = 'X'.
 CLEAR g_pageno.
 CLEAR g_start_of_list.
ENDFORM.                    "END_OF_LIST
*---------------------------------------------------------------------*
* Form get_total_number_of_pages
*---------------------------------------------------------------------*
* Calcualtes the total page numbers from the number of lines in
* the header of the report and the number of entries in the
* input table
*----------------------------------------------------------------------*

FORM get_total_number_of_pages CHANGING p_total_number_of_pages.
 DATA: l_tot_pages TYPE f ,
        l_tot_lines TYPE i,
        l_lines_per_page TYPE i,
        l_number_of_header_lines TYPE i VALUE 13.
* Find number of lines in report table
 DESCRIBE TABLE it_makt LINES l_tot_lines.
* Number of lines per pages excl. page header (13 lines)
 l_lines_per_page = sy-linct - l_number_of_header_lines.
* Total number ofpages
* Round up the the page number to nearest integer
 l_tot_pages = CEIL( l_tot_lines / l_lines_per_page ).
  p_total_number_of_pages = l_tot_pages.
* In case that there are no data in the report
 IF p_total_number_of_pages = '0'.
    p_total_number_of_pages = '1'.
 ENDIF.
ENDFORM.                    " get_total_number_of_pages
 
*&---------------------------------------------------------------------* *& Report ZTEXT03 *&---------------------------------------------------------------------* *& *&---------------------------------------------------------------------* REPORT ZTEXT03. * 定义数据类型 TYPES: BEGIN OF ty_sflight, carrid TYPE s_carr_id, connid TYPE s_conn_id, fldate TYPE s_date, price TYPE s_price, currency TYPE s_currcode, planetype TYPE s_planetye, seatsmax TYPE s_seatsmax, seatsocc TYPE s_seatsocc, END OF ty_sflight. data lv_c TYPE i VALUE 1. * 定义内表和变量 DATA: gt_sflight TYPE TABLE OF ty_sflight, gt_output TYPE TABLE OF ty_sflight, " 当前显示的数据 gs_layout TYPE lvc_s_layo, gt_fieldcat TYPE lvc_t_fcat. *DATA LV_C TYPE I VALUE 1. DATA: gv_current_page TYPE i VALUE 1, " 当前页码 gv_page_size TYPE i VALUE 100, " 每显示行数 gv_total_pages TYPE i, " 总数 gv_total_records TYPE i. " 总记录数 DATA GT_light TYPE STANDARD TABLE OF ty_sflight WITH HEADER LINE. * 选择屏幕 SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001. PARAMETERS: p_max TYPE i DEFAULT 1000 OBLIGATORY. SELECT-OPTIONS: s_carrid FOR GT_light-carrid. SELECTION-SCREEN END OF BLOCK b1. SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002. PARAMETERS: p_pagesz TYPE i DEFAULT 100 OBLIGATORY. " 每大小 SELECTION-SCREEN END OF BLOCK b2. * 主程序 START-OF-SELECTION. PERFORM get_all_data. PERFORM calculate_paging. PERFORM get_current_page_data. PERFORM display_alv. *&---------------------------------------------------------------------* *& Form GET_ALL_DATA *&---------------------------------------------------------------------* FORM get_all_data. SELECT carrid, connid, fldate, price, currency, planetype, seatsmax, seatsocc FROM sflight UP TO @p_max ROWS INTO TABLE @gt_sflight WHERE carrid IN @s_carrid. IF gt_sflight IS INITIAL. MESSAGE 'No flight data found!' TYPE 'I' DISPLAY LIKE 'E'. STOP. ENDIF. gv_total_records = lines( gt_sflight ). ENDFORM. " GET_ALL_DATA *&---------------------------------------------------------------------* *& Form CALCULATE_PAGING *&---------------------------------------------------------------------* FORM calculate_paging. gv_page_size = p_pagesz. " 计算总数 gv_total_pages = gv_total_records DIV gv_page_size. IF gv_total_records MOD gv_page_size > 0. gv_total_pages = gv_total_pages + 1. ENDIF. " 确保当前页码在有效范围内 IF gv_current_page > gv_total_pages. gv_current_page = 1. ENDIF. ENDFORM. " CALCULATE_PAGING *&---------------------------------------------------------------------* *& Form GET_CURRENT_PAGE_DATA *&---------------------------------------------------------------------* FORM get_current_page_data. DATA: lv_start_index TYPE i, lv_end_index TYPE i. *lv_c = lv_c + 1. CLEAR gt_output. " 计算当前数据的起始和结束索引 lv_start_index = ( gv_current_page - 1 ) * gv_page_size + 1. lv_end_index = lv_start_index + gv_page_size - 1. " 确保结束索引不超过总记录数 IF lv_end_index > gv_total_records. lv_end_index = gv_total_records. ENDIF. " 提取当前的数据 APPEND LINES OF gt_sflight FROM lv_start_index TO lv_end_index TO gt_output. ENDFORM. " GET_CURRENT_PAGE_DATA *&---------------------------------------------------------------------* *& Form DISPLAY_ALV *&---------------------------------------------------------------------* FORM display_alv. PERFORM build_field_catalog. PERFORM set_layout. CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC' EXPORTING i_callback_program = sy-repid i_callback_pf_status_set = 'SET_PF_STATUS' " 设置工具栏 i_callback_user_command = 'HANDLE_USER_COMMAND' " 处理用户命令 is_layout_lvc = gs_layout it_fieldcat_lvc = gt_fieldcat TABLES t_outtab = gt_output EXCEPTIONS program_error = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. ENDIF. ENDFORM. " DISPLAY_ALV *&---------------------------------------------------------------------* *& Form BUILD_FIELD_CATALOG *&---------------------------------------------------------------------* FORM build_field_catalog. DATA: ls_fieldcat TYPE lvc_s_fcat. DEFINE add_field. CLEAR ls_fieldcat. ls_fieldcat-fieldname = &1. ls_fieldcat-ref_table = &2. ls_fieldcat-ref_field = &3. ls_fieldcat-reptext = &4. ls_fieldcat-coltext = &5. ls_fieldcat-outputlen = &6. APPEND ls_fieldcat TO gt_fieldcat. END-OF-DEFINITION. add_field: 'CARRID' 'SFLIGHT' 'CARRID' 'Airline' 'Airline' 3, 'CONNID' 'SFLIGHT' 'CONNID' 'Connection' 'Conn' 4, 'FLDATE' 'SFLIGHT' 'FLDATE' 'Flight Date' 'Date' 8, 'PRICE' 'SFLIGHT' 'PRICE' 'Price' 'Price' 12, 'CURRENCY' 'SFLIGHT' 'CURRENCY' 'Currency' 'Curr' 5, 'PLANETYPE' 'SFLIGHT' 'PLANETYPE' 'Aircraft Type' 'Aircraft' 10, 'SEATSMAX' 'SFLIGHT' 'SEATSMAX' 'Max Seats' 'Max Seats' 8, 'SEATSMAX' 'SFLIGHT' 'SEATSOCC' 'Occupied Seats' 'Occupied' 8. ENDFORM. " BUILD_FIELD_CATALOG *&---------------------------------------------------------------------* *& Form SET_LAYOUT *&---------------------------------------------------------------------* FORM set_layout. gs_layout-zebra = 'X'. " 斑马线模式 gs_layout-cwidth_opt = 'X'. " 列宽优化 gs_layout-sel_mode = 'A'. " 选择模式 gs_layout-info_fname = 'COLOR'. " 行颜色字段(如果需要) " 设置网格标题显示信息 gs_layout-grid_title = |Flight Data - Page { gv_current_page } of { gv_total_pages } - Total Records: { gv_total_records }|. ENDFORM. " SET_LAYOUT *&---------------------------------------------------------------------* *& Form SET_PF_STATUS *&---------------------------------------------------------------------* FORM set_pf_status USING rt_extab TYPE slis_t_extab. SET PF-STATUS 'ZALV_PAGING_STATUS'. ENDFORM. " SET_PF_STATUS *&---------------------------------------------------------------------* *& Form HANDLE_USER_COMMAND *&---------------------------------------------------------------------* FORM handle_user_command USING r_ucomm TYPE sy-ucomm rs_selfield TYPE slis_selfield. * *&---刷新屏幕数据到内表 DATA: lr_grid1 TYPE REF TO cl_gui_alv_grid. CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = lr_grid1. CALL METHOD lr_grid1->check_changed_data. CASE r_ucomm. WHEN 'FIRST_PAGE'. " 第一 gv_current_page = 1. PERFORM refresh_display. WHEN 'PREV_PAGE'. " 上一 IF gv_current_page > 1. gv_current_page = gv_current_page - 1. PERFORM refresh_display. ELSE. MESSAGE 'Already on first page!' TYPE 'S'. ENDIF. WHEN 'NEXT_PAGE'. " 下一 IF gv_current_page < gv_total_pages. gv_current_page = gv_current_page + 1. PERFORM refresh_display. ELSE. MESSAGE 'Already on last page!' TYPE 'S'. ENDIF. WHEN 'LAST_PAGE'. " 最后一 gv_current_page = gv_total_pages. PERFORM refresh_display. WHEN 'REFRESH'. " 刷新 PERFORM refresh_display. WHEN 'BACK' OR 'CANCEL' OR 'EXIT'. " 退出 CLEAR r_ucomm. LEAVE TO transaction 'SESSION_MANAGER'. * SET SCREEN 0. LEAVE SCREEN. ENDCASE. * *&---调用后数据保存处理 CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = lr_grid1. CALL METHOD lr_grid1->check_changed_data. *&---刷新ALV 显示值 rs_selfield-refresh = 'X' . ENDFORM. *&---------------------------------------------------------------------* *& Form REFRESH_DISPLAY *&---------------------------------------------------------------------* FORM refresh_display. DATA LV_MES TYPE STRING. PERFORM get_current_page_data. LV_MES = '当前数第' && gv_current_page && '/ ' && gv_total_pages. MESSAGE LV_MES TYPE 'S'. ENDFORM. " REFRESH_DISPLAY
最新发布
10-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值