PDA

View Full Version : Tạo report trong C# bằng XtraReport của DevExpress, bác nào rành?



anhdh
09-03-2011, 16:57
Hi all,

Mình đang làm một dự án winform có sử dụng Control của DevExpress, giờ làm đến phần thiết kế các report, mình không muốn dùng Crystal Report nữa mà muốn dùng ngay XtraReport của DevExpress vì thấy nó khá hay, cho phép end-user có thể tùy chỉnh report. Khi cài Deverloper Express, nó đều có các Demo, các ví dụ nhưng không có Tutorial hướng dẫn cách làm từ A-Z, tất cả các mẫu ví dụ về report hình như toàn dùng Wizard, giờ mình muốn code hoàn toàn, tức là không có kiểu kéo thả mấy cái dataset, DataAdaper... nữa. Bạn nào rành về XtraReport vui lòng dành ít thời gian comment cho mình nhé. Thanks.

Scorpion.vn
09-03-2011, 22:56
Chào bạn!
Bạn thử vào bài viết này xem sao, hy vọng nó sẽ giải đáp được phần nào thắc mắc của bạn!
http://lichsu.vn/0/90/Tao-report-don-gian-voi-ExtraReport-cua-DevExpress.html

anhdh
10-03-2011, 09:04
Oh cảm ơn bạn thật nhiều, mình đã đọc qua bài viết của bạn. Bây giờ vấn đề đặt ra là các report sẽ có tham số đầu vào, nếu bạn đã làm chuyện này rồi thì cho mình biết cách làm. Cảm ơn

Scorpion.vn
10-03-2011, 15:03
Bài của bạn đã có câu trả lời tại http://www.lichsu.vn/0/90/Tao-report-don-gian-voi-ExtraReport-cua-DevExpress-C-Net-2-0.html
Chúc bạn thành công!

anhdh
10-03-2011, 16:31
Cảm ơn sự nhiệt tình của bạn. :)
Cách làm của bạn như vậy cũng tạm ổn. Tuy nhiên, bây giờ tôi cũng muốn bàn với bạn về vấn đề tận dụng cái parameter có sẵn trong trong XtraReport, chẳng hạn như thay vì bạn phải làm riêng một cái form và đặt các control để nhận dữ liệu tham số thì trong XtraReport nó làm luôn cho mình cái này. Bạn chỉ phải định nghĩa các parameter trong cửa sổ Field List (trong cửa sổ design report sẽ thấy cửa sổ con này). Khi chạy báo cáo, trên thanh công cụ sẽ xuất hiện menu Parameter có biểu tượng hình dấu "?". Click vào nó sẽ hiển ra phần nhập tham số. Giờ chỉ code thế nào thôi, mình đọc các ví dụ mẫu nhưng áp dụng chưa được.

Scorpion.vn
10-03-2011, 17:49
Không biết bạn dùng phiên bản DevExpress nào? Bạn có thể gửi cho mình code demo để mình xem thử được không? Field List mình thấy trong Documention của Dev toàn là kéo thả, nên mình chưa hiểu ý bạn lắm!
Theo mình tốt nhất bạn làm một ví dụ nhỏ (đến đoạn vướng mắc), rồi send qua email cho mình, mình sẽ làm tiếp xem sao.
nhandt@lichsu.vn

anhdh
11-03-2011, 08:35
Mình đang dùng bản 2009 v9.1.3. Mình làm được rồi, sẽ post code lên trong thời gian tới.

Sao khi chạy báo cáo chỉ có 1 dòng dữ liệu nhỉ? Kỳ wa' ??? Tất nhiên là hiển thị trong phần detail. Mình còn thiếu xót gì không vậy? Đã debug thì k vấn đề gì, datasource để cung cấp cho report chứa nhiều dữ liệu mà report chỉ hiển thị đúng record đầu tiên. Không hiểu!

Vấn đề nữa là trong báo cáo có cột số thứ tự, giờ mình muốn hiển thị nó nhưng không phải là từ Datasource mà là tự phát sinh thì XtraReport có hỗ trợ k nhỉ? Mình chưa tìm ra.

Scorpion.vn
11-03-2011, 18:41
http://lichsu.vn/0/90/Cach-them-cot-so-thu-tu-vao-XtraReport-cua-DevExpress-C-Net-2-0.html
Bạn thử cái này xem sao! :D

anhdh
14-03-2011, 11:19
Không hiểu tại sao chạy báo cáo ra chỉ có 1 record? Bác biết sao k nhỉ???

Scorpion.vn
14-03-2011, 14:29
Bạn có thể post đoạn code bạn lấy dữ liệu và bind lên report được không?

anhdh
14-03-2011, 14:52
Đây là code của file report


public partial class rptBangLuongTamUng_ChiTiet : DevExpress.XtraReports.UI.XtraReport
{
public rptBangLuongTamUng_ChiTiet()
{
InitializeComponent();
}

private List<ChiTietBangLuongTamUng> DataSource = new List<ChiTietBangLuongTamUng>();

private COMHRM.Entities.Luong.KyBaoCaoInfo GetKyLuong(int Year, short Month)
{
COMHRM.Entities.Luong.KyBaoCaoInfo kyluong = null;
KyBaoCaoController controller = new KyBaoCaoController();

kyluong = controller.GetKyBaoCao(Year, Month);

return kyluong;
}

private void BindData()
{
cellFullName.DataBindings.Add("Text", DataSource, "NhanVien.FullName");
cellLuongTamUng.DataBindings.Add("Text", DataSource, "MucLuongTamUng");
}

public void SetReportParameters(int Year, short Month, int MaDonVi)
{
KyBaoCaoInfo kyluong = GetKyLuong(Year, Month);

if (kyluong != null)
{
DataSource = kyluong.BangLuong.GetBangLuongTamUngByDonVi(MaDonV i);
}
else
DataSource = new List<ChiTietBangLuongTamUng>();

BindData();
}

private void rptBangLuongTamUng_ChiTiet_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
SetReportParameters((int)parameterYear.Value, Convert.ToInt16(parameterMonth.Value), (int)parameterDonVi.Value);
}

private void rptBangLuongTamUng_ChiTiet_ParametersRequestBefore Show(object sender, DevExpress.XtraReports.Parameters.ParametersReques tEventArgs e)
{
foreach (ParameterInfo info in e.ParametersInformation)
{
if(info.Parameter.Name == "parameterYear")
{
info.Parameter.Value = DateTime.Today.Year;
}
else if(info.Parameter.Name == "parameterMonth")
{
ImageComboBoxEdit cboMonth = new ImageComboBoxEdit();
for(int m=1; m<=12; m++)
{
cboMonth.Properties.Items.Add(new DevExpress.XtraEditors.Controls.ImageComboBoxItem( m.ToString(), m));
}

cboMonth.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.Dis ableTextEditor;
cboMonth.SelectedIndex = DateTime.Today.Month-1;
info.Editor = cboMonth;
}
else if(info.Parameter.Name == "parameterDonVi")
{
DonViController donviController = new DonViController();
List<DonViInfo> donvis = donviController.GetAllDonVis(false);

LookUpEdit lookUpEdit = new LookUpEdit();
lookUpEdit.Properties.DataSource = donvis;
lookUpEdit.Properties.DisplayMember = "TenDonVi";
lookUpEdit.Properties.ValueMember = "MaDonVi";
lookUpEdit.Properties.Columns.Add(new DevExpress.XtraEditors.Controls.LookUpColumnInfo("TenDonVi", 0, "Đơn vị"));
info.Editor = lookUpEdit;
}
else
return;

}
}

private void Detail_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
int STT = 0;
STT++;
cellSTT.Text = STT.ToString();
}

}

Giải thích chút xíu:
- Trong phần thiết kế báo cáo, mình có định nghĩa 3 parameter để nhận vào năm, tháng và đơn vị: parameterYear, parameterMonth, parameterDonVi. Cả 3 parameter này đều public giúp PreviewControl class có thể nhìn thấy.

- Dự án của mình không dùng dataset mà các đối tượng đều được định nghĩa qua class, ví dụ: ChiTietBangLuongTamUng là class mô ta chi tiết một bảng lương tạm ứng gồm: MaKyBaoCao, NhanVien, MucLuongTamUng,... (NhanVien la thuộc tính của ChiTietBangLuongTamUng, nó có kiểu đối tượng NhanVienInfo(MaNhanVien, FullName, MaDonVi,...) Và một bảng lương tạm ứng thể hiện qua: List<ChiTietBangLuongTamUng>.

Như vậy, datasource của report là một bảng lương tạm ứng List<ChiTietBangLuongTamUng>. 1 bảng lương tạm ứng chỉ thuộc về một kỳ lương, điều này thể hiện qua đoạn code: kyluong.GetBangLuongTamUngByDonVi(MaDonVi)


và đây là code của ReviewControl


namespace COMHRM.Reports
{
public partial class PreviewControl : DevExpress.XtraEditors.XtraUserControl
{
public PreviewControl()
{
InitializeComponent();
}

private void PreviewControl_Load(object sender, EventArgs e)
{
try
{
rptBangLuongTamUng_ChiTiet report = new rptBangLuongTamUng_ChiTiet();
report.SetReportParameters((int)report.parameterYe ar.Value, Convert.ToInt16(report.parameterMonth.Value), (int)report.parameterDonVi.Value);
printControl1.PrintingSystem = report.PrintingSystem;
report.CreateDocument();
}
catch (Exception ex)
{
string error = ex.ToString();
}

}

}
}



Đoạn nào bạn k hiểu thì trích dẫn và hilight nhé

Scorpion.vn
16-03-2011, 13:27
Đợt này đang cài lại computer, nâng cấp lên win 7, cài lại nhiều thứ quá, lại lỗi linh tinh. Chưa test được bài của bạn, thông cảm nhé! :D

anhdh
16-03-2011, 14:01
Đợt này đang cài lại computer, nâng cấp lên win 7, cài lại nhiều thứ quá, lại lỗi linh tinh. Chưa test được bài của bạn, thông cảm nhé! :D

Hix, mấy ngày nay tôi đang chờ câu trả lời của bạn, sếp đang dí quá. Để tôi đổ dữ liệu vào dataset xem có gì khác biệt không? Gấp gấp nhé

Scorpion.vn
16-03-2011, 15:16
Bạn làm theo hướng DataSet thì thấy thế nào? Bạn có thể chụp hình lúc bạn design báo cáo được không?

anhdh
18-03-2011, 16:16
Haizzzzzzzzzz, tìm ra nguyên nhân sai rồi, nó nằm ở đây:

Thứ nhất:


private List<ChiTietBangLuongTamUng> DataSource = new List<ChiTietBangLuongTamUng>();

Dòng khai báo này thực ra không cần thiết, và trớ trêu khi tên biến lại cùng tên thuộc tính DataSource của report, nên đoạn code sau sẽ bị hiểu sai:


this.DataSource = DataSource; //this.DataSource là biến chứ k phải thuộc tính của report


Thứ 2, không có đoạn code gắn nguồn dữ liệu cho report:


private void BindData(List<ChiTietBangLuongTamUng> dataSource)
{
try
{
this.DataSource = dataSource;
cellFullName.DataBindings.Add("Text", dataSource, "NhanVien.FullName");
cellLuongTamUng.DataBindings.Add("Text", dataSource, "MucLuongTamUng");
}
catch (Exception exc)
{
string error = exc.ToString();
}
}


...và như vậy, sửa lại xíu trong hàm SetReportParameters


public void SetReportParameters(int Year, short Month, int MaDonVi)
{
KyBaoCaoInfo kyluong = GetKyLuong(Year, Month);
List<ChiTietBangLuongTamUng> dataSource = new List<ChiTietBangLuongTamUng>();

if (kyluong != null)
dataSource = kyluong.BangLuong.GetBangLuongTamUngByDonVi(MaDonV i);

stt = 0;
BindData(dataSource);
}

anhdh
22-03-2011, 10:22
Bạn cho mình hỏi thêm là mình muốn khi bấm nút in thì chương trình in ngay lập tức một report (hóa đơn chẳng hạn) mà không phải preview nữa.

qhhqnavy
07-04-2011, 22:09
cám ơn mấy anh hai nhé.
em cũng đang tìm mấy cái này

jackytoral
19-07-2013, 14:57
anhdh!

mình vẫn không hiểu làm sau để thể hiện dữ liệu lên, mình đang sử dụng Entity Framework.

bạn có thể hướng dẫn cụ thể bằng hình ảnh không?

nếu được mình cảm ơn bạn nhiều lắm