ReportViewer in Visual Studio 2010-恐怖的報表地獄

ReportViewer in Visual Studio 2010-恐怖的報表地獄

這個星期過得不太順,除了睡眠嚴重不足之外

還有做不完的報表地獄,搞得我頭昏腦脹。

害我為了一個找不到組件的白痴錯誤搞了半個鐘頭,結果原來是參考錯了專案@@

然後帶著我的筆電去MOS想好好發篇文章的,卻遇到一個超瞎的問題又花了我兩個小時...

這個問題,對寫程式習慣越好的人,傷害越大,為什麼這麼說呢?

待我娓娓道來...

 

最近因為專案需求,做了不少報表。其實我個人不太喜歡這種拖拉的東西

我喜歡的是邏輯跟敲打鍵盤的快感,但好好學的話,其實報表對分析方面還滿有用的,

所以今天就來發一篇用2010做的報表吧。

首先先拉出一個Linq to Sql(這是我在資策會上課時的專題DB其中一部分)

2010-06-24_234317 

 

 

接著在專案中新增一個Report資料夾,然後新增一個 DataSet

2010-06-24_2344292010-06-24_234714

接著在這個DataSet中,新增一個DataTable

(注意!不是TableAdapter唷,因為我只要一個空殼,方便供等下的報表精靈使用)2010-06-24_234506

然後加入資料行,(快捷鍵   Ctrl+L  很好用喔)

2010-06-24_234542

 

 

 

 

完成之後,我要的殼長這個樣子

2010-06-24_235214

接著呢,就可以新增一個報表精靈啦~

2010-06-24_234736

 

新增完之後,精靈就會帶著你一步一步做,這邊弔詭的事情發生了,找不到我的DataSet!!

2010-06-24_234820

就在這邊!!花了我兩個鐘頭的時間Google跟重建,因為我把DataSet放在Report資料夾裡面

所以他找不到我的DataSet,所以把DataSet移到根目錄下...

2010-06-24_235000

就找到了....可以賠我兩個小時的青春嗎@@

最前面有提到說對習慣好的人傷害越大,因為會依類型分門別類擺檔案,所以才會遇到這問題

如果直接新增在根目錄下,就沒這問題了..

 

2010-06-24_235046

剩下的就是跟著精靈,選一選,拉一拉

2010-06-25_002541

2010-06-25_002555 2010-06-25_002604

2010-06-25_002614

 

 

 

 

 

一張報表就出來啦~不過難的才剛要開始。做報表簡單,難是難在資料要如何整理統計

簡單的報表10分鐘就可以做完一張,但難的有時候光下SQL就可以花掉半天時間

接著就開始Code的部分,我是用MVC寫的,但加入WebForm對專案完全不會有影響,照一般開發模式就行了

 

2010-06-24_235705

在頁面中拉入一個ReportViewer

 

2010-06-25_015000

然後這個報表沒有參數跟按鈕,所以直接在Page_Load寫Code就好

 

 

 


public partial class ProductReport : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //給報表檔案的路徑
            ReportViewer1.LocalReport.ReportPath = Server.MapPath("~/Report/ProductReport.rdlc");

            //將資料清空
            ReportViewer1.LocalReport.DataSources.Clear();

            //撈出我要的資料
            IEnumerable<產品報表> model = GetModel();

            //新增一個ReportDataSource,第一個參數的名稱來源要注意
            ReportDataSource source = new ReportDataSource("ProductReport", model);

            //將資料倒進去
            ReportViewer1.LocalReport.DataSources.Add(source);

            //重整
            ReportViewer1.LocalReport.Refresh();
        }
    }

    //資料怎麼整理看個人
    private IEnumerable<產品報表> GetModel()
    {
        MyDataContext db = new MyDataContext();

        //如果要分析區間的資料,我覺得這樣用滿方便的
        Dictionary<string,int[]> dic=new Dictionary<string,int[]>();
        dic.Add("500以下",new int[]{0,500});
        dic.Add("501~1000",new int[]{501,1000});
        dic.Add("1000~2000",new int[]{1001,2000});
        dic.Add("2001~5000",new int[]{2001,5000});
        dic.Add("5000以上",new int[]{5001,int.MaxValue});

        //用SelectMany方法
       IEnumerable<產品報表> data = dic
                .SelectMany(p =>db.Category,(c,d)=> new 產品報表
                { 大類別=d.CategoryPrimary_主分類.CategoryPrimary_主分類1
                , 小類別=d.CategorySecondary_次分類.CategorySecondary_次分類1
                , 價格區間=c.Key
                , 數量=d.Products.Where(w=>w.UnitPrice_單價>=c.Value[0]&&w.UnitPrice_單價<=c.Value[1]).Count()});
       return data;

    }
}

//自訂的class,名稱要跟DataSet裡的一樣
class 產品報表
{
    public string 產品名稱 { get; set; }
    public string 大類別 { get; set; }
    public string 小類別 { get; set; }
    public string 價格區間 { get; set; }
    public int 數量 { get; set; }
}

如果是要統計某個區間內的資料的話,我覺得用上方的寫法還滿簡單易懂的

不過我也是想了滿久才想到

OK之後,然Run看看

2010-06-25_003600

出現這個錯誤,不過這個簡單,把ScriptManager拖進去就行了

2010-06-25_003620

再Run一次,又有錯~

2010-06-25_003929

不過錯誤說明很清楚,所以在web.config裡面把該加的加一加。(我的是IIS 7,所以要多加system.webServer那段)


<system.web>
  .......
  <httpHandlers>
    <add verb="*" path="Reserved.ReportViewerWebControl.axd" type = "Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </httpHandlers>
  ......
</system.web>
<system.webServer>
      .......
  <handlers>
    <add name="ReportViewerWebControlHandler" preCondition="integratedMode" verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  </handlers>
  ........
</system.webServer>

 

 

 

 

接著再執行一次,就OK了。一張報表就完成啦。(2010做出來的真的比2008的好看太多了~)

2010-06-25_011616

 

不過還沒結束,注意一下上方的分類順序錯了,因為預設會從小到大排序,這個問題我找了好久都

不知道怎麼解,不過後來發現一個不知道是哪個天才想出來的辦法!!

首先先改一下分類的Code,注意我在前面加了01…02…03的編號

2010-06-25_020931

但這樣報表出來的價格區間不就很怪嗎,所以在要報表上動點手腳,加上一個Mid的函數

2010-06-25_021254

有點類似SubString,從第3個字開始抓

結果就完美啦

2010-06-25_021413

 

 

呼,我一個多星期在報表地獄裡的心得,加上今天四個鐘頭的鬼打牆加寫文章時間

希望能對要用到報表的人有幫助啦。