05模块化编程,A3-使用功能模块,输出雇员信息表

图5-A3 使用功能模块输出雇员信息表

需求分析:

1、具体需求

本《使用功能模块输出雇员信息表》有如下需求:

  1. 从雇员表中获得雇员信息并按图示输出;
  2. 根据出生日期和入职日期计算雇员的年龄和工龄,并在列表中输出。
    其中列表输出效果如图5-4。


    图5- 4 列表输出效果
2、开发分析

要达成本实践目标,分析有如下:

  1. 大部分信息包括雇员ID、姓名、职务等可直接从数据库表中获得及输出,可有多种方式进行处理;
  2. 年龄和工龄分别是根据出生年月和雇佣日期,以及当前日期进行计算的,而且在此需求中年龄和工龄的计算逻辑假设为一样,都是根据当前年和出生年(雇佣年)的差值算出年龄(工龄),然后再将当前月与出生月(雇佣月)进行比较,如果当前月>出生月(雇佣月),则将根据年算出的年龄(工龄)基础上-1;
  3. 年龄和工龄可以分开编写代码,而考虑代码的复用性,在此需求中使用功能模块予以实现;同时在功能模块中对输入的日期进行判断,如果大于当前日期,则抛出异常。

实践步骤:

本实践可以在ABAP工作台(SE80)中完成,也可以分别使用函数构建器(SE37)和程序编辑器(SE38)完成;编写的代码将有如下几部分组成,按开发人员风格不同,其组成部分并非强制一致。

No 部分 说明 TCode
1 功能模块建立 通过函数构建器,建立函数组和功能模块,以根据输入日期计算年龄(工龄)。 SE37
2 程序声明 声明本程序执行后是否包含标准标题,数据输出宽度和每页的行数量为多少,另需考虑页脚输出 SE38
3 对象定义 通过定义要使用的结构、内表和变量等,以在程序执行过程中计算和存储临时值 -
4 页眉输出 通过代码设置输出页眉 -
5 获取输出数据 从表中获得要输出的数据数据并存储到内表中;
然后遍历内表后调用功能模块计算出年龄和工龄后,输出雇员数据
-
1、功能模块建立

执行TCode:SE37后,将显示初始界面如图,在此界面中可以对函数组(Function Group)和功能模块(Function Module)进行维护。

图5- 5 函数构建器初始界面
1)创建函数组

建立功能模块时必须指定函数组,由此对实现对功能模块的分类,以方便管理和维护。

在如上初始界面中,点击“转到-->函数组-->创建组”,将弹出“创建功能组”的界面如图所示,在界面中输入名称和文本后点击对勾保存,由此完成了函数组的建立。

图5- 6 创建功能组界面
2)创建功能模块

在初始界面输入功能模块名称后,点击创建,将显示如图所示的“创建功能模块”的界面,在此指定函数组和文本后点击保存,则将进入功能模块具体属性定义的界面。


图5- 7 创建功能模块界面

在“属性”页签,保持默认设置不修改,如图。

图5- 8 功能模块属性

在“导入”(IMPORT)页签,定义参数名称及相应类型文本,如图,在调用功能模块时会将对应变量的值传入到功能模块的此参数中,以在功能模块的代码中进行处理。

图5- 9 功能模块导入参数

在“导出”(EXPORT)页签,定义参数名称及相应类型文本,如图,在调用此功能模块时将通过此参数输出结果。

图5- 10 功能模块导出参数

不设置“正在更改” “表”页签,在“例外”(EXCEPTIONS)中定义程序执行时抛出的异常,如图所示。

图5- 11 功能模块例外

切换到“源代码”页签后,输入代码如下,实现根据输入日期进行年龄的计算和输出。

FUNCTION zu05_get_age.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     REFERENCE(IDATE) TYPE  DATS
*"  EXPORTING
*"     REFERENCE(OAGE) TYPE  I
*"  EXCEPTIONS
*"      DATE_NOT_VALID
*"      DATE_GT_CURRENT
*"----------------------------------------------------------------------
  CALL FUNCTION 'DATE_CHECK_PLAUSIBILITY'
    EXPORTING
      date                      = idate  "根据输入的idate调用功能模块进行检查
    EXCEPTIONS
      plausibility_check_failed = 1
      OTHERS                    = 2.
  IF sy-subrc NE 0.                     "如果返回非0,则日期不合法
    MESSAGE idate && '是无效日期' TYPE 'W'
                       RAISING date_not_valid.
  ENDIF.

  IF idate GT sy-datum.                 "如果输入日期大于当前日期,则日期不对
    MESSAGE idate && '大于当前日期,请检查数据是否正确' TYPE 'W'
                       RAISING date_gt_current.
  ENDIF.

  oage = sy-datum+0(4) - idate+0(4).    "根据当前年与输入年的差额得到年龄
  IF sy-datum+4(2) < idate+4(2).        "如果当前月小于输入月,得到的年龄需-1
    oage = oage - 1.
  ENDIF.
ENDFUNCTION.

在此功能模块中,调用了另一个功能模块“DATE_CHECK_PLAUSIBILITY”,以对执行此功能模块时传入的IDATE值是否有效,如果无效(返回的SY-SUBRC不为0)则输出警告信息同时抛出“例外”中指定的异常DATE_NOT_VALID;按常规逻辑,出生日期和雇佣日期肯定不能大于当前日期,因此随后判断IDATE值是否大于当前日期,如大于也抛出DATE_GT_CURRENT。

完成如上各项工作后,点击检查,没问题后则进行激活,由此完成了一个功能模块的创建。

3)功能模块的测试

点击界面上的测试按钮,可对功能模块进行测试,以确定功能模块是否按逻辑执行。


2、程序声明

程序声明部分的代码如下:

REPORT zu0503_emp_get_age_function NO STANDARD PAGE HEADING
      LINE-COUNT 50 LINE-SIZE 100.

通过如上代码定义,程序输出时,页面宽度为100(能容纳100个数字或英文字符),每页容纳50行。

3、对象定义

对象定义部分的代码如下:

*****对象定义
TYPES: BEGIN OF emp_mode,                                " EMP_MODE-结构体类型
         employeeid   TYPE ztemployee-employeeid,
         employeename TYPE ztemployee-employeename,
         post         TYPE ztemployee-post,
         sex          TYPE ztemployee-sex,
         hiredate     TYPE ztemployee-hiredate,
         birthdate    TYPE ztemployee-birthdate,
       END OF emp_mode.

DATA: emp_stru TYPE emp_mode,                           "通过类型定义结构体
      emp_itab TYPE SORTED TABLE OF emp_mode
               WITH UNIQUE KEY employeeid.              "通过类型定义内表

DATA: eage TYPE i,                                      "雇员年龄
      hage TYPE i.                                      "雇员工龄

如上代码,定义了一个类型EMP_MODE,并以此类型定义了一个结构EMP_STRU和一个排序内表EMP_ITAB以获得和处理数据,同时定义了2个变量分别用以存储年龄和工龄值。

4、输出页眉

输出页眉部分的代码如下:

*&----------------------------------------------------------------------*
*& 输出页眉
*&----------------------------------------------------------------------*
TOP-OF-PAGE.
  WRITE:/5(8) '员工编号', (8) '员工姓名', (15) '职位', (4) '性别',
           (8) '出生日期', (4) '年龄', (8) '入职日期', (4) '工龄',
        /5(65) sy-uline.
5、获得和输出数据

获得和输出数据部分的代码如下:

*&----------------------------------------------------------------------*
*& START-OF-SELECTION
*&----------------------------------------------------------------------*
START-OF-SELECTION.
*****获取员工信息
  SELECT employeeid employeename post sex hiredate birthdate
        INTO TABLE emp_itab
        FROM ztemployee.
*****输出员工信息
  LOOP AT emp_itab INTO emp_stru.
    CALL FUNCTION 'ZU05_GET_AGE'                   "根据出生日期调用函数返回年龄给EAGE
      EXPORTING
        idate           = emp_stru-birthdate
      IMPORTING
        oage            = eage
      EXCEPTIONS
        date_not_valid  = 1
        date_gt_current = 2.
    CALL FUNCTION 'ZU05_GET_AGE'                  "根据入职日期调用函数返回年龄给hage
      EXPORTING
        idate           = emp_stru-hiredate
      IMPORTING
        oage            = hage
      EXCEPTIONS
        date_not_valid  = 1
        date_gt_current = 2.

    WRITE:/5(8) emp_stru-employeeid, (8) emp_stru-employeename, (15) emp_stru-post,
            (4) emp_stru-sex,
            (8) emp_stru-birthdate, (4) eage, (8) emp_stru-hiredate, (4) hage.
  ENDLOOP.

如上代码,首先从ztemployee表中获得数据后存入到内表emp_itab;随后通过LOOP AT遍历内表数据并存储到结构emp_stru,接下来,分别根据结构中存储的出生日期(emp_stru-birthdate)和入职日期(emp_stru-hiredate),通过CALL FUNCTION调用功能模块,计算出年龄和工龄;同时在调用功能模块后如果遇到异常,则将异常结果赋值给SY-SUBRC(如按代码,在日期无效时为1,大于当前日期时则为2),然后可根据异常情况进行相应处理(如对输出的年龄跟工龄处的输出进行相应提示,或在状态栏输出消息,如上代码中没实现);最后根据需求输出数据。

将如上2~5部分的代码顺序合并后,则得到本需求的实现代码。

本实践小结:功能函数

功能模块(FUNCTION MODULE)也是代码复用的一种技术,且相对于宏(Macro)、子程序(Subroute)等,是独立的ABAP对象,应用更为广泛,在定义后,不仅可以在不同程序中调用,还可以通过RFC(Remote Function Call)技术,实现在在不同的SAP之间、非SAP系统与SAP之间的调用。

1、功能组(函数组Function Group)

建立任一功能模块都需要指定其对应的功能组,功能组是功能模块的容器。也可以把功能组理解为一种ABAP程序,在创建一个功能组后,系统将生成一个名称为SAPL<fgrp>的主程序,并包括有如下包含(Include)程序:

2、功能模块的属性和参数

功能模块的属性设置主要有类型的选择:

功能模块的参数:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容