自定義Report 變數儲存功能
在顯示報表之前,系統會自動生成變數輸入介面,這個介面乃系統生成無法定製(或不知道如何做到)。這個介面在SAP 提供的基於Excel 的Bex Analysis是可以儲存輸入的變數的,使用者接觸之後希望能夠移植到Web上,甚至說新增一個button來儲存自己輸入的變數值即可。需求簡單明確,IT 捶胸頓足。
開始試圖去發現,是否系統本身有這個功能,只是沒人發揚光大而已,不過沒有結果。以此同時,使用者提到是否可以顯示開啟使用者儲存的View,還真在Web Application Designer發現相關控制元件,是一個Dropdown List。系統提供Save View的Button,這個一點我開始忽視了,這時突然覺得兩者的相同之處,都是儲存值到BW,無非都是提交Form給server處理,是否可以借鑑?答案是肯定的。
首先分析Save View Button的程式碼,通過WAD開啟標準模板0ADHOC_TABLE
<!-- Save View -->
title="
href="JavaScript.:SAPBWOpenWindow(SAP_BW_URL_Get() + '&CMD=PROCESS_HELP_WINDOW&HELP_SERVICE=HW_SAVE_VIEW&item=QueryName', 'SaveView',500,250);">
看上去比較長,不過分析之後會發現關鍵是這裡執行了一段Javascript,所以可以把關鍵部分拿出來分析。SAPBWOpenWindow 為Function 名,傳入幾個引數,第一個是URL,其它可以不用管它。用過BW的人對裡面的某些關鍵字一定熟悉了,比如CMD,HELP_SERVICE,ITEM。對,這裡用到了SAP Command URLs(即傳說中的WebAPI)。所以這次的突破點就是:如果定製SAP Command URLs。
我們先來看看Save View是如何實現的:
前提:為了使用這個命令,必須將help service 註冊到某個Web Item。就是將下述屬性加入到web Item 中。
Attribute |
Description |
HELP_SERVICE |
Name of the help service (SAVE_VIEW) |
HELP_SERVICE_CLASS |
Technical name of the help service class (CL_RSR_WWW_HWIND_SAVE_VIEW) |
以上我們可以獲知,需要用到類,需要Register。
首先我們通過CL_RSR_WWW_HWIND_SAVE_VIEW認識一下這個類的定義和使用。
1. 繼承CL_RSR_WWW_HELP_WINDOW
2. 通過Method PROCESS_CMD處理接受到的引數及引數值
3. 通過i_r_parameter獲取引數及引數值
上述三步算是吧Class的框架立了起來。另外涉及到如何傳引數,以及如何儲存引數的問題,隨後一一道來。
要把變數值整批的傳遞,自然考慮用Form以及Form的Submit功能。到這裡會想到幾個問題。
1. 傳什麼
2. 變數的型別決定使用者會輸入不同的資料,或單值或區間或萬用字元等等
3. 輸入框的數量是變化的,比如Multiple Selection,Select-Option
4. 如何把Save Button嵌入到標準的介面
Rsrrepdir - Directory of all reports
Rsrvarianttxt - Texts for Variants
Rsrvariantdir - Directory of Variants for Queries and Selection Objects
RSRVARIANT - Variant Values
看完這三個表,並結合之前存的一些變數值,可以發現內部存值採用的都是Option的方式,即:queryId、variantName、POS、SIGN,OPT,LOW,HIGH.這些都是很熟悉的東西。所以要儲存的值就是變數的名稱以及各種各樣的值。
第二、三個問題其實鬥可以通過第一個問題獲得答案,因為SAP的存值無法採用Option的方式。
第四個問題比較麻煩,因為我們很清楚標準的變數輸入介面我們是無法插足的,可是我們需要動態去取輸入介面的引數值。最終選擇採用的方式是Iframe,當然內嵌網頁的技術都可以實現,只是Iframe用的方便些。
marginWidth=0>
採用Iframe還有一個原因是後面需要動態去改變Iframe的內容,用Javascript去改變SRC的值即可實現。
使用者不單單需要儲存,同時還需要選擇各種已儲存的變數組合,甚至可能要修改已儲存的變數,這些都是需要考慮而使用者不一定會說的。最終的樣式如下:
我用了一個下拉框來顯示系統已儲存變數,以及使用者新增的變數。因為沒有現成的Dropdown List可以顯示儲存變數,所以我對錶RSRVARIANT 建了一個Remote Cube,直接拉一個query顯示變數列表,然後通過JS把值組裝到Dropdown List。
Dropdown List的HTML
初始化組裝Dropdown List的程式碼
$(document).ready(function(){
var arr = new Array();
//輸出的是一個兩列的表,第一列是技術名,第二列是描述,所以直接寫談不上邏輯
$("table[name='TABLE_1']").find("tr").each(function(i){
arr[i] = new Array();
$(this).find("td").each(function(j){
arr[i][j] = $(this).text();
});
});
var i ,opt_str;
for( i = 0; i < arr.length ; i ++){
opt_str = "";
//採用JQuery把可能值寫入下拉框 sel01是Dropdown List的ID
$(opt_str).appendTo($("#sel01"));
}
})
Dropdown List值變化的處理函式
function fs(vari){
var iframe1 = document.getElementById("if01");
var if_src = iframe1.src;
iframe1.src = if_src + "&variant=" + vari;
$("#DESCRIPTION").val( $("#sel01 option:selected").text() ); //新增到編輯框
$("#TECH_NAME").val( $("#sel01 option:selected ").val() ); //新增到編輯框
}
變數值名稱儲存form
target=show>
……..
儲存傳送程式碼
function pre_submit(){
var flag = check_val();
if(flag == 'N'){return ;}
//以下程式碼實現將Iframe. 的頁面的變數存放的Form的值存到當前Form
$("#selection").empty();
input_txt = $(window.frames["if01"].document).find("form[name='VARI']").html() ;
$("#selection").append(input_txt);
//提交表單
$("form[0]").submit();
$("#frm01").css("display", "none")
}
開始的時候我還在考慮變數值怎麼取,後來乾脆把這個變數Form都拷貝出來,一起傳,到Process_CMD裡面去處理。
為了簡潔,我還特意把儲存框,在不用的時候隱藏起來,可以通過下述Funtion去切換。
function show( ){
var flag;
flag = $("#frm01").css("display");
if( flag == 'none'){
$("#frm01").css("display", "block");
}else{
$("#frm01").css("display", "none")
}
}
之前我們有提到,要把Class註冊到Web Item,所以我們就把Class註冊到Table上,注意最後兩個引數設定。
還有一個函式是用來判斷值是否存在的
function check_val(){
var flag;
var is_ort;
var desc,tech_name;
var size;
var opt_txt;
flag = 'Y';
desc = $("#DESCRIPTION").val();
tech_name = $("#TECH_NAME").attr("value");
is_ort = $("#OVERWRITE").attr("checked");
if (is_ort != true){
size = $("#sel01").find("option[value='"+ tech_name +"']").size()
if(size > 0){
alert("The technical name is exist");
flag = 'N';
return flag;
}
size = $("option:contains('"+desc+"')").size();
if(size > 0){
alert("The description is exist");
flag = 'N'; return flag;
}
}
size = $("#sel01").find("option[value='"+ tech_name +"']").size()
if(size > 0){
$("#sel01").find("option[value='"+ tech_name
+"']").text(desc).attr("selected","selected");
}else{
opt_txt = "";
$(opt_txt).appendTo("#sel01").attr("selected","selected");
}
}
以上部分把頁面處理的過程以及程式碼都做了交代,應該可以參照完成了。
第三部分是關於如何儲存值,這裡還需要好好看看輸入些什麼。如何看輸入的值呢?第一到輸入變數的介面,看Web的原始碼,就可以很清楚的看到相應的input的內容,裡面一大串的input就是變數值的內容。另外可以在class的接收部分去傳遞過來的值的規律。
處理程式碼如下:
***Get The Parameters List
CALL METHOD i_r_parameter->get_table
RECEIVING
r_th_parameter = para_itab.
***Get Technical Name & Descript
l_view_id = i_r_parameter->get_upper_case( i_id = 'TECH_NAME' ).
……
***Get Query COMPUID
SELECT SINGLE compuid INTO l_compuid
FROM rsrrepdir
WHERE compid = l_queryname.
***Get Variant Name List
SORT para_itab BY id index.
LOOP AT para_itab INTO para_wa WHERE id EQ 'VAR_ID'.
***Set the sign
LOOP AT para_itab INTO para_wa WHERE id EQ 'VAR_SIGN'.
***Set the operation
LOOP AT para_itab INTO para_wa WHERE id EQ 'VAR_OPERATOR'.
***Set the low value
LOOP AT para_itab INTO para_wa WHERE id EQ 'VAR_VALUE_EXT'.
***Set the Low value
LOOP AT para_itab INTO para_wa WHERE id EQ 'VAR_VALUE_LOW_EXT'.
***Set the HIGH value
LOOP AT para_itab INTO para_wa WHERE id EQ 'VAR_VALUE_HIGH_EXT'.
DATA: moff TYPE i,mlen TYPE i.
LOOP AT itab_dat INTO wa_dat.
***這裡主要是處理時間格式的問題
IF wa_dat-low NE ''.
MOVE wa_dat TO str.
FIND REGEX '\d{2}[\.\\]\d{4}' IN str.
IF sy-subrc EQ 0.
CONCATENATE wa_dat-low+3(4) wa_dat-low+0(2)
INTO wa_dat-low.
ENDIF.
ENDIF.
***這裡比較麻煩,因為後來發現傳過來的值沒有嚴格的遵從Option的規則,比如說單值
***sign和opt的欄位都是空的,所以要結合low和high對sign和opt進行值的設定
***,有空值的情況,也要把opt,sign清空。
IF wa_dat-sign EQ ''.
IF wa_dat-high NE '' .
wa_dat-sign = 'I'.
wa_dat-opt = 'BT'.
ELSEIF wa_dat-low ne ''.
wa_dat-sign = 'I'.
wa_dat-opt = 'EQ'.
ENDIF.
ELSE.
IF wa_dat-low EQ ''.
CLEAR: wa_dat-sign , wa_dat-opt .
ENDIF.
ENDIF.
MODIFY itab_dat FROM wa_dat INDEX l_index.
ENDLOOP.
***先刪除後儲存值
DELETE FROM rsrvariant WHERE compuid = l_compuid AND
vari = l_view_id.
MODIFY rsrvariant FROM TABLE itab_dat.
***Set variant dir
MODIFY rsrvariantdir FROM wa_dir.
***Set Variant Text
MODIFY rsrvarianttxt FROM wa_txt.
IF sy-subrc EQ 0.
COMMIT WORK.
ELSE.
ROLLBACK WORK.
ENDIF.
完畢!
完整文件下載
http://space.itpub.net/batch.download.php?aid=23978
//雷國海 2010.08.12
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/554557/viewspace-670861/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- NSUserDefault 儲存自定義物件物件
- Nginx 如何自定義變數?Nginx變數
- Laravel 自定義配置資訊的儲存方式Laravel
- PHP 自定義session儲存 FILE 方式類PHPSession
- CSS 自定義屬性(變數)CSS變數
- java呼叫oracle儲存過程的自定義型別(可變陣列)JavaOracle儲存過程型別陣列
- MySQL自定義函式與儲存過程MySql函式儲存過程
- 使用SpringBoot JPA進行自定義的儲存及批量儲存Spring Boot
- mysql中自定義變數有哪些MySql變數
- 使用 CSS 自定義屬性(變數)CSS變數
- mysql 儲存過程中變數的定義與賦值操作MySql儲存過程變數賦值
- 使用SpringBoot-JPA進行自定義的儲存及批量儲存Spring Boot
- Mysql中儲存過程、儲存函式、自定義函式、變數、流程控制語句、游標/遊標、定義條件和處理程式的使用示例MySql儲存過程儲存函式變數
- Laravel 5.8 自定義位置日誌按天儲存Laravel
- 很亂,臨時儲存,自定義v-model
- 自定義效能統計儲存過程包runstats儲存過程
- JavaScript變數儲存淺析(一)JavaScript變數
- JavaScript變數儲存淺析(二)JavaScript變數
- MySQL自定義變數執行順序MySql變數
- spark:自定義分割槽,自定義排序,spark與jdbc,廣播變數等Spark排序JDBC變數
- 集合框架-ArrayList集合儲存自定義物件的排序案例框架物件排序
- 集合框架-HashSet儲存字串、自定義物件並遍歷框架字串物件
- CSS變數(自定義屬性)實踐指南CSS變數
- Apache Linkis自定義變數實踐分享Apache變數
- MySQL自定義變數的三個小技巧MySql變數
- (9)mysql 中的儲存過程和自定義函式MySql儲存過程函式
- JS 變數儲存?棧 & 堆?NONONO!JS變數
- 【精】C語言之變數儲存型別C語言變數型別
- c語言中的變數儲存區域C語言變數
- Python閉包和儲存自由變數Python變數
- 變數的儲存方式和生存期變數
- 儲存過程中巢狀儲存過程的變數執行方式儲存過程巢狀變數
- CSS Var 自定義屬性中使用 Scss 變數CSS變數
- MySQL使用自定義變數模擬分析函式MySql變數函式
- MySQL自定義變數處理行號問題MySql變數
- [Hive]建表例項與引數解釋——自定義表的儲存格式(textfile、sequencefile、refile)Hive
- FastDFS加Redis實現自定義檔名儲存海量檔案ASTRedis
- Redis序列化儲存Java集合List等自定義型別RedisJava型別