如何設計矩陣的隔行換色

by adonis 12. 十二月 2012 12:15

作    者:楊先民
審    稿:張智凱

前言
來解決報表製作的問題系列之二!本期也是將上課時學員所提到
的一些報表製作上的問題,解答之後寫成的雜誌文章內容,希望
能夠透過思考的方式,一步步將你想要做的報表產生出來。

隔行換色
隔行換色是報表中很常做的設定,主要在資料表控制項中,利用運算式來控制,在控制顏色的地方,輸入如下的運算式以達成目的:

=iif(RowNumber ("PRODUCTCATEGORY_NAME") mod 2=0,"Moccasin","White")

如此一來,就可以在顯示時,呈現隔行換色的效果如下:

image

然而,如果你把這樣的機制,放在矩陣上時,隔行換色的效果就會變成如下圖:

image

咦,怎麼看起來怪怪的?

是的,資料表控制項可以隔行換色,不代表矩陣可以隔行換色啊!

解開矩陣無法隔行換色之謎

要解開矩陣無法隔行換色之謎,首先我們在資料表控制項旁邊增加一個資料欄,並且利用 rownumber函數將資料表的連續數字呈現出來,產生出來的結果如下:

image

由上圖可以發現,序號1的編號由1、2、3、4按照資料表的順序產生,而這個資料列與資料來源產生出來的順序是吻合的,我們把資料來源的資料表展現出來,你對照看看就知道我所說的意思為何。

以下是用 SQL指令將資料來源呈現出來的結果,如下:

image

兩張圖對照一下,就可以發現兩張圖的資料列先後順序是相同的,所以很自然的序號欄就可以正常的顯示1234的順序。

但是如果我們將矩陣旁也加上序號的話,看看會有什麼結果,如下圖:
(在此我們換一個例子,以 Northwind資料庫為範例,也就是上一期的報表資料內容,指令也幾乎相同),不過請注意,這裡的序號,我們用的是 =rownumber(nothing),不然會得到不預期的結果。

image

請注意圖上的紅色框線1234的位置…咦,怎麼會如此呢?並不是如我們所想像的1234連續位置,但其實這才是矩陣的真正位置。

如果你把資料來源產生成資料表,你就會晃然大悟原來如此,所有的謎團皆以解開!

呈現的資料表如下:

image

請對照1996年 CategoryName為 Beverages的位置(順序為1),以及 1997年 CategoeyName為 Beverages的位置(順序為2)在前一張矩圖的位置即可明白。

image

也就是,若以資料表的方式撰寫隔行換色,和矩陣的呈現方式原本就不同,矩陣是交叉分析,以欄與列中間包夾著待分析的資料,所以資料會以「欄列包夾」的方式填入數值。看圖上即可了解123的位置是水平排列,並非和資料表一般垂直排列就知道。
那麼,這樣的方式要如何隔行換色呢?嚴格來說是做不到,不過如果要用一個很醜的做法,還是可以達成目的。

所以,以下的做法是一個很醜的寫法,最後目的是達成了,但是其實不怎麼好看就是。我們要注意圖中的第二行,最後一筆序號是 6,我們要拿這個數字下手,也就是說,我們要找出序號 mod(取餘數)為4的,則換顏色,序號 mod為5,換顏色,以及能被6整除。

換言之,我們要寫死。

mod為4的條件是當年份為1996年時,mod為5的條件是當年份為1997年時,mod為0的條件是當年份是1998年時,所以我們必需要寫死方能滿足我們的需求。

所以我們將 TextBox中的 backgroupcolor的屬性改成運算式如下:
=switch(Fields!years.Value=1996,iif(rownumber(nothing) mod 6 = 4,"Moccasin","white"),Fields!years.Value=1997,iif(rownumber(nothing) mod 6 = 5,"Moccasin","white"),Fields!years.Value=1998,iif(rownumber(nothing) mod 6 = 0,"Moccasin","white"))

對的,改用 switch函數,判斷年份是否為1996年,若是的話,再用 iif單行假設句判斷是否 rownumber(nothing) mod 6是否會餘4,我們的欄位有1996、1997與1998年三個欄位,故要寫三次即可解決這個煩人的需求。

你可以看到結果如下圖:

image

看吧!已經達到隔行換色的效果。

不過此例在使用時要特別小心一件事,就是若資料沒有對應到,即有空值時,會有序號錯亂的問題發生,為此,我們再舉一個範例如下:

image

上圖我們的欄為年,列為階層分組,產品大類下接產品次分類,我們的運算式已經改成如下的設定:

=switch(Fields!TRX_YEAR.Value=2007,iif(rownumber(nothing) mod 10 = 6,"Moccasin","white"),Fields!TRX_YEAR.Value=2008,iif(rownumber(nothing) mod 10 = 7,"Moccasin","white"),Fields!TRX_YEAR.Value=2009,iif(rownumber(nothing) mod 10 = 8,"Moccasin","white"),Fields!TRX_YEAR.Value=2010,iif(rownumber(nothing) mod 10 = 9,"Moccasin","white"),Fields!TRX_YEAR.Value=2011,iif(rownumber(nothing) mod 10 = 0,"Moccasin","white"))

因為第二行最後一列序號是10,所以用 mod 10餘6,餘7…依此類推。
(所以欄位才是問題所在,但一般欄位都不會太多,因為畫面的關係)
但最後所呈現的結果如下圖:

image

咦,怎麼沒有得到預期的結果?
結果定神一看發現2007年的地材分類白板次分類並沒有資料,而rownumber依舊有給值,而這個10,和第二列的數字是相同的,都是10。

而我們把資料來源取出來看,會發現2007年地材白板確實沒資料,連資料表都是空的,如下圖:

image

請特別留意地材白板與2007年,發現並沒有這筆資料,而你也不可能利用 outer join把2007年這筆資料生出來,因為在明細中確實沒有這筆資料。

結論就是資料表中沒有此筆記錄,而矩陣會把這筆資料空出來,並且依舊會給一個連續的 rownumber號碼,所以你要能寫隔行換色就是有難度的,除非你在明細資料中,無論有沒有資料都會新增一筆2007年的空格結果,不然此為資料表與矩陣的不對應,無法隔行換色的,要小心這一點。

另一種設定方式
但是,天無絕人之處,之前我們用資料表查詢,再利用矩陣控制項顯示,無法隔行換色,那我們何不用另一招,也就是用pivot table方式查詢資料,但用資料表控制項來顯示,這樣應該就可以隔行換色吧。

即知即行,立刻改變內容,將 SQL指令改成 pivot的寫法,如下:

SELECT         *
FROM             (SELECT         D .PRODUCTCATEGORY_NAME,
                                                      C.PRODUCTSUBCATEGORY_NAME, YEAR(A.TRX_DTE)
                                                      AS TRX_YEAR, SALES_AMT
                           FROM              FACT_SALES AS A LEFT OUTER JOIN
                                                      DIM_PRODUCT AS B ON
                                                      A.PRODUCT_KEY = B.PRODUCT_KEY LEFT OUTER JOIN
                                                      DIM_PRODUCTSUBCATEGORY AS C ON
                                                      B.PRODUCTSUBCATEGORY_KEY = C.PRODUCTSUBCATEGORY_KEY
                                                       LEFT OUTER JOIN
                                                      DIM_PRODUCTCATEGORY AS D ON
                                                      C.PRODUCTCATEGORY_KEY = D .PRODUCTCATEGORY_KEY)
                          AS a PIVOT (Sum(A.SALES_AMT) FOR trx_year IN ([2007], [2008], [2009], [2010],
                          [2011])) AS PivotTable
                          ORDER BY PRODUCTCATEGORY_NAME,PRODUCTSUBCATEGORY_NAME

這個指令得到的資料表如下:

image

有沒有看到,2007年即便是沒有對應到資料,還是會呈現 Null,這個是一般資料表無法做到的,接下來你只要把它套到 Reporting Service中的資料表控制項,再撰寫運算式顯示背景顏色即可,如下圖:

image

Expr目的只是要顯示數字序號出來,以證明最後是否能隔行換色的關鍵。

最後得到的報表結果如下:

image

看到沒,還是可以隔行換色啊,只是如果限定用矩陣控制項就沒辦法了,要用資料表才可以啊!

image

Tags:

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List