版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的
图99A-28 入库单操作窗口设计
入库单中,如果修改了货物种类、数量,应该对前后货物情况进行组合,获得货物增删情况,并最终对应修改在货物信息表的库存量字段中的数据。例如下面
原入库单中入库的三种货物的ID和数量: 1,10 2,203,30
修改后入库单中三种货物的ID和数量:2,253,204,15
先进行组合,然后再修改货物信息表的库存量
组合后的货物ID和数量: 1,102,-53,104,-15
在代码中使用 Dictionary
全部代码如下:
//是否新增标志,如果是,设置为True;否则False
Boolean isAdd;
//传入的入库单ID号,也是判断新增还是修改的依据
int orderId;
OleDbConnection connection;
//修改入库清单中的物品时设置标记
Boolean isEditGoods = false;
protected struct GoodsType
{
public int TypeId;
public string TypeInfo;
}
List<int> arrExpress;
List
//如果是修改原入库单
//键值对分别保存 货物ID和对应数量 ,需要在货物信息表(库存)中进行增删
//原入库单中的
Dictionary<int, int> dicGoodsInfoOld;
//修改后入库单中的
Dictionary<int, int> dicGoodsInfoNew;
//根据传入的入库单号进行确认操作
//如果入库号为0,那么新增
//否则,修改
public FormStorageInOrder(int OrderId)
{
// 此调用是设计器所必需的。
InitializeComponent();
// 在 InitializeComponent() 调用之后添加任何初始化。
this.orderId = OrderId;
if (this.orderId == 0)
isAdd = true;
else
isAdd = false;
}
private void FormStorageInOrder_Load(object sender, EventArgs e)
{
dtpOrder.Value = DateTime.Now;
dtpEnter.Value = DateTime.Now;
arrExpress = new List<int>();
arrGoodsType = new List
dicGoodsInfoOld = new Dictionary<int, int>();
dicGoodsInfoNew = new Dictionary<int, int>();
connection = new OleDbConnection(classMod.databaseConnString);
//打开数据连接
connection.Open();
fillControls();
drawControls();
}
//填充数据选项,主要是 cbExpress 和 cbGoodsType
private void fillControls()
{
//新建OleDbCommand对象实例
OleDbCommand command = new OleDbCommand();
//==========填充货物种类选择框===================
//要执行的SQL查询
command.CommandText = "select * from 货物类别";
//设置OleDbCommand的数据连接为OleDbConnection
command.Connection = connection;
//声明OleDbDataReader对象
OleDbDataReader odReader;
//通过OleDbCommand的ExecuteReader方法获得OleDbDataReader对象实例。
odReader = command.ExecuteReader();
GoodsType gt;
//如果OleDbDataReader中包含数据
if (odReader.HasRows)
{
//循环读取每一行数据,直到Read方法返回False
while (odReader.Read())
{
gt = new GoodsType();
gt.TypeId = (int)odReader.GetValue(0);
cbGoodsType.Items.Add(odReader.GetValue(1));
gt.TypeInfo = odReader.GetValue(2).ToString();
arrGoodsType.Add(gt);
}
}
//关闭数据读取器
odReader.Close();
}
//向控件中填充数据
//如果是新增,那么保持控件原状
//如果是修改,那么需要读取数据库中的数据再填充
private void drawControls()
{
if (isAdd == true)
{
cbGoodsType.SelectedIndex = 0;
EnabledControls();
}
else
{
//如果是修改数据,那么填充所有控件中的数据
//新建OleDbCommand对象实例
OleDbCommand command = new OleDbCommand();
//=========填充lvGoodsType==================
//要执行的SQL查询
command.CommandText = "select 操作员ID,订购日期,入库日期 from 入库单 where 入库单ID=" + orderId;
//设置OleDbCommand的数据连接为OleDbConnection
command.Connection = connection;
//声明OleDbDataReader对象
OleDbDataReader odReader;
//通过OleDbCommand的ExecuteReader方法获得OleDbDataReader对象实例。
odReader = command.ExecuteReader(CommandBehavior.SingleRow);
odReader.Read();
//省略了检查数据记录是否有效
int recordUserID = (int)odReader.GetValue(0);
dtpOrder.Value = (DateTime)odReader.GetValue(1);
dtpEnter.Value = (DateTime)odReader.GetValue(2);
cbGoodsType.SelectedIndex = 0;
odReader.Close();
//=========填充 lvEnterInfo ==================
//要执行的SQL查询
command.CommandText = "SELECT 入库单明细.产品ID, 货物信息.产品名称, 入库单明细.单价, 入库单明细.数量 " +
"FROM 货物信息 INNER JOIN 入库单明细 ON 货物信息.产品ID = 入库单明细.产品ID " +
"where 入库单明细.入库单ID=" + orderId;
//设置OleDbCommand的数据连接为OleDbConnection
command.Connection = connection;
odReader = command.ExecuteReader();
ListViewItem lvItem;
//如果OleDbDataReader中包含数据
if (odReader.HasRows)
{
//循环读取每一行数据,直到Read方法返回False
while (odReader.Read())
{
lvItem = new ListViewItem(odReader.GetValue(0).ToString());
lvItem.SubItems.Add(odReader.GetValue(1).ToString());
lvItem.SubItems.Add(odReader.GetValue(2).ToString());
lvItem.SubItems.Add(odReader.GetValue(3).ToString());
lvEnterInfo.Items.Add(lvItem);
dicGoodsInfoOld.Add(odReader.GetInt32(0), odReader.GetInt16(3));
}
}
odReader.Close();
UnabledControls();
if (recordUserID != classMod.loginId)
{
btnSave.Enabled = false;
btnEdit.Enabled = false;
}
}
}
//如果是新建,则允许控件操作
private void EnabledControls()
{
dtpOrder.Enabled = true;
dtpEnter.Enabled = true;
lvGoods.Enabled = true;
btnGoodsAdd.Enabled = true;
btnDelete.Enabled = true;
txtGoodsPrice.Enabled = true;
nudGoodsCount.Enabled = true;
lvEnterInfo.Enabled = true;
btnSave.Enabled = true;
btnEdit.Enabled = false;
btnClose.Enabled = true;
}
//如果是修改,初始不允许控件操作
private void UnabledControls()
{
dtpOrder.Enabled = false;
dtpEnter.Enabled = false;
cbGoodsType.Enabled = false;
lvGoods.Enabled = true;
btnGoodsAdd.Enabled = false;
btnDelete.Enabled = false;
txtGoodsPrice.Enabled = false;
nudGoodsCount.Enabled = false;
lvEnterInfo.Enabled = true;
btnSave.Enabled = false;
btnEdit.Enabled = true;
btnClose.Enabled = true;
}
//入库物类别选中
private void cbGoodsType_SelectedIndexChanged(object sender, EventArgs e)
{
int selIndex = cbGoodsType.SelectedIndex;
lblGoodsTypeInfo.Text = arrGoodsType[selIndex].TypeInfo;
lvGoods.Items.Clear();
fillLvGoods(arrGoodsType[selIndex].TypeId);
}
//当选择货物种类时,填充lvGoodsType数据
private void fillLvGoods(int TypeId)
{
//新建OleDbCommand对象实例
OleDbCommand command = new OleDbCommand();
//=========填充lvGoodsType==================
//要执行的SQL查询
command.CommandText = "Select 产品ID,产品名称,采购价格,销售价格,库存量 from 货物信息 where 类别ID=" + TypeId;
//设置OleDbCommand的数据连接为OleDbConnection
command.Connection = connection;
//声明OleDbDataReader对象
OleDbDataReader odReader;
//通过OleDbCommand的ExecuteReader方法获得OleDbDataReader对象实例。
odReader = command.ExecuteReader();
ListViewItem lvItem;
//如果OleDbDataReader中包含数据
if (odReader.HasRows)
{
//循环读取每一行数据,直到Read方法返回False
while (odReader.Read())
{
lvItem = new ListViewItem(odReader.GetValue(0).ToString());
lvItem.SubItems.Add(odReader.GetValue(1).ToString());
lvItem.SubItems.Add(odReader.GetValue(2).ToString());
lvItem.SubItems.Add(odReader.GetValue(3).ToString());
lvItem.SubItems.Add(odReader.GetValue(4).ToString());
lvGoods.Items.Add(lvItem);
}
}
odReader.Close();
}
//修改数据
private void btnEdit_Click(object sender, EventArgs e)
{
//按下后允许修改数据
EnabledControls();
}
//保存数据
private void btnSave_Click(object sender, EventArgs e)
{
//新建OleDbCommand对象实例
OleDbCommand command = new OleDbCommand();
//设置OleDbCommand的数据连接为OleDbConnection
command.Connection = connection;
//保存数据,分两种情况
//新增或修改
if (isAdd == true)
{
//1、将出库单添加到数据库中
//新增的SQL语句
command.CommandText = getAddSql();
//不管是新增还是修改,都不用返回值,所以使用ExecuteNonQuery。
command.ExecuteNonQuery();
//2、新增需要返回此次出库单对应的编号
command.CommandText = "Select top 1 入库单ID from 入库单 order by 入库单ID desc";
OleDbDataReader odReader;
odReader = command.ExecuteReader(CommandBehavior.SingleResult);
odReader.Read();
//记录刚建的入库单ID号
int newOrderID = odReader.GetInt32(0);
odReader.Close();
//3、向出库单明细中加入出库物品
addGoodsDetailed(newOrderID);
//4、修改货物信息表中对应的数量
editGoodsCount();
//当前出库单ID
orderId = newOrderID;
//设置标志为修改
isAdd = false;
}
else
{
//修改的SQL语句
command.CommandText = getEditSql();
//不管是新增还是修改,都不用返回值,所以使用ExecuteNonQuery。
command.ExecuteNonQuery();
//如果修改了出库物品,那么
if (isEditGoods == true)
{
//1、删除出库单明细中原有出库物品
command.CommandText = "delete * from 出库单明细 where 订单ID=" + orderId;
command.ExecuteNonQuery();
//2、重新向出库单明细中加入出库物品
addGoodsDetailed(orderId);
//3、修改货物信息表中对应的数量
editGoodsCount();
}
}
//刷新货物信息 lvGoods
int selIndex = cbGoodsType.SelectedIndex;
lblGoodsTypeInfo.Text = arrGoodsType[selIndex].TypeInfo;
lvGoods.Items.Clear();
fillLvGoods(arrGoodsType[selIndex].TypeId);
//保存之后禁止编辑数据
UnabledControls();
}
//新增时候插入入库单详细使用的sql语句
private string getAddSql()
{
//订购日期时间
string orderTime = dtpOrder.Text;
//入库日期时间
string enterTime = dtpEnter.Text;
string sqlString;
sqlString = "insert into 入库单(操作员ID,订购日期,入库日期,是否删除) " +
"values(" + classMod.loginId + ",'" + orderTime + "','" + enterTime + "','否')";
return sqlString;
}
//修改时候入库单详细使用的sql语句
private string getEditSql()
{
//订购日期时间
string orderTime = dtpOrder.Text;
//入库日期时间
string enterTime = dtpEnter.Text;
string sqlString;
sqlString = "update 入库单 set 订购日期='" + orderTime + "',入库日期='" + enterTime + "' where 入库单ID=" + orderId;
return sqlString;
}
//增加入货单明细内容
private void addGoodsDetailed(int id)
{
//新建OleDbCommand对象实例
OleDbCommand command = new OleDbCommand();
//设置OleDbCommand的数据连接为OleDbConnection
command.Connection = connection;
ListViewItem lvi;
int GoodsID;
Single GoodsPrice;
int GoodsCount;
//购买清单中的货物逐项加入数据表 出库单明细
for (int i = 0; i < lvEnterInfo.Items.Count; i++)
{
lvi = lvEnterInfo.Items[i];
GoodsID = int.Parse(lvi.SubItems[0].Text);
GoodsPrice = Single.Parse(lvi.SubItems[2].Text);
GoodsCount = int.Parse(lvi.SubItems[3].Text);
command.CommandText = "insert into 入库单明细 values(" + id + "," + GoodsID + "," + GoodsPrice + "," + GoodsCount + ")";
command.ExecuteNonQuery();
dicGoodsInfoNew.Add(int.Parse(lvi.SubItems[0].Text), int.Parse(lvi.SubItems[3].Text));
}
}
//修改货物信息表中的数量
private void editGoodsCount()
{
//将前后两个Dictionary组合在一起,获得修改后货物的增减量
//A B 组合后
//1,10 2,25 1,10
//2,20 3,20 2,-5
//3,30 4,15 3,10
// 4,-15
//修改原 Dictionary
for (int i = 0; i < dicGoodsInfoNew.Count; i++)
{
KeyValuePair<int, int> singleGoodsNew = dicGoodsInfoNew.ElementAt(i);
if (dicGoodsInfoOld.ContainsKey(singleGoodsNew.Key) == true)
{
Console.WriteLine("输出 : {0} {1}", dicGoodsInfoOld[singleGoodsNew.Key], singleGoodsNew.Value);
dicGoodsInfoOld[singleGoodsNew.Key] = dicGoodsInfoOld[singleGoodsNew.Key] - singleGoodsNew.Value;
}
else
dicGoodsInfoOld.Add(singleGoodsNew.Key, 0 - singleGoodsNew.Value);
}
//修改数据库
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
//购买清单中的货物逐项加入数据表 出库单明细
foreach (KeyValuePair<int, int> singleGoodsNew in dicGoodsInfoOld)
{
//只需要对数量有变化的货物进行修改
if (singleGoodsNew.Value != 0)
{
command.CommandText = "update 货物信息 set 库存量=库存量-(" + singleGoodsNew.Value + ") where 产品ID=" + singleGoodsNew.Key;
//Console.WriteLine("value:" + singleGoodsNew.Value);
//Console.WriteLine(command.CommandText);
command.ExecuteNonQuery();
}
}
//数据库中修改后,将原Dictionary的值修改为 新Dictionary的值
dicGoodsInfoOld = dicGoodsInfoNew;
dicGoodsInfoNew.Clear();
}
//按下关闭按钮
private void btnClose_Click(object sender, EventArgs e)
{
if (btnSave.Enabled == true)
{
if (MessageBox.Show("数据未保存,是否退出?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK)
this.Close();
}
else
{
this.Close();
}
}
//点击lvGoods中的项目,将数据添加到对应位置
private void lvGoods_MouseClick(object sender, MouseEventArgs e)
{
ListViewHitTestInfo lvhti = lvGoods.HitTest(e.X, e.Y);
if (lvhti.Item == null)
return;
lblGoodsID.Text = lvhti.Item.SubItems[0].Text;
lblGoodsName.Text = lvhti.Item.SubItems[1].Text;
txtGoodsPrice.Text = lvhti.Item.SubItems[3].Text;
}
//购买的货物信息增加到lvBuyInfo
private void btnGoodsAdd_Click(object sender, EventArgs e)
{
string GoodsID = lblGoodsID.Text;
string GoodsName = lblGoodsName.Text;
Single GoodsPrice;
if (Single.TryParse(txtGoodsPrice.Text, out GoodsPrice) == false)
{
MessageBox.Show("不是有效的货物价格。");
return;
}
int GoodsCount = (int)nudGoodsCount.Value;
for (int i = 0; i < lvEnterInfo.Items.Count; i++)
if (GoodsID == lvEnterInfo.Items[i].Text)
{
MessageBox.Show("该货物已经添加,请先删除再添加。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//添加到lvEnterInfo
ListViewItem lvi = new ListViewItem(GoodsID);
lvi.SubItems.Add(GoodsName);
lvi.SubItems.Add(GoodsPrice.ToString());
lvi.SubItems.Add(GoodsCount.ToString());
lvEnterInfo.Items.Add(lvi);
//标记修改了出库物品
isEditGoods = true;
}
//删除增加的出库物品
private void btnDelete_Click(object sender, EventArgs e)
{
if (lvEnterInfo.SelectedItems.Count < 1)
{
MessageBox.Show("未选择需要删除的数据");
return;
}
lvEnterInfo.Items.Remove(lvEnterInfo.SelectedItems[0]);
//标记修改了出库物品
isEditGoods = true;
}
private void FormStorageInOrder_FormClosing(object sender, FormClosingEventArgs e)
{
connection.Close();
}
学习更多vb.net知识,请参看vb.net 教程 目录
学习更多C#知识,请参看C#教程 目录