Xây dựng chương trình quản lý bán hàng bằng C#


Với sự ra đời của .Net và Visual Studio của Microsoft, việc xây dựng một chương trình quản lý với cơ sở dữ liệu đã đơn giản hơn rất nhiều. Bài này hướng dẫn bạn cách tạo ứng dụng quản lý bán hàng lưu niệm sử dụng ngôn ngữ lập trình C# và hệ quản trị cơ sở dữ liệu SQL Server.

Nội dung chính

  1. Yêu cầu
  2. Thiết kế cơ sở dữ liệu
  3. Thiết kế giao diện
  4. Xử lý sự kiện

1. Yêu cầu

Xây dựng chương trình quản lý cửa hàng Bán hàng lưu niệm sư dụng ngôn ngữ C# và hệ quản trị cơ sở dữ liệu SQL Server. Hệ thống có các chức năng cơ bản như quản lý mặt hàng, quản lý khách hàng, quản lý hoá đơn bán. Cửa hàng có thể có một hoặc nhiều người bán, với mỗi hoá đơn bán hàng phải có thông tin của người bán cho khách hàng cụ thể.

2. Thiết kế cơ sở dữ liệu

a) Tạo ứng dụng mới

– Tên project: QuanLyBanHang
b) Tạo cơ sở dữ liệu

– Trong cửa sổ  Solution Explorer, nháy phải chuột lên tên ứng dụng, chọn Add ->New Item… Chọn Data -> Service-based Database (hoặc SQL Database trong Visual Studio Net 2005).

– Đặt tên cơ sở dữ liệu: Quanlybanhang.mdf

qlbh1

– Tạo các bảng: Trong cửa sổ Server Explorer, chọn cơ sở dữ liệu, nháy phải lên Tables, chọn Add New Table…

Bảng tblChatlieu (chất liệu)

tblchatlieu

Bảng tblKhach (khách)

tblkhach

Bảng tblHang (hàng)

tblhang

Bảng tblNhanvien (nhân viên)

tblnhanvien

Bảng tblHDBan (hoá đơn bán)

tblhoadonban

Bảng tblChitietHDBan (chi tiết hoá đơn bán)

tblcthdb

Quan hệ giữa các bảng (Relationship)

quanhebang

Chú ý:

– Để cho phép người dùng sửa đổi thông tin của các bảng, thực hiện như sau:

Vào Tools -> Options, chọn Database Tools ->Table and Database Designers, bỏ dấu chọn ở mục Prevent saving changes that require table re-creation.

– Xoá bản sao cơ sở dữ liệu: trong cửa sổ Solution Explorer, nháy phải lên file dữ liệu (Quanlybanhang.mdf), chọn Exclude From Project

– Sao chép file dữ liệu (Quanlybanhang.mdf) vào thư mục bin\Debug (chứa file Quanlybanhang.exe) (phải đóng project trước khi thực hiện sao chép file dữ liệu).

– Thực hiện kết nối dữ liệu:

Trong Server Explorer, nháy phải Data Connections, chọn Add Connection, chọn Microsoft SQL Server Database File, nhấn Continue. Trong hộp thoại Add Connection, nhấn Browse tìm file dữ liệu (Quanlybanhang.mdf) (đã sao chép vào thư mục bin\Debug). Nhấn Test Connection, nếu thành công sẽ xuất hiện thông báo “Test connection succeeded”.

– Sao lưu dữ liệu (Quanlybanhang.mdf) bằng cách sao chép file dữ liệu này vào thư mục chứa các file mã nguồn (*.cs) của project.

– Nên tạo thư mục chứa ảnh: nháy phải lên tên project Quanlybanhang, chọn Add, chọn New Folder, đặt tên thư mục là Images. Nháy phải lên thư mục Images, chọn Add, chọn Existing Item và duyệt chọn các file ảnh, nhấn Add để thêm vào thư mục Images.

3. Thiết kế giao diện

a) Form chính

– Tên form: frmMain

 frmchinh

Các thành phần của menu

Name Text
mnuFile Tập tin
mnuThoat     Thoát
mnuDanhmuc Danh mục
mnuChatlieu      Chất liệu
mnuNhanvien      Nhân viên
mnuKhachhang      Khách hàng
mnuHanghoa      Hàng hoá
mnuHoadon Hoá đơn
mnuHoadonban      Hoá đơn bán
mnuTimkiem Tìm kiếm
mnuFindHoadon      Hoá đơn
mnuFindHang      Hàng
mnuFindKhachhang      Khách hàng
mnuBaocao Báo cáo
mnuBCHangton      Hàng tồn
mnuBCDoanhthu      Doanh thu
mnuTrogiup Trợ giúp
mnuHientrogiup      Trợ giúp
 mnuVainet      Vài nét

b) Form Danh mục chất liệu

 Tên form: frmDMChatlieu

 frmdanhmuc

Các thành phần trên form:

Điều khiển Name Text
TextBox txtMachatlieu
txtTenchatlieu
Button btnThem Thêm
btnXoa Xoá
btnSua Sửa
btnLuu Lưu
btnBoqua Bỏ qua
btnDong Đóng
DataGridView DataGridView

c) Form Danh mục nhân viên

 Tên form: frmDMNhanvien

frmdanhmucnv

Các thành phần trên form:

Điều khiển Name Text
TextBox txtManhanvien
txtTennhanvien
txtDiachi
Button btnThem, btnXoa, btnSua, btnLuu, btnBoqua, btnDong
CheckBox chkGioitinh Nam
MaskedTextBox mskDienthoai Mask: Phone Number
mskNgaysinh Mask: Short Date
DataGridView DataGridView

d) Form Danh mục khách hàng

 Tên form: frmDMKhachhang

frmdanhmuckh

Các thành phần trên form:

Điều khiển Name Text
TextBox txtMakhach
txtTenkhach
txtDiachi
Button btnThem, btnXoa, btnSua, btnLuu, btnBoqua, btnDong
CheckBox chkGioitinh Nam
MaskedTextBox mskDienthoai Mask: Phone Number
DataGridView DataGridView

e) Form Danh mục hàng hoá

 Tên form: frmDMHang

frmdanhmuchh

Các thành phần trên form

Điều khiển Name
TextBox txtMahang, txtTenhang, txtSoluong,  txtDongianhap, txtDongiaban, txtAnh,  txtGhichu
ComboBox cboMachatlieu
PictureBox picAnh (thuộc tính SizeMode = Zoom)
DataGridView DataGridView
Button btnThem, btnXoa, btnSua, btnLuu, btnBoqua,

btnTimkiem, btnHienthi, btnDong, btnOpen

f) Form Hoá đơn bán hàng

 Tên form: frmHoadonBan

frmhoadonbh

Các thành phần trên form

Điều khiển Name Text
Label lblBangchu Bằng chữ:
TextBox txtMaHDBan, txtNgayban, txtTennhanvien,txtTenkhach, txtDiachi, txtDienthoai, txtTongtien, txtTenhang, txtDongiaban, txtSoluong, txtGiamgia, txtThanhtien.
ComboBox cboManhanvien, cboMakhach, cboMahang, cboMaHDBan.
DataGridView DataGridView
Button btnNgay, btnThemmoi, btnLuu, btnXoa, btnInhoadon,

btnDong,  btnTimkiem

g) Form Tìm kiếm hoá đơn

 Tên form: frmTimHDBan

frmtkhd

Các thành phần trên form

Điều khiển Name
TextBox txtMaHDBan, txtThang, txtNam, txtManhanvien,

txtMakhach, txtTongtien.

DataGridView DataGridView
Button btnTimkiem, btnTimlai, btnDong

 

Chú ý:

– Tất cả các form (trừ frmMain), thuộc tính StartPostion = CenterParent, ShowInTaskbar = False

4. Xử lý sự kiện

4.1. Lớp Functions

– Chứa các phương thức dùng chung

– Trong khung Solution Explorer, nháy phải lên tên project, chọn Add -> New Folder, đặt tên thư mục là Class

– Nháy phải thư mục Class, nháy phải chọn Add -> Class, đặt tên Functions.cs

– Trong class Functions:

+ Khai báo bổ sung các thư viện:


using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;     // Sử dụng đối tượng MessageBox


+ Viết 2 phương thức: connect() và disconnect()


namespace QuanLyBanHang.Class
{
    class Functions
    {
        public static SqlConnection Con;  //Khai báo đối tượng kết nối        

        public static void Connect()
        {
            Con = new SqlConnection();   //Khởi tạo đối tượng
            Con.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=" + Application.StartupPath + @"\Quanlybanhang.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
            Con.Open();                  //Mở kết nối
            //Kiểm tra kết nối
            if (Con.State == ConnectionState.Open)
                MessageBox.Show("Kết nối thành công");
            else MessageBox.Show("Không thể kết nối với dữ liệu");

        }
        public static void Disconnect()
        {
            if (Con.State == ConnectionState.Open)
            {
                Con.Close();   	//Đóng kết nối
                Con.Dispose(); 	//Giải phóng tài nguyên
                Con = null;
            }
        }
}


4.2. Form frmMain

a) Sự kiện frmMain_Load


private void frmMain_Load(object sender, EventArgs e)
        {
            Class.Functions.Connect(); //Mở kết nối
        }


b) Sự kiện mnuThoat_Click


private void mnuThoat_Click(object sender, EventArgs e)
        {
            Class.Functions.Disconnect(); //Đóng kết nối
            Application.Exit(); //Thoát
        }


c) Hiển thị các form khác:

Cú pháp:

<Tên lớp form> <Tên đối tượng> = new <Tên lớp form>(); //Khởi tạo đối tượng

<Tên đối tượng>.ShowDialog(); //Hiển thị dưới dạng hộp thoại

Hoặc <Tên đối tượng>.Show(); //Hiện thị dạng thông thường

+ Hiển thị form frmChatlieu


private void mnuChatlieu_Click(object sender, EventArgs e)
        {
            frmDMChatlieu frmChatlieu = new frmDMChatlieu(); //Khởi tạo đối tượng
            frmChatlieu.ShowDialog(); //Hiển thị
        }


4.3. Form Chất liệu

a) Khai báo

– Khai báo


using System.Data.SqlClient; //Sử dụng thư viện để làm việc SQL server
using QuanLyBanHang.Class; //Sử dụng class Functions.cs


– Khai báo biến toàn cục


DataTable tblCL; //Chứa dữ liệu bảng Chất liệu

b) Sự kiện frmDMChatlieu_Load


private void frmDMChatlieu_Load(object sender, EventArgs e)
        {
            txtMachatlieu.Enabled = false;
            btnLuu.Enabled = false;
            btnBoqua.Enabled = false;
            LoadDataGridView(); //Hiển thị bảng tblChatlieu
        }


Trong đó, phương thức LoadDataGridView có tác dụng lấy dữ liệu từ bảng tblChatlieu đổ vào DataGridView
c) Phương thức LoadDataGridView


private void LoadDataGridView()
        {
            string sql;
            sql = "SELECT Machatlieu, Tenchatlieu FROM tblChatlieu";
            tblCL = Class.Functions.GetDataToTable(sql); //Đọc dữ liệu từ bảng
            DataGridView.DataSource = tblCL; //Nguồn dữ liệu            
            DataGridView.Columns[0].HeaderText = "Mã chất liệu";
            DataGridView.Columns[1].HeaderText = "Mã chất liệu";
            DataGridView.Columns[0].Width = 100;
            DataGridView.Columns[1].Width = 300;
            DataGridView.AllowUserToAddRows = false; //Không cho người dùng thêm dữ liệu trực tiếp
            DataGridView.EditMode = DataGridViewEditMode.EditProgrammatically; //Không cho sửa dữ liệu trực tiếp
        }


Với GetDataToTable được viết trong lớp Functions có tác dụng thực hiện câu lệnh SQL truy vấn dữ liệu từ CSDL đổ vào đối tượng bảng.
d) Phương thức GetDataToTable

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:


//Lấy dữ liệu vào bảng
        public static DataTable GetDataToTable(string sql)
        {
            SqlDataAdapter MyData = new SqlDataAdapter(); //Định nghĩa đối tượng thuộc lớp SqlDataAdapter
            //Tạo đối tượng thuộc lớp SqlCommand
            MyData.SelectCommand = new SqlCommand();
            MyData.SelectCommand.Connection = Functions.Con; //Kết nối cơ sở dữ liệu
            MyData.SelectCommand.CommandText = sql; //Lệnh SQL
            //Khai báo đối tượng table thuộc lớp DataTable
            DataTable table = new DataTable();
            MyData.Fill(table);
            return table;
        }


Hoặc có thể thực hiện ngắn gọn bằng cách gán tham số khi khai báo đối tượng như sau:


//Lấy dữ liệu vào bảng
        public static DataTable GetDataToTable(string sql)
        {
            SqlDataAdapter MyData = new SqlDataAdapter(sql, Con); //Định nghĩa đối tượng thuộc lớp SqlDataAdapter
            //Khai báo đối tượng table thuộc lớp DataTable
            DataTable table = new DataTable();
            MyData.Fill(table); //Đổ kết quả từ câu lệnh sql vào table
            return table;
        }


e) Phương thức dataGridView_Click

Phương thức này có tác dụng lấy nội dung dòng dữ liệu người dùng chọn trong lưới DataGridView và hiển thị lên các điều khiển trên Form.


private void dataGridView_Click(object sender, EventArgs e)
        {
            if (btnThem.Enabled == false)
            {
                MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMachatlieu.Focus();
                return;
            }
            if (tblCL.Rows.Count == 0) //Nếu không có dữ liệu
            {
                MessageBox.Show("Không có dữ liệu!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            txtMachatlieu.Text = DataGridView.CurrentRow.Cells["Machatlieu"].Value.ToString();
            txtTenchatlieu.Text = DataGridView.CurrentRow.Cells["Tenchatlieu"].Value.ToString();
            btnSua.Enabled = true;
            btnXoa.Enabled = true;
            btnBoqua.Enabled = true;
        }


f) Phương thức btnThem_Click


    private void btnThem_Click(object sender, EventArgs e)
        {
            btnSua.Enabled = false;
            btnXoa.Enabled = false;
            btnBoqua.Enabled = true;
            btnLuu.Enabled = true;
            btnThem.Enabled = true;
            btnThem.Enabled = false;
            ResetValue(); //Xoá trắng các textbox
            txtMachatlieu.Enabled = true; //cho phép nhập mới
            txtMachatlieu.Focus();
        }


Với ResetValues là phương thức của form frmDMChatlieu có tác dụng xóa hết dữ liệu trong các điều khiển trên Form.
g) Phương thức ResetValues


private void ResetValue()
        {
            txtMachatlieu.Text = "";
            txtTenchatlieu.Text = "";
        }


h) Phương thức btnLuu_Click

Phương thức này có tác dụng kiểm tra thông tin người dùng nhập vào các điều khiển trên Form trong trường hợp thêm mới và lưu các thông tin đó vào CSDL.


private void btnLuu_Click(object sender, EventArgs e)
        {
            string sql; //Lưu lệnh sql
            if (txtMachatlieu.Text.Trim().Length == 0) //Nếu chưa nhập mã chất liệu
            {
                MessageBox.Show("Bạn phải nhập mã chất liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMachatlieu.Focus();
                return;
            }
            if(txtTenchatlieu.Text.Trim().Length==0) //Nếu chưa nhập tên chất liệu
            {
                MessageBox.Show("Bạn phải nhập tên chất liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtTenchatlieu.Focus();
                return;
            }
            sql = "Select MaChatlieu From tblChatlieu where MaChatlieu=N'" + txtMachatlieu.Text.Trim() + "'";
            if (Class.Functions.CheckKey(sql))
            {
                MessageBox.Show("Mã chất liệu này đã có, bạn phải nhập mã khác", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtMachatlieu.Focus();                
                return;
            }

            sql = "INSERT INTO tblChatlieu VALUES(N'" + 
                txtMachatlieu.Text + "',N'" + txtTenchatlieu.Text +"')";
            Class.Functions.RunSQL(sql); //Thực hiện câu lệnh sql
            LoadDataGridView(); //Nạp lại DataGridView
            ResetValue();
            btnXoa.Enabled = true;
            btnThem.Enabled = true;
            btnSua.Enabled = true;
            btnBoqua.Enabled = false;
            btnLuu.Enabled = false;
            txtMachatlieu.Enabled = false;
        }


Với CheckKeyRunSQL là các phương thức được viết trong lớp Functions.

CheckKey có tác dụng kiểm tra khóa trùng, RunSQL có tác dụng thực thi các câu lệnh SQL.
i) Hàm CheckKey

Mở cửa sổ lớp Class Functions viết mã lệnh:


//Hàm kiểm tra khoá trùng
        public static bool CheckKey(string sql)
        {
            SqlDataAdapter MyData = new SqlDataAdapter(sql,Con);
            DataTable table = new DataTable();
            MyData.Fill(table);
            if (table.Rows.Count > 0)
                return true;
            else return false;
        }


j) Phương thức RunSQL

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:


//Hàm thực hiện câu lệnh SQL
        public static void RunSQL(string sql)
        {
            SqlCommand cmd; //Đối tượng thuộc lớp SqlCommand
            cmd = new SqlCommand();
            cmd.Connection = Con; //Gán kết nối
            cmd.CommandText = sql; //Gán lệnh SQL
            try
            {
                cmd.ExecuteNonQuery(); //Thực hiện câu lệnh SQL
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            cmd.Dispose();//Giải phóng bộ nhớ
            cmd = null;
        }


Chú ý: Đối tượng SqlCommand có hai phương thức để thực thi câu lệnh SQL, trong đó:

  • ExecuteReader: thực thi câu lệnh SQL có dữ liệu trả về, ví dụ SELECT.
  • ExecuteNoneQuery: thực thi các câu lệnh SQL không yêu cầu trả về tập dữ liệu, ví dụ: INSERT, UPDATE, DELETE.

k) Phương thức btnSua_Click

Khi người dùng nháy chuột vào một dòng bản ghi bất kỳ trên lưới để hiển thị dữ liệu của bản ghi đó lên Form thì người dùng có thể chỉnh sửa các thông tin đó.

Phương thức btnSua_Click có tác dụng lưu các thông tin người dùng đã sửa vào CSDL.


private void btnSua_Click(object sender, EventArgs e)
        {
            string sql; //Lưu câu lệnh sql
            if (tblCL.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtMachatlieu.Text == "") //nếu chưa chọn bản ghi nào
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtTenchatlieu.Text.Trim().Length==0) //nếu chưa nhập tên chất liệu
            {
                MessageBox.Show("Bạn chưa nhập tên chất liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            sql = "UPDATE tblChatlieu SET Tenchatlieu=N'" + 
                txtTenchatlieu.Text.ToString() + 
                "' WHERE Machatlieu=N'" + txtMachatlieu.Text + "'";
            Class.Functions.RunSQL(sql);
            LoadDataGridView();
            ResetValue();

            btnBoqua.Enabled = false;
        }


l) Phương thức btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
        {
            string sql;
            if (tblCL.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtMachatlieu.Text == "") //nếu chưa chọn bản ghi nào
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (MessageBox.Show("Bạn có muốn xoá không?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                sql = "DELETE tblChatlieu WHERE Machatlieu=N'" + txtMachatlieu.Text + "'";
                Class.Functions.RunSqlDel(sql);
                LoadDataGridView();
                ResetValue();
            }
        }


m) Phương thức RunSQLDel

Phương thức RunSQLDel tương tự như RunSQL nhưng trong trường hợp xóa dữ liệu nếu dữ liệu đang được dùng bởi một đối tượng khác thì không được phép xóa.

Mở cửa sổ lớp Class Functions viết mã lệnh như sau:


public static void RunSqlDel(string sql)
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = Functions.Con;
            cmd.CommandText = sql;
            try
            {
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Dữ liệu đang được dùng, không thể xoá...", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                MessageBox.Show(ex.ToString());
            }
            cmd.Dispose();
            cmd = null;
        }


n) Phương thức btnBoqua_Click

Phương thức này được gọi khi người dùng muốn hủy bỏ các chức năng Thêm mới hoặc Sửa dữ liệu.


private void btnBoqua_Click(object sender, EventArgs e)
        {
            ResetValue();
            btnBoqua.Enabled = false;
            btnThem.Enabled = true;
            btnXoa.Enabled = true;
            btnSua.Enabled = true;
            btnLuu.Enabled = false;
            txtMachatlieu.Enabled = false;
        }


o) Phương thức dùng phím Enter thay cho phím Tab


private void txtMachatlieu_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                SendKeys.Send("{TAB}");
        }


Thực hiện tương tự cho txtTenchatlieu_KeyUp
p) Phương thức btnDong_Click


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


 

4.4. Form Danh mục Nhân viên

a) Khai báo

– Thư viện:


using System.Data;
using System.Data.SqlClient;
using QuanLyBanHang.Class;


– Biến:


DataTable tblNV; //Lưu dữ liệu bảng nhân viên

b) Phương thức frmDMNhanvien_Load


private void frmDMNhanvien_Load(object sender, EventArgs e)
        {
            txtManhanvien.Enabled = false;
            btnLuu.Enabled = false;
            btnBoqua.Enabled = false;
            LoadDataGridView();
        }


c) Phương thức LoadDataGridView – Hiển thị dữ liệu lên lưới


public void LoadDataGridView()
        {
            string sql;
            sql = "SELECT Manhanvien,Tennhanvien,Gioitinh,Diachi,Dienthoai,Ngaysinh FROm tblNhanvien";
            tblNV = Functions.GetDataToTable(sql); //lấy dữ liệu
            DataGridView.DataSource = tblNV;
            DataGridView.Columns[0].HeaderText = "Mã nhân viên";
            DataGridView.Columns[1].HeaderText = "Tên nhân viên";
            DataGridView.Columns[2].HeaderText = "Giới tính";
            DataGridView.Columns[3].HeaderText = "Địa chỉ";
            DataGridView.Columns[4].HeaderText = "Điện thoại";
            DataGridView.Columns[5].HeaderText = "Ngày sinh";
            DataGridView.Columns[0].Width = 100;
            DataGridView.Columns[1].Width = 150;
            DataGridView.Columns[2].Width = 100;
            DataGridView.Columns[3].Width = 150;
            DataGridView.Columns[4].Width = 100;
            DataGridView.Columns[5].Width = 100;
            DataGridView.AllowUserToAddRows = false;
            DataGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
        }


d) Phương thức DataGridView_Click


private void dataGridView_Click(object sender, EventArgs e)
        {
            if (btnThem.Enabled == false)
            {
                MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo",  MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtManhanvien.Focus();
                return;
            }
            if (tblNV.Rows.Count == 0)
            {
                MessageBox.Show("Không có dữ liệu!", "Thông báo", MessageBoxButtons.OK,  MessageBoxIcon.Information);
                return;
            }
            txtManhanvien.Text = DataGridView.CurrentRow.Cells["Manhanvien"].Value.ToString();
            txtTennhanvien.Text = DataGridView.CurrentRow.Cells["Tennhanvien"].Value.ToString();
            if (DataGridView.CurrentRow.Cells["Gioitinh"].Value.ToString() == "Nam") chkGioitinh.Checked = true;
            else chkGioitinh.Checked = false;
            txtDiachi.Text = DataGridView.CurrentRow.Cells["Diachi"].Value.ToString();
            mskDienthoai.Text = DataGridView.CurrentRow.Cells["Dienthoai"].Value.ToString();
            mskNgaysinh.Text = DataGridView.CurrentRow.Cells["Ngaysinh"].Value.ToString();
            btnSua.Enabled = true;
            btnXoa.Enabled = true;
            btnXoa.Enabled = true;
        }


e) Phương thức btnThem_Click


private void btnThem_Click(object sender, EventArgs e)
        {
            btnSua.Enabled = false;
            btnXoa.Enabled = false;
            btnBoqua.Enabled = true;
            btnLuu.Enabled = true;
            btnThem.Enabled = false;
            ResetValues();
            txtManhanvien.Enabled = true;
            txtManhanvien.Focus();
        }


f) Phương thức ResetValues


private void ResetValues()
        {
            txtManhanvien.Text = "";
            txtTennhanvien.Text = "";
            chkGioitinh.Checked = false;
            txtDiachi.Text = "";
            mskNgaysinh.Text = "";
            mskDienthoai.Text = "";
        }


g) Phương thức btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
        {
            string sql,gt;
            if (txtManhanvien.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập mã nhân viên", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtManhanvien.Focus();
                return;
            }
            if (txtTennhanvien.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập tên nhân viên", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtTennhanvien.Focus();
                return ;
            }
            if (txtDiachi.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtDiachi.Focus();
                return ;
            }
            if (mskDienthoai.Text == "(   )     -")
            {
                MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                mskDienthoai.Focus();
                return ;
            }
            if (mskNgaysinh.Text == "  /  /")
            {
                MessageBox.Show("Bạn phải nhập ngày sinh", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                mskNgaysinh.Focus();
                return ;
            }
            if (!Functions.IsDate(mskNgaysinh.Text))
            {
                MessageBox.Show("Bạn phải nhập lại ngày sinh", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
               // mskNgaysinh.Text = "";
                mskNgaysinh.Focus();
                return ;
            }
            if (chkGioitinh.Checked == true)
                gt = "Nam";
            else
                gt = "Nữ";
            sql = "SELECT Manhanvien FROM tblNhanvien WHERE Manhanvien=N'" + txtManhanvien.Text.Trim() + "'";
            if (Functions.CheckKey(sql))
            {
                MessageBox.Show("Mã nhân viên này đã có, bạn phải nhập mã khác", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtManhanvien.Focus();
                txtManhanvien.Text = "";
                return ;
            }
            sql = "INSERT INTO tblNhanvien(Manhanvien,Tennhanvien,Gioitinh, Diachi,Dienthoai, Ngaysinh) VALUES (N'" + txtManhanvien.Text.Trim() + "',N'" + txtTennhanvien.Text.Trim() + "',N'" + gt + "',N'" + txtDiachi.Text.Trim() + "','" + mskDienthoai.Text + "','" + Functions.ConvertDateTime(mskNgaysinh.Text) + "')";
            Functions.RunSQL(sql);
            LoadDataGridView();
            ResetValues();
            btnXoa.Enabled = true;
            btnThem.Enabled = true;
            btnSua.Enabled = true;
            btnBoqua.Enabled = false;
            btnLuu.Enabled = false;
            txtManhanvien.Enabled = false;
        }


Với IsDateConvertDateTime là các hàm được viết trong lớp Functions

IsDate có tác dụng kiểm tra một biến có ở dạng ngày tháng không, ConvertDateTime có tác dụng đổi một chuỗi ngày tháng do người dùng nhập có dạng dd/mm/yyyy thành chuỗi ngày tháng có dạng mm/dd/yyyy để lưu vào CSDL.

 
h) Hàm IsDate

Soạn thảo trong lớp Functions:


public static bool IsDate(string date)
        {
            string[] elements = date.Split('/');
            if ((Convert.ToInt32(elements[0]) >= 1) && (Convert.ToInt32(elements[0]) <= 31) && (Convert.ToInt32(elements[1]) >= 1) && (Convert.ToInt32(elements[1]) <= 12) && (Convert.ToInt32(elements[2]) >= 1900))
                return true;
            else return false;
        }


i) Hàm ConvertDateTime
Soạn thảo hàm trong lớp Functions:


public static string ConvertDateTime(string date)
        {
            string[] elements = date.Split('/');
            string dt = string.Format("{0}/{1}/{2}", elements[0], elements[1], elements[2]);
            return dt;
        }


j) Phương thức btnSua_Click


private void btnSua_Click(object sender, EventArgs e)
        {
            string sql, gt;
            if (tblNV.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu!", "Thông báo", MessageBoxButtons.OK,MessageBoxIcon.Information);
                return;
            }
            if (txtManhanvien.Text == "")
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtTennhanvien.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập tên nhân viên", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Warning);
                txtTennhanvien.Focus();
                return;
            }
            if (txtDiachi.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo", MessageBoxButtons.OK,MessageBoxIcon.Warning);
                txtDiachi.Focus();
                return;
            }
            if (mskDienthoai.Text == "(   )     -")
            {
                MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Warning);
                mskDienthoai.Focus();
                return;
            }
            if (mskNgaysinh.Text == "  /  /")
            {
                MessageBox.Show("Bạn phải nhập ngày sinh", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Warning);
                mskNgaysinh.Focus();
                return;
            }
            if (!Functions.IsDate(mskNgaysinh.Text))
            {
                MessageBox.Show("Bạn phải nhập lại ngày sinh", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Warning);
                mskNgaysinh.Text = "";
                mskNgaysinh.Focus();
                return;
            }
            if (chkGioitinh.Checked == true)
                gt = "Nam";
            else
                gt = "Nữ";
            sql = "UPDATE tblNhanvien SET  Tennhanvien=N'" +txtTennhanvien.Text.Trim().ToString() +
                    "',Diachi=N'" + txtDiachi.Text.Trim().ToString() +
                    "',Dienthoai='" + mskDienthoai.Text.ToString() + "',Gioitinh=N'" + gt +
                    "',Ngaysinh='" + Functions.ConvertDateTime(mskNgaysinh.Text) +
                    "' WHERE Manhanvien=N'" + txtManhanvien.Text + "'";
            Functions.RunSQL(sql);
            LoadDataGridView();
            ResetValues();
            btnBoqua.Enabled = false;
        }


k) Phương thức btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
        {
            string sql;
            if (tblNV.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu!", "Thông báo", MessageBoxButtons.OK,MessageBoxIcon.Information);
                return;
            }
            if (txtManhanvien.Text == "")
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (MessageBox.Show("Bạn có muốn xóa không?", "Thông báo",MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                sql = "DELETE tblNhanvien WHERE Manhanvien=N'" + txtManhanvien.Text + "'";
                Functions.RunSqlDel(sql);
                LoadDataGridView();
                ResetValues();
            }
        }


}
l) Phương thức btnBoqua_Click


private void btnBoqua_Click(object sender, EventArgs e)
        {
            ResetValues();
            btnBoqua.Enabled = false;
            btnThem.Enabled = true;
            btnXoa.Enabled = true;
            btnSua.Enabled = true;
            btnLuu.Enabled = false;
            txtManhanvien.Enabled = false;
        }


m) Phương thức dùng phím Enter thay cho phím Tab


private void txtManhanvien_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                SendKeys.Send("{TAB}");
        }


Thực hiện tương tự cho txtTennhanvien.KeyUp, txtDiachi.KeyUp, mskDienthoai.KeyUp, mskNgaysinh.KeyUp.
n) Phương thức btnDong_Click


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


4.5. Form Danh mục Khách hàng

a) Khai báo

– Thư viện


using System.Data;
using System.Data.SqlClient;
using Quanlybanhang.Class;  


– Biến


DataTable tblKH; //Bảng khách hàng

b) Phương thức frmDMKhachhang_Load


private void frmDMKhachhang_Load(object sender, EventArgs e)
        {
            txtMakhach.Enabled = false;
            btnLuu.Enabled = false;
            btnBoqua.Enabled = false;
            LoadDataGridView();
        }


c) Phương thức LoadDataGridView


private void LoadDataGridView()
        {
            string sql;
            sql = "SELECT * from tblKhach";
            tblKH = Functions.GetDataToTable(sql); //Lấy dữ liệu từ bảng
            DataGridView.DataSource = tblKH; //Hiển thị vào dataGridView
            DataGridView.Columns[0].HeaderText = "Mã khách";
            DataGridView.Columns[1].HeaderText = "Tên khách";
            DataGridView.Columns[2].HeaderText = "Địa chỉ";
            DataGridView.Columns[3].HeaderText = "Điện thoại";
            DataGridView.Columns[0].Width = 100;
            DataGridView.Columns[1].Width = 150;
            DataGridView.Columns[2].Width = 150;
            DataGridView.Columns[3].Width = 150;
            DataGridView.AllowUserToAddRows = false;
            DataGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
        }


d) Phương thức DataGridView_Click


private void dataGridView_Click(object sender, EventArgs e)
        {
            if (btnThem.Enabled == false)
            {
                MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMakhach.Focus();
                return;
            }
            if (tblKH.Rows.Count == 0)
            {
                MessageBox.Show("Không có dữ liệu!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            txtMakhach.Text = DataGridView.CurrentRow.Cells["Makhach"].Value.ToString();
            txtTenkhach.Text = DataGridView.CurrentRow.Cells["Tenkhach"].Value.ToString();
            txtDiachi.Text = DataGridView.CurrentRow.Cells["Diachi"].Value.ToString();
            mskDienthoai.Text = DataGridView.CurrentRow.Cells["Dienthoai"].Value.ToString();
            btnSua.Enabled = true;
            btnXoa.Enabled = true;
            btnBoqua.Enabled = true;
        }


e) Phương thức btnThem_Click


private void btnThem_Click(object sender, EventArgs e)
        {
            btnSua.Enabled = false;
            btnXoa.Enabled = false;
            btnBoqua.Enabled = true;
            btnLuu.Enabled = true;
            btnThem.Enabled = false;
            ResetValues();
            txtMakhach.Enabled = true;
            txtMakhach.Focus();
        }


f) Phương thức ResetValues


private void ResetValues()
        {
            txtMakhach.Text = "";
            txtTenkhach.Text  = "";
            txtDiachi.Text = "";
            mskDienthoai.Text = "";
        }


g) Phương thức btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
        {
            string sql;
            if (txtMakhach.Text.Trim().Length  == 0)
            {
                MessageBox.Show("Bạn phải nhập mã khách", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMakhach.Focus();
                return;
            }
            if (txtTenkhach.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập tên khách", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtTenkhach.Focus();
                return;
            }
            if (txtDiachi.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtDiachi.Focus();
                return;
            }
            if (mskDienthoai.Text == "(  )    -")
            {
                MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                mskDienthoai.Focus();
                return;
            }
            //Kiểm tra đã tồn tại mã khách chưa
            sql = "SELECT Makhach FROM tblKhach WHERE Makhach=N'" + txtMakhach.Text.Trim() + "'";
            if (Functions.CheckKey(sql))
            {
                MessageBox.Show("Mã khách này đã tồn tại", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMakhach.Focus();
                return;                
            }
            //Chèn thêm
            sql = "INSERT INTO tblKhach VALUES (N'" + txtMakhach.Text.Trim() +
                "',N'" + txtTenkhach.Text.Trim() + "',N'" + txtDiachi.Text.Trim() + "','" + mskDienthoai.Text + "')";
            Functions.RunSQL(sql);
            LoadDataGridView();
            ResetValues();

            btnXoa.Enabled = true;
            btnThem.Enabled = true;
            btnSua.Enabled = true;
            btnBoqua.Enabled = false;
            btnLuu.Enabled = false;
            txtMakhach.Enabled = false;
        }


h) Phương thức btnSua_Click


private void btnSua_Click(object sender, EventArgs e)
        {
            string sql;
            if (tblKH.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtMakhach.Text == "")
            {
                MessageBox.Show("Bạn phải chọn bản ghi cần sửa", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtTenkhach.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập tên khách", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtTenkhach.Focus();
                return;
            }
            if (txtDiachi.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập địa chỉ", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtDiachi.Focus();
                return;
            }
            if (mskDienthoai.Text=="(  )    -")
            {
                MessageBox.Show("Bạn phải nhập điện thoại", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                mskDienthoai.Focus();
                return;
            }
            sql = "UPDATE tblKhach SET Tenkhach=N'" + txtTenkhach.Text.Trim().ToString() + "',Diachi=N'" +
                txtDiachi.Text.Trim().ToString() + "',Dienthoai='" + mskDienthoai.Text.ToString() +
                "' WHERE Makhach=N'" + txtMakhach.Text + "'";
            Functions.RunSQL(sql);
            LoadDataGridView();
            ResetValues();
            btnBoqua.Enabled = false;
        }


i) Phương thức btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
        {
            string sql;
            if (tblKH.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtMakhach.Text.Trim() == "")
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (MessageBox.Show("Bạn có muốn xoá bản ghi này không?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                sql = "DELETE tblKhach WHERE Makhach=N'" + txtMakhach.Text + "'";
                Functions.RunSqlDel(sql);
                LoadDataGridView();
                ResetValues();
            }
        }


j) Phương thức btnBoqua_Click


private void btnBoqua_Click(object sender, EventArgs e)
        {
            ResetValues();
            btnBoqua.Enabled = false;
            btnThem.Enabled = true;
            btnXoa.Enabled = true;
            btnSua.Enabled = true;
            btnLuu.Enabled = false;
            txtMakhach.Enabled = false;
        }


k) Phương thức dùng phím Enter thay cho phím Tab


private void txtMakhach_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                SendKeys.Send("{TAB}");
        }


l) Phương thức btnDong_Click


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


4.6. Form Danh mục hàng

a) Khai báo
– Thư viện


using System.Data;
using System.Data.SqlClient;
using Quanlybanhang.Class;  


– Biến


DataTable tblH; //Bảng hàng

b) Phương thức frmDMHang_Load


private void frmDMHang_Load(object sender, EventArgs e)
        {
            string sql;
            sql = "SELECT * from tblChatlieu";
            txtMahang.Enabled = false;
            btnLuu.Enabled = false;
            btnBoqua.Enabled = false;
            LoadDataGridView();
            Functions.FillCombo(sql, cboMachatlieu, "Machatlieu", "Tenchatlieu");
            cboMachatlieu.SelectedIndex = -1;
            ResetValues();
        }


Với FillCombo là một phương thức được viết trong Class Functions, có tác dụng lấy dữ liệu từ một câu lệnh SQL đổ vào một ComboBox.
c) Phương thức FillCombo
Soạn thảo trong Class Functions :


public static void FillCombo(string sql, ComboBox cbo, string ma, string ten)
        {
            SqlDataAdapter Mydata = new SqlDataAdapter(sql, Con);
            DataTable table = new DataTable();
            Mydata.Fill(table);
            cbo.DataSource = table;
            cbo.ValueMember = ma; //Trường giá trị
            cbo.DisplayMember = ten; //Trường hiển thị
        }


d) Phương thức ResetValues


private void ResetValues()
        {
            txtMahang.Text = "";
            txtTenhang.Text = "";
            cboMachatlieu.Text = "";
            txtSoluong.Text = "0";
            txtDongianhap.Text = "0";
            txtDongiaban.Text = "0";
            txtSoluong.Enabled = true ;
            txtDongianhap.Enabled = false;
            txtDongiaban.Enabled = false;
            txtAnh.Text = "";
            picAnh.Image = null;
            txtGhichu.Text = "";
        }


e) Phương thức LoadDataGridView


private void LoadDataGridView()
        {
            string sql;
            sql = "SELECT * from tblHang";
            tblH = Functions.GetDataToTable(sql);
            DataGridView.DataSource = tblH;
            DataGridView.Columns[0].HeaderText = "Mã hàng";
            DataGridView.Columns[1].HeaderText = "Tên hàng";
            DataGridView.Columns[2].HeaderText = "Chất liệu";
            DataGridView.Columns[3].HeaderText = "Số lượng";
            DataGridView.Columns[4].HeaderText = "Đơn giá nhập";
            DataGridView.Columns[5].HeaderText = "Đơn giá bán";
            DataGridView.Columns[6].HeaderText = "Ảnh";
            DataGridView.Columns[7].HeaderText = "Ghi chú";
            DataGridView.Columns[0].Width = 80;
            DataGridView.Columns[1].Width = 140;
            DataGridView.Columns[2].Width = 80;
            DataGridView.Columns[3].Width = 80;
            DataGridView.Columns[4].Width = 100;
            DataGridView.Columns[5].Width = 100;
            DataGridView.Columns[6].Width = 200;
            DataGridView.Columns[7].Width = 300;
            DataGridView.AllowUserToAddRows = false;
            DataGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
        }


f) Phương thức DataGridView_Click


private void DataGridView_Click(object sender, EventArgs e)
        {
            string machatlieu;
            string sql;
            if (btnThem.Enabled == false)
            {
                MessageBox.Show("Đang ở chế độ thêm mới!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMahang.Focus();
                return;
            }
            if (tblH.Rows.Count == 0)
            {
                MessageBox.Show("Không có dữ liệu!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);                
                return;
            }
            txtMahang.Text = DataGridView.CurrentRow.Cells["Mahang"].Value.ToString();
            txtTenhang.Text = DataGridView.CurrentRow.Cells["Tenhang"].Value.ToString();
            machatlieu = DataGridView.CurrentRow.Cells["Machatlieu"].Value.ToString();
            sql = "SELECT Tenchatlieu FROM tblChatlieu WHERE Machatlieu=N'" + machatlieu + "'";
            cboMachatlieu.Text = Functions.GetFieldValues(sql);
            txtSoluong.Text = DataGridView.CurrentRow.Cells["Soluong"].Value.ToString();
            txtDongianhap.Text = DataGridView.CurrentRow.Cells["Dongianhap"].Value.ToString();
            txtDongiaban.Text = DataGridView.CurrentRow.Cells["Dongiaban"].Value.ToString();
            sql = "SELECT Anh FROM tblHang WHERE Mahang=N'" + txtMahang.Text + "'";
            txtAnh.Text = Functions.GetFieldValues(sql);
            picAnh.Image = Image.FromFile(txtAnh.Text);
            sql = "SELECT Ghichu FROM tblHang WHERE Mahang = N'" + txtMahang.Text + "'";
            txtGhichu.Text = Functions.GetFieldValues(sql);
            btnSua.Enabled = true;
            btnXoa.Enabled = true;
            btnBoqua.Enabled = true;
        }


Với GetFieldValues là một hàm được viết trong Class Functions, có tác dụng lấy dữ liệu từ một câu lệnh SQL.
g) Hàm GetFieldValues
Soạn thảo trong Class Functions


public static string GetFieldValues(string sql)
        {
            string ma = "";
            SqlCommand cmd = new SqlCommand(sql, Con);
            SqlDataReader reader;
            reader = cmd.ExecuteReader();
            while (reader.Read())
                ma = reader.GetValue(0).ToString();
            reader.Close();
            return ma;
        }


h) Phương thức btnThem_Click


private void btnThem_Click(object sender, EventArgs e)
        {
            btnSua.Enabled = false;
            btnXoa.Enabled = false;
            btnBoqua.Enabled = true;
            btnLuu.Enabled = true;
            btnThem.Enabled = false;
            ResetValues();
            txtMahang.Enabled = true;
            txtMahang.Focus();
            txtSoluong.Enabled = true;
            txtDongianhap.Enabled = true;
            txtDongiaban.Enabled = true;
        }


i) Phương thức btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
        {
            string sql;
            if (txtMahang.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập mã hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMahang.Focus();
                return;
            }
            if (txtTenhang.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập tên hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtTenhang.Focus();
                return;
            }
            if (cboMachatlieu.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập chất liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                cboMachatlieu.Focus();
                return;
            }
            if (txtAnh.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải chọn ảnh minh hoạ cho hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                btnOpen.Focus();
                return;
            }
            sql = "SELECT Mahang FROM tblHang WHERE Mahang=N'" + txtMahang.Text.Trim() + "'";
            if (Functions.CheckKey(sql))
            {
                MessageBox.Show("Mã hàng này đã tồn tại, bạn phải chọn mã hàng khác", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMahang.Focus();
                return;
            }
            sql = "INSERT INTO tblHang(Mahang,Tenhang,Machatlieu,Soluong,Dongianhap, Dongiaban,Anh,Ghichu) VALUES(N'" 
                + txtMahang.Text.Trim() + "',N'" + txtTenhang.Text.Trim() + 
                "',N'" + cboMachatlieu.SelectedValue.ToString() +
                "'," + txtSoluong.Text.Trim() + "," + txtDongianhap.Text + 
                "," + txtDongiaban.Text + ",'" + txtAnh.Text + "',N'" + txtGhichu.Text.Trim() + "')";
            
            Functions.RunSQL(sql);
            LoadDataGridView();
            //ResetValues();
            btnXoa.Enabled=true;
            btnThem.Enabled = true;
            btnSua.Enabled = true;
            btnBoqua.Enabled = false;
            btnLuu.Enabled = false;
            txtMahang.Enabled = false;
        }


j) Phương thức btnSua_Click


private void btnSua_Click(object sender, EventArgs e)
        {
            string sql;
            if (tblH.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtMahang.Text == "")
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtMahang.Focus();
                return;
            }
            if (txtTenhang.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập tên hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtTenhang.Focus();
                return;
            }
            if (cboMachatlieu.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải nhập chất liệu", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                cboMachatlieu.Focus();
                return;
            }
            if (txtAnh.Text.Trim().Length == 0)
            {
                MessageBox.Show("Bạn phải ảnh minh hoạ cho hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtAnh.Focus();
                return;
            }
            sql = "UPDATE tblHang SET Tenhang=N'" + txtTenhang.Text.Trim().ToString() +
                "',Machatlieu=N'" + cboMachatlieu.SelectedValue.ToString() +
                "',Soluong="+txtSoluong.Text+
                ",Anh='" + txtAnh.Text + "',Ghichu=N'" + txtGhichu.Text +"' WHERE Mahang=N'" + txtMahang.Text + "'";
            Functions.RunSQL(sql);
            LoadDataGridView();
            ResetValues();
            btnBoqua.Enabled = false;
        }


k) Phương thức btnXoa_Click


private void btnXoa_Click(object sender, EventArgs e)
        {
            string sql;
            if (tblH.Rows.Count == 0)
            {
                MessageBox.Show("Không còn dữ liệu!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (txtMahang.Text == "")
            {
                MessageBox.Show("Bạn chưa chọn bản ghi nào", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if (MessageBox.Show("Bạn có muốn xoá bản ghi này không?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                sql = "DELETE tblHang WHERE Mahang=N'" + txtMahang.Text + "'";
                Functions.RunSqlDel(sql);
                LoadDataGridView();
                ResetValues();
            }
        }


l) Phương thức btnBoqua_Click


private void btnBoqua_Click(object sender, EventArgs e)
        {
            ResetValues();
            btnXoa.Enabled = true;
            btnSua.Enabled = true;
            btnThem.Enabled = true;
            btnBoqua.Enabled = false;
            btnLuu.Enabled = false;
            txtMahang.Enabled = false;
        }


m) Phương thức btnOpen_Click


private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlgOpen = new OpenFileDialog();
            dlgOpen.Filter = "Bitmap(*.bmp)|*.bmp|JPEG(*.jpg)|*.jpg|GIF(*.gif)|*.gif|All files(*.*)|*.*";
            dlgOpen.FilterIndex = 2;
            dlgOpen.Title = "Chọn ảnh minh hoạ cho sản phẩm";
            if (dlgOpen.ShowDialog() == DialogResult.OK)
            {
                picAnh.Image = Image.FromFile(dlgOpen.FileName);
                txtAnh.Text = dlgOpen.FileName;
            }
        }


n) Phương thức btnTimkiem_Click
Phương thức tìm kiếm cho phép tìm các bản ghi thỏa mãn một số điều kiện nào đấy và hiển thị kết quả tìm được vào lưới DataGridView.


private void btnTimkiem_Click(object sender, EventArgs e)
        {
            string sql;
            if ((txtMahang.Text == "") && (txtTenhang.Text == "") && (cboMachatlieu.Text == ""))
            {
                MessageBox.Show("Bạn hãy nhập điều kiện tìm kiếm", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            sql = "SELECT * from tblHang WHERE 1=1";
            if (txtMahang.Text != "")
                sql += " AND Mahang LIKE N'%" + txtMahang.Text + "%'";
            if (txtTenhang.Text != "")
                sql += " AND Tenhang LIKE N'%" + txtTenhang.Text + "%'";
            if (cboMachatlieu.Text!="")
                sql += " AND Machatlieu LIKE N'%" + cboMachatlieu.SelectedValue + "%'";
            tblH = Functions.GetDataToTable(sql);
            if (tblH.Rows.Count == 0)
                MessageBox.Show("Không có bản ghi thoả mãn điều kiện tìm kiếm!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            else MessageBox.Show("Có " + tblH.Rows.Count + "  bản ghi thoả mãn điều kiện!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            DataGridView.DataSource = tblH;
            ResetValues();
        }


o) Phương thức btnHienthi_Click


private void btnHienthi_Click(object sender, EventArgs e)
        {
            string sql;
            sql = "SELECT Mahang, Tenhang,Machatlieu,Soluong,Dongianhap,Dongiaban,Anh,Ghichu FROM tblHang";
            tblH = Functions.GetDataToTable(sql);
            DataGridView.DataSource = tblH;
        }


p) Phương thức btnDong_Click


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


4.7. Form Hóa đơn bán

a) Khai báo
Chọn menu Project/Add Reference, chọn thẻ COM hộp thoại Add Reference, chọn Microsoft Excel 14.0 Object Library, nhấn OK.

frmkb

– Thư viện


using System.Data.SqlClient;
using QuanLyBanHang.Class;
using COMExcel = Microsoft.Office.Interop.Excel;


– Biến


DataTable tblCTHDB; //Bảng chi tiết hoá đơn bán

b) Phương thức frmHoadonBan_Load


private void frmHoadonBan_Load(object sender, EventArgs e)
        {
            btnThemmoi.Enabled = true;
            btnLuu.Enabled = false;
            btnXoa.Enabled = false;
            btnInhoadon.Enabled = false;
            txtMaHDBan.ReadOnly = true;
            txtTennhanvien.ReadOnly = true;
            txtTenkhach.ReadOnly = true;
            txtDiachi.ReadOnly = true;
            txtDienthoai.ReadOnly = true;
            txtTenhang.ReadOnly = true;
            txtDongiaban.ReadOnly = true;
            txtThanhtien.ReadOnly = true;
            txtTongtien.ReadOnly = true;
            txtGiamgia.Text = "0";
            txtTongtien.Text = "0";
            Functions.FillCombo("SELECT Makhach, Tenkhach FROM tblKhach", cboMakhach,"Makhach", "Makhach");
            cboMakhach.SelectedIndex = -1;
            Functions.FillCombo("SELECT Manhanvien, Tennhanvien FROM tblNhanvien",cboManhanvien, "Manhanvien", "Tenkhach");
            cboManhanvien.SelectedIndex = -1;
            Functions.FillCombo("SELECT Mahang, Tenhang FROM tblHang", cboMahang,"Mahang", "Mahang");
            cboMahang.SelectedIndex = -1;
            //Hiển thị thông tin của một hóa đơn được gọi từ form tìm kiếm
            if (txtMaHDBan.Text != "")
            {
                LoadInfoHoadon();
                btnXoa.Enabled = true;
                btnInhoadon.Enabled = true;
            }
            LoadDataGridView();
        }


c) Phương thức LoadDataGridView


private void LoadDataGridView()
        {
            string sql;
            sql = "SELECT a.Mahang, b.Tenhang, a.Soluong, b.Dongiaban, a.Giamgia,a.Thanhtien FROM tblChitietHDBan AS a, tblHang AS b WHERE a.MaHDBan = N'" + txtMaHDBan.Text + "' AND a.Mahang=b.Mahang";
            tblCTHDB = Functions.GetDataToTable(sql);
            DataGridView.DataSource = tblCTHDB;
            DataGridView.Columns[0].HeaderText = "Mã hàng";
            DataGridView.Columns[1].HeaderText = "Tên hàng";
            DataGridView.Columns[2].HeaderText = "Số lượng";
            DataGridView.Columns[3].HeaderText = "Đơn giá";
            DataGridView.Columns[4].HeaderText = "Giảm giá %";
            DataGridView.Columns[5].HeaderText = "Thành tiền";
            DataGridView.Columns[0].Width = 80;
            DataGridView.Columns[1].Width = 130;
            DataGridView.Columns[2].Width = 80;
            DataGridView.Columns[3].Width = 90;
            DataGridView.Columns[4].Width = 90;
            DataGridView.Columns[5].Width = 90;
            DataGridView.AllowUserToAddRows = false;
            DataGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
        }


d) Phương thức LoadInfoHoadon()


private void LoadInfoHoadon()
        {
            string str;
            str = "SELECT Ngayban FROM tblHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
            txtNgayban.Text = Functions.ConvertDateTime(Functions.GetFieldValues(str));
            str = "SELECT Manhanvien FROM tblHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
            cboManhanvien.Text = Functions.GetFieldValues(str);
            str = "SELECT Makhach FROM tblHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
            cboMakhach.Text = Functions.GetFieldValues(str);
            str = "SELECT Tongtien FROM tblHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
            txtTongtien.Text = Functions.GetFieldValues(str);
            lblBangchu.Text = "Bằng chữ: " + Functions.ChuyenSoSangChu(txtTongtien.Text);
        }


e) Phương thức btnThemmoi_Click


private void btnThemmoi_Click(object sender, EventArgs e)
        {
            btnXoa.Enabled = false;
            btnLuu.Enabled = true;
            btnInhoadon.Enabled = false;
            btnThemmoi.Enabled = false;
            ResetValues();
            txtMaHDBan.Text = Functions.CreateKey("HDB");
            LoadDataGridView();
        }


Với CreateKey là một hàm được viết trong Class Functions, có tác dụng sinh khóa tự động cho Mã hóa đơn bán.
f) Hàm CreateKey
Soạn thảo trong Class Functions:


//Hàm tạo khóa có dạng: TientoNgaythangnam_giophutgiay
        public static string CreateKey(string tiento)
        {
            string key = tiento;
            string[] partsDay;
            partsDay = DateTime.Now.ToShortDateString().Split('/');
            //Ví dụ 07/08/2009
            string d = String.Format("{0}{1}{2}", partsDay[0], partsDay[1], partsDay[2]);
            key = key + d;
            string[] partsTime;
            partsTime = DateTime.Now.ToLongTimeString().Split(':');
            //Ví dụ 7:08:03 PM hoặc 7:08:03 AM
            if (partsTime[2].Substring(3, 2) == "PM")
                partsTime[0] = ConvertTimeTo24(partsTime[0]);
            if (partsTime[2].Substring(3, 2) == "AM")
                if (partsTime[0].Length == 1)
                    partsTime[0] = "0" + partsTime[0];
            //Xóa ký tự trắng và PM hoặc AM
            partsTime[2] = partsTime[2].Remove(2, 3);
            string t;
            t = String.Format("_{0}{1}{2}", partsTime[0], partsTime[1], partsTime[2]);
            key = key + t;
            return key;
        }


Với ConvertTimeTo24 là một hàm toàn cục được viết trong Class Functions, có tác dụng chuyển đổi giờ từ dạng PM sang dạng 24h.
g) Hàm ConvertTimeTo24
Soạn thảo trong Class Functions:


//Chuyển đổi từ PM sang dạng 24h
        public static string ConvertTimeTo24(string hour)
        {
            string h = "";
            switch (hour)
            {
                case "1":
                    h = "13";
                    break;
                case "2":
                    h = "14";
                    break;
                case "3":
                    h = "15";
                    break;
                case "4":
                    h = "16";
                    break;
                case "5":
                    h = "17";
                    break;
                case "6":
                    h = "18";
                    break;
                case "7":
                    h = "19";
                    break;
                case "8":
                    h = "20";
                    break;
                case "9":
                    h = "21";
                    break;
                case "10":
                    h = "22";
                    break;
                case "11":
                    h = "23";
                    break;
                case "12":
                    h = "0";
                    break;
            }
            return h;
        }


h) Phương thức ResetValues


private void ResetValues()
        {
            txtMaHDBan.Text = "";
            txtNgayban.Text = DateTime.Now.ToShortDateString();
            cboManhanvien.Text = "";
            cboMakhach.Text = "";
            txtTongtien.Text = "0";
            lblBangchu.Text = "Bằng chữ: ";
            cboMahang.Text = "";
            txtSoluong.Text = "";
            txtGiamgia.Text = "0";
            txtThanhtien.Text = "0";
        }


i) Phương thức btnLuu_Click


private void btnLuu_Click(object sender, EventArgs e)
        {
            string sql;
            double sl, SLcon, tong, Tongmoi;
            sql = "SELECT MaHDBan FROM tblHDBan WHERE MaHDBan=N'" + txtMaHDBan.Text + "'";
            if( ! Functions.CheckKey(sql) )
            {
                // Mã hóa đơn chưa có, tiến hành lưu các thông tin chung
                // Mã HDBan được sinh tự động do đó không có trường hợp trùng khóa
                if( txtNgayban.Text.Length == 0 )
                {
                    MessageBox.Show("Bạn phải nhập ngày bán", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtNgayban.Focus();
                    return ;
                }
                if( cboManhanvien.Text.Length == 0 )
                {
                    MessageBox.Show("Bạn phải nhập nhân viên", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    cboManhanvien.Focus();
                    return;
                }
                if( cboMakhach.Text.Length == 0 )
                {
                    MessageBox.Show("Bạn phải nhập khách hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information );
                    cboMakhach.Focus();
                    return;
                }
                sql = "INSERT INTO tblHDBan(MaHDBan, Ngayban, Manhanvien, Makhach, Tongtien) VALUES (N'" + txtMaHDBan.Text.Trim() + "','" +
                        Functions.ConvertDateTime(txtNgayban.Text.Trim()) + "',N'" + cboManhanvien.SelectedValue + "',N'" + 
                        cboMakhach.SelectedValue + "'," + txtTongtien.Text + ")";                
                Functions.RunSQL(sql);
            }
            // Lưu thông tin của các mặt hàng
            if( cboMahang.Text.Trim().Length == 0 )
            {
                MessageBox.Show("Bạn phải nhập mã hàng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                cboMahang.Focus();
                return;
            }
            if( (txtSoluong.Text.Trim().Length == 0) || (txtSoluong.Text == "0" ))
            {
                MessageBox.Show("Bạn phải nhập số lượng", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information );
                txtSoluong.Text = "";
                txtSoluong.Focus();
                return;
            }
            if( txtGiamgia.Text.Trim().Length == 0 )
            {
                MessageBox.Show("Bạn phải nhập giảm giá", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtGiamgia.Focus();
                return;
            }
            sql = "SELECT Mahang FROM tblChitietHDBan WHERE MaHang=N'" + cboMahang.SelectedValue + "' AND MaHDBan = N'" + txtMaHDBan.Text.Trim() + "'";
            if(Functions.CheckKey(sql))
            {
                MessageBox.Show("Mã hàng này đã có, bạn phải nhập mã khác", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Information);
                ResetValuesHang();
                cboMahang.Focus();
                return;
            }
            // Kiểm tra xem số lượng hàng trong kho còn đủ để cung cấp không?
            sl = Convert.ToDouble(Functions.GetFieldValues("SELECT Soluong FROM tblHang WHERE Mahang = N'" + cboMahang.SelectedValue + "'"));
            if( Convert.ToDouble(txtSoluong.Text) > sl )
            {
                MessageBox.Show("Số lượng mặt hàng này chỉ còn " + sl, "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                txtSoluong.Text = "";
                txtSoluong.Focus();
                return;
            }
            sql = "INSERT INTO tblChitietHDBan(MaHDBan,Mahang,Soluong,Dongia, Giamgia,Thanhtien) VALUES(N'" + txtMaHDBan.Text.Trim() + "',N'" + cboMahang.SelectedValue + "'," + txtSoluong.Text + "," + txtDongiaban.Text+ ","+  txtGiamgia.Text + "," + txtThanhtien.Text + ")";            
            Functions.RunSQL(sql);            
            LoadDataGridView();
            // Cập nhật lại số lượng của mặt hàng vào bảng tblHang
            SLcon = sl - Convert.ToDouble(txtSoluong.Text);
            sql = "UPDATE tblHang SET Soluong =" + SLcon + " WHERE Mahang= N'" + cboMahang.SelectedValue + "'";
            Functions.RunSQL(sql);
            // Cập nhật lại tổng tiền cho hóa đơn bán
            tong = Convert.ToDouble(Functions.GetFieldValues("SELECT Tongtien FROM tblHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'"));
            Tongmoi = tong + Convert.ToDouble(txtThanhtien.Text);
            sql = "UPDATE tblHDBan SET Tongtien =" + Tongmoi + " WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
            Functions.RunSQL(sql);
            txtTongtien.Text = Tongmoi.ToString();
            lblBangchu.Text = "Bằng chữ: " + Functions.ChuyenSoSangChu(Tongmoi.ToString());
            ResetValuesHang();
            btnXoa.Enabled = true;
            btnThemmoi.Enabled = true;
            btnInhoadon.Enabled = true;
        }


Với ChuyenSoSangChu là một hàm toàn cục được viết trong Class Functions, có tác dụng đọc từ dạng số sang dạng chữ.
j) Hàm ChuyenSoSangChu
Soạn thảo trong Class Functions:


public static string ChuyenSoSangChu(string sNumber)
        {
            int mLen, mDigit;
            string mTemp = "";
            string[] mNumText;
            //Xóa các dấu "," nếu có
            sNumber = sNumber.Replace(",", "");
            mNumText = "không;một;hai;ba;bốn;năm;sáu;bảy;tám;chín".Split(';');
            mLen = sNumber.Length - 1; // trừ 1 vì thứ tự đi từ 0
            for (int i = 0; i <= mLen; i++) { mDigit = Convert.ToInt32(sNumber.Substring(i, 1)); mTemp = mTemp + " " + mNumText[mDigit]; if (mLen == i) // Chữ số cuối cùng không cần xét tiếp break; switch ((mLen - i) % 9) { case 0: mTemp = mTemp + " tỷ"; if (sNumber.Substring(i + 1, 3) == "000") i = i + 3; if (sNumber.Substring(i + 1, 3) == "000") i = i + 3; if (sNumber.Substring(i + 1, 3) == "000") i = i + 3; break; case 6: mTemp = mTemp + " triệu"; if (sNumber.Substring(i + 1, 3) == "000") i = i + 3; if (sNumber.Substring(i + 1, 3) == "000") i = i + 3; break; case 3: mTemp = mTemp + " nghìn"; if (sNumber.Substring(i + 1, 3) == "000") i = i + 3; break; default: switch ((mLen - i) % 3) { case 2: mTemp = mTemp + " trăm"; break; case 1: mTemp = mTemp + " mươi"; break; } break; } } //Loại bỏ trường hợp x00 mTemp = mTemp.Replace("không mươi không ", ""); mTemp = mTemp.Replace("không mươi không", ""); //Loại bỏ trường hợp 00x mTemp = mTemp.Replace("không mươi ", "linh "); //Loại bỏ trường hợp x0, x>=2
            mTemp = mTemp.Replace("mươi không", "mươi");
            //Fix trường hợp 10
            mTemp = mTemp.Replace("một mươi", "mười");
            //Fix trường hợp x4, x>=2
            mTemp = mTemp.Replace("mươi bốn", "mươi tư");
            //Fix trường hợp x04
            mTemp = mTemp.Replace("linh bốn", "linh tư");
            //Fix trường hợp x5, x>=2
            mTemp = mTemp.Replace("mươi năm", "mươi lăm");
            //Fix trường hợp x1, x>=2
            mTemp = mTemp.Replace("mươi một", "mươi mốt");
            //Fix trường hợp x15
            mTemp = mTemp.Replace("mười năm", "mười lăm");
            //Bỏ ký tự space
            mTemp = mTemp.Trim();
            //Viết hoa ký tự đầu tiên
            mTemp = mTemp.Substring(0, 1).ToUpper() + mTemp.Substring(1) + " đồng";
            return mTemp;
        }


k) Phương thức ResetValuesHang


private void ResetValuesHang()
        {
            cboMahang.Text = "";
            txtSoluong.Text = "";
            txtGiamgia.Text = "0";
            txtThanhtien.Text = "0";
        }


l) Phương thức DataGridView_DoubleClick
Phương thức này cho phép người dùng nháy đúp chuột vào một mặt hàng trong lưới để xóa.


private void DataGridView_DoubleClick(object sender, EventArgs e)
        {
            string mahangxoa,sql;
            Double thanhtienxoa, soluongxoa, sl, slcon, tong, tongmoi;
            if (tblCTHDB.Rows.Count == 0)
            {
                MessageBox.Show("Không có dữ liệu!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            if ((MessageBox.Show("Bạn có chắc chắn muốn xóa không?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes))
            {
                //Xóa hàng và cập nhật lại số lượng hàng 
                mahangxoa = DataGridView.CurrentRow.Cells["Mahang"].Value.ToString();
                soluongxoa = Convert.ToDouble(DataGridView.CurrentRow.Cells["Soluong"].Value.ToString());
                thanhtienxoa = Convert.ToDouble(DataGridView.CurrentRow.Cells["Thanhtien"].Value.ToString());
                sql = "DELETE tblChitietHDBan WHERE MaHDBan=N'" + txtMaHDBan.Text + "' AND Mahang = N'" + mahangxoa + "'";
                Functions.RunSQL(sql);
                // Cập nhật lại số lượng cho các mặt hàng
                sl = Convert.ToDouble(Functions.GetFieldValues("SELECT Soluong FROM tblHang WHERE Mahang = N'" + mahangxoa + "'"));
                slcon = sl + soluongxoa;
                sql = "UPDATE tblHang SET Soluong =" + slcon + " WHERE Mahang= N'" +  mahangxoa + "'";
                Functions.RunSQL(sql);
                // Cập nhật lại tổng tiền cho hóa đơn bán
                tong = Convert.ToDouble(Functions.GetFieldValues("SELECT Tongtien FROM tblHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'"));
                tongmoi = tong - thanhtienxoa;
                sql = "UPDATE tblHDBan SET Tongtien =" + tongmoi + " WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
                Functions.RunSQL(sql);
                txtTongtien.Text = tongmoi.ToString();
                lblBangchu.Text = "Bằng chữ: " + Functions.ChuyenSoSangChu(tongmoi.ToString());
                LoadDataGridView();
            }
        }


m) Phương thức btnXoa_Click
Phương thức này cho phép xóa toàn bộ thông tin của một hóa đơn


private void btnXoa_Click(object sender, EventArgs e)
        {
            double sl, slcon, slxoa;
            if (MessageBox.Show("Bạn có chắc chắn muốn xóa không?", "Thông báo", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) 
            {
                string sql = "SELECT Mahang,Soluong FROM tblChitietHDBan WHERE MaHDBan = N'" + txtMaHDBan.Text + "'";
                DataTable tblHang = Functions.GetDataToTable(sql);
                for (int hang = 0; hang <= tblHang.Rows.Count - 1; hang++)
                {
                    // Cập nhật lại số lượng cho các mặt hàng
                    sl = Convert.ToDouble(Functions.GetFieldValues("SELECT Soluong FROM tblHang WHERE Mahang = N'" + tblHang.Rows[hang][0].ToString() + "'"));
                    slxoa = Convert.ToDouble(tblHang.Rows[hang][1].ToString());
                    slcon = sl + slxoa;
                    sql = "UPDATE tblHang SET Soluong =" + slcon + " WHERE Mahang= N'" + tblHang.Rows[hang][0].ToString() + "'";
                    Functions.RunSQL(sql);
                }

                //Xóa chi tiết hóa đơn
                sql = "DELETE tblChitietHDBan WHERE MaHDBan=N'" + txtMaHDBan.Text + "'";
                Functions.RunSqlDel(sql);

                //Xóa hóa đơn
                sql = "DELETE tblHDBan WHERE MaHDBan=N'" + txtMaHDBan.Text + "'";
                Functions.RunSqlDel(sql);
                ResetValues();
                LoadDataGridView();
                btnXoa.Enabled = false;
                btnInhoadon.Enabled = false;
            }
        }


n) Phương thức cboManhanvien_TextChanged


private void cboManhanvien_TextChanged(object sender, EventArgs e)
        {
            string str;
            if (cboManhanvien.Text == "")
                txtTennhanvien.Text = "";
            // Khi chọn Mã nhân viên thì tên nhân viên tự động hiện ra
            str = "Select Tennhanvien from tblNhanvien where Manhanvien =N'" + cboManhanvien.SelectedValue + "'";
            txtTennhanvien.Text = Functions.GetFieldValues(str);
        }


o) Phương thức cboMakhach_TextChanged


private void cboMakhach_TextChanged(object sender, EventArgs e)
        {
            string str;
            if (cboMakhach.Text == "")
            {
                txtTenkhach.Text = "";
                txtDiachi.Text = "";
                txtDienthoai.Text = "";
            }
            //Khi chọn Mã khách hàng thì các thông tin của khách hàng sẽ hiện ra
            str = "Select Tenkhach from tblKhach where Makhach = N'" + cboMakhach.SelectedValue+ "'";
            txtTenkhach.Text = Functions.GetFieldValues(str);
            str = "Select Diachi from tblKhach where Makhach = N'" + cboMakhach.SelectedValue + "'";
            txtDiachi.Text = Functions.GetFieldValues(str);
            str = "Select Dienthoai from tblKhach where Makhach= N'" + cboMakhach.SelectedValue  + "'";
            txtDienthoai.Text = Functions.GetFieldValues(str);
        }


p) Phương thức cboMahang_TextChanged


private void cboMahang_TextChanged(object sender, EventArgs e)
        {
            string str;
            if (cboMahang.Text == "")
            {
                txtTenhang.Text = "";
                txtDongiaban.Text = "";
            }
            // Khi chọn mã hàng thì các thông tin về hàng hiện ra
            str = "SELECT Tenhang FROM tblHang WHERE Mahang =N'" + cboMahang.SelectedValue+ "'";
            txtTenhang.Text = Functions.GetFieldValues(str);
            str = "SELECT Dongiaban FROM tblHang WHERE Mahang =N'" + cboMahang.SelectedValue+ "'";
            txtDongiaban.Text = Functions.GetFieldValues(str);
        }


q) Phương thức txtSoluong_TextChanged


private void txtSoluong_TextChanged(object sender, EventArgs e)
        {
            //Khi thay đổi số lượng thì thực hiện tính lại thành tiền
            double tt, sl, dg, gg;
            if (txtSoluong.Text == "")
                sl = 0;
            else
                sl = Convert.ToDouble(txtSoluong.Text);
            if (txtGiamgia.Text == "")
                gg = 0;
            else
                gg = Convert.ToDouble(txtGiamgia.Text);
            if (txtDongiaban.Text == "")
                dg = 0;
            else
                dg = Convert.ToDouble(txtDongiaban.Text);
            tt = sl * dg - sl * dg * gg / 100;
            txtThanhtien.Text = tt.ToString();
        }


r) Phương thức txtGiamgia_TextChanged


private void txtGiamgia_TextChanged(object sender, EventArgs e)
        {
            //Khi thay đổi giảm giá thì tính lại thành tiền
            double tt, sl, dg, gg;
            if (txtSoluong.Text == "")
                sl = 0;
            else
                sl = Convert.ToDouble(txtSoluong.Text);
            if (txtGiamgia.Text == "")
                gg = 0;
            else
                gg = Convert.ToDouble(txtGiamgia.Text);
            if (txtDongiaban.Text == "")
                dg = 0;
            else
                dg = Convert.ToDouble(txtDongiaban.Text);
            tt = sl * dg - sl * dg * gg / 100;
            txtThanhtien.Text = tt.ToString();
        }


s) Phương thức Inhoadon_Click


private void btnInhoadon_Click(object sender, EventArgs e)
        {
            // Khởi động chương trình Excel
            COMExcel.Application exApp = new COMExcel.Application();
            COMExcel.Workbook exBook; //Trong 1 chương trình Excel có nhiều Workbook
            COMExcel.Worksheet exSheet; //Trong 1 Workbook có nhiều Worksheet
            COMExcel.Range exRange; 
            string sql;
            int hang=0, cot=0;
            DataTable  tblThongtinHD, tblThongtinHang;
            exBook = exApp.Workbooks.Add(COMExcel.XlWBATemplate.xlWBATWorksheet);
            exSheet = exBook.Worksheets[1];
            // Định dạng chung
            exRange = exSheet.Cells[1, 1];
            exRange.Range["A1:Z300"].Font.Name = "Times new roman"; //Font chữ
            exRange.Range["A1:B3"].Font.Size = 10;            
            exRange.Range["A1:B3"].Font.Bold = true;
            exRange.Range["A1:B3"].Font.ColorIndex = 5; //Màu xanh da trời
            exRange.Range["A1:A1"].ColumnWidth = 7;
            exRange.Range["B1:B1"].ColumnWidth = 15;
            exRange.Range["A1:B1"].MergeCells = true;
            exRange.Range["A1:B1"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["A1:B1"].Value = "Shop B.A.";
            exRange.Range["A2:B2"].MergeCells = true;
            exRange.Range["A2:B2"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["A2:B2"].Value = "Chùa Bộc - Hà Nội";
            exRange.Range["A3:B3"].MergeCells = true;
            exRange.Range["A3:B3"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["A3:B3"].Value = "Điện thoại: (04)38526419";
            exRange.Range["C2:E2"].Font.Size = 16;
            exRange.Range["C2:E2"].Font.Bold = true;
            exRange.Range["C2:E2"].Font.ColorIndex = 3; //Màu đỏ
            exRange.Range["C2:E2"].MergeCells = true;
            exRange.Range["C2:E2"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["C2:E2"].Value = "HÓA ĐƠN BÁN";
            // Biểu diễn thông tin chung của hóa đơn bán
            sql = "SELECT a.MaHDBan, a.Ngayban, a.Tongtien, b.Tenkhach, b.Diachi, b.Dienthoai, c.Tennhanvien FROM tblHDBan AS a, tblKhach AS b, tblNhanvien AS c WHERE a.MaHDBan = N'" + txtMaHDBan.Text + "' AND a.Makhach = b.Makhach AND a.Manhanvien = c.Manhanvien";
            tblThongtinHD = Functions.GetDataToTable(sql);
            exRange.Range["B6:C9"].Font.Size = 12;
            exRange.Range["B6:B6"].Value = "Mã hóa đơn:";
            exRange.Range["C6:E6"].MergeCells = true;
            exRange.Range["C6:E6"].Value = tblThongtinHD.Rows[0][0].ToString();
            exRange.Range["B7:B7"].Value = "Khách hàng:";
            exRange.Range["C7:E7"].MergeCells = true;
            exRange.Range["C7:E7"].Value = tblThongtinHD.Rows[0][3].ToString();
            exRange.Range["B8:B8"].Value = "Địa chỉ:";
            exRange.Range["C8:E8"].MergeCells = true;
            exRange.Range["C8:E8"].Value = tblThongtinHD.Rows[0][4].ToString();
            exRange.Range["B9:B9"].Value = "Điện thoại:";
            exRange.Range["C9:E9"].MergeCells = true;
            exRange.Range["C9:E9"].Value = tblThongtinHD.Rows[0][5].ToString();
            //Lấy thông tin các mặt hàng
            sql = "SELECT b.Tenhang, a.Soluong, b.Dongiaban, a.Giamgia, a.Thanhtien " +
                  "FROM tblChitietHDBan AS a , tblHang AS b WHERE a.MaHDBan = N'" + 
                  txtMaHDBan.Text + "' AND a.Mahang = b.Mahang";
            tblThongtinHang = Functions.GetDataToTable(sql);
            //Tạo dòng tiêu đề bảng
            exRange.Range["A11:F11"].Font.Bold = true;
            exRange.Range["A11:F11"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["C11:F11"].ColumnWidth = 12;
            exRange.Range["A11:A11"].Value = "STT";
            exRange.Range["B11:B11"].Value = "Tên hàng";
            exRange.Range["C11:C11"].Value = "Số lượng";
            exRange.Range["D11:D11"].Value = "Đơn giá";
            exRange.Range["E11:E11"].Value = "Giảm giá";
            exRange.Range["F11:F11"].Value = "Thành tiền";
            for (hang = 0 ; hang < tblThongtinHang.Rows.Count; hang ++)
            {
                //Điền số thứ tự vào cột 1 từ dòng 12
                exSheet.Cells[1][hang + 12] = hang + 1;
                for (cot = 0; cot < tblThongtinHang.Columns.Count; cot++)
                //Điền thông tin hàng từ cột thứ 2, dòng 12
                {                    
                    exSheet.Cells[cot + 2][hang + 12] = tblThongtinHang.Rows[hang][cot].ToString();                    
                    if (cot == 3) exSheet.Cells[cot + 2][hang + 12] = tblThongtinHang.Rows[hang][cot].ToString() + "%";
                }
            }
            exRange = exSheet.Cells[cot][hang + 14];
            exRange.Font.Bold = true;
            exRange.Value2 = "Tổng tiền:";
            exRange = exSheet.Cells[cot + 1][hang + 14];
            exRange.Font.Bold = true;
            exRange.Value2 = tblThongtinHD.Rows[0][2].ToString();
            exRange = exSheet.Cells[1][hang + 15]; //Ô A1 
            exRange.Range["A1:F1"].MergeCells = true;
            exRange.Range["A1:F1"].Font.Bold = true;
            exRange.Range["A1:F1"].Font.Italic = true;
            exRange.Range["A1:F1"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignRight;
            exRange.Range["A1:F1"].Value = "Bằng chữ: " + Functions.ChuyenSoSangChu(tblThongtinHD.Rows[0][2].ToString ());
            exRange = exSheet.Cells[4][hang + 17]; //Ô A1 
            exRange.Range["A1:C1"].MergeCells = true;
            exRange.Range["A1:C1"].Font.Italic = true;
            exRange.Range["A1:C1"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            DateTime d = Convert.ToDateTime(tblThongtinHD.Rows[0][1]);
            exRange.Range["A1:C1"].Value = "Hà Nội, ngày " + d.Day + " tháng " + d.Month + " năm " + d.Year;
            exRange.Range["A2:C2"].MergeCells = true;
            exRange.Range["A2:C2"].Font.Italic = true;
            exRange.Range["A2:C2"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["A2:C2"].Value = "Nhân viên bán hàng";
            exRange.Range["A6:C6"].MergeCells = true;
            exRange.Range["A6:C6"].Font.Italic = true;
            exRange.Range["A6:C6"].HorizontalAlignment = COMExcel.XlHAlign.xlHAlignCenter;
            exRange.Range["A6:C6"].Value = tblThongtinHD.Rows[0][6];
            exSheet.Name = "Hóa đơn nhập";
            exApp.Visible = true;
        }
Kết quả ta có tệp Excel như sau:
vdhd

t) Phương thức btnTimkiem_Click


private void btnTimkiem_Click(object sender, EventArgs e)
        {
            if (cboMaHDBan.Text == "")
            {
                MessageBox.Show("Bạn phải chọn một mã hóa đơn để tìm", "Thông báo",MessageBoxButtons.OK, MessageBoxIcon.Information);
                cboMaHDBan.Focus();
                return;
            }
            txtMaHDBan.Text = cboMaHDBan.Text;
            LoadInfoHoadon();
            LoadDataGridView();
            btnXoa.Enabled = true;
            btnLuu.Enabled = true;
            btnInhoadon.Enabled = true;
            cboMaHDBan.SelectedIndex = -1;
        }


u) Phương thức txtSoluong_KeyPress


private void txtSoluong_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (((e.KeyChar >= '0') && (e.KeyChar <= '9')) || (Convert.ToInt32(e.KeyChar) == 8))
                e.Handled = false;
            else    e.Handled = true;
        }


Thực hiện tương tự cho txtGiamgia_KeyPress.
v) Phương thức cboMaHDBan_DropDown
Phương thức này cập nhật lại danh sách các mã hóa đơn bán và lưu vào cboMaHDBan mỗi khi người dùng nháy chuột vào nút xổ xuống của cbo.


private void cboMaHDBan_DropDown(object sender, EventArgs e)
        {
            Functions.FillCombo("SELECT MaHDBan FROM tblHDBan", cboMaHDBan, "MaHDBan","MaHDBan");
            cboMaHDBan.SelectedIndex = -1;
        }


w) Phương thức frmHoadonBan_FormClosing


private void frmHoadonBan_FormClosing(object sender, FormClosingEventArgs e)
        {
            //Xóa dữ liệu trong các điều khiển trước khi đóng Form
            ResetValues();
        }


x) Phương thức btnDong_Click


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


4.8. Form tìm kiếm Hóa đơn bán

a) Khai báo
– Thư viện


using System.Data.SqlClient;
using QuanLyBanHang.Class;


– Biến


DataTable tblHDB; //Hoá đơn bán

b) Phương thức frmTimHDBan_Load


private void frmTimHDBan_Load(object sender, EventArgs e)
        {
            ResetValues();
            DataGridView.DataSource = null;
        }


c) Phương thức ResetValues


private void ResetValues()
        {
            foreach (Control Ctl in this.Controls)
                if (Ctl is TextBox)
                    Ctl.Text = "";
            txtMaHDBan.Focus();
        }


d) Phương thức btnTimkiem_Click


private void btnTimkiem_Click(object sender, EventArgs e)
        {
            string sql;
            if ((txtMaHDBan.Text == "") && (txtThang.Text == "") && (txtNam.Text == "") &&
               (txtManhanvien.Text == "") && (txtMakhach.Text == "") &&
               (txtTongtien.Text == ""))
            {
                MessageBox.Show("Hãy nhập một điều kiện tìm kiếm!!!", "Yêu cầu ...",    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            sql = "SELECT * FROM tblHDBan WHERE 1=1";
            if (txtMaHDBan.Text != "")
                sql = sql + " AND MaHDBan Like N'%" + txtMaHDBan.Text + "%'";
            if (txtThang.Text != "")
                sql = sql + " AND MONTH(Ngayban) =" + txtThang.Text;
            if (txtNam.Text != "")
                sql = sql + " AND YEAR(Ngayban) =" + txtNam.Text;
            if (txtManhanvien.Text != "")
                sql = sql + " AND Manhanvien Like N'%" + txtManhanvien.Text + "%'";
            if (txtMakhach.Text != "")
                sql = sql + " AND Makhach Like N'%" + txtMakhach.Text + "%'";
            if (txtTongtien.Text != "")
                sql = sql + " AND Tongtien <=" + txtTongtien.Text;
            tblHDB = Functions.GetDataToTable(sql);
            if (tblHDB.Rows.Count == 0)
            {
                MessageBox.Show("Không có bản ghi thỏa mãn điều kiện!!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
                MessageBox.Show("Có " + tblHDB.Rows.Count + " bản ghi thỏa mãn điều kiện!", "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Information);
            DataGridView.DataSource = tblHDB;
            LoadDataGridView();
        }


e) Phương thức LoadDataGridView


private void LoadDataGridView()
        {
            DataGridView.Columns[0].HeaderText = "Mã HĐB";
            DataGridView.Columns[1].HeaderText = "Mã nhân viên";
            DataGridView.Columns[2].HeaderText = "Ngày bán";
            DataGridView.Columns[3].HeaderText = "Mã khách";
            DataGridView.Columns[4].HeaderText = "Tổng tiền";
            DataGridView.Columns[0].Width = 150;
            DataGridView.Columns[1].Width = 100;
            DataGridView.Columns[2].Width = 80;
            DataGridView.Columns[3].Width = 80;
            DataGridView.Columns[4].Width = 80;
            DataGridView.AllowUserToAddRows = false;
            DataGridView.EditMode = DataGridViewEditMode.EditProgrammatically;
        }


f) Phương thức btnTimlai_Click


private void btnTimlai_Click(object sender, EventArgs e)
        {
            ResetValues();
            DataGridView.DataSource = null;
        }


g) Phương thức txtTongtien_KeyPress


private void txtTongtien_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (((e.KeyChar >= '0') && (e.KeyChar <= '9')) || (Convert.ToInt32(e.KeyChar) == 8))
                e.Handled = false;
            else
                e.Handled = true;
        }


h) Phương thức DataGridView_DoubleClick
Phương thức này cho phép người dùng nháy đúp chuột chọn một hóa đơn trên lưới, rồi gọi và hiển thị thông tin của hóa đơn đó lên form frmHoadonBan.

Chú ý: Thay đổi phạm vi truy cập của điều khiển txtMaHDBan thành Public trong form frmHoadonBan (trong file frmHoadonBan.Designer.cs)

 


private void DataGridView_DoubleClick(object sender, EventArgs e)
        {
            string mahd;
            if (MessageBox.Show("Bạn có muốn hiển thị thông tin chi tiết?", "Xác nhận",MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                mahd = DataGridView.CurrentRow.Cells["MaHDBan"].Value.ToString();
                frmHoadonBan frm = new frmHoadonBan();
                frm.txtMaHDBan.Text = mahd;
                frm.StartPosition = FormStartPosition.CenterParent;
                frm.ShowDialog();
            }
        }


i) Phương thức btnDong_Click


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


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

108 phản hồi

  1. Phùng Văn Thịnh viết:

    Mình làm như bài viết bạn hướng dẫn mà báo lỗi 1 số như sau:
    1. Lỗi khi nhập ngày sinh lớn hơn 12. máy tính mình đang để định dạng ngày là M/d/yyyy.
    2. Lỗi trong phương thức In hóa đơn. báo lỗi Error 1 Cannot apply indexing with [] to an expression of type ‘object’ exSheet.Cells[1][hang + 12]

    chỗ nào có exSheet.Cells là lỗi. Mong bạn giúp mình với. Ban hướng dẫn mình làm báo cáo luôn được không?

    • Phan Tiến viết:

      Chào bạn, mình xin trả lời các lỗi bạn gặp phải:
      1. Lỗi về ngày tháng là lỗi mà các bạn hay gặp khi lập trình Insert vào cơ sở dữ liệu. Lỗi này xảy ra do định dạng ngày tháng trên hệ thống và định dạng dữ liệu ngày tháng của người dùng nhập là khác nhau, người việt hay sử dụng định dạng là dd/MM/yyyy (ngày/tháng/năm) nhưng trên hệ thống (mặc định của người Mỹ/Anh …) sử dụng định dạng MM/dd/yyyy (tháng/ngày/năm)
      Trong chương trình trên sử dụng control MaskedTextBox để nhập nên sẽ phát sinh nhiều lỗi nhập dữ liệu ngày tháng. Bạn có thể thay thế sử dụng control DateTimePicker và thiết lập Format = Short, control này sẽ giúp giảm thiểu rất nhiều lỗi liên quan đến kiểu dữ liệu ngày tháng.
      2. Phần In hoá đơn này thực hiện việc xuất dữ liệu ra file Excel, phần này thực hiện lập trình thao tác với thư viện Excel do đó bạn cần phải Reference tới thư viện này thì sẽ không gặp lỗi. Bạn làm như sau: kích vào Solution Explorer > References, kích chuột phải chọn Add Reference … cửa sổ Add Reference hiện ra, bạn chọn Tab COM rồi tìm đến thư viện có tên Microsoft Excel 14.0 Object Library rồi kích nút OK. Như vậy bạn sẽ không gặp lõi đó nữa
      3. Về phần tạo báo cáo mình đã viết 2 bài, bạn có thể tham khảo làm theo nhé
      http://timoday.edu.vn/tao-bao-cao-dung-control-reportviewer/
      http://timoday.edu.vn/tao-bao-cao-voi-crystal-report-trong-c/
      Chúc bạn thành công.

  2. Phước viết:

    Mình không rành về c# lắm ! nhưng sao mình thấy ứng dụng của bạn ít form qá vậy.

    • Phan Tiến viết:

      Hi Bạn,
      Các form tương đối đầy đủ, bởi trong mỗi form gộp rất nhiều chức năng nên bạn cảm thấy ít. Và đây cũng là một CSDL tương đối đơn giản, chỉ có tất cả 6 bảng nên số form nó cũng không quá nhiều.
      Bạn có thể làm theo, form nào bạn cảm thấy thiếu thì có thể thông báo cho mình. Mình sẽ giải thích thêm.

  3. VoDanhLapTrinh viết:

    cho mình hỏi khi Xoá bản sao cơ sở dữ liệu: trong cửa sổ Solution Explorer rồi có mở lại được k. ví dụ mình cần cập nhật thêm 1 table nữa thì làm sao có để thêm .
    write me soon

  4. Maria viết:

    sau khi viết xong form nhân viên . chạy chương trình thì bị lỗi này :
    InvailidOperatationException was Unhandled
    An unhandled exception of type ‘System.InvalidOperationException’ occurred in System.Data.dll

    Additional information: Fill: SelectCommand.Connection property has not been initialized.
    ví trí lỗi chỉ tới :
    //Lấy dữ liệu vào bảng
    public static DataTable GetDataToTable(string sql)
    {

    SqlDataAdapter MyData = new SqlDataAdapter(); //Định nghĩa đối tượng thuộc lớp SqlDataAdapter
    //Tạo đối tượng thuộc lớp SqlCommand
    MyData.SelectCommand = new SqlCommand();
    MyData.SelectCommand.Connection = Functions.Con; //Kết nối cơ sở dữ liệu
    MyData.SelectCommand.CommandText = sql; //Lệnh SQL
    //Khai báo đối tượng table thuộc lớp DataTable
    DataTable table = new DataTable();
    MyData.Fill(table);
    return table;
    }
    giúp e với a

    • Phan Tiến viết:

      Hi Em,
      Lỗi của em xảy ra khi em chưa khởi tạo chuỗi kết nối tới cơ sở dữ liệu.
      Thứ nhất: Kiểm tra lại lớp Functions ở mục 4.1, chỗ phần phương thức public static void Connect() xem dòng code
      Con.ConnectionString = “chuỗi kết nối tới CSDL” xem em truyền đã đúng chưa.
      Thứ hai: Kiểm tra xem em khởi tạo đúng rồi thì em kiểm tra ở mục 4.2 phương thức frmMain_Load em đã gọi phương thức Connect() của hàm Functions chưa
      Class.Functions.Connect();

  5. Sơn viết:

    Làm thế nào để đóng gói phần mềm mình viết vậy thầy ơi. Mà khi cài ra máy tính khác, thì sử dụng được đó thầy. Thầy chỉ em với thầy ơi.

    • Phan Tiến viết:

      Cảm ơn câu hỏi rất hay của em. Phần đóng gói phần mềm là công đoạn cuối cùng trong quá trình phát triển phần mềm để đóng gói chuyển giao cho khách hàng.
      Trong Visual Studio em làm rất đơn giản:
      – Em kích chuột phải vào Solution của Project hiện tại của em (ví dụ em đang làm quản lý bán hàng), rồi am chọn Add => New Project => Other project type => Setup Project
      Chú ý: đối với những phiên bản VS 2012 trở đi, cần cài đặt thêm Visual Studio Installer (search google)
      Em thử nghịch, lựa chọn các tuỳ chọn để xem kết quả. Khi có thời gian mình sẽ viết bài hướng dẫn chi tiết.

  6. Phước viết:

    Thầy cho em hỏi. nút tìm kiếm với hiển thị danh sách trong form hàng để làm gì . với lại mnu tìm kiếm khách hàng với hàng liên kết với form nào vậy ! thanks.

    • Phan Tiến viết:

      Hi em,
      Trong form hàng hoá có rất nhiều hàng, chức năng nút tìm kiếm để cho phép tìm kiếm một sản phẩm theo một tiêu chí nào đó.
      mnuFindKhachHang hiện tại trong code thiếu, em có liên kết với form frmDMKhachHang, trong form này thêm một nút tìm kiếm

  7. Sơn viết:

    Thầy ơi, thầy chỉ cho em cách làm báo cáo từ ngày đến ngày của sản phẩm bài quản lý bán hàng mà thầy viết đi thầy. Em cảm ơn thầy nhiều ạ.

    • Phan Tiến viết:

      Em có thể xem sơ đồ thực thể liên kết (Relationship) thì em thấy chỉ trong bảng dữ liệu tblHDBan có trường Ngày tháng. Ví dụ muốn tạo báo cáo các sản phẩm bán ra trong một khoảng nào đó thì đâu tiên quan trọng em phải viết được câu lệnh SQL lấy dữ liệu mình cần để làm báo cáo, ví dụ câu lệnh SQL em có thể tham khảo:
      “Select Mahang, Tenhang From tblHang, tblChiTietHDBan, tblHDBan Where (tblHang.Mahang = tblChiTietHDBan.Mahang) AND (tblChiTietHDBan.MaHDBan = tblHDBan.MaHDBan) AND (NgayBan>#1/1/2016#) AND (NgayBan< #4/4/2016#)" Sau đó em có thể tham khảo thêm bài này để gắn dữ liệu lên báo cáo http://timoday.edu.vn/tao-bao-cao-dung-control-reportviewer/

  8. Sơn viết:

    Severity Code Description Project File Line Suppression State
    Error CS0161 ‘Functions.ChuyenSoSangChu(string)’: not all code paths return a value QuanLyBanHang C:\Users\SON\Documents\Visual Studio 2015\Projects\QuanLyBanHang\QuanLyBanHang\Class\Functions.cs 206 Active

    Em bị lỗi này là lỗi gì vậy thầy ơi hic hic

    • Phan Tiến viết:

      Em đưa vào dữ liệu cho hàm Functions.ChuyenSoSangChu(string) nhưng nó không thể chuyển được, em kiểm tra lại xem dữ liệu em đưa vào có đúng không.
      Ví dụ như
      Functions.ChuyenSoSangChu(“343545”) => thì ok
      Nhưng Functions.ChuyenSoSangChu(“343a54b5”) => thì sẽ bị lỗi

  9. Sơn viết:

    Dạ thầy ơi đây là lỗi gì vậy thầy. Thầy coi giúp em ạ. Em cảm ơn thầy nhiều ạ hic hic
    http://www.upsieutoc.com/image/54MI

    • Phan Tiến viết:

      Do em thay đổi cấu hình khi biên dịch nên khi biên dịch nó bị lỗi. Em kiểm tra lại:
      1. Đặt đường dẫn ouput cho đúng (kích vào menu Project > Tên Project Properties > Build > Output path đặt lại là bin\Debug)
      2. Vào menu Build > Configuration Manager, và bạn thấy có một dòng tên Project của bạn, kiểm tra xem nếu checkbox Build chưa được chọn thì kích vào để chọn.

  10. Sơn viết:

    Dạ thầy ơi sao em kết nối cơ sở dữ liệu không được thầy ơi. Đây là lỗi gì vậy thầy. Thầy giúp em với thầy. Em cảm ơn thầy nhiều ạ . Em cùi quá nên hỏi thầy riếc, mong thầy thông cảm ạ hic hic.
    http://www.upsieutoc.com/image/Rnhl

    • Phan Tiến viết:

      Đây là lỗi liên quan đến chuối kết nối đến CSDL, em cần kiểm tra lại thông tin kết nối đến SQL Server của em như tên server, tên database và user, password để truy cập CSDL đó.
      Ví dụ trong code :
      Con.ConnectionString = @”Data Source=.\SQLEXPRESS;AttachDbFilename=” + Application.StartupPath + @”\Quanlybanhang.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True”;
      – Data Source: em cần truyền vào tên SQL Server được cài trên máy em
      – AttachDbFilename: em đưa vào đường dẫn đến CSDL của em.

  11. Phước viết:

    Thầy cho e hỏi ! làm sao sứa lỗi khi load ảnh lên trong danh mục sản phẩm khi ảnh đó đã bị xóa.

    • Phan Tiến viết:

      Mình chưa hiểu rõ ý của em hỏi lắm. Khi ảnh đã bị xoá thì trên form hiển thị ảnh sẽ hiển thị dấu “x” và ảnh không được hiển thị. Để sửa thì em phải cập nhật ảnh lại hoặc kiểm tra không có ảnh thì cho hiển thị một ảnh mặc định nào đó.

  12. Vũ Lê Thục Nhi viết:

    http://www.upsieutoc.com/image/epFAl
    Thưa thầy cho em hỏi đây là lỗi gì? Em cảm ơn nhiều

  13. Vũ Lê Thục Nhi viết:

    Thưa thầy cho em hỏi code của btnNgay ở đâu ạ???

    • Phan Tiến viết:

      trong phần f. Form Hoá đơn bán hàng chỗ form frmHoadonBan có nút btnNgay, chức năng để lấy ngày hiện tại mà bán sản phẩm đó. Em có thể kích đúp vào nút đó và viết code:
      txtNgayBan.Text = DateTime.Now.ToString();
      – Chú ý, nếu em không muốn viết code thì có thể thay txtNgayBan và btnNgay bằng control có tên DateTimePicker để người sử dụng chọn vào ngày bán sản phẩm.

  14. Huỳnh Quốc Tuấn viết:

    Thầy ơi em làm giống như thầy mà sao phần dataGridView_Click không hiển thị các điều khiển lên trên Form vậy?

    • Phan Tiến viết:

      Em đang lập trình chức năng e) Phương thức dataGridView_Click này đúng không? Em có thể làm như sau để chắc chắn xem code của em có chạy vào sự kiện này hay không, em thử viết một thông báo hiển thị lên màn hình (ví dụ dùng MessageBox.Show(“Đây là sự kiện dataGridView_Click”), khi em chạy kích thử vào DataGridView mà nó hiển thị được thông báo này thì sự kiện này chạy bình thường.
      Nếu không xuất hiện thông báo trên thì sự kiện của em chưa tích hợp được vào code (có thể do em copy trực tiếp code trên trang rồi paste vào) => Nếu như vậy em xoá phần code này đi, rồi trên giao diện của Form, em kích đúp và DataGridView, nó sẽ tự động sinh cho em sự kiện này. Rồi em viết tiếp code vào đó.

      • Huỳnh Quốc Tuấn viết:

        thầy kiểm tra dùm em đây là lỗi gì mà em sửa dữ liệu ở frmDMNhanvien không được vậy thầy, https://uphinhnhanh.com/images/2016/10/30/loib9d28.png, đây là file của em: http://www.mediafire.com/file/mbigfqdj1si3d2m/QuanLyBanHang.rar

        • Phan Tiến viết:

          Trong frmDMNhanvien có trường dữ liệu nhập dữ liệu ngày sinh, người Việt Nam thường sử dụng định dạng dd/mm/yyyy nên trong chương trình sử dụng mặc định theo định dạng này => nên để không bị lỗi em cần nhập dữ liệu theo định dạng: 2 số cho ngày, 2 số cho tháng và 4 số cho năm.

          • Huỳnh Quốc Tuấn viết:

            em nhập vậy rồi mà vẫn không sửa được ở nút sửa dữ liệu thầy.

          • Huỳnh Quốc Tuấn viết:

            Em sửa dữ liệu ở frmDMNhanvien không được thầy ơi.

          • Phan Tiến viết:

            Chú ý: vì cột dữ liệu ngày sinh mình thiết kế là kiểu dữ liệu datetime nên khi insert một bản ghi vào dữ liệu sẽ có thêm cả thời gian, nên khi em kích trên DataGridView sẽ thấy có cả thời gian ví dụ như 12/02/1999 12:00:00 SA. Để tránh lỗi ta thêm một bước cắt ngày tháng riêng ra và thời gian riêng ra.
            Em có thể tham khảo hàm IsDate mình viết lại như sau:

            
              public static bool IsDate(string date)
                    {
                        string [] d = date.Split(' ');
                        string [] elements = d[0].Split('/');
                        if ((Convert.ToInt32(elements[0]) >= 1) && (Convert.ToInt32(elements[0]) < = 31) && (Convert.ToInt32(elements[1]) >= 1) && (Convert.ToInt32(elements[1]) < = 12) && (Convert.ToInt32(elements[2]) >= 1900))
                            return true;
                        else return false;
                    }
            
      • Huỳnh Quốc Tuấn viết:

        Em cám ơn thầy em làm được rồi!

      • Huỳnh Quốc Tuấn viết:

        Thầy cho em hỏi để bỏ 12:00:00 AM ở phía sau ngày sinh mình làm sao thầy?

  15. Huỳnh Quốc Tuấn viết:

    Thầy cho em hỏi để bỏ 12:00:00 AM ở phía sau ngày sinh mình làm sao thầy?

    • Phan Tiến viết:

      Em chỉ muốn lưu trữ nguyên ngày tháng thì chọn kiểu dữ liệu cho cột dữ liệu cho bảng cơ sở dữ liệu của em, em chọn kiểu dữ liệu là Date thay vì DateTime như hiện nay.

  16. Huỳnh Quốc Tuấn viết:

    Thầy ơi thầy có thể bổ sung thêm phần code phân trang cho datagridview được không thầy?

  17. Tấn Văn viết:

    Thầy có thể chỉ dùm em lam sao để in được nhiều hóa đơn xuất trên một trang giấy A4,ví dụ như một trang giấy em chia làm 4 hóa đơn,em muốn in 8 hóa đơn thì nó sẽ in ra 2 tờ,và mã hóa đơn trên đó tang dần theo ví dụ như 1,2,3,4,5,6,7,8

  18. Nhi viết:

    Thầy cho em hỏi,Ví dụ em muốn cộng cột đơn giá và thành tiền để ra cột mới là tổng của 2 cột trong excel thì sao ạ,giống hàm sum trong excel ạ nhưng em k biết code excel cho c# như thế nào??

    • Phan Tiến viết:

      Việc gì em phải viết code phức tạp làm gì, em chỉ cần viết câu lệnh SQL sau đó hiển thị lên DatagridView là được mà, ví dụ như
      MaSP | DGia | TTien |
      ——-+——-+——-+
      1 | 1.23 | 2.23 |
      2 | 23.03 | 12.23 |
      3 | 7.23 | 9.05 |
      Thì câu lệnh SQL như sau:

      
      SELECT DGia, TTien, (DGia + TTien) as 'Tong'
      FROM SanPham
      
  19. long viết:

    em muốn xem giao diện chạy khi viết code xong a.

    • Phan Tiến viết:

      Theo ý anh hiểu thì em muốn hỏi là sau khi viết xong code, chạy nó ra giao diện đúng không?
      Khi em thiết kế trong chế độ WinForm, em kéo thả các control vào Form và có thể code. Em muốn chạy thì chỉ cần ấn phím F5 trên bàn phím thì nó sẽ biên dịch chương trình. Nếu chương trình em không có lỗi thì sẽ xuất hiện giao diện form em đã thiết kế.

  20. Dũng viết:

    Em chào anh,
    Anh ơi, khi em làm theo anh ấy ạ, lúc chạy phần mềm, nó ko hiển thị ngay cơ sở dữ liệu ấy ạ, hiển thị 1 cái datagridview xám xám như mình mới kéo từ winform thôi. Sau đó em thêm dữ liệu thì nó mới lại có, bắt đầu từ dữ liệu thứ nhất. Nếu lần này em thêm 3 dữ liệu, em tắt đi thì trong SQL có 3 dữ liệu. Lần mở phần mềm sau, nó ko hiển thị gì, thêm thì lại từ dữ liệu thứ nhất. Có lẽ do hàm load dữ liệu vào datagridview có vấn đề ạ?

    • Phan Tiến viết:

      Với lỗi mô tả anh biết em bị lỗi gì rồi.
      Do em viết thiếu sự kiện Form_Load nên khi chương trình em mới đầu chạy nó không nạp dữ liệu lên DataGridView, chỉ khi em Insert dữ liệu thì nó mới hiển thị dữ liệu lên.
      Ví dụ như frmChatLieu, em gọi phương thức LoadDataGridView() ở sự kiện frmChatLieu_Load thì khi form hiển thị lên, nó sẽ nạp dữ liệu lên DataGridView

  21. Bảo Ngọc viết:

    ‘QuanLiBanHang.Class.Functions.ChuyenSoSangChu(string)’:not all code paths return a value

  22. Bảo Ngọc viết:

    Thầy xem giúp em lỗi này với ạ!

  23. My Dan viết:

    cho em hỏi , frmHOADONBAN là của form HÓA ĐƠN hay CHITIETHD vậy ạ :'(
    e code xong, lại ko biết 2 form đó liên kết với nhau bằng cách nào?
    – cái Phần MÃ hóa đơn, thầy đang dùng Combobox hay Text vậy ahj :'(

  24. My Dan viết:

    http://www.upsieutoc.com/image/cwGaMM
    thầy xem giúp em lỗi gì vậy ạ 🙁

    • Phan Tiến viết:

      Chào em,
      Lỗi này liên quan đến câu lệnh SQL của em, em viết sai nên nó không chạy được. Em thử show messagebox câu lệnh SQL lên rồi kiểm tra lại nhé

  25. TuanHung viết:

    An unhandled exception of type ‘System.InvalidOperationException’ occurred in System.Data.dll

    Additional information: Fill: SelectCommand.Connection property has not been initialized.
    ————————————————————————————————————————-
    Thầy xem giúp em lỗi này với ạ, em khắc phục nhưng có không kết quả 🙂

  26. TuanHung viết:

    public static bool CheckKey(string sql)
    {
    SqlDataAdapter MyData = new SqlDataAdapter(sql, con);
    DataTable table = new DataTable();
    MyData.Fill(table);
    if (table.Rows.Count > 0)
    return true;
    else return false;
    }
    ——————————————————-
    Em cop lại code bên trên, thầy xem họ em xem là còn thiếu gì không ạ!

  27. huế viết:

    thầy ơi trong class functions cái dòng public static DataTable GetDataToTable(string sql) này là mình tự đánh vào hay là code tự sinh do mình kích vào đâu ạ.

  28. Khoa viết:

    Thầy Ơi cho em hỏi? Em muốn làm web có chức năng login bằng facebook hay bằng CSDL với chức năng nạp tiền bằng card và chức năng mua nhạc chất lượng cao thì phải làm sao thầy?

  29. Tiến Đạt viết:

    Thầy ơi ! giúp em với.
    Em add References thì phiên bản của máy em là Microsoft Excel 15.0

    Em cần chỉnh lại câu lệnh để in háo đơn ra excel như thế nào vậy thầy ?

    CỨ bị lỗi này suốt

    Error 5 Cannot apply indexing with [] to an expression of type ‘object’

    • Phan Tiến viết:

      Lỗi ở dòng bao nhiêu hả em? Em phải cho mình dòng code nó bị lỗi thì mới biết được.
      Lỗi này liên quan đến việc gán dữ liệu không cùng kiểu với nhau.

  30. Lê Cao Thế viết:

    Thầy cho e hỏi, Chương trình này viết trên Visual 2012 được kô ạ, c.ơn thầy !!!

    • Phan Tiến viết:

      Hoàn toàn có thể viết trên VS 2012 em nhé!

    • Lê Cao Thế viết:

      Thầy ơi e chưa rành về CSDL. Không biết có bài viết nào hướng dẫn chi tiết cách tạo CSDL, tạo Table, quan hệ giữa các bảng và kết nối CSDL. Mong thầy giúp đỡ, tks Thầy !!!

  31. Đông viết:

    Thưa thầy e vẫn không hiểu về phần DataGridView_DoubleClick cho lắm.
    Phần Chú ý: Thay đổi phạm vi truy cập của điều khiển txtMaHDBan thành Public trong form frmHoadonBan (trong file frmHoadonBan.Designer.cs) e không hiểu là thay đổi phạm vi truy cập của điều khiển txtMaHDBan thành Public trong frmHoadonban như nào??

    h) Phương thức DataGridView_DoubleClick
    Phương thức này cho phép người dùng nháy đúp chuột chọn một hóa đơn trên lưới, rồi gọi và hiển thị thông tin của hóa đơn đó lên form frmHoadonBan.

    Chú ý: Thay đổi phạm vi truy cập của điều khiển txtMaHDBan thành Public trong form frmHoadonBan (trong file frmHoadonBan.Designer.cs)

    private void DataGridView_DoubleClick(object sender, EventArgs e)
    {
    string mahd;
    if (MessageBox.Show(“Bạn có muốn hiển thị thông tin chi tiết?”, “Xác nhận”,MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
    {
    mahd = DataGridView.CurrentRow.Cells[“MaHDBan”].Value.ToString();
    frmHoadonBan frm = new frmHoadonBan();
    frm.txtMaHDBan.Text = mahd;
    frm.StartPosition = FormStartPosition.CenterParent;
    frm.ShowDialog();
    }
    }

    • Phan Tiến viết:

      – Để thay đổi phạm vi của biến điều khiển, em có thể chọn vào Control đó (cửa ổ thiết kế giao diện) => Chọn thuộc tính Modifier của control rồi em thay đổi thành Public thì nó sẽ được sở mọi nơi.

  32. Lê Cao Thế viết:

    Hi, Thầy
    Em ấn vào “Test Connection” thì bị lỗi này,thầy giúp em với !!!
    http://www.upsieutoc.com/image/pqqGqD

  33. LÊ MINH NHỰT viết:

    Chào Thầy, em bị lỗi ngay bước đầu tiên
    “Trong cửa sổ Solution Explorer, nháy phải chuột lên tên ứng dụng, chọn Add ->New Item… Chọn Data -> Service-based Database”
    Em đã thử nhiều cách sửa lỗi trên “https://stackoverflow.com/questions/13754563/sql-network-interfaces-error-26-error-locating-server-instance-specified” nhưng vẫn không được.
    Mong thầy giúp em, em xin cảm ơn Thầy!
    http://www.upsieutoc.com/image/pK2bQt

    • Phan Tiến viết:

      Em có cài phiên bản SQL Server nào trên máy của em không?
      Em có thể mở SQL Server Management trên máy em được không?

  34. Nguyen Vu viết:

    thầy cho e hỏi cái phần load dữ liêu lên combobox rồi kích Mã chon Thì hiện tên tương ứng trong textbox thì mình cần có 2 hàm này la dc ạ
    1:hàm GetFieldValues ở class Functions
    2:private void cboManhanvien_TextChanged(object sender, EventArgs e)
    {
    string str;
    if (cboManhanvien.Text == “”)
    txtTennhanvien.Text = “”;
    // Khi chọn Mã nhân viên thì tên nhân viên tự động hiện ra
    str = “Select Tennhanvien from tblNhanvien where Manhanvien =N'” + cboManhanvien.SelectedValue + “‘”;
    txtTennhanvien.Text = Functions.GetFieldValues(str);
    }

    • Phan Tiến viết:

      Phần Load dữ liệu lên Combobox nó xảy ra ở sự kiện Form_Load với hàm Functions.FillCombo(….)
      Còn sự kiện cboManhanvien_TextChanged xảy ra khi em thay đổi dữ liệu trong Combobox.

  35. Chi viết:

    Thầy ơi, Sau khi em thêm dữ liệu vào rồi, nhưng lúc tắt chương trình mở lại thì dữ liệu ko còn hả Thầy ?

    • Phan Tiến viết:

      Vì database của em khi chạy, chương trình tự động copy một bản mới vào thư mục chạy của chương trình. Nên khi chương trình em chạy, em thêm dữ liệu thì OK. Nhưng chạy lại thì dữ liệu bị mất hết.
      Em chọn vào tên Database của em ở cửa sổ Solution Explorer, rồi chọn dưới cửa sổ Properties => Thay bằng Copy If Newer
      Xem ảnh tương tự:
      http://timoday.edu.vn/wp-content/uploads/2016/06/ThayDoiCopyReport.png

Bình luận

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 *