Phần 5: Tạo báo cáo với C#


Chức năng báo cáo (Report) là chức năng yêu cầu cần có ở hầu hết các ứng dụng lập trình với cơ sở dữ liệu. Ưu điểm của báo cáo để cho người sử dụng có tổng kết nhanh tình hình kinh doanh, có thể in ấn và xuất ra các định dạng dữ liệu khác một cách dễ dàng. Các loại báo cáo thường gặp như báo cáo doanh thu theo tháng, theo quý hoặc theo năm, báo cáo hàng tồn kho …
Trong bài này chúng ta sẽ tiếp tục phần tạo báo cáo với Cơ sở dữ liệu đã trình bày ở phần 4.


Nội dung


Yêu cầu bài toán

Cho cơ sở dữ liệu QLBanHang có các bảng:

tblMatHang( MaSP nchar(5), TenSP nvarchar(30), NgaySX Date, NgayHH Date, DonVi nvarchar(10), DonGia float , GhiChu nvarchar(200))

tblNhaCC(MaNhaCC nchar(5), TenNhaCC nvarchar(50), DiaChi nvarchar(200), MaSoThue nvarchar(15), TaiKhoan nvarchar(15), DienThoai nvarchar(11))

tblHangNhap(MaSP nchar(5), MaNhaCC nchar(5), SoLuong int, DonGia float, SoHD nvarchar(10), NgayGH Date)

Tạo các báo cáo làm các chức năng sau:

  • Báo cáo thống kê các mặt hàng nhập trong ngày
  • Báo cáo danh sách các mặt hàng theo từng hoá đơn, cho phép nhập vào số hoá đơn.
  • Báo cáo 10 nhà cung cấp có số tiền nhập cao nhất

>Xem hướng dẫn tạo Database trong VisualStudio


Hướng dẫn tạo báo cáo

> Xem hướng dẫn chi tiết.
Trong hướng dẫn ở trên, chúng ta chỉ tạo báo cáo cho một bảng. Với báo cáo lấy dữ liệu từ nhiều bảng, để đơn giản chúng ta có thể tạo Stored Procedure rồi sau đó gọi tên Procedure đó trong code.
Ví dụ báo cáo thống kê các mặt hàng nhập trong ngày câu lệnh sẽ như sau:


CREATE PROCEDURE dbo.BCMHNhapTheoNgay
	@NgayGH DateTime
AS
	SELECT A.MaSP, TenSP, TenNhaCC,DiaChi,SoLuong,A.DonGia,SoHD
	FROM tblHangNhap as A, tblMatHang as B, tblNhaCC C
	WHERE A.MaSP = B.MaSP and A.MaNhaCC = C.MaNhaCC and NgayGH = @NgayGH

  • Xem video hướng dẫn tạo Stored Procedure

  • Xem video hướng dẫn tạo mẫu báo cáo

  • Xem video hướng dẫn code hiển thị báo cáo


Tham khảo thêm

Có thể bạn sẽ thích…

23 phản hồi

  1. nguyenthituoi viết:

    thầy ơi trong nhóm bọn em có 3 người chia phần mỗi bạn làm 1 form con làm thế nào để ghép bài ạ bọn e ghép toàn báo lỗi thôi ạ

    • Phan Tiến viết:

      Em gửi cho mình xem thông báo lỗi gì?
      Chú ý khi ghép bài, vì mỗi bạn làm một form khác nhau trong đó có kết nối tới CSDL thì khi copy code sang, các em phải chỉnh sửa lại chuỗi kết nối tới CSDL.
      Để copy ít bị lỗi hơn, em mở 2 project đồng thời rồi ở cửa sổ Solution Explorer, em copy form từ project này rồi paste tới project kia.

  2. nguyenthituoi viết:

    thầy ơi thầy cho em hỏi là trong phần from thống kế báo cáo của e có 2 lỗi thầy xem hộ e với ạ

    namespace BaiTapLon
    {
    public partial class frmBCMHnhap : Form
    {
    public frmBCMHnhap()
    {
    InitializeComponent();
    }

    private void frmBCMHnhap_Load(object sender, EventArgs e)
    {

    this.rpvBCMHNhap.RefreshReport();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    SqlConnection con = new SqlConnection();
    con.ConnectionString = Properties.Settings.Default.QuanlibanhangConnectionString;
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = “BCMMHnhapTheoThang”;
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Connection = con;
    cmd.Parameters.Add(new SqlParameter(“@NgayGH”,dtpNgayGH.Value.Date));
    //khai báo dataset để lấy dữ liệu
    DataSet ds = new DataSet();
    SqlDataAdapter dap = new SqlDataAdapter(cmd);
    dap.Fill(ds);
    //thiết lập báo cáo
    rpvBCMHNhap.ProcessingMode = ProcessingMode.Local;
    rpvBCMHNhap.LocalReport.reportPath = “rptBCMHNhap.rdlc”;

    if (ds.Tables[0].Rows.Count > 0)

    {
    ReportDataSource rds = new ReportDataSource();
    rds.Name = “dsMaHangNhap”;
    rds.Value = ds.Tables[0];
    //gắn lên mẫu báo cáo
    rpvBCMHNhap.LocalReport.DataSources.Clear();
    rpvBCMHNhap.LocalReport.DataSources.Add(rds);
    rpvBCMHNhap.RefreshReport();

    }

    }
    }
    }

  3. nguyenthituoi viết:

    Error 1 The name ‘dtpNgayGH’ does not exist in the current context D:\SV\BaiTapLon\BaiTapLon\frmBCMHnhap.cs 37 59 BaiTapLon

    Error 2 ‘Microsoft.Reporting.WinForms.LocalReport’ does not contain a definition for ‘reportPath’ and no extension method ‘reportPath’ accepting a first argument of type ‘Microsoft.Reporting.WinForms.LocalReport’ could be found (are you missing a using directive or an assembly reference?) D:\SV\BaiTapLon\BaiTapLon\frmBCMHnhap.cs 44 37 BaiTapLon

    • Phan Tiến viết:

      Lỗi 1: dtpNgayGH là control DateTimePicker để nhập vào ngày tháng. E phải kéo vào form rồi đặt tên thuộc tính Name la dtpNgayGH
      Lỗi 2: em sử dụng thuộc tính không đúng. Tên thuộc tính là ReportPath

  4. duongminhtu viết:

    e thưa thầy e có làm một form đổi mật khẩu với code như sau:
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Data.SqlClient;

    namespace BTLQuanLyKho.View
    {
    public partial class frmDoiMK : Form
    {
    public static string pass;
    // chuỗi kết nối
    string strConnection = @”Data Source=USERNAM-VJEJT5S\DUONGMINHTU;Initial Catalog=QLKho;Integrated Security=True”;
    SqlConnection conn;
    SqlCommand cmd;
    //string sql = “SELECT * FROM [QLKho].[dbo].[DangNhap]”;

    public frmDoiMK()
    {
    InitializeComponent();
    }

    private void textBox2_TextChanged(object sender, EventArgs e)
    {

    }

    private Boolean kiemtrarong()
    {
    Boolean kq = false;
    if (txtMkcu.Text == “”)
    {
    MessageBox.Show(“Bạn chưa nhập mật khẩu cũ!”);
    txtMkcu.Focus();
    kq = true;
    }
    else if (txtMkmoi.Text == “”)
    {
    MessageBox.Show(“Bạn chưa nhập mật khẩu mới!”);
    txtMkmoi.Focus();
    kq = true;
    }
    else if (txtNhaplai.Text == “”)
    {
    MessageBox.Show(“Bạn chưa nhập lại mật khẩu mới!”);
    txtNhaplai.Focus();
    kq = true;
    }
    return kq;
    }

    private void btnDoimk_Click(object sender, EventArgs e)
    {
    if (kiemtrarong() == false)
    {
    if (txtMkcu.Text == frmDoiMK.pass)
    {
    if (txtMkmoi.Text == txtNhaplai.Text)
    {
    string matkhau = txtMkmoi.Text;
    string capnhat = “UPDATE DangNhap SET Password='” + matkhau + “‘ WHERE Username=’admin’;”;
    conn = new SqlConnection(strConnection);
    cmd = new SqlCommand(capnhat, conn);
    conn.Open();
    cmd.ExecuteNonQuery();
    MessageBox.Show(“Đổi mật khẩu thành công”, “Thông báo”);
    conn.Close();
    }
    else
    {
    MessageBox.Show(“Mật khẩu xác nhận không đúng vui lòng kiểm tra lại!”, “Thông báo”, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
    txtMkmoi.Text = “”;
    txtNhaplai.Text = “”;
    }
    }
    else
    {
    MessageBox.Show(“Mật khẩu hiện tại không đúng vui lòng kiểm tra lại!”);
    txtMkcu.Text = “”;
    txtMkmoi.Text = “”;
    txtNhaplai.Text = “”;
    }
    }
    }

    private void btnThoat_Click(object sender, EventArgs e)
    {
    this.Close();
    }

    private void frmDoiMK_Load(object sender, EventArgs e)
    {

    }

    }
    }
    nhưng e không biết cách làm để đổ data của pass cũ để so sánh với pass cũ mình nhập có giống nhau không nên nó toàn thông báo “mật khẩu hiện tại không đúng”
    thầy giúp e sửa code với ạ
    em xin cảm ơn

    • Phan Tiến viết:

      Theo code bạn gửi thì bạn thiết kế Form có 3 TextBox:
      – 1 TextBox cho nhập mật khẩu cũ
      – 1 TextBox cho nhập mật khẩu mới
      – 1 TextBox bắt người sử dụng nhập lại mật khẩu mới
      Nhưng câu lệnh if (txtMkcu.Text == frmDoiMK.pass) => Biến pass này em lấy dữ liệu ở đâu? Làm sao để so sánh được chứ nên luôn luôn nó nhày đến thông báo lỗi như của em thôi.

  5. Nguyễn Văn Đạo viết:

    ở chỗ đáp.Fill(đs); nó báo lỗi này em phải khắc phục như thế nào thưa thầy?
    An unhandled exception of type ‘System.Data.SqlClient.SqlException’ occurred in System.Data.dll

    Additional information: Procedure or function ‘BCPNTheoNgay’ expects parameter ‘@NgayNhap’, which was not supplied.

    • Phan Tiến viết:

      Trong câu lệnh SQL mình có một tham số truyền vào là @NgayNhap => bạn cần truyền vào ngày này. Bạn xem lại code nhé.

  6. Trần Anh Sơn viết:

    thầy cho em hỏi em có một database đã tạo bằng sql server thì làm thế nào để sử dụng nó như tỏng phần 4.4 của thầy

    • Phan Tiến viết:

      Em vào cửa sổ Server Explorer, kích vào biểu tượng có hình Database có phích cắm (Connect to Database), sau đó có cửa sổ Choose Data Source hiển thị ra => Chọn Microsoft SQL Server =>Rồi em điền các thông số như tên Server, User, Pass và tên Database của em vào là sẽ làm được giống như phần 4.4.

  7. Tiến Thành viết:

    thầy cho em hỏi, trong bảng lọc thống kê của em, em muốn thêm một thuộc tính lọc theo ngày (vd: tìm các hóa đơn từ ngày X đến ngày Y), em có viết một Store để lọc, nhưng khi truyền dữ liệu từ C# vào SQL thì không được nhận do type date của winform C# và SQL server không giống nhau. Thầy có thể hướng dẫn em cách chỉnh sửa không ạ

    • Phan Tiến viết:

      Gửi cho mình code store và phần code c# em truyền vào store.

      • Tiến Thành viết:

        Dạ đây là store
        create proc spTongSoHoaDon
        (
        @Ngay1 date,
        @Ngay2 date
        )
        as
        Begin
        select COUNT(MaHD)
        from HoaDon
        where Ngay between @Ngay1 and @Ngay2
        End

        còn phần này là code C#:
        public DataTable DemHoaDon_Ngay(string Ngay1, string Ngay2)
        {
        return db.ExecuteQueryDataSet(“exec spTongSoHoaDon ” + Ngay1 + “,” + Ngay2 + “”, CommandType.Text, null);
        }
        public DataTable ExecuteQueryDataSet(string strSQL, CommandType ct, params SqlParameter[] p)
        {
        if (conn.State == ConnectionState.Open)
        conn.Close();
        conn.Open();
        comm.CommandText = strSQL;
        comm.CommandType = ct;
        da = new SqlDataAdapter(comm);
        DataTable ds = new DataTable();
        da.Fill(ds);
        return ds;
        }

        • Phan Tiến viết:

          Đoạn code em viết rối quá.
          Em chỉ cần viết như sau:
          public DataTable ExecuteQueryDataSet(string sql, string Ngay1, string Ngay2)
          {
          if (conn.State == ConnectionState.Open)
          conn.Close();
          conn.Open();
          comm.CommandText = sql;
          comm.CommandType = CommandType.StoreProcedured;
          comm.Parameters.AddWithValue(“@Ngay1”,Ngay1);
          comm.Parameters.AddWithValue(“@Ngay2”,Ngay2);
          da = new SqlDataAdapter(comm);
          DataTable ds = new DataTable();
          da.Fill(ds);
          return ds;
          }

  8. Cuong viết:

    thầy ơi
    Cho em hỏi làm sao để thêm sản phẩm vào hoá đơn cùng lúc 2 bảng hoá đơn với chi tiết hoá đơn vậy thầy
    Code như thế nào v thầy
    em muốn chọn sảnphẩm sau đó thêm vào bên chi tiết hoá đơn gồm có MaSP,TenSP,Giá,SL,Thành Tiền.
    khi load lại hoá đơn có sao để k hiện lại hoá đơn cũ trên girlConTrol
    Em cảm ơn thầy

    • Phan Tiến viết:

      – Để thêm dữ liệu vào 2 bảng cùng một lúc, em viết 2 câu lệnh SQL insert. Khi kích nút thêm dữ liệu thì sẽ thêm truyền từng câu lệnh SQL vào và thực hiện ExcuteNonQuery() với từng câu lệnh SQL đó. Chú ý nếu 2 bảng em Insert có quan hệ cha – con (ví dụ Hoá Đơn và Hoá Đơn chi tiết) thì em Insert vào bảng Hoá Đơn trước rồi sau đó mới Insert vào bảng hoá đơn chi tiết.
      Ví dụ viết vào sự kiện btnThem_Click(….)
      SqlCommand cmd = new SqlCommand();
      cmd.CommandText = sql1;//Câu lệnh insert vào Hoá đơn
      cmd.Connection = con;//Đối tượng Connection
      cmd.ExecuteNonQuery();
      cmd.CommandText = sql2;//Câu lệnh insert vào Hoá đơn chi tiết
      cmd.Connection = con;//Đối tượng Connection
      cmd.ExecuteNonQuery();

  9. Phạm Tươi viết:

    thầy ơi, phần tblHangNhap thì của e chia làm tblChitietHDN và tblHoadonnhap thì phải làm sao thầy?

  10. Thắng Nguyễn viết:

    Thầy cho em hỏi là làm thế nào để form cho người dùng chọn tháng, năm và in ra báo cáo từng ngày trong tháng đó ạ? vì êm thấy datetimepicker chỉ cho phép chọn ngày, tháng, năm chứ ko cho chọn riêng tháng,năm!

  11. Trang viết:

    thầy ơi cho em hỏi muốn làm báo cáo mặt hàng bán chạy nhất trong tháng thì làm như thế nào ah, và em code như video hướng dẫn nhưng lúc chọn ngày thì không lọc ra ngày mình đã chọn mà sổ ra tất cả các ngày nhập hàng ah lỗi này sửa như thế nào ah.

Trả lời Tiến Thành Hủy

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *