Smartform的简单应用

来源:互联网 发布:标签数据库设计 编辑:程序博客网 时间:2024/05/02 00:22
导读:
  以下例子引用自baoning的BLOG
  用到DDIC 表SFLIGHT
  
  
  Smart Form 相对SAP Script来说,系统给封装了很多功能,这样用户在Form中的代码写的少了一些,更容易维护,如果把SAP Script比作汇编语言的话,Smart Form可以算上C++了,不过个人感觉对于复杂表单的设计来说,用SAP Script更容易实现。在Smart Form中调整表格边线比较费劲。
  1. Create a Form named 'ZBSUNTEST'
  用TCode: SMARTFORMS创建一个空白的Form。双击左边树状结构中的'Global Setting'->'Form Attributes'。在
  
  里头可以看到纸张的设置,默认是A4。这里还可以调正一页中可以打印多少行。
  2. Form Interface
  我们生成一个Form的同时,系统也创建了一个相应的function module。Form与Application的数据交换就是通过function的interface来实现的。双击左边树状结构中的'Global Setting'->'Form Interface',我们可以看到
  
  ,这和我们在SE37中看到的function module的接口是一样的。点击'Table'这个tab,输入如下:
  
  
  3. Global Definition这里定义的是在form中共用的全局变量,还可以定义subroutine。
  
  是form初始化的时候调用的一个routine,可以在这里做一些data初始化的工作。
  
  用来设置货币或者数量的单位关联用的。
  下面是'Global Data'里头的定义:
  
  
  上图中的T_SUM类型是我在'Types'里头定义的,其中PRICE, CURRENCY是用来做sum用的:
  TYPES:
  BEGIN OF T_SUM,
  PRICE TYPE S_PRICE,
  CURRENCY TYPE S_CURRCODE,
  END OF T_SUM.
  下面是Currecy &Quantity的单位关联设置。这样关联之后Price会按照Currency的不同,输出格式也不同:
  
  
  4. Create a Style named 'Z_BSUN_TITEL01'
  回过头我们要创建一个给这个Form使用的Style。还是用SMARTFORMS这个TCode来创建。在这个Styel里头我只创建了'Paragrah Format',真正的项目中'Character Format'肯定也是不可缺少的。这个Style使用在Step 1 中创建的Form所有的Output Option中。
  M1: Aligned:left;Indent->left margin:0.20 CM;font family: Arial;font size: 12pt
  M2: Aligned:right;Indent->right margin:0.20 CM;font family: Arial;font size: 11pt
  M3: Aligned:right;Indent->right margin:0.20 CM;font family: Arial;font size: 12pt;font color:blue
  T1: Aligned:center;font family: Arial;font size: 14pt;font style: Bold Italic
  5.Creat a Page named 'FIRSTPG'
  在
  
  下创建一个名为'FIRSTPG'的page,并把它的next page设置为其本身。Page Format设置为'Portrait Format'。
  6.Create Windows under 'FIRSTPG'
  
  
  Windows的Position and Size如下(单位都是CM):
  HEADER: L2.60, U0.20, W14.70, H2.00
  MAIN: L2.00, U2.00, W16.00, H25.00
  FOOTER: L2.60, U27.20, W14.70, H2.00
  7. Create Header's Text
  在'HEADER' Window node下面创建一个Text,取名'TITLE'。Text type设置成'Text Element'。再PC Editor中点
  
  输入
  
  。T1就是在Step 3里头定义的Paragraph Format。
  8. Create a table in 'MAIN' Window在'MAIN' Window node下面创建一个Table,
  
  . Table下面自带了三个node: header, main area, footer,颜色跟别的由用户创建的node有区别。其中Table的header node下面我们可以放表头。Table的footer node跟我们在Step 6创建的FOOTER Window有区别。FOOTER Window的位置是固定的,Table的footer是Table的line在哪里结束,它就紧跟在后面。 文章开头的打印结果中我们可以很直观的看到这两个的区别:FOOTER Window在每页的最下面(打印了两次,尽管内容不一样),Table footer在第二页中间只打印了一次。当然我们说的都是默认的情况。
  9. Insert program line 'CODE_CLEAR' before 'MAIN' Window
  
  
  Input Parameters: G_TAB_DATA;
  Output Parameters: G_REC_TOTAL, G_TAB_TOTAL, G_ITEMS_ONPAGE;
  REFRESH: G_TAB_TOTAL, G_TAB_SUBTOTAL.
  CLEAR: G_REC_TOTAL, G_REC_SUBTOTAL, G_ITEMS, G_ITEMS_ONPAGE.
  DESCRIBE TABLE G_TAB_DATA LINES G_ITEMS. "Get total item number
  Programe Line中使用到的全局变量必须在Input/Output中定义,否则check不通过。
  10. Create some line types in Table 'FLIGHTINFO'Line Type是控制表格格式的,每一个Table Line都要指定一个Line Type
  
  
  Layout如下图,注意这些Line的border是框了线的
  
  
  11. 'DATA' of Table 'FLIGHTINFO'
  
  
  G_TAB_DATA是Step 2在Form Interface定义的一个内部表,也就是从Application传过来准备给Form显示的数据。我们还想让显示的数据排一下序,当然这可以在外部程序中SORT,不过这里的排序还有触发event的作用,后面会讲到。如果内部表已经排好序了,只是想触发类似LOOP的AT NEW/AT END OF这样的功能,那么把
  
  这个勾上就好。下面是SORT的设置,我们对CARRID(Airline),CONNID(Flight No.)排序,并且要触发两个events,用来做subtotal统计。
  
  
  12. 'Calculation' of Table 'FLIGHTINFO'
  
  
  是用来对Table的Fields做简单计算的,包括'Number', 'Total', 'Mean Value'。如果不是涉及到货币或者数量的统计我们可以用'Total'这个Operation,具体使用可以参考help。我这里用了'Number'做一个每页的Items统计,'Number'也可以用来做行号。
  
  
  13. Insert a title in table header
  在Table 'FLIGHTINFO'的header node下增加table line :HEADER_LINE。LINE TYPE选'Line1'。tablbe line自动带出5个cell,cell的数目是根据LINE TYPE :'Line1'来的,Step 10里头可以看到Line1是有5个cell的。我们在每一个cell下面添加一个Text,作为colum title,把paragraph format设置成M1。不过'Price'这个Column因为是数字,paragraph format设置成M3
  
  
  P.S.Table自带的header的Output Option->Print Time有两个选项
  
  
  at start of Table就不说了,不过at Page Break工作不正常,第2页并没有打印出来title,也不知道是不是我写的问题。
  14. Insert table line into table main area
  Main Area是显示Application传进来的内部表的地方,和Step 13一样增加一个Line Type=LINE1的Table Line,每个Cell下各增加一个Text,属性设置成'Text Element'。
  
  
  点PC Editor的
  
  ,编辑Text内容,以CARRID为例:
  
  
  15. Insert a Program Line Under 'DATA_LINES'
  CURRENCY_DATA下的Programe Line: SUM,是为了做合计用的,按照Currecy的不同将Price合计。(当然单价Price的合计没什么实际意义,权当是演示)
  Input Parameters: G_REC_DATA, G_TAB_SUBTOTAL;
  Output Parameters: G_REC_TOTAL, G_TAB_TOTAL;
  G_REC_TOTAL-PRICE = G_REC_DATA-PRICE.
  G_REC_TOTAL-CURRENCY = G_REC_DATA-CURRENCY.
  COLLECT G_REC_TOTAL INTO G_TAB_TOTAL.
  COLLECT G_REC_TOTAL INTO G_TAB_SUBTOTAL.
  CLEAR: G_REC_TOTAL.
  内部表'G_TAB_TOTAL','G_TAB_SUBTOTAL'保存的是合计和根据'Airline'进行小计的数据。
  16. Print 'Grand Total' in table footer
  在table的footer node下增加一个loop node,
  
  。
  Loop的DATA如下:
  
  
  因为我只想在所有的记录打印结束之后显示总计,所以给这个loop增加一个condition。在Condition Tab里的Output Condition中增加一行:
  
  
  G_ITEMS_ONPAGE在Step 12中被赋值Number, G_ITEM在Step 9被赋值内部表中的记录数,当这两个值相等的时候也就是记录输出完毕的时候。再给loop node下一级增加一行table line,LINE TYPE : LINE3
  
  
  GRANDTOTAL: M2 -> 'Grand total:'
  PRICESUM_TAB: M2 -> &G_REC_TOTAL-PRICE&
  CURR_TAB: M2->&G_REC_TOTAL-CURRENCY&
  17. Print subtotal in table (1)
  我们在Step 10里头的Sort中勾选了CARRID字段的两个事件之后就能够发现table node 自动增加了两个节点:
  
  
  首先在'CARRID Event on Sort Begin'下一级增加一个Program Line:SUB_CLEAR,用来在CARRID改变的时候清空subtotal内部表。
  Output Parameters: G_REC_SUBTOTAL;
  CLEAR: G_REC_SUBTOTAL.
  REFRESH: G_TAB_SUBTOTAL.
  然后在'CARRID Event on Sort End'下一级增加一个Program Line:CLEAR_SUBTITLE,用来清空一个打印标志。
  Output Parameters: G_FLG_SUBTITLE;
  CLEAR: G_FLG_SUBTITLE.
  每一个CARRID(Airline)下面可能会有多种不同的货币价格,这个标志的作用是为了限制下面的'Subtotal of &G_REC_SUBTOTAL-CARRID& is'这句话在小计的时候不至于print出来很多遍。
  18. Print subtotal in table (2)
  在'CARRID Event on Sort End'下一级增加一个Loop:PRINTSUBTOTAL:
  
  
  Loop:PRINTSUBTOTAL:下一级增加一个table line:SUBTOTAL,LINE TYPE : LINE3
  
  
  AIRLINE_NAME: M2 -> 'Subtotal of&G_REC_DATA-CARRID& is'
  SUB_PRICE: M2 -> &G_REC_SUBTOTAL-PRICE&
  SUB_CURR: M2->&G_REC_SUBTOTAL-CURRENCY&
  其中AIRLINE_NAME是有显示条件的:G_FLG_SUBTITLE没有赋值的时候才显示。
  
  
  AIRLINE_NAME print出来之后我们在Program Line 'SET_SUBTITLE'中将G_FLG_SUBTITLE设置为'X'。
  Output Parameters: G_FLG_SUBTITLE;
  G_FLG_SUBTITLE = 'X'.
  19. Print 'Grand Total' in page footer在FOOTER Window的下一级添加一个Table Line: FTTABLE, Line Type:
  
  
  DATA:
  
  
  然后,在FTTABLE的Main Area下增加一行Table Line: PRICESUM, Line Type: LINE1
  
  
  为了控制在最后一页的页脚打印出来金额合计,要给PRICESUM增加一个条件。在Conditions Tab里头的
  And Additional Event中勾选'Only after end of main window'。'SUM'和'CURR'这两个Text的设置如下:
  SUM: M2 -> &G_REC_TOTAL-PRICE&
  CURR: M2->&G_REC_TOTAL-CURRENCY&
  最后,在FTTABLE的Footer下增加一行Table Line: FOOTER, Line Type: LINE1
  
  
  ITEMS: M2 -> ITEMS IN THIS PAGE:&G_ITEMS_ONPAGE(3)&
  PAGE: M2->PAGE:&SFSY-PAGE&
  20. Calling a Smart Form from Application生成smart form的同时系统会自动创建一个对应的funtion module,这个function的名字可以通过菜单Enviroment->Function Module Name得到。在程序中一般通过function 'SSF_FUNCTION_MODULE_NAME'来得到。下面是我们的测试这个smart form的代码:
  *&---------------------------------------------------------------------*
  *& Report Z_SUN_SFORM
  *&
  *&---------------------------------------------------------------------*
  REPORT Z_SUN_SFORM NO STANDARD PAGE HEADING LINE-SIZE 150 MESSAGE-ID ZBSUN.
  ************************************************************************
  * D E C L A R A T I O N O F I N T E R N A L T A B L E S
  ************************************************************************
  DATA:
  G_TAB_OUTPUT TYPE STANDARD TABLE OF SFLIGHT.
  ************************************************************************
  * D E C L A R A T I O N O F V A R I A B L E S
  ************************************************************************
  DATA:
  G_REC_OUTPUT TYPE SFLIGHT,
  G_REC_OPTIONS LIKE ITCPO,
  G_REC_RESULT TYPE ITCPP.
  ************************************************************************
  * D E C L A R A T I O N O F C O N S T A N T S
  ************************************************************************
  CONSTANTS:
  G_CON_FLG_ON TYPE C VALUE 'X',
  G_CON_FORMNAME(8) TYPE C VALUE 'ZBSUN_01'.
  ************************************************************************
  * S E L E C T I O N S C R E E N
  ************************************************************************
  SELECTION-SCREEN BEGIN OF BLOCK BLOCK1 WITH FRAME.
  SELECT-OPTIONS S_LINE FOR G_REC_OUTPUT-CARRID NO INTERVALS.
  SELECT-OPTIONS S_DATE FOR G_REC_OUTPUT-FLDATE.
  SELECTION-SCREEN END OF BLOCK BLOCK1.
  ************************************************************************
  * S T A R T - O F - S E L E C T I O N
  ************************************************************************
  START-OF-SELECTION.
  PERFORM FRM_GET_DATA.
  ************************************************************************
  * E N D - O F - S E L E C T I O N
  ************************************************************************
  END-OF-SELECTION.
  PERFORM FRM_OUTPUT.
  *&---------------------------------------------------------------------*
  *& Form FRM_GET_DATA
  *&---------------------------------------------------------------------*
  * GET FLIGHT DATA
  *----------------------------------------------------------------------*
  FORM FRM_GET_DATA .
  SELECT *
  INTO TABLE G_TAB_OUTPUT
  FROM SFLIGHT
  WHERE CARRID IN S_LINE
  AND FLDATE IN S_DATE.
  IF SY-SUBRC <>0.
  MESSAGE E000.
  * No data selected.
  ENDIF.
  ENDFORM. "FRM_GET_DATA
  *&---------------------------------------------------------------------*
  *& Form FRM_OUTPUT
  *&---------------------------------------------------------------------*
  * OUTPUT DATA
  *----------------------------------------------------------------------*
  FORM FRM_OUTPUT.
  DATA: FM_NAME TYPE RS38L_FNAM.
  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
  EXPORTING
  FORMNAME = 'ZBSUNTEST'
  * VARIANT = ' '
  * DIRECT_CALL = ' '
  IMPORTING
  FM_NAME = FM_NAME
  * EXCEPTIONS
  * NO_FORM = 1
  * NO_FUNCTION_MODULE = 2
  * OTHERS = 3
  .
  IF SY-SUBRC <>0.
  * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
  * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
  CALL FUNCTION fm_name
  * EXPORTING
  * ARCHIVE_INDEX =
  * ARCHIVE_PARAMETERS =
  * CONTROL_PARAMETERS =
  * MAIL_APPL_OBJ =
  * MAIL_RECIPIENT =
  * MAIL_SENDER =
  * OUTPUT_OPTIONS =
  * USER_SETTINGS = 'X'
  * IMPORTING
  * DOCUMENT_OUTPUT_INFO =
  * JOB_OUTPUT_INFO =
  * JOB_OUTPUT_OPTIONS =
  TABLES
  G_TAB_DATA = G_TAB_OUTPUT
  EXCEPTIONS
  FORMATTING_ERROR = 1
  INTERNAL_ERROR = 2
  SEND_ERROR = 3
  USER_CANCELED = 4
  OTHERS = 5.
  IF SY-SUBRC <>0.
  *
  ENDIF.
  ENDFORM. "FRM_OUTPUT
  以下步骤没有用到的node还有Command, lternative,Graphic,Complex Section等。其中Command主要用来插入分页或者打印控制语句的;Alternative用来插入一个逻辑分支;Graphic插入图片的;Complex Section复合操作时用到

本文转自
http://vkbpl6012.itpub.net/post/28126/293446
原创粉丝点击