Crystal Report在報表精靈中提供了三種嚮導類型給使用者進行選擇——Standard、Cross-Tab和Mail Label,而Visual Studio/BIDS報表精靈只有兩種——表格格式和矩陣,這是和Crystal Report的前兩種報表類型相對對應的,那麼怎麼在Visual Studio/BIDS中實現Mail Label呢?
先來看一下什麼是Mail Label。Mail Label如果直譯成中文的話,就是“郵件標籤”,這是一個有歧義的名詞,一些郵箱(如Gmail)和用戶端郵件工具(如Foxmail)將“郵件標籤”作為一種將郵件進行分類以方便資訊管理的工具。而本篇隨筆討論的顯然無關“電子”郵件,而是一種比較常用的報表。設想如下的情境:如果一個組織(比如一家出版社)需要向一批客戶發一份比較正式的書面信件(比如征訂啟事)。而這些客戶的通訊地址、收件者郵遞區號等又以某種形式(資料庫、一般檔案等)儲存在電腦中,工作人員顯然不希望在每一個信封上手工書寫這些資訊,他/她要做的無非是把這些列印出來並粘貼到信封上就可以了。這樣的話,一個普通的報表也可能就已經能夠滿足他/她的需求了,儘管我們知道郵遞區號、通訊地址、收件者三個欄位之間是需要換行的。但是,如果他/她恰巧使用的是常見的如A4之類的紙張,而同時他/她又不希望浪費紙張,那麼他/她希望要的報表可能就是1所示的報表了。這就是所謂的“郵件標籤”報表了,當然“郵件標籤”報表不僅僅局限於多個信件通訊地址的一次列印,凡是具有類似結構的報表都可以被稱為“郵件標籤”報表。
圖1 Access的Northwind樣本資料庫中的“郵件標籤”報表(點擊小圖看大圖)
正1的標題所示,Access是支援“郵件標籤”報表的,不過在報表設計上只是讓標籤中涉及到的欄位縱向排列而已,真正實現多欄標籤列印是通過對報表的“版面設定”來完成的,2所示。
圖2 Access中“郵件標籤”報表的“版面設定”
在進行報表設計之前,我們先為本文的郵件標籤進行資料準備。本文的樣本報表的資料來源於SQL Server 2005的樣本資料庫AdventureWorks,在AdventureWorks資料庫中使用以下SQL語句建立視圖Production.MailLabel:
代碼1:建立視圖Production.MailLabel
USE [AdventureWorks]
GO
/**//****** 對象: View [Production].[MailLabel] 指令碼日期: 08/26/2006 16:05:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [Production].[MailLabel]
AS
SELECT Production.Product.Name, Production.Product.Color, Production.ProductPhoto.ThumbNailPhoto
FROM Production.Product INNER JOIN
Production.ProductProductPhoto ON Production.Product.ProductID =
Production.ProductProductPhoto.ProductID INNER JOIN
Production.ProductPhoto ON Production.ProductProductPhoto.ProductPhotoID =
Production.ProductPhoto.ProductPhotoID
WHERE (Production.Product.Color IS NOT NULL)
GO
開啟視圖,我們可以得到3所示的樣本資料,這將是本文樣本所使用的報表資料。
圖3 樣本使用資料
也就是說,本文的樣本示範的郵件標籤中展示的資料是AdventureWorks生產的單車的名稱、顏色以及縮圖。
既然是郵件標籤,我們要將Name、Color以及ThumbNailPhoto這三個一行中欄位縱向顯示,這個比較容易實現;我們還需要將指定行數的資料作為一列顯示在報表中,這就涉及到行到列的轉換問題。事實上,可以說行列轉換問題是郵件標籤報表面臨的最大的問題,要解決這個問題,一種可行的方案是使用SQL語句中出現在FROM子句中的PIVOT關係運算子將表結構進行轉換,然後使用Table控制項顯示資料。另外,我們知道標準控制項中的Matrix控制項的功能其實就是一個Pivot Table(樞紐分析表),我們可以清楚地在控制項工具欄上看到對Matrix控制項的提示是“用於任何多列樣式報表的行列布局”,該控制項對資料的處理其實是和PIVOT運算子是相通的,就是說使用該控制項可以避免使用PIVOT運算子而實現一個交叉表的結構,所以本文選擇使用這種方案來實現郵件標籤報表。
1、建立報表伺服器項目RDLML。
2、建立共用資料來源DataMailLabel,設定到資料庫AdventureWorks的串連,並為報表指定相應的訪問憑據。
3、不使用嚮導建立報表rptMailLabel,在報表設計師的“資料”選項卡,建立資料集MailLabel,使用工具列按鈕切換到通用查詢設計工具,在“關係圖”窗格中使用右鍵菜單“添加表”並選擇視圖Production.MailLabel,選擇Name、Color、ThumbNailPhoto三列作為輸出,這樣我們在SQL視窗中可以看到以下SQL語句:
代碼2:選擇資料的SQL語句
SELECT
Name,
Color,
ThumbNailPhoto
FROM Production.MailLabel
4、在SQL窗格中修改代碼2中的SQL語句如代碼3所示。
代碼3:修改代碼2得到的SQL語句
SELECT
(ROW_NUMBER() OVER (ORDER BY Name) - 1) / 4 + 1 AS TitleRow,
(ROW_NUMBER() OVER (ORDER BY Name) - 1) % 4 + 1 AS TitleColumn,
Name,
Color,
ThumbNailPhoto
FROM Production.MailLabel
代碼3中,ROW_NUMBER()用於為返回資料的行號,需要和OVER關鍵字結合使用,使用OVER關鍵字可能會導致圖4所示提示資訊的出現,這是由於通用查詢設計工具不支援OVER關鍵字所導致的,而事實上T-SQL是支援該關鍵字的,可以忽略此資訊的出現。
圖4 使用OVER關鍵字出現的提示資訊
代碼3選擇出的資料5所示。
圖5 代碼3選擇出的資料
5、按照圖6的方式進行報表布局設計。
圖6 報表布局設計
其中,拖動影像控制到報表布局時會出現“映像嚮導”,在“選擇映像源”頁面中選中“資料庫”,並在接下來的“指定映像欄位”頁面中,進行7所示的設定。
圖7 指定映像欄位(點擊小圖看大圖)
6、選中值為“=Fields!TitleRow.Value”的文字框,右鍵“屬性”,在“文字框屬性”對話方塊的“可見度”選項卡中,選擇“初始可見度”為“隱藏”,同樣設定值為“=Fields!TitleColumn.Value”的文字框。
7、為了明顯區分郵件標籤列表中的各個項目,可以選中列表框控制項,F4調出屬性瀏覽器,設定BorderColor為LightGray,設定BorderStyle為Dashed;另外,為了使報表看起來更美觀,可以在列表框中微調控制項的位置。
OK,到此為止,一個郵件標籤報表就設計完成了,其預覽效果8所示。
圖8 預覽效果(點擊小圖看大圖)
至於在這些步驟中隱藏的設計思路,請朋友們自己總結。
DEMO下載
感謝jimmyhell在本Blog的評論,是他提出了這個問題,不然我不會想到要去做一個郵件標籤報表,謝謝!