在報表中錄入資料時如何實現行列轉換

xiaohuihui發表於2019-12-29
應用場景及需求:

某電力集團在實際應用中需要在填報資料時將資料庫中的欄位以更符合業務人員使用習慣的方式進行呈現,其中就有行列轉換的情況。在常規的應用開發中,一般都是透過專門設計的資料介面進行錄入,然後再透過程式轉換存入資料庫。而現在有了集算器支援的潤乾填報表,就能夠處理各種有關資料結構的填報需求了,這種行列轉換自然也不在話下。

首先,我們來看一下行列轉換的準確含義:

在一些企業應用中,一些指標項在資料庫儲存時會做為不同的欄位儲存,這樣資料結構會更加清晰,但是在報表展示或填報表資料錄入時,又需要將列轉換成行的形式,從而更加符合業務人員的使用習慣,這就是行列轉換。首先看一個報表展示頁面:

1jpg

需求一:這個填報表是月度報表,要求按照月份查詢某公司下各專案以及機組資訊資料,並且能夠對資料進行修改。

需求二:工具欄中增加兩個按鈕:“報表儲存”儲存當前頁面資料,“報表鎖定”能夠對當前頁面資料進行儲存並對資料鎖定,鎖定後使用者再次訪問該月份資料就無法再修改了。

需求三:報表第二列是專案名稱。使用者系統結構比較特殊,頁面中每個專案名稱都是資料庫表中的欄位名稱,第三列和第四列為機組資訊資料,在資料庫中每個機組為一條記錄,也就是說資料存放在資料庫中兩個表中,分別是 rep_tl_config 表和 rep_tl_yb 表,取數或回寫時要根據專案名稱從不同表中取數或回寫。

下面是這些需求的實現過程。

解決方案:

這個報表的格式相對比較簡單,按照需求製作即可,如下圖:

2jpg

A 列為序號列,單元格中設定序號。

B 列為專案名稱

C 設定,B 列中專案名稱中是有特殊符號的,和資料庫中欄位名稱無法完全對應,會對取數造成影響,所以增加了 C 列,單元格型別為維度格,值為對應的欄位名稱。

D 列、E 列為數值格,該報表要取兩個機組的資料,分別顯示在 D 列、E 列中。

F 列為固定列,輸入相應資訊即可,

G 列用於控制頁面端加鎖後資料是否能夠被修改。

C、D、E、G 列均需要設定欄位名稱,根據資料取數的資料物件來確定。

取數設定

由於資料結構較為特殊,所以取數使用集算器檔案(dfx),並且由於報表中資料來自資料庫兩張資料表,所以取數指令碼分兩部分處理,指令碼一如下:

3jpg

A1:連結資料來源

D1:單元格從資料表中取出公司名稱賦值給變數:公司名稱

E1:填報表首次訪問時,如果沒有傳入年月,則取當前系統時間上月資料,表示式為:>month=if(month==null,pdate@m(now()),date(month/“-01”))

A2、A3 單元格分別定義了從兩個資料表中取數的欄位名稱

D4、E4 分別定義兩個變數設定機組名稱,groupID 為機組傳入引數,傳入格式為 #1#2 方式,所以此處做了拆分。

A5:從 rep_tl_config 表中取出需要資料,資料返回如下:

4jpg

A6:使用集算器的 pivot 函式,將 A5 中的資料做行列轉換,將列轉成行,將欄位名稱轉為行資料。

A8:將 A7 資料按照脫硫裝置編號進行分組拆分,將資料放到 data 列中

A9、B9、C9 取第一個脫硫編號的資料,處理後放到 t1 物件中

A10、B10、C10 取第二個脫硫編號的資料,處理後放到 t2 物件中

A11:透過序號欄位,將 t1、t2 兩個物件關聯在一起

A12:取出需要資料,此時資料格式為:

5jpg

可以看到,已經將資料進行了行列轉換,原來的欄位做為專案欄位中的值,另外兩列儲存對應的資料值。

A13:將 A12 單元格資料賦值給 tl_config 物件

至此,第一部分取數完成,接下來看下第二部分資料處理。

6jpg

A16:從 rep_tl_yb 表中取出相應資料

B16:設定頁面端是否加鎖標誌,資料表中有個欄位“是否經過修正”,判斷 A16 是否為空,如果為空,那麼證明是第一次訪問該月資料,所以值為 false,否則取資料庫中對應值。

A17 中做判斷,如果 A16 資料為空,則直接在之前定義的 tl_config 物件基礎上增加公司名稱、month、是否經過修正、flag 欄位,返回給報表,即報表第二部分資料為空。

B22~B30 之間單元格設定和指令碼一中設定設定方式類似,由於篇幅原因,此處不做過詳細說明,最終將所需要資料放到 tl_config 物件中,tl_config 物件中資料為:

7jpg

接下來,設定填報表中對應單元格的欄位名稱,將 C 列單元格欄位名稱設定為:tl_config. 專案,D 列欄位名稱設定為:1 脫硫裝置,E 列欄位名稱設定為:2 脫硫裝置,G 列設定為:是否經過修正

這樣,填報表能夠從資料庫中取出相應資料展示到頁面中。

資料回寫

接下來看下資料回寫指令碼,同樣,回寫時也需要將資料回寫到資料庫的兩個表中,此處指令碼分兩段來說明:

8jpg

B1:取出公司名稱

D1:設定 month 物件值,如果傳入引數為空,則取當前系統時間的前一個月

A2、A3 分別定義兩個表中的欄位名

D4、E4,分別解析兩個機組編號放大 groupID1、groupID2 中

A7:>tl_config=tl_config.new(專案,1 脫硫裝置,2 脫硫裝置, 是否經過修正),從 tl_config 物件中取出相應欄位,並生成新物件 tl_config

A9:從物件中取出專案在 A2 中的資料,A2 為資料庫表 rep_tl_config 中欄位名

B9:=A9.new(#1,#2).derive(groupID1: 脫硫裝置編號,kks:kks 編碼,B1(1). 所屬公司: 所屬公司 ),從 A9 中取第 1、第 2 兩列資料,並且增加相應欄位,之前看過 tl_config 物件中資料,1、2 列中儲存的是專案名稱、機組 1 資料

C9:=B9.pivot(kks 編碼, 脫硫裝置編號, 所屬公司;#1,#2),透過 pivot 函式,將行在轉回成列形式。

B10、C10,取 1、3 列,同上,將機組 2 資料取出並作行列轉換。

A11:>A1.update@u(C9|C10,rep_tl_config,${C9.fname().concat(“,”)};kks 編碼, 脫硫裝置編號, 所屬公司 ),用 update 函式執行更新操作,將頁面中資料更新到 rep_tl_config 表中,其中 C9|C10 是將機組 1 和機組 2 縱向拼接,fname() 取 C9 的欄位名,並轉換成字串格式。

這樣,rep_tl_config 表更新完畢,接下來看下 rep_tl_yb 表的處理,指令碼如下:

9jpg

處理方式和之前一樣,A3 單元格定義的是 rep_tl_yb 中的欄位名稱,在 A14~A17 中按照之前方式,取出對應欄位並透過 pivot 做行列轉換,將資料更新到資料庫即可。

這樣就完成了資料的取數及回寫操作。

加鎖設定

在取數物件中,取出了資料庫的是否經過修正欄位,透過該欄位的值控制頁面中的資料是否經過鎖定,該欄位的值在報表的 G 列中取出,所以報表可以根據 G 列的值控制頁面端是否能夠修改資料,是否修改資料可以透過報表單元格的是否可編輯表示式屬性控制,在 D、E 兩列(兩個機組資料列)的是否可編輯表示式中寫入:G4!=“true”,表示 G4 單元格不為 true 時,在頁面端可編輯。

上述完成了報表取數時可以根據相應欄位控制頁面端是否能夠修改資料,接下來看下,如果在頁面端點選報表鎖定按鈕,實現資料加鎖操作。

報表工具欄預設使用的是 inputtoolbar.jsp,裡邊定義了工具欄的按鈕,可在該頁面自定義按鈕:

<li class="borderRight submitLi" %>');return false;" href="#"> <a title="加鎖" href="#" class="jiasuo"></a></li>

裡邊增加按鈕,點選時呼叫 submit 函式,在 showInput.jsp 中增加 submit 函式如下:

function submit(arg1){

for(var i=4;i<=65;i++){// 報表共 65 行,從第 4 行開始設定

document.getElementById(arg1+“0_G”+i).setAttribute(“value”,“true”);// 將值設成 true

_inputSubmit(arg1);// 呼叫報表儲存的 js 函式

}

這樣,在頁面端點選報表鎖定按鈕,就能透過 js 更改標識位的值並將值儲存到資料庫中,再次訪問報表時,頁面中的資料處於鎖定狀態,無法編輯。

總結:

至此,完成了客戶的所有需求,該例中可以看到,對於資料庫結構比較特殊的表,可以透過集算器先對資料進行處理,將處理後的資料返回給報表使用,點選填報後又能在指令碼中對資料再次處理,從而實現行列轉換的需求,此例中主要是 pivot 函式的使用,具體可以看一下函式說明。並且,潤乾填報表頁面端的值可以透過 javascript 進行處理,從而實現資料加鎖等相應需求。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900830/viewspace-2671111/,如需轉載,請註明出處,否則將追究法律責任。

相關文章