報表載入大資料時顯示進度條

u010117647發表於2013-07-22

 由於某些報表長度非常大,如果要生成或執行非常大的報表,需要一段時間,這段時間可能是幾秒,最長也可能達到幾十秒,這時進度條的需求就出現了。終端使用者需要一個進度條來顯示 報表生成的進度,不然終端使用者可能將正常報表生成時間理解為應用系統的不穩定。

  ActiveReports允許開發者將一個使用者顯示報表生成進度的進度條整合到報表瀏覽器中,類似一下效果:

報表開發工具ActiveReports顯示載入進度條

  我們需要Windows forms ProgressBar 這個控制元件,此外還需要一個標籤控制元件用於顯示進度的百分比和提示報表生成完成。

  首先要確定報表記錄數來確定進度條的最大值,ActiveReports支援多種型別的資料來源,所以還要確定報表使用的資料來源型別,下面的程式碼示例就是建立一個GetNoOfRecords函式來計算記錄數,這種方式適用於常見資料來源。

public int GetNoOfRecords(object ds)
{
    int noOfRecs = 0;
  
    if (ds.GetType().ToString() == "GrapeCity.ActiveReports.Data.SqlDBDataSource")
    {
       GrapeCity.ActiveReports.Data.SqlDBDataSource ods = (GrapeCity.ActiveReports.Data.SqlDBDataSource)ds;
       SqlConnection con = new SqlConnection(ods.ConnectionString);
       SqlCommand com = new SqlCommand("Select count(*) as totalRecs from (" + ods.SQL + ")", con);
       con.Open();
       SqlDataReader sdr = com.ExecuteReader();
       sdr.Read();
       if (sdr.HasRows)
       {
          noOfRecs = Convert.ToInt32(sdr[0]);
       }
       con.Close();
    }
    else if (ds.GetType().ToString() == "GrapeCity.ActiveReports.Data.OleDBDataSource")
    {
       GrapeCity.ActiveReports.Data.OleDBDataSource ods = (GrapeCity.ActiveReports.Data.OleDBDataSource)ds;
       OleDbConnection con = new OleDbConnection(ods.ConnectionString);
       OleDbCommand com = new OleDbCommand("Select count(*) as totalRecs from (" + ods.SQL + ")", con);
       con.Open();
       OleDbDataReader odr = com.ExecuteReader();
       odr.Read();
       if (odr.HasRows)
       {
          noOfRecs = Convert.ToInt32(odr[0]);
       }
       con.Close();
    }
    else if (ds.GetType().ToString() == "GrapeCity.ActiveReports.Data.XMLDataSource")
    {
       GrapeCity.ActiveReports.Data.XMLDataSource xds = (GrapeCity.ActiveReports.Data.XMLDataSource)ds;
       noOfRecs = xds.NodeList.Count;
    }
    else if (ds.GetType().ToString() == "System.Data.DataTable")
    {
       System.Data.DataTable dtds = (System.Data.DataTable)ds;
       noOfRecs = dtds.Rows.Count;
    }
    else
    {
       GrapeCity.ActiveReports.Data.ListDataSource lds = (GrapeCity.ActiveReports.Data.ListDataSource)ds;
       noOfRecs = lds.List.Count;
    }
    return noOfRecs;
}

   在得到記錄數後,需要將其值設定為最大進度數,並在一個單獨的執行緒中執行的ActiveReports。在單獨程式執行報表能夠實現報表的後臺執行而 且能獲取報表進度。接下來定義一個在FetchData事件中遞增的變數recordCount,這個變數將用來控制進度條的運動,示例程式碼如下所示:

private void CheckProgress(object sender, EventArgs e)
{
    if (progressBar1.Maximum > recordCount)
    {
       progressBar1.Value = recordCount;
       label1.Text = ((int)((progressBar1.Value * 100) / progressBar1.Maximum)).ToString() + "%";
    }
    else
    {
       timer1.Enabled = true;
       label1.Text = "Done!";
       progressBar1.Value = progressBar1.Maximum;
       StopTimer();
    }
}

  以上程式碼中的label1是用來顯示進度百分比的。程式碼中也包含了停止和重啟報表生成的按鈕。

相關文章