ABAP:SmartForms--设计
要求:
1、不是套打,表格線也需要輸出
2、每張報表打印8行記錄,不足的空白行也需要輸出
3、按憑證號打印單據,可以連續打印多張報表。
?一、創建樣式:
在創建Form之前,需要創建多種段落和字體樣式,供Form中的文字使用。需要設置多種“段落格式”,并且必須在“表頭數據”中設定“標準段落”
1.創建段落格式,一般有RH(Report Header),PD(Page Header), PB(Page Bottom),LD(Line Header and Details),字體:CNSONG,9pt。注意最好在各段落的“首行縮”中設定1mm的縮進,否則,在Form中表格線和文字之間會沒有任何間隙。
2.設置“表頭數據”中“標準段落”
3、保存并激活樣式文件。
二、創建SmartForm
1、在“全局設置”-〉“表格屬性”-〉“輸出選項”中
設定“頁格式”:即紙張的大小
“樣式”:設定本Form使用的默認樣式文件,這里指定為第一步創建的樣式文件。
2、在“全局設置”-〉“表格接口”-〉“導入”
設置兩個參數:
ptr_header type c
ptr_items? type c
這兩個參數用來傳入我們在Report中Export內表數據的句柄(ID key)。
3、在“全局設置”-〉“全局定義”中進行多項設定
a、“類型”設定,在這里需要定義4個類型,一個用來保存表頭數據的工作區和內表,一個用來保存明細數據的工作區和內表,它們的結構必須與Report中Export到數據庫中的內表的結構完全對應一致,否則,我們將不能從傳入的句柄(ID key)中恢復內表數據。
TYPES:
BEGIN?OF?TYP_header_ROW?,
????????mblnr??????????LIKE?mseg-mblnr,????"?憑證號
????????bldat??????????LIKE?rkpf-rsdat,????"?憑證日期
????????c_so(16)???????TYPE?c,?????????????"?銷售訂單號
????????c_issdt????????LIKE?sy-datum,??????"?發貨日期
????????werks??????????LIKE?mseg-werks,????"?地點
????????PLNAT_NAME?????LIKE?t001w-name1,???"?出貨單位名稱
????????kokrs??????????LIKE?mseg-kokrs,????"?控制范圍
????????kostl??????????LIKE?mseg-kostl,????"?成本中心
????????cc_name????????LIKE?cskt-ktext,????"?成本中心名稱名稱
????????c_depart(45)???TYPE?c,?????????????"?領料部門
????????bwart??????????LIKE?mseg-bwart,????"?移動類型代碼
????????btext_mt???????LIKE?t156t-btext,???"?移動類型描述
????????c_btext_mt(60)?TYPE?c,?????????????"?移動類型次數
????????C_TOTAL(17)????TYPE?C,?????????????"合計輸出時由用戶手工填寫
END?OF?TYP_header_ROW?.
TYPES:?TYP_HEADER_TABLE?TYPE?TYP_HEADER_ROW?OCCURS?0.
*?領料單明細信息
TYPES:
BEGIN?OF?TYP_ITEMS_ROW?,
????????mblnr???????LIKE?mseg-mblnr,??????"?物料憑證編號?:?物料憑證
????????rsnum???????LIKE?rkpf-rsnum,??????"?憑證號?:?預留單
????????mjahr???????LIKE?mseg-mjahr,??????"?物料憑證年度
????????zeile???????LIKE?mseg-zeile,??????"?序號
????????bwart???????LIKE?mseg-bwart,??????"?移動類型代碼
????????werks???????LIKE?mseg-werks,??????"?地點
????????kokrs???????LIKE?mseg-kokrs,??????"?控制范圍
????????kostl???????LIKE?mseg-kostl,??????"?成本中心
????????matnr???????LIKE?mseg-matnr,??????"?物料號碼
????????maktx???????LIKE?makt-maktx,??????"?物料描述
????????erfme???????LIKE?mseg-erfme,??????"?計量單位
????????c_planc?????LIKE?resb-bdmng,??????"?計劃數量(手工填寫)
????????c_outc??????LIKE?mseg-erfmg,??????"?實發數量
????????c_count(6)??TYPE?c,???????????????"?件數(手工填寫)
????????lgort???????LIKE?mseg-lgort,??????"?倉儲地點
????????charg???????LIKE?mseg-charg,??????"?備注
END?OF?TYP_ITEMS_ROW.
TYPES:?TYP_ITEMS_TABLE?TYPE?TYP_ITEMS_ROW?OCCURS?0.
b、在“全局數據”中,定義全局的變量,我們需要定義如下幾個變量
? wa_header type typ_header_row??? "表頭數據工作區,由于SmartForms中的內表不能有HeaderLine,因此必須定義一個與內表結構一樣的工作區
??wa_items??type?typ_items_row?????"表單明細工作區
??ig_items??type?typ_items_table???"表單明細內表
??wa_blanks?type?typ_items_row?????"空白行工作區
??ig_blanks?type?typ_items_table???"空白行內表
??g_count???type?i?????????????????"記錄一張報表的明細的記錄數量
??G_CURRLINE?type?i????????????????"記錄所有報表共計打印了多少行,用于判斷最后一頁
??G_TOTALLINES?type?i??????????????"記錄內表ig_items總行數,用于判斷最后一頁
??G_CURRPAGE?type?i????????????????"一個憑證的當前頁碼
??G_TOTALPAGE?type?i???????????????"一個憑證的總頁碼
c、在“初始化”中,將數據句柄中的內表恢復到剛設定的全局變量中
輸入參數:ptr_header,ptr_items,ig_header,ig_items,g_totallines
perform?Restor_buffer?using?ptr_items??changing?ig_items.
DESCRIBE?TABLE?IG_ITEMS?LINES?G_TOTALLINES.
d、在Freecode"格式化程序"中,定義Form Restor_buffer函數
??import?t?from?database?indx(hk)?id?typeid.
endform.
至此,我們已經得到了表頭和明細這2個內表的數據,下面準備畫報表并輸出數據。
4、在“頁和窗口”中,在“%Page1”頁下,添加3個窗口
"MAIN主窗口": 在SmartForm中,只有窗口類型為“主窗口”的窗口,才能被循環。例如,在最前面的樣表中,明細數據有20條,不能在一頁中打印輸出完畢,需要輸出4頁才能打印完一張單據的數據,在這4張單據中,表頭和表尾是不變的,但是表中間部分數據卻是變化的,中間這個窗口需要被循環輸出4次。因此需要將這個窗口類型設定為“主窗口”。在本例中為現實明細數據的這部分。
“窗口1”:從表最上面到明細欄的標題欄(包括標題欄)
“窗口2”:最底下2行。
注意:窗口的寬度加上遍距不能大于紙張寬度。
創建好這三個窗口,設定好窗口的寬度,高度,以及位置信息。下圖是整個SmartForm的結構
注意,我將輸出表頭的窗口“%windows1 頁頭”放在了輸出明細數據的窗口“主窗口”的下面,這是必須的,因為表頭中的數據需要從表頭內表ig_header中來。loop1是循環內表ig_header,將數據放到表頭工作區wa_header中。因此,%windows1 頁頭窗口就可以直接使用工作區wa_header中的數據。如果該窗口放在了主窗口的前面,那么至少第一頁中表頭會沒有數據,而且后面每一頁的表頭顯示的都是下一個表頭的內容。
注:雖然打印機輸出時,現打印%WINDOWS1 頁頭,再打印MAIN主窗口,最后打印%WINDOW2頁尾窗口,但是程序執行時,卻是按照上圖中樹結構從上到下進行處理的,是先處理MAIN主窗口,其次%WINDOWS1 頁頭,最后%WINDOW2頁尾窗口的邏輯順序,可以從跟蹤SMARTFORMS程序得知。
下面詳細介紹整個邏輯流程和代碼:
1、%LOOP1表頭循環
設置:數據-〉loop循環-〉操作數:ig_header into wa_header
作用:循環表頭內表中的數據,每次打印一個憑證的行項目數據。由于內表在這里不能有工作區,因此將每個表頭數據放置到另外的工作區。
2、%LOOP4計算單個憑證總頁碼
設置:數據-〉loop循環-〉操作數:IG_ITEMS INTO WA_ITEMS
????? WHERE條件:IBLNR = WA_HEADER-IBLNR
作用:由于在打印每張憑證及行項目之前,需要知道該憑證的總頁數,因此需要首先計算IG_ITEMS內表中有多少條當前憑證的行記錄數。
3、%CODE4累計單個憑證的行項目數
輸入參數:G_COUNT
代碼:
作用:累計當前憑證的行項目數。
4、%CODE1計算當前憑證總頁碼
輸入參數:G_TOTALPAGE,G_COUNT
代碼:
*計算單個憑證的總頁碼
G_TOTALPAGE?=?G_COUNT?MOD?8.
IF?G_TOTALPAGE?=?0.
??G_TOTALPAGE?=?G_COUNT?DIV?8.
ELSE.
??G_TOTALPAGE?=?G_COUNT?DIV?8?+?1.
ENDIF.
G_COUNT?=?0.
作用:根據第三步累計的單個憑證的總行項目數,以及每頁打印的行記錄數(8),計算該憑證需要打印的總頁數。計算完畢以后,G_COUNT重新置0。
6、%LOOP2循環輸出明細
設置:數據-〉loop循環-〉操作數:IG_ITEMS INTO WA_ITEMS
????? WHERE條件:IBLNR = WA_HEADER-IBLNR
作用:這里的循環條件與第2步的條件完全一致,準備循環打印當前憑證的所有行項目。
7、%CODE2記錄行數加1
輸入參數:G_COUNT,G_CURRLINE
代碼:
G_COUNT?=?G_COUNT?+?1.
G_CURRLINE?=?G_CURRLINE?+?1.
作用:每循環一次,當前憑證打印的行記錄數加1,所有憑證打印的總行記錄數加1。
8、%TEMPLATE4數據明細
作用:模板,行記錄的表格,以及相關文本內容。LOOP2每循環一次,就打印輸出一行該模板以及文本內容。行高一般為5mm(根據實際調整),注意模板的寬度不能超過窗口的寬度。在“細節”中可以調整模板的每個單元格的寬度,以及每行的高度。
9、%TEXT22 - %TEXT30文本內容
%TEXT22??? 序號:&G_COUNT(CZT4R)&? 輸出選項-〉輸出結構:第1行第1列?
%TEXT23物料號碼:&WA_ITEMS-MATNR&? 輸出選項-〉輸出結構:第1行第2列
依此類推。
10、%CODE5計算當前頁碼
輸入參數:G_COUNT,G_CURRPAGE
代碼:
L_LINE?=?G_COUNT?MOD?8.
IF?L_LINE?=?0.
??G_CURRPAGE?=?G_COUNT?/?8.
ELSE.
??G_CURRPAGE?=?G_COUNT?DIV?8?+?1.
ENDIF.
作用:每輸出一行,計算當前行所在的頁碼,即為當前頁
11、%CODE3計算空行
輸入參數:G_COUNT,IG_BLANKS,WA_BLANKS
代碼:
*?需要的空記錄行數
IF?G_COUNT?<>?0.
??G_COUNT?=?8?-?G_COUNT.
ENDIF.
CLEAR?IG_BLANKS[].
DO?G_COUNT?TIMES.
??APPEND?wa_blanks?to?ig_blanks.
ENDDO.
G_COUNT?=?0.
作用:在當前憑證的所有有效數據行打印完畢以后,還需要計算需要打印多少空行,才能剛好打印滿一張紙。用計算的數量,填充內表IG_BLANKS,計算完畢以后,G_COUNT必須清0。
12、%LOOP3 補充打印空行
設置:數據-〉loop循環-〉操作數:IG_BLANKSS INTO WA_BLANKS
????? WHERE條件:無
作用:循環內表IG_BLANKS,次數為內表中的記錄數,即空行數,打印輸出空行。
13、%TEMPLATE5空數據明細
作用:該模板與第8步的TEMPLATE4完全一樣,只是該模板下不需要有文本TEXT,只序號輸出模板的表格線即可。
到此步驟,已經打印完畢了當前憑證的所有有效數據行和補充的空行,如果當前憑證需要打印多頁,例如有30條行記錄,需要打印3個滿頁,第4頁數出6行數據,補充2個空行,這3次分頁是系統自動分頁的,分也之前,自動處理頁頭和頁尾窗口,輸出這兩個窗口的內容。自動分頁的條件是“MAIN主窗口”的高度被打印滿了,因此一定要注意,主窗口的高度必須等于你需要的高度,不要多,也不要少,在本例中,高度為8行 x 5mm = 40mm
14、%CONDITION1分頁
設置:一般屬性-〉節點條件:G_CURRLINE <> G_TOTALLINES
作用:在一個憑證打印完畢以后,將要進入打印下一個憑證之前,需要分頁,但是在打印完最后一個憑證的最后一頁以后,卻不能有分頁,否則最后會多一個空行。
15、%COMMAND1強制分頁
設置:一般屬性-〉轉到新頁:%PAGE1
作用:在G_CURRLINE <> G_TOTALLINES 條件成立(不是最后一行)的情況下,強制分頁。
你也許會說,這里不強制分頁,系統也會自動分頁,因為前面輸出的高度正好都滿足的各窗口的高度,會自動進行分頁,確實如此,系統會自動進行分頁,但是在這里強調:強制分頁是必須的,不能使用自動分頁,原因是:自動分頁發生的時間不是我們預想的,我們需要在第13步執行完畢以后,馬上進行分頁,這時,WA_HEADER中的內容還是當前憑證的數據,這樣,在處理頁頭和頁尾窗口時,數據是正確的。而自動分頁卻不在此時發生,而是在第1步LOOP1循環再次執行以后,也就是WA_HEADER之中的內容變成下一條以后才發生,這樣我們就不能輸出正確的表頭和表尾數據,因此必須使用強制的分頁命令。
16、表頭和表尾窗口
由于這兩個窗口非常簡單,僅輸出文字描述和WA_HEADER中的內容,因此不詳細說明。
Q&A
1.打印預覽表格線都正常,但是用針式打印機輸出出現部分表格線無法輸出。
答:這個可能是由于針式打印機的分辨率較小的緣故,使用激光或者噴墨打印機可以正常輸出,或者在SmartForms中加粗表格線,使用30TW。
2.在使用穿孔紙連續打印時,后面的紙張出現錯位現象。
答:原因不是很清楚,需要設置打印機中的紙張格式,將紙張高度根據錯位的距離進行加或者減,多次調整以后可以達到沒有錯位。
總結
以上是生活随笔為你收集整理的ABAP:SmartForms--设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Smartform中如何设置背景阴影色(
- 下一篇: T001W更新逻辑