最近需要做一个样品单管理系统,需要的功能有如下要求:
1.需要能批量导入数据 即支持从Excel里复制粘贴数据,或复制粘贴到Excel里
2.需要能展示出BOM结构,即各节点,点击可以查看数据
3.能区分出新料,旧料,如是新料自动进入要样阶段,旧料进入领料阶段
4.能实时跟踪要样材料进度,进行适时提醒通知
5.可以通过邮件或短信通知
6.完成的样品单可以进行存档
7.其它一些功能要求等
数据使用MySql存放,对于前两点用C# 写个客户端处理,主要是将BOM导入到数据库里
然后后续工作用PHP 在浏览器里执行
这里记录一下前两点的需要解决的问题 过程记录如下
第一点参考了网上一部分代码,经过实际测试没有问题,代码如下
private void toolStripMenuItem_Paste_Click(object sender, EventArgs e) { if (pcb_panel == true && pcb_type == "N") { MessageBox.Show("请选择PCB制程!"); return; } if (dataGridView1.SelectedCells.Count == 0) { MessageBox.Show("请选择一个单元格再操作!"); return; } else if (dataGridView1.SelectedCells[0].ColumnIndex != 0) { MessageBox.Show("请选择第一列的单元格粘贴!"); return; } string pText = Clipboard.GetText(); if (string.IsNullOrEmpty(pText)) return; //获取所复制区域的行数和列数 int rowNum = 0, colNum = 0; for (int i = 0; i < pText.Length; i++) { if (pText.Substring(i, 1) == "\n") rowNum++; if (pText.Substring(i, 1) == "\t") colNum++; } if (pText.Substring(pText.Length - 1, 1) == "\n") rowNum -= 1; //针对Excel单元格末行为\n colNum = colNum / (rowNum + 1); if (colNum > 12) { MessageBox.Show("复制的数据-列数不能超过10列!!!"); return; } //将获取的pText字符串按行和列拆分为二维数组 object[,] data = new object[rowNum + 1, colNum + 1]; string rowStr = null; for (int rowIndex = 0; rowIndex < (rowNum + 1); rowIndex++) { for (int colIndex = 0; colIndex < (colNum + 1); colIndex++) { rowStr = null; if (colIndex == colNum && pText.IndexOf("\r") != -1) rowStr = pText.Substring(0, pText.IndexOf("\r")); if (colIndex == colNum && pText.IndexOf("\r") == -1) rowStr = pText.Substring(0); if (colIndex != colNum) { rowStr = pText.Substring(0, pText.IndexOf("\t")); pText = pText.Substring(pText.IndexOf("\t") + 1); } if (rowStr == string.Empty) rowStr = null; data[rowIndex, colIndex] = rowStr; } pText = pText.Substring(pText.IndexOf("\n") + 1); } //获取选中单元格区域中左上角单元格的行号和列号 int columnindex = -1, rowindex = -1; int columnindextmp = -1, rowindextmp = -1; if (dataGridView1.SelectedCells.Count != 0) { columnindextmp = dataGridView1.SelectedCells[0].ColumnIndex; rowindextmp = dataGridView1.SelectedCells[0].RowIndex; } foreach (DataGridViewCell cell in dataGridView1.SelectedCells) { columnindex = cell.ColumnIndex; if (columnindex > columnindextmp) columnindex = columnindextmp; else columnindextmp = columnindex; rowindex = cell.RowIndex; if (rowindex > rowindextmp) rowindex = rowindextmp; else rowindextmp = rowindex; cell.Selected = false; } //如果当前DataGridView中的行数不够,则自动在底部扩充 if (rowindex + rowNum + 1 > dataGridView1.RowCount) { int m = rowindex + rowNum + 1 - dataGridView1.RowCount; for (int i = 0; i < m + 1; i++) { dataGridView1.Rows.Add(); } } //如果当前DataGridView中的列数不够,则自动在右侧扩充 if (columnindex + colNum + 1 > dataGridView1.ColumnCount) { int n = columnindex + colNum + 1 - dataGridView1.ColumnCount; int colNameNo = dataGridView1.Columns.Count + 1; for (int i = 0; i < n; i++) { DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn(); column.HeaderText = dataGridView1.Columns[0].HeaderText.Substring(0, 1) + colNameNo.ToString(); column.Width = dataGridView1.Columns[0].Width; dataGridView1.Columns.Add(column); colNameNo++; } } //将二维数组中的值赋给单元格 for (int i = 0; i < rowNum + 1; i++) { for (int j = 0; j < colNum + 1; j++) { dataGridView1.Rows[i + rowindex].Cells[j + columnindex].Value = data[i, j]; } } //int columnindex = 0, rowindex = 0;//dataTable //if (rowindex + rowNum + 1 > dataTable.Rows.Count) //{ // int m = rowindex + rowNum + 1 - dataTable.Rows.Count; // for (int i = 0; i < m; i++) // { // dataTable.Rows.Add(); // } //} //if (columnindex + colNum + 1 > dataTable.Columns.Count) //{ // int n = columnindex + colNum + 1 - dataTable.Columns.Count; // int colNameNo = dataTable.Columns.Count + 1; // for (int i = 0; i < n; i++) // { // dataTable.Columns.Add(new DataColumn()); // colNameNo++; // } //} }
第二点展示BOM结构,我使用的是递归方法获取所有节点数据,因为数据量不是太大,顶多一千多行,实际使用速度很快 /// <summary> ///递归调用此函数 获取所有节点数据,并显示出来 /// </summary> /// <param name="currentnode"></param> /// <param name="name"></param> private void GetNodeListData(Node currentnode,string name) { List<string> data = GetAmpNameFromMySql(sqlConnect, "hgc_node_list", name); if (data.Count > 0) { for (int i = 0; i < data.Count; i++) { Node nodeChild = new Node(data[i]); nodeChild.Style = elementStyle8; nodeChild.StyleMouseOver = elementStyle6; nodeChild.StyleSelected = elementStyle3; currentnode.Nodes.Add(nodeChild); GetNodeListData(nodeChild, data[i]); } } else { return; } } 下边是递归删除数据 根据选择的节点删除 /// <summary> /// 递归删除数据,选中的节点还未删除,递归完成后 /// </summary> /// <param name="name"></param> private void DeleteNodeListData(string name) { List<string> data = GetAmpNameFromMySql(sqlConnect, "hgc_node_list", name); if (data.Count > 0) { for (int i = 0; i < data.Count; i++) { DeleteNodeListData(data[i]); } } else { DeleteNodeDataFromMySql(name);//递归删除子节点 } } private List<string> GetAmpNameFromMySql(MySqlConnection con, string table, string ampcode) { MySqlCommand cmd = null; string sql_Cmd = null; MySqlDataReader reader = null; List<string> data = new List<string>(); sql_Cmd = string.Format("SELECT son_code FROM web_manager_engineer.{0} WHERE asian_name=\"{1}\"", table, ampcode); cmd = new MySqlCommand(sql_Cmd, con); try { reader = cmd.ExecuteReader(); while (reader.Read()) { data.Add(reader.GetString(0)); } } catch (MySqlException ex) { Console.WriteLine("Failed to populate database list: " + ex.Message); } finally { if (reader != null) reader.Close(); } return data; }