ReportingService 通過RowNumber函數獲取行號和生成隔行變色樣式


以前一直沒有搞明白SSRS里面的RowNumber函數到底該怎么用,所以一直沒有很好的辦法在SSRS中的表格上實現隔行變色的樣式,實現隔行變色的關鍵就是獲取表格中每一行的行號。在最近了解了下這個函數,發現RowNumber函數“在某些時候”獲取行號還是非常有用的,之所以說“某些時候”是因為RowNumber函數獲取的行號實際上是數據集中最小粒度行的行號,這是什么意思呢?意思就是RowNumber函數只能用來計算數據集的行號,如果報表上Tablix(Matrix,Table等控件都是基於Tablix)中分組的粒度比數據集行要大那么RowNumber函數就無能為力了,因為RowNumber永遠都是基於數據集中的行來計算行號的,所以其計算出來行號的粒度永遠都是和數據集的粒度保持一致。

 

那么我們現在來看看RowNumber函數的概念,RowNumber函數使用的時候要傳一個參數,參數就是數據范圍(Scope)的名稱,SSRS中數據范圍(Scope)一般指的就是行組、列組、數據集等可以划分數據范圍的數據結構,RowNumber函數在運行的時候會根據當前所在的數據范圍迭代過的記錄來計算數據集中的行計數,從而生成行號,而RowNumber函數參數是用來指定重置行計數的數據范圍的。前面這句話說的很抽象不好理解,下面我們通過圖文結合方式來詳細介紹下RowNumber函數的使用以方便理解。

 

假設我們現在的報表上有一個數據集叫DBSet用來獲取數據庫中的數據

 

然后我們在報表上定義了一個Matrix用來展示數據集DBSet中的數據,我們只用到了Matrix的一個行組(行組名DateID),該行組通過數據集DBSet字段DateID來分組,而字段DateID的粒度也是數據集DBSet的最小粒度,也就是說在數據集DBSet中字段DateID每一行的值都是不同的。

 

然后我們在Matrix上定義了一列Row Number用於顯示當前行的行號,行號通過我們本文中所述的RowNumber函數來生成,RowNumber函數的參數是設置的數據集DBSet的名稱,所以RowNumber函數的行計數范圍是整個數據集,行計數在Matrix上永遠都不會被重置。

而上圖中RowNumber函數是位於行組DateID中的單元格內的,所以RowNumber函數當前所在的數據范圍就是行組DateID,所以RowNumber函數會根據行組DateID的迭代范圍來做數據集的行計數,我們來看看運行報表的結果:

在上圖中我們看到,當列Date為20100101時,Matrix中行組DateID只迭代過數據集中一行數據,所以這時RowNumber函數返回的結果是1。當Date為20100102時,Matrix中行組DateID迭代過的DateID值為20100101、20100102,所以行組DateID的當前迭代包含數據集中的兩行數據,所以RowNumber函數返回的結果是2。而當Date為20100103時,Matrix中行組DateID迭代過的DateID值為20100101、20100102、20100103,所以行組DateID的當前迭代包含數據集中的三行數據,所以RowNumber函數返回的結果是3。以此類推所以RowNumber函數在行組DateID上每一行的迭代就生成了整個Matrix的行號。

 

在上面這個例子中我們了解到了RowNumber函數可以用來生成行號,但是RowNumber函數的參數可以用來做什么並沒有很好地被體現出來。我們將上面的例子稍作修改如下,我們在行組DateID上添加了一個父組叫YearMonth,根據數據集中的字段YearMonth來進行分組,字段YearMonth的粒度要比DateID大,所以在數據集DBSet中字段YearMonth和字段DateID是一對多關系,也就是說一個YearMonth值包含多行DateID記錄。

緊接着我們將列Row Number的表達式改為了RowNumber("YearMonth"),我們將RowNumber函數的參數指定為了Matrix的行組YearMonth,那么根據我們上面所述,現在RowNumber函數會根據行組YearMonth的迭代值來進行行計數重置,當行組YearMonth的迭代值發生變化的時候RowNumber函數的行計數會清0。

根據上圖的修改,我們再次運行報表結果如下,我們可以看到RowNumber函數返回的行計數在行組YearMonth的值變化后又從1開始了,印證了我們上面所說的當RowNumber函數參數指定的數據范圍的迭代值發生變化后RowNumber函數的行統計被清0了。

 

在本文開始的時候我們說了RowNumber函數是在“在某些時候”可以用來獲取行號,上面的例子中Matrix的最小粒度也就是行組DateID的粒度,而DateID的粒度和數據集DBSet的粒度剛好一致,所以用RowNumber函數來返回行號是沒有問題的,也就是我們本文中提到的“在某些時候”。但是如果Matrix的最小粒度要比數據集DBSet的粒度要大,那么用RowNumber函數來返回行號就是不行的了,現在我們將上面的例子再稍作修改如下:

我們刪除了行組DateID只留下了行組YearMonth,那么現在Matrix的最小粒度就是行組YearMonth了,然后我們將列Row Number的表達式改回RowNumber("DBSet"),那么RowNumber函數的行計數重置范圍又變回整個數據集了,行計數在整個Matrix上不會被清0。運行報表我們查看到結果如下:

可以看到每一行的行計數都不正確了,為什么會出現這樣的結果呢?我們來分析下,RowNumber函數當前所在的數據范圍就是行組YearMonth,所以RowNumber函數會根據行組YearMonth的迭代范圍來做數據集的行計數當行組YearMonth等於201001的時候,行組YearMonth迭代了數據集中31行數據,所以RowNumber函數返回值31。當行組YearMonth等於201002的時候,行組YearMonth迭代了數據集中YearMonth為201001、201002的數據集行總共59行數據,所以RowNumber函數返回值59。當行組YearMonth等於201003的時候,行組YearMonth迭代了數據集中YearMonth為201001、201002、201003的數據集行總共90行數據,所以RowNumber函數返回值90。以此類推行組YearMonth的每一次迭代都會把從201001到當前行包含的數據集行數作為RowNumber函數的返回值,所以就有了上圖中報表運行的結果。所以我們在使用RowNumber函數的時候一定要確保Tablix中的最小粒度要和數據集的粒度保持一致,否則統計出來的行號就會像上圖一樣是完全錯誤的。

 

正確使用RowNumber函數生成行號就可以設置報表為隔行變色的效果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM