ALV详解:OO ALV
OO ALV
EnjoySAP Controls and CFW
EnjoySAP Control是SAP提供的基于OO架构的UI技术。CFW:Control Framework
现在在SAP中,在传统的ABAP中,我们可以“画”出很多自己的screen element,如input field、button、table、tabstrip、Table Control等等(SE51 Screen Painter)。但是,想想,如果我们需要在screen上面显示图片、使用Tree来组织数据结构等,我们该怎么实现呢?
现在SAP提供另一种基于OO的处理UI的技术名为EnjoySAP,它是以CFW(Control Framework)为基础来实现的,CFW框架继承体系如下:
CL_GUI_OBJECT Proxy Class for a GUI Object
|-- CL_FORMPAINTER_BASEWINDOW SAP Form Painter Window Base Class
| |-- CL_FORMPAINTER_BITMAPWINDOW SAP Form Painter Bitmap Window Class
| |-- CL_FORMPAINTER_TEXTWINDOW SAP Form Painter Text Window Class
|-- CL_GUI_CONTROL Proxy Class for Control in GUI
| |-- CL_DSVAS_GUI_BUSIGRAPH DSVAS: Proxy for Business Graphic
| |-- CL_GFW_GP_PRES_CHART GFW: Product--specific section of CL_GUI_GP_PRES (Chart)
| |-- CL_GFW_GP_PRES_PIG GFW: product specific section for web view
| |-- CL_GFW_GP_PRES_SAP GFW: product--specific section of CL_GUI_GP_PRES (SAP BUSG)
| |-- CL_GUI_ALV_GRID_BASE Basis Class for ALV Grid
| | |-- CL_CALENDAR_CONTROL_SCHEDULE Calendar View (Day, Week, Month)
| | |--CL_GUI_ALV_GRID ALV List Viewer
| | |-- CL_ALV_DD_LISTBOX D&D List Box
| | |-- CL_BUKF_CAT_GRID Key Figures -- Grid of categories
| | |-- CL_BUKF_DSRC_GRID Key Figures -- Grid for Data sources
| | |-- CL_BUKF_FILTER_GRID Key Figures -- Filter for Key Figure
| | |-- CL_BUKF_KF_GRID Key Figures -- Grid for Key Figures
| | |-- CL_BUKF_TERMS_GRID Key Figures -- Grid for terms
| | |-- CL_FTR_GUI_ENTRY_ALV Class: ALV Grid Control for Initial Screen (Without Toolbar)
| | |-- CL_GFW_GP_GRID_ALV ALV grid proxy
| |-- CL_GUI_AQQGRAPHIC_ADAPT Network Adapter
| |-- CL_GUI_AQQGRAPHIC_CONTROL BW Basis Class Network Control
| | |-- CL_GUI_AQQGRAPHIC_NETPLAN Network Control
| |-- CL_GUI_BARCHART Bar chart wrapper
| |-- CL_GUI_BORDERPAINTER SAP Border Painter Control Proxy Class
| |-- CL_GUI_BTFEDITOR SAP BTF Editor Control Proxy Class
| |-- CL_GUI_CALENDAR Calendar Control Proxy Class
| |-- CL_GUI_CHART_ENGINE_WIN Graphics: Presentation Graphics (SAP GUI for Windows)
| |-- CL_GUI_CONTAINER Abstract Container for GUI Controls
| | |-- CL_GUI_CONTAINER_INFO Information on Container Controls
| | |-- CL_GUI_CUSTOM_CONTAINER Container for Custom Controls in the Screen Area
| | |-- CL_GUI_DIALOGBOX_CONTAINER Container for Custom Controls in the Screen Area
| | | |-- CL_ECL_VIEWER_FRAME Manage EAI Control in Own Window
| | | |-- CL_GUI_ECL_VIEWERBOX ECL Viewer as Dialog Box
| | |-- CL_GUI_DOCKING_CONTAINER Docking Control Container
| | |-- CL_GUI_EASY_SPLITTER_CONTAINER Reduced Version of Splitter Container Control
| | | |-- CL_EU_EASY_SPLITTER_CONTAINER Internal Test; Do Not Use
| | |-- CL_GUI_GOS_CONTAINER Generic Object Services Container
| | |-- CL_GUI_SIMPLE_CONTAINER Anonymous Container
| | |-- CL_GUI_SPLITTER_CONTAINER Splitter Control
| |-- CL_GUI_ECL_2DCOMPARE Compare Module for 2D Viewer
| |-- CL_GUI_ECL_3DCOMPARE Compare Module for 3D Viewer
| |-- CL_GUI_ECL_3DMEASUREMENT Measurement Module for 3D Viewer
| |-- CL_GUI_ECL_3DSECTIONING Sectioning Module for 3D Viewer
| |-- CL_GUI_ECL_MARKUP Markup (Redlining) Component
| |-- CL_GUI_ECL_PMI PMI Module for the 3D Viewer
| |-- CL_GUI_ECL_PRIMARYVIEWER Basis Class for ECL Viewers (2D und 3D)
| | |-- CL_GUI_ECL_2DVIEWER Engineering Client 2D Viewer
| | |-- CL_GUI_ECL_3DVIEWER Engineering Client 3D Viewer
| |-- CL_GUI_ECL_VIEWER Proxy Class for Engineering Client Viewer
| |-- CL_GUI_FORMPAINTER SAP Form Painter Control Proxy Class
| |-- CL_GUI_GLT Internal; Do Not Use!
| |-- CL_GUI_GP GFW: Superclass of all graphics proxies
| | |-- CL_GUI_GP_GRID GFW: Grid proxy
| | |-- CL_GUI_GP_HIER GFW: Structure graphics
| | |-- CL_GUI_GP_PRES GFW: Business graphic
| |-- CL_GUI_GRLT Internal; Do Not Use !! ( restricted license -- see docu)
| |-- CL_GUI_HTML_EDITOR HTML Editor
| |-- CL_GUI_ILIDRAGNDROP_CONTROL Interactive List: Drag & Drop
| |-- CL_GUI_MOVIE SAP Movie Control
| |-- CL_GUI_NETCHART Network wrapper
| | |-- CL_GFW_GP_HIER_SAP GFW: Product--specific section of CL_GUI_GP_HIER (NETZ)
| |-- CL_GUI_PDFVIEWER PDF Viewer
| |-- CL_GUI_PICTURE SAP Picture Control
| |-- CL_GFW_GP_PRES_WEB GFW: product specific section for web view
| |-- CL_GUI_RTF_EDITOR SAP SAPscript Editor Control
| | |-- CL_GUI_SAPSCRIPT_EDITOR SAP SAPscript Editor Control
| |-- CL_GUI_SELECTOR SAPSelector: Control for selecting colors or bitmaps
| |-- CL_GUI_SPH_STATUS_CONTROL SAPphone: Status Event Control
| |-- CL_GUI_TABLEPAINTER SAP Table Painter Control Proxy Class
| |-- CL_GUI_TIMER SAP Timer Control
| |-- CL_GUI_TOOLBAR Toolbar Control
| | |-- CL_CCMS_AL_GUI_TOOLBAR Alerts: GUI Toolbar Used in the Visual Framework
| |-- CL_GUI_WCF_WWP Internal Tool -- DO NOT USE
| |-- CL_KW_AUTOMATION_CONTROL Helper Class for General Automation Objects
| |-- CL_LC_EDITOR_CONTROL Lifecycle Editor Control
| | |-- CL_GCM_LCEDITOR_CONTROL Control for the display of definition life cycles
| |-- CL_SOTR_SPELLCHECKER Interface with OTR Spellchecker
| |-- CL_SRM_BASE_CONTROL SRM Control
| | |-- CL_SRM_STACKED_CONTROL RM Control with Stack
| |-- CL_TREE_CONTROL_BASE Internal Tree Control Class
| | |--CL_GUI_SIMPLE_TREE(参考《User Dialogs.docx》文档) Simple Tree Control
| | |-- CL_ITEM_TREE_CONTROL Internal Tree Control Class
| | |-- CL_GUI_COLUMN_TREE Column Tree Control
| | | |-- BDMT_CONTROL Administers Tree Control for Monitoring
| | | |-- CL_BUCC_TREE Consistency Checks -- Library Tree
| | | |-- CL_GFW_COLUMN_TREE Do not use!!!!!!!!
| | | |-- CL_GFW_GP_HIER_SAPTREE GFW: Product--specific section of CL_GUI_GP_HIER
| | | |-- CL_HU_COLUMN_TREE Tree that Displays Handling Units
| | |-- CL_GUI_LIST_TREE List Tree Control
| |-- C_OI_CONTAINER_CONTROL_PROXY For Internal Use
| |-- SCE_HTML_CONTROL_EVENT_HANDLER Event Handler for SCE HTML Control
| |-- CL_ALV_TREE_BASE Basis Class ALV Tree Control
| | |-- CL_GUI_ALV_TREE ALV Tree Control
| | | |-- CL_GCM_WORKLIST_TREE CM: Worklist
| | | |-- CL_PT_GUI_TMW_ALV_TREE Small Modification to CL_GUI_ALV_TREE
| | |-- CL_GUI_ALV_TREE_SIMPLE Simple ALV Tree
| | |-- CL_SIMPLE_TREE_VIEW_MM Simplest Kind of Tree
| |-- CL_GUI_ECATT_RECORDER SAP eCATT Recorder Control -- To be used by eCATT only!
| |-- CL_GUI_TEXTEDIT(参考《User Dialogs.docx》文档) SAP TextEdit Control
| | |-- CL_GCM_TEXTEDIT CM: Long text control
| | |-- CL_SOTR_TEXTEDIT Edit Control for the OTR
| |-- CL_GUI_HTML_VIEWER HTML Control Proxy Class
| |-- CL_BFW_HTML_VIEWER_POC Browser Framework: Proxy for HTML Control
| |-- CL_CCMS_BSP_VIEWER HTML Control Proxy Class
| | |-- CL_CCMS_AL_OBJ_DET_HTML_VIEWER Alerts: Component That Displays Object Properties with HTML
| |-- CL_CCMS_FROG_HTML_VIEWER CL_GUI_FROG_HTML_VIEWER
| |-- CL_SSF_HTML_VIEWER Smart Forms: Enhanced HTML Viewer
|-- CL_GUI_ECL_MATRIX Represents a Complete Data Type with 13 Floats
|-- CL_GUI_RESOURCES GUI Resources (Fonts, Colors, ...)
| |-- CL_WF_GUI_RESOURCES Getting Front Settings
| |-- CL_WF_GUI_RESOURCES_4_HTML Get Front Settings for HTML Generation
|-- CL_KW_AUTOMATION_OBJECT For Internal Use
|-- CL_TABLEPAINTER_BASETABLE SAP Table Painter Table Base Class
| |-- CL_TABLEPAINTER_TABLE SAP Table Painter Table Class
| |-- CL_TABLEPAINTER_TEMPLATE SAP Table Painter Template Class
|-- C_OI_AUTOMATION_OBJECT For Internal Use
|-- CL_GUI_FRONTEND_SERVICES Frontend services
对于CFW主要有三点需要理清:
(1)OO处理
(2)Automation Queue
(3)Events
在现实的GUI程序中,这时一共会有四个对象实例:2个 in ABAP program, 2 在 the presentation server(GUI).它的处理逻辑简单可以使用以下的截图来表示:
这里说明一下:
1.在创建将要使用的enjoy SAP control时的步骤:
* 在screen painter中画一个area(custom area)
* 然后在我们的程序中,以上一步创建SubArea(Custom area)为基础,来创建Container control class “CL_GUI_<>_CONTAINER”的实例
* 最后,再以上一步创建出来的container control为基础,来创建Enjoy SAP Control的实例
2.同时,在创建这些control时,需要注意它们的lifetime(生命周期):
* <classname>=>lifetime_imode:指定其当该Internal session存在时就一直”存活”着(也就是没有离开当前的session,如没使用Leave program)
* <classname>=>lifetime_dynpro:指定其一直“存活着”,只要该screen instance存在。
* default是imode;另外在创建时,要注意,instance只需创建一个,防止每次触发PBO时又创建instance
3.关于使用EnjoySAP Control时的数据传输
使用这些control时,在传递数据时,不同于一般的dialog程序是整体性地传递(例如一个screen中的所有input field会一次性进行交互),而这些control却是在“需要”的情况下才传递,例如只需要改变picture的长宽高等;所以,为了提高performance,在CFW中使用Automation Queue是flushed.
通常,当我们调用这些control的method或者读取它们的attribute时,这些操作会被buffer在CFW service里面(Automation Queue),这些actions只有当CFW调用了“Flush”方法后,才会将其传递给presentation server。同时因为在CFW中只有一个automation queue,它被所有的control所使用着,所以当 flush发生时,all of the actions stored for all presentaion server controls are transferred,同时,“Result values”将从presentation server controls 传回给 CFW 。我们也可以自己调用cl_gui_cfw=>flush来触发这些actions(特别有用的是:当我们的screen是compound(复和的)的,因为在Flush一般发生在PBO事件的结束,如果我们的第二个Instance method需要dependent 第一个instance method,因为没有flush)
4.关于使用EnjoySAP Control时的Event机制
在处理上, GUI上的control有很多的event,通过automation handler与CFW service,将user action传递并处理给ABAP program里的Proxy class Instance
* 首先要知道control有哪些event。这要以通过SE24中查看相关的class中有定义。
* 定义好了event,需要再定义event handler。此时,一般我们采用的是local event handler,即在程序中定义handler,然后通过set handler来进行注册这些event
* 使用CL_GUI_CFW=>dispatch
EnjoySAP Control中的Picture control与HTML control比较特别,它们需要指定data source(来源于external或者Internal)
LVC_S_FCAT
ROW_POS ALV control: Output line (INTERNAL USE)
COL_POS ALV control: Output column
FIELDNAME ALV control: Field name of internal table field
TABNAME LVC tab name
CURRENCY ALV control: Currency unit
CFIELDNAME ALV control: Field name for currency unit referenced
QUANTITY ALV control: Unit of measure
QFIELDNAME ALV control: Field name for unit of measure referenced
IFIELDNAME ALV control: Field name of internal table field
ROUND ALV control: ROUND value
EXPONENT ALV control: Exponent for float representation
KEY ALV control: Key field
KEY_SEL ALV control: Key column that may be hidden
ICON ALV control: Output as icon
SYMBOL ALV control: Output as symbol
CHECKBOX ALV control: Output as checkbox
JUST ALV control: Alignment
LZERO ALV control: Output leading zeros
NO_SIGN ALV Control: Suppress Signs for Output
NO_ZERO ALV control: Suppress zeros for output
NO_CONVEXT ALV control: Do not consider conversion exit for output
EDIT_MASK ALV control: EditMask for output
EMPHASIZE ALV control: Highlight column with color
FIX_COLUMN ALV Control: Fix Column
DO_SUM ALV control: Aggregate values of column
NO_SUM ALV control: No aggregation over values of column
NO_OUT ALV control: Column is not output
TECH ALV control: Technical field
OUTPUTLEN ALV control: Column width in characters
CONVEXIT Conversion Routine
SELTEXT ALV control: Column identifier for dialog functions
TOOLTIP ALV control: Tool tip for column header
ROLLNAME ALV control: Data element for F1 help
DATATYPE Data Type in ABAP Dictionary
INTTYPE ABAP data type (C,D,N,...)
INTLEN Internal Length in Bytes
LOWERCASE Lowercase letters allowed/not allowed
REPTEXT Heading
HIER_LEVEL ALV control: Internal use
REPREP ALV control: Value is selection criterion for rep./rep.intf.
DOMNAME Domain name
SP_GROUP Group key
HOTSPOT ALV control: SingleClick-sensitive
DFIELDNAME ALV control: Field name for column group in database
COL_ID ALV control: Column ID
F4AVAILABL Does the field have an input help
AUTO_VALUE ALV control: Automatic value copy
CHECKTABLE Table Name
VALEXI Existence of fixed values
WEB_FIELD ALV control: Field name of internal table field
HREF_HNDL Natural Number
STYLE ALV control: Style
STYLE2 ALV control: Style
STYLE3 ALV control: Style
STYLE4 ALV control: Style
DRDN_HNDL Natural Number
DRDN_FIELD ALV control: Field name of internal table field
NO_MERGING Character Field Length 1防止在排序时,将相同的列合并成一个单元格
H_FTYPE ALV tree control: Functional type (sum, avg, max, min, ...)
COL_OPT Entry for Optional Column Optimization
NO_INIT_CH Character Field Length 1
DRDN_ALIAS Character Field Length 1
DECFLOAT_STYLE DD: Output Style (Output Style) for Decfloat Types
PARAMETER0 30 Characters
PARAMETER1 30 Characters
PARAMETER2 30 Characters
PARAMETER3 30 Characters
PARAMETER4 30 Characters
PARAMETER5 Natural Number
PARAMETER6 Natural Number
PARAMETER7 Natural Number
PARAMETER8 Natural Number
PARAMETER9 Natural Number
REF_FIELD ALV control: Reference field name for internal table field
REF_TABLE ALV control: Reference table name for internal table field
TXT_FIELD ALV control: Field name of internal table field
ROUNDFIELD ALV control: Field name with ROUND specification
DECIMALS_O ALV control: Number of decimal places for output
DECMLFIELD ALV control: Field name with DECIMALS specification
DD_OUTLEN ALV control: Output length in characters
DECIMALS Number of Decimal Places
COLTEXT ALV control: Column heading
SCRTEXT_L Long Field Label
SCRTEXT_M Medium Field Label
SCRTEXT_S Short Field Label
COLDDICTXT ALV control: Determine DDIC text reference
SELDDICTXT ALV control: Determine DDIC text reference
TIPDDICTXT ALV control: Determine DDIC text reference
EDIT ALV control: Ready for input
TECH_COL ALV control: Internal use
TECH_FORM ALV control: Internal use
TECH_COMP ALV control: Internal use
HIER_CPOS ALV control: Hierarchical column position
H_COL_KEY Tree Control: Column Name / Item Name
H_SELECT Indicates if a column in the tree control can be selected
DD_ROLL Data element (semantic domain)
DRAGDROPID ALV control: Drag&Drop handle for DragDrop object
MAC Character Field Length 1
INDX_FIELD Natural Number
INDX_CFIEL Natural Number
INDX_QFIEL Natural Number
INDX_IFIEL Natural Number
INDX_ROUND Natural Number
INDX_DECML Natural Number
GET_STYLE Character Field Length 1
MARK Character Field Length 1
LVC_S_LAYO
ZEBRA ALV control: Alternating line color (striped)
EDIT ALV control: Ready for input
EDIT_MODE ALV control: Edit mode
NO_KEYFIX ALV control: Do not fix key columns
FRONTEND ALV control: Excel, Crystal or ALV
OBJECT_KEY Business Document Service: Object key
DOC_ID Business Document Service: Document ID
TEMPLATE Business Document Service: File names
LANGUAGE Language ID
GRAPHICS GUID in 'CHAR' Format in Uppercase
SMALLTITLE ALV control: Title size 标题大小
NO_HGRIDLN ALV control: Hide horizontal grid lines
NO_VGRIDLN ALV control: Hide vertical grid lines
NO_HEADERS ALV control: Hide column headings
NO_MERGING ALV control: Disable cell merging 排序时不会合并相邻相同的单元格
CWIDTH_OPT ALV control: Optimize column width
TOTALS_BEF ALV control: Totals output before individual records
NO_TOTARR Character Field Length 1
NO_TOTEXP Character Field Length 1
NO_ROWMOVE Character Field Length 1
NO_ROWINS Character Field Length 1
NO_COLEXPD Character Field Length 1
NO_F4 Character Field Length 1
COUNTFNAME ALV control: Field name of internal table field
COL_OPT Character Field Length 1
VAL_DATA Character Field Length 1
BLOB_SCOPE Identifier if BLOB is from SAP or Customer
BLOB_FLAVOUR Key Field for BLOB Store in SALV_BS_BLOB_...
BLOB_NAME Name for BLOB Store in SALV_BS_BLOB_...
BLOB_KEY Key Field for BLOB Storage
BLOB_TYPE ID from ALV Layout for BLOB Display Mode
.INCLUDE ALV control: General display options
STYLEFNAME ALV control: Field name of internal table field
.INCLUDE ALV control: Grid customizing
NO_ROWMARK ALV control: Disable row selections 删除GRID的行选择按钮,SEL_MODE = D时删除行选择按钮,为A时列/行选择按钮?
NO_TOOLBAR ALV control: Hide toolbar不会显示工具条
GRID_TITLE ALV Control: Title bar text
SEL_MODE ALV control: SelectionMode 选择模式(A,B,C,D,SPACE)
1.如果你设置了ALV 是可编辑的,可能会覆盖你在布局中选择方式的设置的.
2.设置了选择方式以后,我们可以使用很多方法来获取用户的选择.比如"GET_SELECTED_CELLS","GET_SELECTED_CELLS_ID","GET_SELECTED_ROWS","GET_SELECTED_COLUMNS"
3.在执行PAI 以后,用户所选择的单元格,行或者列可能丢失.你可以在PBO中,使用对应的SET 方法来恢复这些选择.
BOX_FNAME ALV control: Field name of internal table field
SGL_CLK_HD ALV control: SingleClick on column header
.INCLUDE ALV control: Totals options
NO_TOTLINE ALV control: Do not output totals line
NUMC_TOTAL ALV control: Disallow NUMC field summation
NO_UTSPLIT ALV control: Split totals lines by unit
EXCP_FNAME ALV control: Field name with exception coding
EXCP_ROLLN ALV control: Data element for exception documentation
EXCP_CONDS ALV control: Aggregate exceptions
EXCP_LED ALV control: Exception as LED
EXCP_GROUP ALV Control: Exception Group
.INCLUDE ALV control: Interactive control
DETAILINIT ALV control: Display initial values on detail screen
DETAILTITL ALV control: Title bar of detail screen
KEYHOT ALV control: Key columns as hotspot
NO_AUTHOR ALV control: Do not perform ALV standard authority check
XIFUNCKEY SAP Query (S): Name of additional function
XIDIRECT General Flag
S_DRAGDROP ALV control: Drag&Drop control settings 允许行拖放功能
.INCLUDE ALV control: Colors
INFO_FNAME ALV control: Field name with simple row color coding
CTAB_FNAME ALV control: Field name with complex cell color coding
.INCLUDE ALV control: Web options
WEBLOOK ALV control: Web look
WEBSTYLE ALV control: Style
WEBROWS ALV control: Number of lines to be displayed in the Web
WEBXWIDTH Natural Number
WEBXHEIGHT Natural Number
set_table_for_first_dispaly()方法参数
函数REUSE_ALV_GRID_DISPLAY创建ALV报,需要构造fieldcat、数据输出内表、以及设置Layout,然后将它们通过it_fieldcat、 t_outtab、is_layout 参数传递给REUSE_ALV_GRID_DISPLAY函数。其实通过面向对象的方式生成ALV时,基本上也是一样,先也要准备这些信息,然后通过CL_GUI_ALV_GRID类的实例方法set_table_for_first_display的相关参数传递进去,即可生成ALV
CL_GUI_ALV_GRID的set_table_for_first_dispaly ()方法参数与函数REUSE_ALV_GRID_DISPLAY参数类似,其作用都是一样:生产ALV:
参数 含义
I_BUFFER_ACTIVE: 如果方法调用是静态的,可以设置这个标记,这表示,如果每次显示ALV 都是相同的字段目录。既然这样,那么字段目录会被放到一个特殊的缓存里,这样加速了ALV 的显示
I_STRUCTURE_NAME: 输出数据参考的数据字典的结构名,例如'SFLIGHT'。如果指定了这个参数,字段目录会自动生成,下面的参数T_FIELDCATALOG 不需要传值。
IS_VARIANT: 展示时所使用的布局变式
I_SAVE: 决定用户是否可以保存变式:'X' 只能保存全局变式;'U' 只能保存特定变式;'A' 都可以保存;SPACE 不可以将布局保存为变式
I_DEFAULT: 决定用户是否可以设置默认的布局:'X' 可以定义默认布局,这个参数是默认的;SPACE 不可以设置默认布局
IS_LAYOUT: ALV布局设置(外观设置)
IS_PRINT: 后台打印属性的参数
IT_SPECIAL_GROUPS: 如果在字段目录中,一些字段通过SP_GROUP 被分组在一起。我们就必须为这些组传递一个组的文本内表进去
IT_TOOLBAR_EXCLUDING: 需要隐藏的标准按钮的内表
IT_HYPERLINK: 设置HTTP超链接
IT_ALV_GRAPHICS: 比较复杂,没有用过,意思好象是可以在图表中显示ALV。
IT_OUTTAB: 输出数据存放的内表,数据都是存放在这个内表里
IT_FIELDCATALOG: 字段目录
IT_SORT: 排序
IT_FILTER: 数据过滤
隐藏工具栏中预置按钮(IT_TOOLBAR_EXCLUDING参数接口)
标准按钮的Funcode可以打开 CL_GUI_ALV_GRID 进行查看
refresh_table_display( )参数
参数 含义
IS_STABLE: 刷新的稳定性,有2 个参数,一个是行,一个是列。如果设置了相应的值,那么对应的行或者列,在刷新的时候将会保持稳定(就是滚动条保持不动)
I_SOFT_REFRESH: 软刷新。这个参数只是在异常情况下被使用,如果设置了这个参数,任何创建的合计,任何排序次序,任何为了显示数据而设置的过滤都将保持不变。这个是非常有意义的,例如:当然你没有修改数据内表里的数据,但因布局修改了想刷新ALV可使用(仅仅只是改变一下布局和字段目录,输出内表中的数据根本没有发生变化,所以不需要硬刷新了)
创建ALV
ALV表格控件对应的全局类是“CL_GUI_ALV_GRID”,因为所有的Controls控件必须被嵌入在一个SAP容器(SAP Container Control,以下简称容器),其全局类为“CL_GUI_CUSTOM_CONTAINER”,而该容器的实例对象又必须以屏幕上的用户自定义控件区域(Custom Control)中为基础来创建:所以创建ALV之前先需要创建用户对话屏幕,再在屏幕上绘制一个用户自定义控件区域,然后该用户自定义控件区域为基础来创建CL_GUI_CUSTOM_CONTAINER容器实例,最后以此容器实例来创建CL_GUI_ALV_GRID实例即可。用户自定义控件区域、容器、ALV控件三都之间的关系如下:
在创建容器对象实例时,其构造方法有一个必传参数CONTAINER_NAME,它的值就是屏幕上绘制的“用户自定义控件区域(Custom Control)”的控件的名称:
当容器实例创建好以后,CL_GUI_ALV_GRID再以此容器对象为参数实例化,即可得到CL_GUI_ALV_GRID对象,最后再调用CL_GUI_ALV_GRID实例对象的set_table_for_first_display方法来生成ALV报表,CL_GUI_ALV_GRID的重要方法如下:
1、 构造函数Constructor( ):必传参数“I_parent”,容器对象引用,即需要将ALV显示在在哪容器中
2、 生成表报set_table_for_first_display( ):产生ALV报表,与REUSE_ALV_GRID_DISPLAY函数的作用一样,参数也大体相同
3、 刷新报表refresh_table_display( ):刷新并重新显示ALV,当输出内表数据变更、或其他ALV设置变化时,可以调用此方法重新显示ALV
实例:带查询条件、行颜色、事件
一、创建对话屏幕
由于ALV没有专门实现的控件,需要先在对话屏幕100上增加一个用户自定义控件区域(Custom Control),名为CONTAINER_1:
二、新增子屏幕区域,嵌入查询条件
将查询条件放在100对话屏幕中的子屏幕101上,所以需要在100屏幕上增加一个子屏幕区域,用来存放子屏幕:
注:这里我们并没有直接创建出101子屏幕,而是通过ABAP程序来创建的子屏幕,具体请看程序。
子屏幕的详细使用可参考《User Dialogs.docx》文档中的“对话屏幕(Dynpro Screen)->复合屏幕元素->子屏幕Subscreens”章节
三、创建Gui Status,新增查询按钮
还为100对话屏幕增加一个“查询”按钮,用于条件查询:
四、在ALV工具栏中新增自定义按钮
ALV控件会自带一组工具按钮,如果要在工具栏上加上按钮,则需要使用STB_BUTTON结构,该结构的字段介绍如下:
具体作法请参见程序
五、程序代码设计
CLASS cl_event_handle DEFINITION. "定义事件处理类
PUBLIC SECTION.
"初始化ALV工具栏对象事件,如增加按钮并设定属性
METHODS handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING e_object e_interactive.
"该事件用于在下ALV工具栏的下拉菜单按钮中增加选项
METHODS handle_menu_button FOR EVENT menu_button OF cl_gui_alv_grid
IMPORTING e_object e_ucomm.
"ALV工具栏按钮的点击事件
METHODS handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
IMPORTING e_ucomm.
"ALV表格双击事件
METHODS handle_double_click FOR EVENT double_click OF cl_gui_alv_grid
IMPORTING e_row e_column es_row_no.
ENDCLASS.
DATA: gs_toolbar TYPE stb_button.
DATA:BEGIN OF gt_sflight OCCURS 0.
INCLUDE STRUCTURE sflight.
DATA: color TYPE char10,"在原表的基础上附加此列,用来存储每行颜色
END OF gt_sflight.
CLASS cl_event_handle IMPLEMENTATION."事件处理类实现部分
METHOD handle_toolbar.
gs_toolbar-function = 'B_SUM'."按钮的FunctionCode
gs_toolbar-icon = icon_display."按钮图标
gs_toolbar-text = '总行数'."按钮标签
gs_toolbar-butn_type = '0'."定义按钮类型,0为标准按钮,具体取值可参考这里
APPEND gs_toolbar TO e_object->mt_toolbar."添加按钮到工具栏中
gs_toolbar-function = 'B_LIST'."按钮的FunctionCode
gs_toolbar-quickinfo = '自定义下拉菜单按钮'."按钮的冒泡提示
gs_toolbar-icon = icon_biw_report_view."按钮图标
gs_toolbar-text = '下拉菜单按钮'."按钮标签
gs_toolbar-butn_type = '1'."定义按钮类型,1为下拉菜单按钮
APPEND gs_toolbar TO e_object->mt_toolbar."添加下拉菜单按钮到工具栏中
ENDMETHOD.
METHOD handle_menu_button.
IF e_ucomm = 'B_LIST'."给下拉菜单按钮增加选项,可以多次调用该方法以增加多行
CALL METHOD e_object->add_function
EXPORTING
icon = icon_display
fcode = 'B_SUM'"字菜单按钮的FunCode
text = '显示ALV总行数'.
ENDIF.
ENDMETHOD.
METHOD handle_user_command.
DATA: sum TYPE i .
IF e_ucomm = 'B_SUM'.
DESCRIBE TABLE gt_sflight[] LINES sum.
MESSAGE i001(00) WITH '当前ALV表格中的数据总行数为:' sum.
ENDIF.
ENDMETHOD.
METHOD handle_double_click.
READ TABLE gt_sflight INTO gt_sflight INDEX es_row_no-row_id.
MESSAGE i001(00) WITH '当前行:' es_row_no-row_id ',航线代码:' gt_sflight-carrid.
ENDMETHOD.
ENDCLASS.
DATA: event_handle TYPE REF TO cl_event_handle."定义类对象的引用
DATA: grid_r TYPE REF TO cl_gui_alv_grid ,
container_r TYPE REF TO cl_gui_custom_container.
DATA:fieldcat TYPE lvc_t_fcat.
DATA: gs_layout TYPE lvc_s_layo.
TABLES: spfli.
"查询条件子屏幕
SELECTION-SCREEN BEGIN OF SCREEN 101 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK 10 WITH FRAME TITLE title.
SELECT-OPTIONS:s_carrid FOR spfli-carrid,
s_connid FOR spfli-connid.
SELECTION-SCREEN END OF BLOCK 10.
SELECTION-SCREEN END OF SCREEN 101.
INITIALIZATION.
title = '查询条件'.
START-OF-SELECTION.
CALL SCREEN 100.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'T001'.
ENDMODULE.
MODULE user_command_0100 INPUT.
CASE sy-ucomm.
WHEN 'EXEC'.
SELECT * FROM sflight INTO CORRESPONDING FIELDS OF TABLE gt_sflight
WHERE carrid IN s_carrid AND connid IN s_connid.
"以字母C加上一个3位数据作为颜色代码:C510表示绿色,C610表示红色,C310表示黄色
gt_sflight-color = 'C610'.
MODIFY gt_sflight TRANSPORTING color WHERE seatsocc < 100.
IF container_r IS INITIAL.
CREATE OBJECT container_r"创建ALV容器对象
EXPORTING container_name = 'CONTAINER_1'.
CREATE OBJECT grid_r"创建ALV控件
EXPORTING i_parent = container_r.
gs_layout-info_fname = 'COLOR'."指定存放颜色字段
CALL METHOD grid_r->set_table_for_first_display
EXPORTING
i_structure_name = 'sflight'
is_layout = gs_layout
i_save = 'X'"可以保存变式
CHANGING
it_outtab = gt_sflight[]
it_fieldcatalog = fieldcat[]."如果fieldcat内表为空,则相当于没有配置,采用默认方式显示
CREATE OBJECT :event_handle.
"为ALV按钮注册监听事件
SET HANDLER :event_handle->handle_toolbar FOR grid_r,
event_handle->handle_menu_button FOR grid_r,
event_handle->handle_user_command FOR grid_r,
event_handle->handle_double_click FOR grid_r.
"调用此方法才能激活工具栏上增加的自定义按钮
CALL METHOD grid_r->set_toolbar_interactive.
ELSE.
CALL METHOD grid_r->refresh_table_display.
ENDIF.
ENDCASE.
ENDMODULE.
容器Container
SAP容器是连接着最终显示控件(如ALV Grid、Tree、Picture、TextEdit、Splitter)与屏幕区域的中间控件,在构造这些显示控件前都需要创建相应的容器实例对象。目前容器控件有以下5种:
CL_GUI_DOCKING_CONTAINER容器
上面程序中使用的是cl_gui_custom_container容器类,在使用该时,需要传递一个已经在屏幕上绘制好的用户自定义控件区域(Custom Control)中,
Docking容器最大特点是在代码中可以动态创建容器,不需要像创建自定义容器CL_GUI_CUSTOM_CONTAINER那样,在创建时需要将其绑定到一个预先绘制好的用户自定义控件区域中,但是还是要先创建用户对话屏幕,如:
DATA: gt_fieldcat TYPE lvc_t_fcat WITH HEADER LINE.
DATA: gs_layout TYPE lvc_s_layo.
DATA: grid_r TYPE REF TO cl_gui_alv_grid ,
container_r TYPE REF TO cl_gui_docking_container.
DATA:BEGIN OF gt_data OCCURS 0,
val1(40),
val2(40),
END OF gt_data.
START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-scrtext_l = &2.
append gt_fieldcat.
END-OF-DEFINITION.
fill_fdcat 'VAL1' '列1'.
fill_fdcat 'VAL2' '列2'.
CALL SCREEN 100.
FORM inital .
gt_data-val1 = 'cell1'.
gt_data-val2 = 'cell2'.
APPEND gt_data.
ENDFORM.
MODULE init_0100 OUTPUT.
CREATE OBJECT container_r"创建ALV容器对象,这里不需要与用户自定义控件绑定
EXPORTING
repid = sy-repid
dynnr = sy-dynnr
extension = 300."ALV初始宽度
CREATE OBJECT grid_r"创建ALV控件
EXPORTING
i_parent = container_r.
CALL METHOD grid_r->set_table_for_first_display
EXPORTING
is_layout = gs_layout
CHANGING
it_outtab = gt_data[]
it_fieldcatalog = gt_fieldcat[].
ENDMODULE.
CL_GUI_SPLITTER_CONTAINER容器
SAP Splitter Container可以将屏幕区域划分成多个子区域,具有如下特性:
(1)它可以显示在其他的container control中
(2)它最大可以达到16 * 16 单元格
(3)可以在每个单元格中显示其他的control
(4)Split bars可以移动或者固定
(5)可以通过程序来控制其高度和宽度
(6)可以显示Frame
DATA: gt_fieldcat TYPE lvc_t_fcat WITH HEADER LINE.
DATA: gs_layout TYPE lvc_s_layo.
DATA: grid_r TYPE REF TO cl_gui_alv_grid ,
grid_r2 TYPE REF TO cl_gui_alv_grid ,
container_r TYPE REF TO cl_gui_docking_container,
ref_splitter TYPE REF TO cl_gui_splitter_container,
ref_cell TYPE REF TO cl_gui_container.
DATA:BEGIN OF gt_data OCCURS 0,
val1(40),
val2(40),
END OF gt_data.
START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-scrtext_l = &2.
append gt_fieldcat.
END-OF-DEFINITION.
fill_fdcat 'VAL1' '列1'.
fill_fdcat 'VAL2' '列2'.
CALL SCREEN 100.
FORM inital .
gt_data-val1 = 'cell1'.
gt_data-val2 = 'cell2'.
APPEND gt_data.
ENDFORM.
MODULE init_0100 OUTPUT.
CREATE OBJECT container_r
EXPORTING
repid = sy-repid
dynnr = sy-dynnr
extension = 300.
CREATE OBJECT ref_splitter
EXPORTING
parent = container_r
rows = 1"将父容器分成两个子容器
columns = 2.
"得到第一行第一列子容器
CALL METHOD ref_splitter->get_container
EXPORTING
row = 1
column = 1
RECEIVING
container = ref_cell.
CREATE OBJECT grid_r"创建第一个ALV,并放在左边子容器中
EXPORTING
i_parent = ref_cell.
CALL METHOD grid_r->set_table_for_first_display
EXPORTING
is_layout = gs_layout
CHANGING
it_outtab = gt_data[]
it_fieldcatalog = gt_fieldcat[].
"得到第一行第二列容器
CALL METHOD ref_splitter->get_container
EXPORTING
row = 1
column = 2
RECEIVING
container = ref_cell.
CREATE OBJECT grid_r2 "创建第一个ALV,并放在右边子容器中
EXPORTING
i_parent = ref_cell.
CALL METHOD grid_r2->set_table_for_first_display
EXPORTING
is_layout = gs_layout
CHANGING
it_outtab = gt_data[]
it_fieldcatalog = gt_fieldcat[].
ENDMODULE.
CL_GUI_ALV_GRID常用方法
get_current_cell( )方法
获取鼠标所在网格中的位置,如果未选中任何单元格,则row值返回为0。这个方法会返回两种索引,一个是网格的行列索引,另一个是输入内表的行列索引,这是因为当设置隐藏字段时实际界面上显示的顺序与内表的不同,所以都返回了
get_frontend_layout( )方法
获取现在设置的ALV GriD的布局
get_selected_cells( )方法
获取所选的多个单元格
get_selected_columns( )方法
获取所选的多列
get_selected_rows( )方法
获取所选的多行
refresh_table_display( )方法
当输出内表的数据更新后,需要使用此方法来刷新网格
set_frontend_layout( )方法
修改布局,调用此方法后还需调用refresh_table_display再生效
CL_GUI_ALV_GRID常用事件
双击事件DOUBLE_CLICK
行的双击事件与下面的HOTSPOT_CLICK事件触发时,回调的参数是一样的
热点单击事件HOTSPOT_CLICK
某个字段的字段目录HOTSPOT设置为"X",那么这个字段就可以接受单击事件HOTSPOT_CLICK。这个HOTSPOT_CLICK 事件有三个参数,其中第一个参数"E_ROW_ID"已经作废,另外2 个参数是:参考类型LVC_S_COL 定义的"E_COLUMN_ID",可以通过E_COLUMN_ID-FIELDNAME 来反映当前点击的字段名(定位哪列);参考类型LVC_S_ROID 定义的"ES_ROW_NO",可以通过ES_ROW_NO-ROW_ID 来反映当前点击的行号,从而可以定位鼠标的位置(定位哪行)。
FORM handle_hotspot_click USING i_row_id TYPE lvc_s_row
i_column_id TYPE lvc_s_col
is_row_no TYPE lvc_s_roid.
READ TABLE gt_data INDEX is_row_no-rowid.
IF sy-subrc = 0 AND i_column_id-fieldname = 'XXX'.
...
ENDIF.
ENDFORM.
Toolbar加载事件TOOLBAR
工具栏中下拉菜单加载事件menu_button
用户命令事件USER_COMMAND、
覆盖预设功能FunCode:BEFORE_USER_COMMAND
ALV 也给我们提供了修改标预置按钮功能的机会,为了实现这个目的,我们需要在"before_user_command"事件中截取标准的功能,然后使用方法"set_user_command"来修改功能码,这样便可以指向自己定义的功能码
FORM handle_before_user_command USING i_ucomm TYPE syucomm .
CASE e_ucomm .
WHEN '&INFO' .
CALL FUNCTION 'ZSFLIGHT_PROG_INFO' .
CALL METHOD gr_alvgrid->set_user_command
EXPORTING
i_ucomm = space.
ENDCASE .
ENDFORM .
数据变化事件data_changed、data_changed_finished
我们可以设置alv 处于可编辑状态,当然ALV 也提供给我们控制数据的输入。Alv grid有两个事件:data_changed和ata_changed_finished.第一个事件在可编辑字段的数据发生变化时触发,可用来检查数据的输入正确性,第二个事件是当数据修改完成后触发
注:如果数据没有被修改,当失去焦点或回车时(具体在失去焦点或回车是是否触发,则要看是否通过REGISTER_EDIT_EVENT此方法注册过这两种触发方式,见后面)那么它不会走data change,而是直接触发data change finish事件
我们可以通过方式CL_GUI_ALV_GRID类的REGISTER_EDIT_EVENT方法来设置,如何触发数据改变事件,2 种方式:
1.按回车触发: i_event_id = cl_gui_alv_grid=>mc_event_enter
2.单元格失去焦点: i_event_id = cl_gui_alv_grid=>mc_event_modifies
必须设置一种方式,要不然数据变化事件不会被触发事件
为了获取ALV 中被修改字段的一些信息,DATA_CHANGED 事件会把参考CL_ALV_CHANGED_DATA_PROTOCOL实例通过参数ER_DATA_CHANGED传递给ALV,通过这个参数我们可以知道哪些单元格被修改了,修改了什么值,下面是类CL_ALV_CHANGED_DATA_PROTOCOL 的一些方法:
Get_cell_value 获取单元格的值
Modify_cell 修改单元格
Add_protocol_entry 增加日志记录
Protocol_is_visible 是否允许错误表可见
Refresh_protocol 刷新日志记录
另外,通过CL_ALV_CHANGED_DATA_PROTOCOL的实例属性,
通过上述一系列方式和属性,可以获取修改的值,从而进行一些输入的检查
FORM handle_data_changed USING ir_data_changed
TYPE REF TO cl_alv_changed_data_protocol.
DATA: ls_mod_cell TYPE lvc_s_modi,
lv_value TYPE lvc_value.
SORT ir_data_changed->mt_mod_cells BY row_id."对发生改变所有单元格进行排序
"只对有过修改的 SEATSMAX 字段所对应单元格进行处理
LOOP AT ir_data_changed->mt_mod_cells INTO ls_mod_cell
WHERE fieldname = 'SEATSMAX'.
CALL METHOD ir_data_changed->get_cell_value"获取单元格中的值
EXPORTING
i_row_id = ls_mod_cell-row_id"行号
i_fieldname = 'CARRID'"要获取的列的列名
IMPORTING
e_value = lv_value."获取到的单元格中的值
"进行关联性验证,即 SEATSMAX 与 CARRID 两个单元格中的值一起进行验证
IF lv_value = 'THY' AND ls_mod_cell-value > '500'.
"如果验证不通过,记录错误消息日志
CALL METHOD ir_data_changed->add_protocol_entry
EXPORTING
i_msgid = 'SU'
i_msgno = '000'
i_msgty = 'E'
i_msgv1 = 'This number can not exceed 500 for '
i_msgv2 = lv_value
i_msgv3 = 'The value is et to ''500'''
i_fieldname = ls_mod_cell-fieldname
i_row_id = ls_mod_cell-rowid.
"然后将值修改回到500
CALL METHOD ir_data_changed->modify_cell
EXPORTING
i_row_id = ls_mod_cell-row_id
i_fieldname = ls_mod_cell-fieldname
i_value = '500'.
ENDIF.
ENDLOOP.
ENDFORM.
拖入事件ONDRAG、ONDROP
按钮点击事件BUTTON_CLICK
参数与HOTSPOT_CLICK事件后两个参数是一样的
首次显示后更新FieldCat、Layout
在很多时候,当报表第一次显示出来后,有时后通过ALV工具栏中的布局按钮,可能切换布局或已修改了布局,此时的字段目录或Layout发生了变化,但可能需要在此基础上做一些人为的手动修改,此时可以调用以下这些方法:
字段目录 : get_frontend_fieldcatalog
set_frontend_fieldcatalog
布局: get_frontend_layout
set_frontend_layout
使用这些方法,在首次展示后,可以获取这些内容,然后修改他们:
DATA ls_fcat TYPE lvc_s_fcat .
DATA lt_fcat TYPE lvc_t_fcat .
DATA ls_layout TYPE lvc_s_layo .
CALL METHOD gr_alvgrid->get_frontend_fieldcatalog
IMPORTING
et_fieldcatalog = lt_fcat[].
LOOP AT lt_fcat INTO ls_fcat .
IF ls_fcat-fieldname = 'PAYMENTSUM' .
ls_fcat-no_out = space .
MODIFY lt_fcat FROM ls_fcat .
ENDIF .
ENDLOOP .
CALL METHOD gr_alvgrid->set_frontend_fieldcatalog
EXPORTING
it_fieldcatalog = lt_fcat[].
CALL METHOD gr_alvgrid->get_frontend_layout
IMPORTING
es_layout = ls_layout.
ls_layout-grid_title = 'Flights (with Payment Sums)' .
CALL METHOD gr_alvgrid->set_frontend_layout
EXPORTING
is_layout = ls_layout.
HTTP超链接
DATA: gt_fieldcat TYPE lvc_t_fcat WITH HEADER LINE.
DATA: gs_layout TYPE lvc_s_layo.
DATA: grid_r TYPE REF TO cl_gui_alv_grid ,
container_r TYPE REF TO cl_gui_docking_container.
DATA:BEGIN OF gt_data OCCURS 0,
val1(40),"需要给此字段设置HTTP超链接
val2(40),
"存储VAL1字段的超链接所对应的链接值,由该字段的值来决定VAL1
"具体链接到哪个网址(即网址所对应的Key,这种映射关系是在后面lvc_t_hype内表中指定的),该字段一般不做显示
val1_link_val TYPE int4,
END OF gt_data.
START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-scrtext_l = &2.
"将VAL1列设置成HTTP超链接
if &1 = 'VAL1'.
"指定VAL1超链接所对应的链接值字段,这样VAL1列就会自动成为超链接了
gt_fieldcat-web_field = 'VAL1_LINK_VAL'.
endif.
append gt_fieldcat.
END-OF-DEFINITION.
fill_fdcat 'VAL1' '超链接列'.
fill_fdcat 'VAL2' '列2'.
CALL SCREEN 100.
FORM inital .
gt_data-val1 = '打开百度'.
gt_data-val2 = '百度'.
gt_data-val1_link_val = 1.
APPEND gt_data.
gt_data-val1 = '打开谷歌'.
gt_data-val2 = '谷歌'.
gt_data-val1_link_val = 2.
APPEND gt_data.
ENDFORM.
MODULE 100_pbo OUTPUT.
CREATE OBJECT container_r
EXPORTING
repid = sy-repid
dynnr = sy-dynnr
extension = 300.
CREATE OBJECT grid_r
EXPORTING
i_parent = container_r.
"==========HTTP超链接
DATA ls_hype TYPE lvc_s_hype .
DATA lt_hype TYPE lvc_t_hype ."网址映射关系表,在具体链接到哪个网址就是根据 handle 中设定的值来获取的
ls_hype-handle = 1 ."相当于HashMap中的Key
ls_hype-href = 'http://www.baidu.com' ."相当于HashMap中的Value
APPEND ls_hype TO lt_hype .
ls_hype-handle = 2 .
ls_hype-href = 'http://www.google.com' .
APPEND ls_hype TO lt_hype .
CALL METHOD grid_r->set_table_for_first_display
EXPORTING
is_layout = gs_layout
it_hyperlink = lt_hype
CHANGING
it_outtab = gt_data[]
it_fieldcatalog = gt_fieldcat[].
ENDMODULE.
下拉框
设置为下拉,和上面设置HTTP超级链接是类似的,也是使用了一个内表存放了Key和Value的键值对,这个表类型为LVC_T_DROP。不过传递给ALV 的方式有点区别:超级链接是通过方法SET_TABLE_FOR_FIRST_DISPLAY的参数来传递的,而下拉的内表传递需要使用方法SET_DROP_DOWN_TABLE
DATA: gt_fieldcat TYPE lvc_t_fcat WITH HEADER LINE.
DATA: gs_layout TYPE lvc_s_layo.
DATA: grid_r TYPE REF TO cl_gui_alv_grid ,
container_r TYPE REF TO cl_gui_docking_container.
DATA:BEGIN OF gt_data OCCURS 0,
val1(40),"需要将此字段设置为下拉框
val2(40),
"val1列的每个单元格中的下拉框中的值集所对应的句柄Key
"注:如果整列所有单元格的下拉框的值是一样,则不需要附加下以字段
",而是直接通过 gt_fieldcat-drdn_hndl 设置下拉框所对应的句柄Key即可
drop_down_handle TYPE int4,
END OF gt_data.
START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-scrtext_l = &2.
"将VAL1列设置成下拉框形式
if &1 = 'VAL1'.
"注:该设置是在整列所有单元下拉框值都是一样的情况下,可以这样设置
",如果每个单元格下拉框中的值不一样,则需要使用后面 drdn_field来设置
"gt_fieldcat-drdn_hndl = '1' .
"设置下拉框值所对应的句柄Key列名。这里是假设每个单元格的下拉框值不
"一样才有必要这样设置,如果都有一样,通过上面 drdn_hndl 简单设置即
"可,也根本就不在输出内表中再定义一个 drop_down_handle 列来存储每个
"单元格值所对应的句柄Key
gt_fieldcat-drdn_field = 'DROP_DOWN_HANDLE' .
endif.
append gt_fieldcat.
END-OF-DEFINITION.
fill_fdcat 'VAL1' '下拉框列'.
fill_fdcat 'VAL2' '列2'.
CALL SCREEN 100.
FORM inital .
gt_data-val1 = '值1'.
gt_data-drop_down_handle = 1.
APPEND gt_data.
gt_data-val1 = '值2'.
gt_data-drop_down_handle = 2.
APPEND gt_data.
ENDFORM.
MODULE 100_pbo OUTPUT.
CREATE OBJECT container_r
EXPORTING
repid = sy-repid
dynnr = sy-dynnr
extension = 300.
CREATE OBJECT grid_r
EXPORTING
i_parent = container_r.
"==========下拉框中的值
DATA lt_ddval TYPE lvc_t_drop.
DATA ls_ddval TYPE lvc_s_drop.
"句柄Key,相同句柄Key的值为一个值集,即同属于一个下拉框
ls_ddval-handle = '1' .
"出现在下拉框中的值。注:这里只有值,没有Key,即这里的下拉框
"与以往的下拉框不同:值就是Key,key就是值(其实是可以做成有Key也有Value的下拉框的,请参考后面)
ls_ddval-value = '值1' .
APPEND ls_ddval TO lt_ddval .
ls_ddval-handle = '1' .
ls_ddval-value = '值2' .
APPEND ls_ddval TO lt_ddval .
"上面设置了一个下拉框的值,下面再设置另外一个下拉框的值
ls_ddval-handle = '2' .
ls_ddval-value = '值2' .
APPEND ls_ddval TO lt_ddval .
ls_ddval-handle = '2' .
ls_ddval-value = '值3' .
APPEND ls_ddval TO lt_ddval .
CALL METHOD grid_r->set_drop_down_table
EXPORTING
it_drop_down = lt_ddval.
CALL METHOD grid_r->set_table_for_first_display
EXPORTING
is_layout = gs_layout
CHANGING
it_outtab = gt_data[]
it_fieldcatalog = gt_fieldcat[].
ENDMODULE.
Key-Value
上面设计的下拉框中没有Key的概念,只有Value,其实是可以做成像以前HTML中下拉框那样有Key也有Value
DATA: gt_fieldcat TYPE lvc_t_fcat WITH HEADER LINE.
DATA: gs_layout TYPE lvc_s_layo.
DATA: grid_r TYPE REF TO cl_gui_alv_grid ,
container_r TYPE REF TO cl_gui_docking_container.
DATA:BEGIN OF gt_data OCCURS 0,
val1(40),
val2(40),
drop_down_handle TYPE int4,
END OF gt_data.
START-OF-SELECTION.
PERFORM inital.
DEFINE fill_fdcat.
clear gt_fieldcat.
gt_fieldcat-fieldname = &1.
gt_fieldcat-scrtext_l = &2.
if &1 = 'VAL1'.
gt_fieldcat-drdn_field = 'DROP_DOWN_HANDLE' .
"下拉框有Key,有也Value,如果不设置,则下拉框只有值,没有Key(即
"与以往HTML中的下拉框不一样)
gt_fieldcat-drdn_alias = 'X'.
endif.
append gt_fieldcat.
END-OF-DEFINITION.
fill_fdcat 'VAL1' '下拉框列'.
fill_fdcat 'VAL2' '列2'.
CALL SCREEN 100.
FORM inital .
gt_data-val1 = '值1'.
gt_data-drop_down_handle = 1.
APPEND gt_data.
gt_data-val1 = '值2'.
gt_data-drop_down_handle = 2.
APPEND gt_data.
ENDFORM.
MODULE 100_pbo OUTPUT.
CREATE OBJECT container_r
EXPORTING
repid = sy-repid
dynnr = sy-dynnr
extension = 300.
CREATE OBJECT grid_r
EXPORTING
i_parent = container_r.
DATA lt_ddval TYPE lvc_t_dral.
DATA ls_ddval TYPE lvc_s_dral.
ls_ddval-handle = '1' .
ls_ddval-int_value = 'Key1' ."key
ls_ddval-value = '值1' ."value
APPEND ls_ddval TO lt_ddval .
ls_ddval-handle = '1' .
ls_ddval-int_value = 'Key2' .
ls_ddval-value = '值2' .
APPEND ls_ddval TO lt_ddval .
ls_ddval-handle = '2' ..
ls_ddval-int_value = 'Key2' .
ls_ddval-value = '值2' .
APPEND ls_ddval TO lt_ddval .
ls_ddval-handle = '2' .
ls_ddval-int_value = 'Key3' .
ls_ddval-value = '值3' .
APPEND ls_ddval TO lt_ddval .
CALL METHOD grid_r->set_drop_down_table
EXPORTING
it_drop_down_alias = lt_ddval.
CALL METHOD grid_r->set_table_for_first_display
EXPORTING
is_layout = gs_layout
CHANGING
it_outtab = gt_data[]
it_fieldcatalog = gt_fieldcat[].
ENDMODULE.
设置单元格的风格
单元格最终展现形式的style 可以在CL_GUI_ALV_GRID 的属性中可以查到,分MC_STYLE4_LINK、MC_STYLE4_LINK_NO、MC_STYLE_BUTTON、MC_STYLE_DISABLED....,包含单元格级别的可编辑/不可编辑,是否有F4,是否有链接,把单元格设置为按钮,单元格级别的热点......
单元格显示为PushButton
要想实现这个功能,我们需要在数据输出内表中要多增加一个字段,并参考表类型"LVC_T_STYL":
DATA: BEGIN OF gt_data OCCURS 0.
INCLUDE STRUCTURE sflight.
DATA cellstyles TYPE lvc_t_styl.
DATA END OF gt_data.
把需要设置为按钮的字段填进内表字段中,如这里把第7 行的字段SEATSMAX 设置为按钮:
DATA ls_style TYPE lvc_s_styl.
READ TABLE gt_data INDEX 7.
"需要对第7行的SEATSMAX列单元格样式进行设置
ls_style-fieldname = 'SEATSMAX'.
ls_style-style = cl_gui_alv_grid=>mc_style_button."显示成按钮形式
APPEND ls_style TO gt_data-cellstyles.
MODIFY gt_data INDEX 7.
最后在布局中指定对应的STYLE 输出内表字段:
gs_layout-stylefname = 'CELLSTYLES'.
单元格中展示的按钮点击事件和按钮事件BUTTON_CLICK类似,也是需要2 个参数来确定位置.
设置单元格级别的可编辑
单元格级别的可编辑和不可编辑是个非常有用的功能,在SAP 标准的一些事务中,经常可以看到这些方面的应用。通常用到的比较多的地方,是需要数据验证的,比如输入类型A,后面的某个字段才可以编辑,如果输入了类型B,后面的这个字段就不可编辑
想让一列(整列)可以编辑,我们可以在字段目录中设置EDIT 为"X"。在可编辑的情况下,ALV 工具栏中会自动多出来几个编辑按钮:删除、新增、插入、复制,如果你不需要它们,可以使用前面介绍的方法去掉它们
单元格级别的可编辑和不可编辑,实现起来和上面PushButton类似的,也是内表字段,参考表类型"LVC_T_STYL",不过填入的style 应该为CL_GUI_ALV_GRID=>MC_STYLE_ENABLED(可编辑)和CL_GUI_ALV_GRID=>MC_STYLE_DISABLED(不可编辑)样式:
FORM adjust_edittables USING pt_data LIKE gt_data[].
DATA ls_datarow LIKE LINE OF pt_data.
DATA ls_stylerow TYPE lvc_s_styl.
DATA lt_styletab TYPE lvc_t_styl.
LOOP AT pt_data INTO ls_datarow."pt_data为传进来的数据输出内表
IF ls_datarow-carrid = 'XY'.
ls_stylerow-fieldname = 'SEATSMAX'."需对哪列进行样式设置
ls_stylerow-style = cl_alv_grid=>mc_style_disabled."样式设置
APPEND ls_stylerow TO lt_styletab.
ENDIF.
IF ls_datarow-connid = '02'.
ls_stylerow-fieldname = 'PLANETYPE'.
ls_stylerow-style = cl_alv_grid=>mc_style_enabled.
APPEND ls_stylerow TO lt_styletab.
ENDIF.
INSERT LINES OF lt_styletab INTO ls_datarow-cellstyles.
MODIFY pt_data FROM ls_datarow.
ENDLOOP.
ENDFORM.
当然也是一样,需要告诉ALV 哪个字段是控制STYLE 的内表字段:
gs_layout-stylefname = 'CELLSTYLES'.
一般情况下,单元格的设置会覆盖整列的设置。如果想在程序里动态切换各种样式,只需要修改内表里关于STYLE 字段的值然后刷新即可
另外,使用CL_GUI_ALV_GRID的方法set_ready_for_input传入参数i_ready_for_input = 1 可以是ALV 进入编辑状态,使用这个方法可以使ALV 在编辑和不可编辑模式之间切换。显然如果把参数i_ready_for_input 设置为0 就进入不可编辑状态。
当然还可以设置搜索帮助啊,等等,这里就不一一赘述了: