Preface
之前差不多已经介绍过了SAP中的一些报表通过ALV来展示数据的方法,这一次我打算再介绍下用Adobe(PDF) Form来展示报表数据的方法。一般用这种形式的展示多半就是为了把结果打印出来,作为纸质记录或者上报用的,所以它对格式的要求就有比较严格的特定性,比如需要上报政府机构的一些税务报表啊,财务报表啊之类的。因此通过Adobe Form展示的报表数据就会有一个比较特有的格式,传统的ALV展示也就没法很好的来满足这样的需求了。
Introduction to Adobe Form
首先,要在SAP系统里展示Adobe Form需要在系统在一个比较新的版本(ECC6.0以上),而且要开发自定Adobe Form的话还得额外在系统前端安装一个Adobe Life Cycle Designer的工具。这样就可以在系统里画一些自定义的Form格式或者查看一些系统标准Form的具体格式内容了。总之,有了上述版本的系统跟这个工具,我们就可以开发一个自己想要用Adobe Form展示的报表了。
Step to Create and Call the Adobe Form
- 通过SE11创建一个新的表格式。既然要自定一个报表格式,那么它的内容基本也是通过一个自定表来展示的(除非系统里的某个标准的表格式已经能满足内容需求了),所以创建一个新的表格式是这整个步骤的开端了。而这个表的line type可以指向一个系统标准的structure也可以指向一个自定的structure,这就好比在ALV里创建那些field category的步骤了。所以在拿到了报表开发的需求之后,对应的报表内容确定就是在这一步完成了。需要说明一下,这里的报表内容是指表里的内容,而不是那些抬头名称,日期年月,署名之类的表之外的内容。
- 通过SFP创建一个Adobe Form的Interface。这里的Interface的概念其实比较好解释,它就是相当于一个后台数据的接口,可以为前台各种Adobe Form提供对应的数据。也就是说,不同格式的Adobe Form可以调用相同的Interface,其结果就是同样的数据可以在不同的layout中被展示。这样的设计框架,可以减少很多重复性的数据绑定的动作,毕竟Form的Layout是多种多样的,但数据源可能就会单一许多。因此,在Interface里面,就需要提供一些对应的输入参数来作为将来Form前台展示的接口。举个我实际开发中的一个例子吧,这个例子是创建一个银行转账信息的Form,输入的参数有: 付款人名称以及账号,币种,总计与收款人名称。具体Interface的输入参数可见下图:
- 第一个是系统的默认参数不需要去更改,后面2-5个参数就是Form中需要展示的4个总体信息数据。最后那个就是第一步里确定的报表内容信息,它所关联到的就是之前创建的那个表结构。至于其他的设置我还不是很熟悉,需要以后再去多研究下吧。
- 通过SFP创建新的Form。这里的Form就最终要打印出来的报表的Form了,其中我们也可以把这一步再细分一下:
- 那么首先要给它提供一个数据源的Interface,也就上一步建立的Interface。
- 通过给定的Interface的数据源,对这个Form进行再一次的数据内容筛选(可以通过拖拽,把interface里的字段拖到Form的Content里)。这里的例子是把Interface里所有的数据都放到这个Form的content里了:
 - 选择好数据内容之后,可以进入到layout里进行具体的绘制,这里绘制的页面其实也比较值得去研究。因为它可以决定该Form的整体格式与相关的页面设置(翻页设置,页面结构,页码,页边间距等等),其实操作就跟word上差不多。自己多倒腾倒腾应该都能明白。不过其中最关键的应该还是数据绑定的内容,这里的绑定就能把报表里的数据展示到这个Form中对应的field里。对于那个核心的表的绑定其实可以在Data View里通过拖拽直接把绑定的内容放到具体的Layout里,然后在修饰一下与要求的格式想匹配,下面就是我这个例子中Form的格式截图:
 - 画好了对应的Form格式与数据绑定,下面就是Report里的通过一些具体的代码进行调用了:打开->导入->填充数据->关闭
* Sets the output parameters and opens the spool job
CALL FUNCTION 'FP_JOB_OPEN' "& Form Processing: Call Form
CHANGING
ie_outputparams = fp_outputparams
EXCEPTIONS
cancel = 1
usage_error = 2
system_error = 3
internal_error = 4
OTHERS = 5.
IF sy-subrc <> 0.
* <error handling>
ENDIF.
*&---- Get the name of the generated function module
CALL FUNCTION 'FP_FUNCTION_MODULE_NAME' "& Form Processing Generation
EXPORTING
i_name = 'ZFI_BK_PAYMENT_FRM'
IMPORTING
e_funcname = fm_name.
IF sy-subrc <> 0.
* <error handling>
ENDIF.
*-- Fetch the Data and store it in the Internal Table
LOOP AT gt_hsbc INTO ls_hsbc.
MOVE-CORRESPONDING ls_hsbc TO ls_bkpayment.
lv_index = lv_index + 1.
ls_bkpayment-reccount = lv_index.
IF ls_hsbc-ktokk = gc_lfa1_zemp. " '货款'
ls_bkpayment-paydtl1 = text-005.
ELSE.
ls_bkpayment-paydtl1 = text-006.
ENDIF.
WRITE ls_hsbc-rbetr TO lv_sigamt_cur CURRENCY gc_currency_cny.
ls_bkpayment-bkamt = lv_sigamt_cur.
APPEND ls_bkpayment TO lt_bkpayment.
lv_totamt = lv_totamt + ls_hsbc-rbetr.
lv_payer_account = ls_hsbc-ubknt.
lv_currency = ls_hsbc-waers.
ENDLOOP.
* Language and country setting (Chinese)
fp_docparams-langu = 'D'.
fp_docparams-country = 'CN'.
WRITE lv_totamt TO lv_totamt_cur CURRENCY gc_currency_cny.
*&--- Call the generated function module
CALL FUNCTION fm_name
EXPORTING
/1bcdwb/docparams = fp_docparams
im_payee_info = lt_bkpayment
im_totamt = lv_totamt_cur
im_currency = lv_currency
im_payer_account = lv_payer_account
im_payer_name = gv_compname
* IMPORTING
* /1BCDWB/FORMOUTPUT =
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3.
IF sy-subrc <> 0.
* <error handling>
ENDIF.
*&---- Close the spool job
CALL FUNCTION 'FP_JOB_CLOSE'
* IMPORTING
* E_RESULT =
EXCEPTIONS
usage_error = 1
system_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* <error handling>
ENDIF.
- 最后就是运行测试了,这个例子的打印预览如下:

Summary
总之,自己开发下来的感觉就是整体思路比较简单,但在Form的绘制与数据绑定的时候会比较繁琐。碰上那些很精细很复杂的表格需要绘制的时候需要花很大的精力。不过对于Adobe Form这种形式的报表输出而言,已经比原先的Smart Form跟SAP Script在表格绘制上方便了许多,这也是为什么在新版本上开始越来越流行用Adobe Form来作为需要打印的表单
谢谢阅读
nw
|