分組聚合的展開和收起效果在SSRS Report中非常常用,並且有時還要處理一些比較特別的情況。比如分組合並時有的層次結構是不規則的,有的組有兩層,遇到這種情況應該如何處理?
注意到下面的這個需求,如果 France 下面沒有其它的子層級,就不顯示 + 號,如果 United States - Utah/Minnesota 州沒有城市的子層次那么它們也不顯示 + 號.
這樣的需求在 SSRS Report 中會偶爾碰到,可以理解為如何處理非對稱層次結構中的顯示和隱藏問題.

下面展示的技巧先回顧了如何垂直分組,使用的是Table這個控件,而沒有使用Tablix. 最后展現了在沒有子層次結構的時候如何不顯示 + 號,以免給用戶以誤導做出無謂的點擊。
使用的Demo數據庫是 AdventureWorks2012, 為了展示不規則層次帶來的問題,把Dataset中的SQL給故意寫成這樣-
SELECT CountryRegionName, CASE WHEN CountryRegionName = 'France' THEN '' ELSE StateProvinceName END AS StateProvinceName, CASE WHEN CountryRegionName = 'France' THEN '' WHEN City = 'Nevada' THEN '' WHEN City = 'Duluth' THEN '' ELSE City END AS City, SalesQuota, SalesYTD, SalesLastYear FROM Sales.vSalesPerson WHERE CountryRegionName IN ('United States','United Kingdom','France')
下面開始先創建一個報表,以及添加DataSource, DataSet和 Table控件並填充數據

預覽一下看看,France 這個國家下面沒有身份和城市信息, United States 的 Utah 和 Minnesota 州下面沒有 City 信息, 我們要基於 國家,州和城市來分組聚合.

選中行,右鍵來為這一行添加一個 Parent Group

雖然,先按城市分組 (最后這個分組會被去掉的,目前只是為了實現這個效果),添加一個 Group Header

添加完之后,多出一行,是以 City 分組之后的組行. 繼續基於這個組添加新的 Group.

城市上面的分組是州,添加 Group Header

同樣的給州組添加一個Group-國家, 添加完之后可以看到 -
上左部分是基於原始行添加的 Group 分組, 上右部分是原始行的信息,最下方也顯示了它們之間的層次結構, 但這樣展示出來的數據是不好看的,需要調整.

調整的方法就是將左邊 Group 顯示的內容添加到與原始行數據垂直的位置,這里選擇的是 City, 那么分組后的層次結構顯示的就是一個垂直的層次結構.

其它的列都可以刪除了

刪除之后簡潔很多

下面要做的事情就是分組的展開和收起效果了,選中分組的 City, 注意最后一行 =[City] 它們只是原始行,這里要選中的是組 City.
右鍵 Row Visibility, 默認這個組隱藏,並且由 StateProvinceName2 來控制顯示或隱藏.
在 SSRS Report 中, 只要設置了這個屬性,那么控件分組組件(例如這里的StateProvinceName2)就會在它自己前面顯示 + 或者 - 符號.

同樣選中 StateProvinceName 行,修改它的 Row Visibility, 它受上一層單元格控件.

因為有時同樣的名字出現了很多次,所以要知道如何找到對應的單元格-選中單元格看屬性.

這里要注意了,等到各個分組的 Row Visibility 設置完了之后才可以做這一步的操作,否則效果不出來. (在這里要多說一句,可能不同的版本之間操作順序稍微有一點區別,我記得之前用其它的版本感覺可以先刪除后修改 Row Visibility,但現在無法一一驗證了。我目前使用的版本是 VS2012 + SSDT 插件,關於如何集成 SSDT 插件到 VS2012中,請參考我的另一篇文章 - 在 Visual Studio 2012 開發 SSIS,SSAS,SSRS BI 項目)。

刪除的時候會提示“刪除組和關系”? 刪除!

刪除完成后,原始行信息其實包含在 City 組內了。

調整一下格式,並添加要聚合的數據以及修改一下顯示的數據格式。

預覽一下,感覺還不錯。

展開之后,其實就可以看到我們已經實現了分層瀏覽的效果,如果每一個層次都有數據的話,其實這個顯示和隱藏的效果就算是完成了。
在這里可以看到,France 下面並沒有其它的層級,那么就不應該顯示 + 或者 - 號。
可能有這樣的一個思路,判斷一下下面有沒有數據,如果沒有數據就不展開,這個可以實現,但是 + 號是無法去掉的。數據可以不展示,但是+仍然存在。

由於基於這個例子來演示如何控制不顯示 + 的步驟,所以順着這個例子要做一些修改,不重頭開始做。
先重新添加一個組,因為要先基於組來修改 Rows Visibility 后刪除行.

把 City 組給添加回來,即 Group By City.

由於 Rows Visibility 里有一個特性,就是這一組數據被哪一個元素來控制,那么那個元素就會顯示 + 或 - ,這樣的話我們在第一列之前添加一個空白列。
修改第一行,取一個名字叫做 A,第二行叫做 B,后面的顯示和隱藏是通過 A 和 B 來實現的。

這樣重新來修改 City 組的顯示和隱藏屬性,注意是基於組。

City 組基於 B 顯示或隱藏。

StateProvinceName 基於 A 顯示或隱藏。

等這一步操作完了之后,接着又是像前面的操作一樣,刪除細節行,注意不是刪除組行。

既然顯示和隱藏都設置完了,所以這里的組和行的關系可以一起刪除了。

刪除之后的效果

預覽一下,發現還是這樣的顯示,原因是因為還需要判斷子層次有沒有數據。

分別修改 A 和 B 的屬性。

如果是 A 的話,就要判斷 State 州元素存在不存在,如果是 B 的話,就要判斷 City 有沒有。
=IIF(Fields!StateProvinceName.Value="",True,False) 這是A顯示或隱藏的判斷。
這時看能不能明白為什么要單獨加一個列來控制顯示和隱藏,因為如果把這個判斷寫在數據列的話,那么當子層沒有數據的時候,它自身就隱藏了,那么就丟數據了。

預覽一下,已經實現了。

調整一下,把第一列的顏色給拿掉,讓顯示更好看一些,這樣就實現了我們要的功能。

OK!寫完了!可以睡覺了!
更多 BI 文章請參看 BI 系列隨筆列表 (SSIS, SSRS, SSAS, MDX, SQL Server)
如果覺得這篇文章看了對您有幫助,請幫助推薦,以方便他人在 BIWORK 博客推薦欄中快速看到這些文章。