123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810 |
- Imports System.Data.SqlClient
- Imports System.IO
- Imports NPOI.XSSF.UserModel
- Imports NPOI.SS.UserModel
- Public Class Frm_01_finish_rcp
- Private isFlashing As Boolean = False
- Dim cmd As New SqlCommand
- Dim da As New SqlDataAdapter
- Dim sql As String
- Dim colorArray(10) As Color
- Dim conn As New SqlConnection
- Private Sub SetupAutoCompleteForCustomer()
- Dim customerList As New AutoCompleteStringCollection() : customerList.AddRange(New String() {"客戶A", "客戶B", "客戶C", "客戶D"}) ' 可從數據庫加載
- cbo_customer.AutoCompleteMode = AutoCompleteMode.SuggestAppend : cbo_customer.AutoCompleteSource = AutoCompleteSource.CustomSource
- cbo_customer.AutoCompleteCustomSource = customerList
- End Sub
- Private Sub SetupAutoCompleteForColor()
- Dim colorList As New AutoCompleteStringCollection() : colorList.AddRange(New String() {"紅色", "藍色", "綠色", "黑色", "白色"}) ' 可從數據庫加載
- txtColor.AutoCompleteMode = AutoCompleteMode.SuggestAppend : txtColor.AutoCompleteSource = AutoCompleteSource.CustomSource
- txtColor.AutoCompleteCustomSource = colorList
- End Sub
- Private Sub Set_清單1(條件 As String)
- Dim ds1 As New DataSet
- 處方清單_dgv.DataSource = Nothing : ds1.Clear()
- 處方清單_dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
- 處方清單_dgv.ColumnHeadersHeight = 30 : 處方清單_dgv.AllowUserToAddRows = False : 處方清單_dgv.RowTemplate.Height = 20
- 處方清單_dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
- SQL_塗飾處方清單(條件)
- da.Fill(ds1) : 處方清單_dgv.DataSource = ds1.Tables(0) : conn.Close()
- 處方清單_dgv.Columns(0).FillWeight = 200
- For i As Integer = 0 To 處方清單_dgv.Columns.Count - 1 : 處方清單_dgv.Columns(i).ReadOnly = True : Next
- End Sub
- Private Sub Frm_01_finish_rcp_Load(sender As Object, e As EventArgs) Handles MyBase.Load
- Me.MdiParent = FrmMDI : Me.WindowState = 2 : Me.AutoScroll = True
- Set_清單1("")
- Timer1.Interval = 1000 ' 每 500 毫秒闪烁一次
- txtCustomer.AutoCompleteMode = AutoCompleteMode.SuggestAppend : txtCustomer.AutoCompleteSource = AutoCompleteSource.CustomSource
- SetupAutoCompleteForCustomer() : SetupAutoCompleteForColor()
- End Sub
- Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
- If isFlashing Then : 模式通知_lb.Text = "修改模式" : Else : 模式通知_lb.Text = "" : End If : isFlashing = Not isFlashing ' 切换闪烁状态
- End Sub
- Private Sub 處方清單_dgv_SelectionChanged(sender As Object, e As EventArgs) Handles 處方清單_dgv.SelectionChanged
- Dim ds1 As New DataSet
- 處方_dgv.DataSource = Nothing : ds1.Clear()
- 處方_dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
- 處方_dgv.ColumnHeadersHeight = 30 : 處方_dgv.AllowUserToAddRows = False : 處方_dgv.RowTemplate.Height = 25
- 處方_dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
- SQL_塗飾處方明細(處方清單_dgv.Rows(處方清單_dgv.CurrentCell.RowIndex).Cells(0).Value)
- da.Fill(ds1) : 處方_dgv.DataSource = ds1.Tables(0) : conn.Close()
- 處方_dgv.Columns(0).FillWeight = 220 : 處方_dgv.Columns(2).FillWeight = 180
- For i As Integer = 0 To 處方_dgv.Columns.Count - 1 : 處方_dgv.Columns(i).ReadOnly = True : Next
- For Each row As DataGridViewRow In 處方_dgv.Rows : For Each cell As DataGridViewCell In row.Cells : cell.Tag = cell.Value : Next : Next
- End Sub
- Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles 關鍵字_tb.TextChanged
- Set_清單1("WHERE rcp_name LIKE N'%" & 關鍵字_tb.Text & "%'")
- End Sub
- Private Sub 處方_dgv_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles 處方_dgv.CellPainting
- If e.RowIndex >= 0 AndAlso e.ColumnIndex >= 0 Then ' 自定义单元格绘制,确保字体位置居中,并选中单元格背景色为蓝色
- Dim cell As DataGridViewCell = 處方_dgv.Rows(e.RowIndex).Cells(e.ColumnIndex)
- If cell.Style.ForeColor = Color.Red OrElse e.State.HasFlag(DataGridViewElementStates.Selected) Then ' 判断是否需要自定义绘制
- Dim backgroundColor As Color = If(e.State.HasFlag(DataGridViewElementStates.Selected), ' 获取背景颜色
- e.CellStyle.SelectionBackColor, e.CellStyle.BackColor)
- e.Graphics.FillRectangle(New SolidBrush(backgroundColor), e.CellBounds) ' 填充背景色
- e.Paint(e.ClipBounds, DataGridViewPaintParts.Border) ' 使用默认的边框样式绘制边框
- Dim textFormat As TextFormatFlags = TextFormatFlags.VerticalCenter ' 根据单元格的对齐方式调整文本绘制位置
- If e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleRight Then : textFormat = textFormat Or TextFormatFlags.Right
- ElseIf e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter Then : textFormat = textFormat Or TextFormatFlags.HorizontalCenter
- Else : textFormat = textFormat Or TextFormatFlags.Left : End If ' 绘制文本内容
- TextRenderer.DrawText(e.Graphics, cell.Value?.ToString(), e.CellStyle.Font, e.CellBounds, cell.Style.ForeColor, textFormat)
- e.Handled = True ' 阻止默认绘制
- End If
- End If
- End Sub
- Private Sub 處方_dgv_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles 處方_dgv.CellValueChanged
- Dim currentCell As DataGridViewCell = 處方_dgv.Rows(e.RowIndex).Cells(e.ColumnIndex) ' 获取修改的单元格
- If currentCell.Tag IsNot Nothing AndAlso Not currentCell.Value.Equals(currentCell.Tag) Then ' 检查 Tag 是否存在,以及当前值是否与原值不同
- currentCell.Style.ForeColor = Color.Red ' 如果值被修改,将字体设置为红色
- Else
- currentCell.Style.ForeColor = Color.Black ' 如果值未修改,恢复默认字体颜色
- End If
- End Sub
-
-
-
-
- Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btnEdit.Click
- ' 启用 Label1
- 模式通知_lb.Enabled = True
- ' 启动 Timer1
- Timer1.Start()
- ' 确保当前 DataGridView 的焦点单元格有效
- Dim currentCell As DataGridViewCell = 處方_dgv.CurrentCell
- If currentCell Is Nothing Then
- MessageBox.Show("请选中一个单元格进行编辑。")
- Return
- End If
- ' 获取当前选中行的第 0 列和第 2 列的值
- Dim sysName As String = 處方_dgv.CurrentRow.Cells(0).Value.ToString() ' 化学品名称
- Dim qty As String = 處方_dgv.CurrentRow.Cells(2).Value.ToString() ' 份数
- ' 从数据库获取化学品名称作为自动完成数据
- Dim suggestions As List(Of String) = ChemicalNamesFromDatabase()
- ' 初始化并显示 AutoCompleteInputBox,传入从数据库获取的建议列表
- Dim inputBox As New AutoCompleteWithListBox("输入化学品名称", suggestions, sysName, qty)
- Dim my_input() As String
- If inputBox.ShowDialog() = DialogResult.OK Then
- my_input = Split(inputBox.UserInput, " ")
- ' Dim chemName = inputBox.UserInput
- ' 显示结果
- MessageBox.Show($"选择的化学品:{my_input(1)}{vbNewLine}数量:{inputBox.Quantity}")
- End If
- Dim chemName = my_input(1)
- Dim re_qty = inputBox.Quantity
- ' 更新 DataGridView 的单元格信息
- If inputBox.DialogResult = DialogResult.OK Then
- ' 判断化学品名称是否被修改
- If sysName <> chemName Then
- 處方_dgv.CurrentRow.Cells("化工品名").Value = my_input(1) ' 更新化学品名称
- 處方_dgv.CurrentRow.Cells("化工品名").Style.ForeColor = Color.Red ' 设置化学品名称为红色字体
- ' 查询化工分类并更新
- Dim type1 As String = GetChemicalTypesFromDatabase(my_input(1))
- 處方_dgv.CurrentRow.Cells("化工分类").Value = type1 ' 更新化工分类
- End If
- ' 判断份数是否被修改
- If qty <> inputBox.Quantity Then
- 處方_dgv.CurrentRow.Cells("份数").Value = re_qty ' 更新份数
- 處方_dgv.CurrentRow.Cells("份数").Style.ForeColor = Color.Red ' 设置份数为红色字体
- End If
- End If
- End Sub
- Private Function GetChemicalTypesFromDatabase(chemicalName As String) As String
- ' 数据库连接字符串
- Dim connectionString As String = connstring ' 请替换为你的实际数据库连接字符串
- ' 查询语句
- Dim query As String = "SELECT type FROM ht_k3_material WHERE name = @sys_name"
- Dim type1 As String = ""
- ' 使用 SQL 连接和命令
- Using connection As New SqlConnection(connectionString)
- Dim command As New SqlCommand(query, connection)
- ' 添加查询参数
- command.Parameters.AddWithValue("@sys_name", chemicalName)
- ' 打开数据库连接
- connection.Open()
- ' 执行查询并获取结果
- Dim result = command.ExecuteScalar()
- If result IsNot Nothing Then
- type1 = result.ToString() ' 确保返回类型为字符串
- End If
- End Using
- ' 返回化工分类
- Return type1
- End Function
- ' 原本返回的是 String(),现在改为 List(Of String)
- Private Function ChemicalNamesFromDatabase() As List(Of String)
- Dim connectionString As String = connstring ' 换成你的数据库连接字符串
- Dim query As String = "SELECT code,name FROM ht_k3_material"
- Dim chemicalNames As New List(Of String)()
- Using connection As New SqlConnection(connectionString)
- Using command As New SqlCommand(query, connection)
- connection.Open()
- Using reader As SqlDataReader = command.ExecuteReader()
- While reader.Read()
- ' 将 sys_name 添加到列表中
- chemicalNames.Add(reader("code").ToString() & " " & reader("name").ToString())
- End While
- End Using
- End Using
- End Using
- ' 返回 List(Of String)
- Return chemicalNames
- End Function
- Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btnSave.Click
- ' 數據庫連接字串
- Dim connectionString As String = connstring ' 確保你的連接字符串正確
- ' **(A) 取得選中的 rcp_name**
- If 處方清單_dgv.CurrentRow Is Nothing OrElse 處方清單_dgv.CurrentRow.Cells("配料名称").Value Is Nothing Then
- MessageBox.Show("請先選擇一個配料名称 (rcp_name)!", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Warning)
- Return
- End If
- Dim rcpName As String = 處方清單_dgv.CurrentRow.Cells("配料名称").Value.ToString()
- ' **(B) 確保 dgv2 內有數據**
- If 處方_dgv.Rows.Count = 0 Then
- MessageBox.Show("沒有數據可更新!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information)
- Return
- End If
- ' **(C) 記錄目前選中的行**
- Dim selectedRowIndex As Integer = 處方_dgv.CurrentCell.RowIndex
- Dim selectedId As String = If(處方_dgv.CurrentRow.Cells("id").Value IsNot Nothing, 處方_dgv.CurrentRow.Cells("id").Value.ToString(), "")
- ' **(D) 開始 SQL Transaction**
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- Using trans As SqlTransaction = conn.BeginTransaction()
- Try
- ' **(E) 刪除資料表中該 rcp_name 的所有數據**
- Dim deleteQuery As String = "DELETE FROM ht_finish_rcp WHERE rcp_name = @rcp_name;"
- Using cmd As New SqlCommand(deleteQuery, conn, trans)
- cmd.Parameters.AddWithValue("@rcp_name", rcpName)
- cmd.ExecuteNonQuery()
- End Using
- ' **(F) 遍歷 dgv2,將沒有刪除線的數據重新插入**
- Dim insertQuery As String = "INSERT INTO ht_finish_rcp (id, rcp_name, chem_name, percents, edited_date)
- VALUES (@id, @rcp_name, @chem_name, @percents, @edited_date);"
- For Each row As DataGridViewRow In 處方_dgv.Rows
- ' 確保不是空白行
- If row.IsNewRow Then Continue For
- ' **(G) 檢查是否有刪除線 (Strikeout)**
- Dim hasStrikeout As Boolean = False
- For Each cell As DataGridViewCell In row.Cells
- If cell.Style.Font IsNot Nothing AndAlso cell.Style.Font.Strikeout Then
- hasStrikeout = True
- Exit For
- End If
- Next
- If hasStrikeout Then
- Debug.Print("跳過刪除線記錄:" & row.Cells("化工品名").Value.ToString()) ' Debug 記錄
- Continue For ' **跳過刪除線的記錄,不插入數據庫**
- End If
- ' 取得數據
- Dim idString As String = If(row.Cells("id").Value IsNot Nothing, row.Cells("id").Value.ToString(), "")
- If String.IsNullOrEmpty(idString) Then Continue For ' 跳過無效數據
- Dim chemName As String = row.Cells("化工品名").Value.ToString()
- Dim percents As String = row.Cells("份数").Value.ToString()
- Dim dPercents As Decimal = 0
- Decimal.TryParse(percents, dPercents)
- ' **(H) 插入新數據**
- Using cmd As New SqlCommand(insertQuery, conn, trans)
- cmd.Parameters.AddWithValue("@id", idString)
- cmd.Parameters.AddWithValue("@rcp_name", rcpName)
- cmd.Parameters.AddWithValue("@chem_name", chemName)
- cmd.Parameters.AddWithValue("@percents", dPercents)
- cmd.Parameters.AddWithValue("@edited_date", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
- cmd.ExecuteNonQuery()
- End Using
- Next
- ' **(I) 提交 Transaction**
- trans.Commit()
- MessageBox.Show("所有數據已成功同步至資料庫!", "更新成功", MessageBoxButtons.OK, MessageBoxIcon.Information)
- ' **(J) 重新載入 dgv2 的資料**
- ReloadDGV2(rcpName)
- ' **(K) 恢復選取的 row**
- RestoreSelectedRow(selectedRowIndex, selectedId)
- Catch ex As Exception
- ' **(L) 出錯時回滾**
- trans.Rollback()
- MessageBox.Show("更新失敗:" & ex.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error)
- End Try
- End Using
- End Using
- End Sub
- Private Sub RestoreSelectedRow(previousRowIndex As Integer, previousId As String)
- ' **確保 dgv2 內有數據**
- If 處方_dgv.Rows.Count = 0 Then Return
- ' **嘗試選擇原來的行**
- For Each row As DataGridViewRow In 處方_dgv.Rows
- If row.Cells("id").Value IsNot Nothing AndAlso row.Cells("id").Value.ToString() = previousId Then
- 處方_dgv.CurrentCell = row.Cells(0)
- row.Selected = True
- Return
- End If
- Next
- ' **如果原行被刪除,則選擇前一行**
- Dim newRowIndex As Integer = previousRowIndex
- If newRowIndex >= 處方_dgv.Rows.Count Then
- newRowIndex = 處方_dgv.Rows.Count - 1 ' 如果超過範圍,則選擇最後一行
- End If
- If newRowIndex >= 0 Then
- 處方_dgv.CurrentCell = 處方_dgv.Rows(newRowIndex).Cells(0)
- 處方_dgv.Rows(newRowIndex).Selected = True
- End If
- End Sub
- Private Sub ReloadDGV2(rcpName As String)
- ' **SQL 查詢 rcp_name 的新數據**
- Dim query As String = "SELECT chem_name AS 化工品名, percents as 份数,id, EDITED_DATE FROM ht_finish_rcp WHERE rcp_name = @rcp_name"
- Dim connectionString As String = connstring
- Dim adapter As New SqlDataAdapter(query, connectionString)
- adapter.SelectCommand.Parameters.AddWithValue("@rcp_name", rcpName)
- Dim dt As New DataTable()
- adapter.Fill(dt)
- ' **重新綁定 DataGridView**
- 處方_dgv.DataSource = dt
- 處方_dgv.Columns(0).Width = 220
- 處方_dgv.Columns(2).Width = 220
- End Sub
- ''' <summary>
- ''' 小工具:安全取得某欄位字串;如果是 Nothing 則回傳 ""
- ''' </summary>
- Private Function SafeCellValue(row As DataGridViewRow, columnName As String) As String
- If row.Cells(columnName).Value IsNot Nothing Then
- Return row.Cells(columnName).Value.ToString().Trim()
- End If
- Return String.Empty
- End Function
- Private Sub Button4_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
- 關鍵字_tb.Enabled = False
- 'For Each cell As DataGridViewCell In dgv2.CurrentRow.Cells
- ' ' 将单元格的值恢复为 Tag 中存储的原始值
- ' cell.Value = cell.Tag
- ' ' 将字体颜色恢复为默认黑色
- ' cell.Style.ForeColor = Color.Black
- 'Next
- Try
- ' **檢查 DataGridView 是否有未保存的變更**
- If 處方_dgv IsNot Nothing AndAlso 處方_dgv.DataSource IsNot Nothing Then
- Dim dt As DataTable = CType(處方_dgv.DataSource, DataTable)
- ' **取消所有變更**
- dt.RejectChanges()
- End If
- ' **清除選取**
- 處方_dgv.ClearSelection()
- ' **隱藏 DataGridView 的空白行**
- 處方_dgv.AllowUserToAddRows = False
- ' **確保數值欄位不為 null**
- For Each row As DataGridViewRow In 處方_dgv.Rows
- If Not row.IsNewRow Then ' 避免影響新行
- For Each cell As DataGridViewCell In row.Cells
- ' **如果是數值欄位,將 null 設為 0**
- If IsDBNull(cell.Value) AndAlso IsNumeric(cell.OwningColumn.DataPropertyName) Then
- cell.Value = 0
- End If
- Next
- End If
- Next
- Catch ex As Exception
- MessageBox.Show("取消變更時發生錯誤:" & ex.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error)
- End Try
- End Sub
- Private Sub dgv2_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles 處方_dgv.DataError
- ' **防止 "無法將 null 設定給 DataGridView" 錯誤**
- If e.Exception IsNot Nothing Then
- MessageBox.Show("數據錯誤:" & e.Exception.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Warning)
- ' **只修正數值欄位,避免影響文字欄位**
- Try
- Dim columnName As String = 處方_dgv.Columns(e.ColumnIndex).DataPropertyName
- If IsNumeric(columnName) Then
- 處方_dgv.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = 0 ' 設為 0,避免錯誤
- Else
- 處方_dgv.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = DBNull.Value ' 保持空值
- End If
- Catch ex As Exception
- Debug.Print("無法修正 DataGridView 錯誤:" & ex.Message)
- End Try
- End If
- End Sub
- Private Sub Button3_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
- If 處方_dgv.CurrentRow IsNot Nothing Then
- For Each cell As DataGridViewCell In 處方_dgv.CurrentRow.Cells
- ' 设置字体为带删除线的样式
- Dim currentFont As Font = cell.Style.Font
- If currentFont Is Nothing Then
- currentFont = 處方_dgv.Font ' 使用默认字体
- End If
- cell.Style.Font = New Font(currentFont, FontStyle.Strikeout)
- ' 设置背景颜色为红色
- cell.Style.BackColor = Color.Red
- Next
- End If
- End Sub
- Private Function GetNewIDWithIncrement() As Decimal
- ' 如果 dgv2 为空,则返回 1 作为第一行的 ID
- If 處方_dgv.Rows.Count = 0 Then Return 1D
- Dim selectedIndex As Integer = 處方_dgv.CurrentRow.Index
- Dim currentID As Decimal = Convert.ToDecimal(處方_dgv.Rows(selectedIndex).Cells("id").Value)
- ' 如果选中的是最后一行,直接加 1
- If selectedIndex = 處方_dgv.Rows.Count - 1 Then
- Return currentID + 1D
- End If
- ' 否则,在当前选中行后插入新记录,新 ID = 当前行 ID + 0.1
- Return currentID + 0.1D
- End Function
- Private Sub Button5_Click(sender As Object, e As EventArgs) Handles btnInsert.Click
- ' 1️⃣ 获取 DataGridView 绑定的 DataTable
- Dim dt As DataTable = CType(處方_dgv.DataSource, DataTable)
- ' 2️⃣ 获取新 ID(当前选中行 ID + 0.1)
- Dim newID As Decimal = GetNewIDWithIncrement()
- ' 3️⃣ 读取数据库中的化工品建议列表
- Dim suggestions As List(Of String) = ChemicalNamesFromDatabase().ToList()
- ' 4️⃣ 打开输入框,用户输入化工品名和数量
- Dim inputBox As New AutoCompleteWithListBox("输入化学品名称", suggestions, "", "0")
- Dim my_input() As String
- If inputBox.ShowDialog() = DialogResult.OK Then
- ' 5️⃣ 读取用户输入
- my_input = Split(inputBox.UserInput, " ")
- Dim chemName As String = my_input(1)
- Dim qty As String = inputBox.Quantity
- Dim type1 As String = GetChemicalTypesFromDatabase(chemName)
- ' 🚨 份数不可为 0,弹出警告并返回 🚨
- If String.IsNullOrWhiteSpace(qty) OrElse Not IsNumeric(qty) OrElse Convert.ToDecimal(qty) = 0 Then
- MessageBox.Show("份数不可为 0,请输入正确的数量!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Return ' 直接退出,不执行插入
- End If
- ' 6️⃣ 在 DataTable 中插入新行
- Dim newRow As DataRow = dt.NewRow()
- newRow("化工品名") = chemName
- newRow("份数") = qty
- newRow("化工分类") = type1
- newRow("id") = newID ' ID 采用小数递增
- ' 檢查 DataTable 是否已經有 "Status" 欄位,沒有則新增
- If Not dt.Columns.Contains("Status") Then
- dt.Columns.Add("Status", GetType(String)) ' 新增一個 "Status" 欄位,型別為 String
- End If
- ' **新增数据,标记为 "NEW"**
- newRow("Status") = "NEW" ' 这里添加一个新列 "Status" 作为标记
- ' 7️⃣ 插入新行到选中行的下一行
- dt.Rows.InsertAt(newRow, 處方_dgv.CurrentRow.Index + 1)
- ' 8️⃣ 重新绑定 DataGridView
- 處方_dgv.DataSource = dt
- ' 9️⃣ 设置新行的字体颜色为红色,表示未保存
- For Each cell As DataGridViewCell In 處方_dgv.Rows(處方_dgv.CurrentRow.Index + 1).Cells
- cell.Style.ForeColor = Color.Red
- Next
- End If
- End Sub
- Private Sub Button6_Click(sender As Object, e As EventArgs) Handles btnGenerate.Click
- Dim my_list As String
- For Each row As DataGridViewRow In 處方_dgv.Rows
- If row.Cells("化工分类").Value.ToString = "" And Not (row.Cells("化工品名").Value Like "水*") Then
- my_list += row.Cells("化工品名").Value & vbNewLine
- End If
- Next
- If Microsoft.VisualBasic.Len(my_list) > 0 Then
- MsgBox("以下化工品名有误:" & vbNewLine & vbNewLine & my_list)
- Exit Sub
- End If
- ' **(1) 請使用者輸入泡料總重量**
- Dim totalWeightStr As String = InputBox("请输入配料的总重量 (kg):", "输入总重量")
- Dim totalWeight As Decimal
- ' **(2) 檢查輸入是否合法**
- If Not Decimal.TryParse(totalWeightStr, totalWeight) OrElse totalWeight <= 0 Then
- MessageBox.Show("請输入有效的总重量!", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Warning)
- Return
- End If
- ' **(3) 計算總份數**
- Dim totalPortions As Decimal = 0
- For Each row As DataGridViewRow In 處方_dgv.Rows
- If row.IsNewRow Then Continue For ' 跳過新行
- Dim portionStr As String = row.Cells("份数").Value.ToString()
- Dim portion As Decimal = 0
- If Decimal.TryParse(portionStr, portion) Then
- totalPortions += portion
- End If
- Next
- ' **(4) 確保份數不為 0**
- If totalPortions = 0 Then
- MessageBox.Show("化工品的總份數為 0,無法計算重量!", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Warning)
- Return
- End If
- ' **(5) 清空 dgv3 並填充新數據**
- Dim dt As New DataTable()
- dt.Columns.Add("化工品名", GetType(String))
- dt.Columns.Add("化工分类", GetType(String))
- dt.Columns.Add("份数", GetType(Decimal))
- dt.Columns.Add("重量 (kg)", GetType(Decimal))
- dt.Columns.Add("总重量 (kg)", GetType(Decimal))
- dt.Columns.Add("化工代码", GetType(String))
- ' **(6) 計算每個化工的重量並填入 dgv3**
- Dim totalCalculatedWeight As Decimal = 0
- For Each row As DataGridViewRow In 處方_dgv.Rows
- If row.IsNewRow Then Continue For
- Dim chemName As String = row.Cells("化工品名").Value.ToString()
- Dim chemCategory As String = row.Cells("化工分类").Value.ToString()
- Dim portion As Decimal = Convert.ToDecimal(row.Cells("份数").Value)
- ' 計算該化工品的重量
- Dim weight As Decimal = Math.Round((portion / totalPortions) * totalWeight, 1)
- totalCalculatedWeight += weight ' 累計總重量
- ' **(7) 加入 DataTable**
- dt.Rows.Add(chemName, chemCategory, portion, weight, totalWeight)
- Next
- ' **(8) 添加總計行**
- Dim totalRow As DataRow = dt.NewRow()
- totalRow("化工品名") = "总计"
- totalRow("化工分类") = ""
- totalRow("份数") = totalPortions
- totalRow("重量 (kg)") = totalCalculatedWeight
- totalRow("总重量 (kg)") = totalWeight
- dt.Rows.Add(totalRow)
- ' **(9) 更新 dgv3**
- DGV3.DataSource = dt
- ' **(3) 設定總計行樣式(紅色粗體)**
- Dim lastRowIndex As Integer = DGV3.Rows.Count - 1
- If lastRowIndex >= 0 Then
- Dim lastRow As DataGridViewRow = DGV3.Rows(lastRowIndex)
- If lastRow.Cells(0).Value IsNot Nothing AndAlso lastRow.Cells(0).Value.ToString() = "总计" Then
- For Each cell As DataGridViewCell In lastRow.Cells
- cell.Style.Font = New Font("Microsoft YaHei", 10, FontStyle.Bold)
- cell.Style.ForeColor = Color.Red
- Next
- End If
- End If
- ' **(10) 美化 dgv3**
- ' CustomizeDataGridView(DGV3)
- End Sub
- Private Sub Button_領料_Click(sender As Object, e As EventArgs) Handles Button7.Click
- ' ------------------------ 1️⃣ 生成領料單號 ------------------------
- Dim out_Number As String = GenerateSerialNumber(DateTimePicker1.Value)
- ' ------------------------ 2️⃣ 計算總重量 ------------------------
- Dim totalWeight As Double = DGV3.Rows.Cast(Of DataGridViewRow)().
- Sum(Function(r) Convert.ToDouble(r.Cells(4).Value))
- totalWeight = Math.Round(totalWeight) ' 四捨五入取整
- ' ------------------------ 3️⃣ 讀取 Excel 模板 ------------------------
- Dim templatePath As String = "C:\表格模版\涂饰配料标签模版.xlsx"
- Dim savePath As String = Path.Combine("C:\GHS", out_Number & ".xlsx")
- Dim workbook As IWorkbook
- Using fs As New FileStream(templatePath, FileMode.Open, FileAccess.Read)
- workbook = New XSSFWorkbook(fs)
- End Using
- ' 假設我們要操作第 1 個工作表
- Dim sheet As ISheet = workbook.GetSheetAt(0)
- ' ------------------------ 4️⃣ 寫入 Excel ------------------------
- ' ========== (A) 設置 rcp_name 到 A1、B1 ==========
- ' 假設 DGV1.CurrentRow.Cells("配料名称") 有你想填入的值
- Dim rcpName As String = 處方清單_dgv.CurrentRow.Cells("配料名称").Value.ToString()
- ' 先確保第 1 行(索引0)已存在
- Dim row0 As IRow = sheet.GetRow(0)
- If row0 Is Nothing Then
- row0 = sheet.CreateRow(0)
- End If
- ' A1 => GetCell(0)
- Dim cellA1 As ICell = row0.GetCell(0)
- If cellA1 Is Nothing Then
- cellA1 = row0.CreateCell(0)
- End If
- cellA1.SetCellValue(rcpName)
- ' B1 => GetCell(1)
- Dim cellB1 As ICell = row0.GetCell(1)
- If cellB1 Is Nothing Then
- cellB1 = row0.CreateCell(1)
- End If
- cellB1.SetCellValue(rcpName)
- ' ========== (B) 成份明細 D2:D14 (化工品) & E2:E14 (重量) ==========
- ' 從 DGV3 把化工品名稱、重量 分別寫到 D、E 欄 (索引3, 4)
- ' 從 Excel 的第 2 行(索引1)開始,直到第 14 行(索引13)
- Dim startExcelRow As Integer = 1 ' D2 所在的行索引
- Dim endExcelRow As Integer = 15 ' D14 所在的行索引
- Dim rowIndex As Integer = startExcelRow
- For Each dgvRow As DataGridViewRow In DGV3.Rows
- If rowIndex > endExcelRow Then Exit For
- Dim chemName As String = dgvRow.Cells("化工品名").Value.ToString()
- Dim weight As Double = Convert.ToDouble(dgvRow.Cells(3).Value)
- ' 確保 Excel 行存在
- Dim excelRow As IRow = sheet.GetRow(rowIndex)
- If excelRow Is Nothing Then
- excelRow = sheet.CreateRow(rowIndex)
- End If
- ' D欄(索引3) 寫化工品名
- Dim chemCell As ICell = excelRow.GetCell(2)
- If chemCell Is Nothing Then
- chemCell = excelRow.CreateCell(2)
- End If
- chemCell.SetCellValue(chemName)
- ' E欄(索引4) 寫重量
- Dim weightCell As ICell = excelRow.GetCell(3)
- If weightCell Is Nothing Then
- weightCell = excelRow.CreateCell(3)
- End If
- weightCell.SetCellValue(weight)
- rowIndex += 1
- Next
- ' ========== 設置字體樣式(可選) ==========
- Dim cellStyle As ICellStyle = workbook.CreateCellStyle()
- Dim font As IFont = workbook.CreateFont()
- font.FontHeightInPoints = 16
- font.Boldweight = FontBoldWeight.Normal
- cellStyle.SetFont(font)
- cellStyle.Alignment = HorizontalAlignment.Right
- cellStyle.VerticalAlignment = VerticalAlignment.Center
- ' 如果想給前面寫入的 D/E 欄都設置樣式,可在上面循環裡賦值
- ' 或者這裡再遍歷一次已寫入的行
- ' ========== 移除最後一行(若你不想保留 '总计' 那一行) ==========
- ' 假設 DGV3.Rows.Count = n,那麼最後一行索引就是 n (對 NPOI 來說)
- ' 如果確定要刪除那一行,就這樣做:
- Dim lastRowIndex As Integer = DGV3.Rows.Count
- If sheet.GetRow(lastRowIndex) IsNot Nothing Then
- sheet.RemoveRow(sheet.GetRow(lastRowIndex))
- End If
- ' ========== 重算總重量並取平均值 ==========
- totalWeight = DGV3.Rows.Cast(Of DataGridViewRow)().
- Sum(Function(r) Convert.ToDouble(r.Cells(4).Value))
- Dim avgWeight As Double = totalWeight / DGV3.Rows.Count
- ' ========== (C) B15: 領料單號, B16: 平均重量, E15: 調料日期 ==========
- ' Excel中 B15 => (Row=14, Col=1), B16 => (Row=15, Col=1), E15 => (Row=14, Col=4)
- ' 先確保 row14, row15 都存在
- Dim row14 As IRow = sheet.GetRow(16)
- If row14 Is Nothing Then row14 = sheet.CreateRow(16)
- Dim row15 As IRow = sheet.GetRow(17)
- If row15 Is Nothing Then row15 = sheet.CreateRow(17)
- ' B15 => 領料單號
- Dim cellB15 As ICell = row14.GetCell(1)
- If cellB15 Is Nothing Then cellB15 = row14.CreateCell(1)
- cellB15.SetCellValue(out_Number)
- ' B16 => 平均重量
- Dim cellB16 As ICell = row15.GetCell(1)
- If cellB16 Is Nothing Then cellB16 = row15.CreateCell(1)
- cellB16.SetCellValue(Math.Round(avgWeight, 0))
- ' E15 => 日期
- Dim cellE15 As ICell = row14.GetCell(4)
- If cellE15 Is Nothing Then cellE15 = row14.CreateCell(4)
- cellE15.SetCellValue(DateTimePicker1.Value.ToString("yyyy-MM-dd"))
- ' ------------------------ 5️⃣ 保存 Excel ------------------------
- Using fs As New FileStream(savePath, FileMode.Create, FileAccess.Write)
- workbook.Write(fs)
- End Using
- ' ------------------------ 6️⃣ 寫入數據庫 ------------------------
- Dim connectionString As String = connstring
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- Using trans As SqlTransaction = conn.BeginTransaction()
- Try
- Dim insertQuery As String = "
- INSERT INTO HT_finish_out (out_no, [date], chem_name, qty, cust, color, rcp_name)
- VALUES (@out_no, @date, @chem_name, @qty, @cust, @color,@rcp_name)"
- For Each dgvRow As DataGridViewRow In DGV3.Rows
- Dim chemName As String = dgvRow.Cells("化工品名").Value.ToString().Trim()
- ' 假設某行叫 "总计" 就跳過
- If chemName = "总计" Then Continue For
- Dim cust As String = txtCustomer.Text.Trim()
- Dim color As String = txtColor.Text.Trim()
- Using cmd As New SqlCommand(insertQuery, conn, trans)
- cmd.Parameters.AddWithValue("@out_no", out_Number)
- cmd.Parameters.AddWithValue("@date", DateTimePicker1.Value)
- cmd.Parameters.AddWithValue("@chem_name", chemName)
- cmd.Parameters.AddWithValue("@qty", Convert.ToDouble(dgvRow.Cells(3).Value))
- cmd.Parameters.AddWithValue("@cust", cust)
- cmd.Parameters.AddWithValue("@color", color)
- cmd.Parameters.AddWithValue("@rcp_name", 處方清單_dgv.Rows(處方清單_dgv.CurrentCell.RowIndex).Cells("配料名称").Value)
- cmd.ExecuteNonQuery()
- End Using
- Next
- trans.Commit()
- Catch ex As Exception
- trans.Rollback()
- MessageBox.Show("數據庫錯誤:" & ex.Message, "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Return
- End Try
- End Using
- End Using
- ' ------------------------ 7️⃣ 自動打開 Excel ------------------------
- Process.Start("explorer.exe", savePath)
- ' ------------------------ 8️⃣ 提示成功 ------------------------
- MessageBox.Show("領料單已成功導出!單號:" & out_Number, "成功", MessageBoxButtons.OK, MessageBoxIcon.Information)
- End Sub
- Private Function GenerateSerialNumber(dateStr As String) As String
- Dim connectionString As String = connstring ' 請替換為你的資料庫連接字串
- Dim dateStr1 As String = DateTimePicker1.Value.ToString("yyMMdd") ' 取得 "250131" 格式
- ' **SQL 查詢,獲取當天的最大流水號**
- Dim query As String = "SELECT MAX(CAST(SUBSTRING(out_no, 9, LEN(out_no) - 8) AS INT)) " &
- "FROM HT_finish_out WHERE out_no LIKE 'P" & dateStr1 & "-%';"
- Dim maxSerial As Integer = 0
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- Using cmd As New SqlCommand(query, conn)
- Dim result As Object = cmd.ExecuteScalar()
- If result IsNot DBNull.Value AndAlso result IsNot Nothing Then
- maxSerial = Convert.ToInt32(result)
- End If
- End Using
- End Using
- ' **流水號遞增**
- Dim newSerial As Integer = maxSerial + 1
- ' **返回格式化的領料單號**
- Return "P" & dateStr1 & "-" & newSerial.ToString()
- End Function
- Private Sub ExportToExcel(orderNumber As String)
- Dim savePath As String = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), orderNumber & ".xlsx")
- ' **(1) 創建 Excel Workbook**
- Dim workbook As IWorkbook = New XSSFWorkbook()
- Dim sheet As ISheet = workbook.CreateSheet("領料單")
- ' **(2) 設定標題行**
- Dim headerRow As IRow = sheet.CreateRow(0)
- For col As Integer = 0 To DGV3.Columns.Count - 1
- Dim cell As ICell = headerRow.CreateCell(col)
- cell.SetCellValue(DGV3.Columns(col).HeaderText)
- ' **設定標題格式**
- Dim headerStyle As ICellStyle = workbook.CreateCellStyle()
- Dim font As IFont = workbook.CreateFont()
- font.IsBold = True
- headerStyle.SetFont(font)
- headerStyle.Alignment = HorizontalAlignment.Center
- cell.CellStyle = headerStyle
- Next
- ' **(3) 填充數據**
- For row As Integer = 0 To DGV3.Rows.Count - 1
- Dim dataRow As IRow = sheet.CreateRow(row + 1)
- For col As Integer = 0 To DGV3.Columns.Count - 1
- Dim cell As ICell = dataRow.CreateCell(col)
- Dim value As Object = DGV3.Rows(row).Cells(col).Value
- If value IsNot Nothing Then
- If TypeOf value Is Decimal OrElse TypeOf value Is Double Then
- cell.SetCellValue(Convert.ToDouble(value))
- Else
- cell.SetCellValue(value.ToString())
- End If
- End If
- Next
- Next
- ' **(4) 自動調整欄位寬度**
- For col As Integer = 0 To DGV3.Columns.Count - 1
- sheet.AutoSizeColumn(col)
- Next
- ' **(5) 寫入文件**
- Using fs As New FileStream(savePath, FileMode.Create, FileAccess.Write)
- workbook.Write(fs)
- End Using
- ' **(6) 自動開啟 Excel 文件**
- If File.Exists(savePath) Then
- Process.Start("explorer.exe", savePath)
- End If
- End Sub
- Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles btnSaveAs.Click
- ' 使用 InputBox 获取用户输入的配料名称
- Dim rcpName As String = InputBox("请输入配料名称:", "输入配料名称", "")
-
- ' 检查用户是否输入了配料名称
- If String.IsNullOrEmpty(rcpName) Then
- MessageBox.Show("请输入配料名称", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error)
- Return
- End If
- ' 检查 rcp_name 是否存在,如果存在,则在后面加上 "副本"
- rcpName = CheckAndModifyRcpName(rcpName)
- ' 获取选择的日期
- Dim createdDate As DateTime = DateTimePicker1.Value
- ' 数据库连接字符串
- Dim connectionString As String = connstring
- ' 获取当前最大ID
- Dim maxId As Integer = GetMaxId(connectionString)
- Dim newId As Integer = maxId + 1 ' 生成新的ID
- ' 使用连接保存数据
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- ' 遍历 dgv2 中的每一行,将数据插入到数据库
- For Each row As DataGridViewRow In 處方_dgv.Rows
- If row.IsNewRow Then Continue For ' 跳过新行
- ' 获取每一列的值
- Dim chemName As String = row.Cells("化工品名").Value.ToString()
- Dim percents As Double = Convert.ToDouble(row.Cells("份数").Value)
- ' 插入数据的 SQL 查询
- Dim query As String = "INSERT INTO HT_finish_rcp (rcp_name, chem_name, percents, created_date, id) " &
- "VALUES (@rcp_name, @chem_name, @percents, @created_date, @id)"
- Using cmd As New SqlCommand(query, conn)
- cmd.Parameters.AddWithValue("@rcp_name", rcpName)
- cmd.Parameters.AddWithValue("@chem_name", chemName)
- cmd.Parameters.AddWithValue("@percents", percents)
- cmd.Parameters.AddWithValue("@created_date", createdDate)
- cmd.Parameters.AddWithValue("@id", newId)
- ' 执行插入
- cmd.ExecuteNonQuery()
- newId += 1 ' 每次插入后,id+1
- End Using
- Next
- ' 显示保存成功的消息
- MessageBox.Show("数据已成功保存!", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information)
- End Using
- End Sub
- Private Function CheckAndModifyRcpName(rcpName As String) As String
- Dim connectionString As String = connstring
- Dim query As String = "SELECT COUNT(*) FROM HT_finish_rcp WHERE rcp_name = @rcp_name"
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- Using cmd As New SqlCommand(query, conn)
- cmd.Parameters.AddWithValue("@rcp_name", rcpName)
- Dim count As Integer = Convert.ToInt32(cmd.ExecuteScalar())
- ' 如果 rcp_name 已经存在,则添加 "副本"
- If count > 0 Then
- rcpName = rcpName & "副本"
- End If
- End Using
- End Using
- Return rcpName
- End Function
- Private Function GetMaxId(connectionString As String) As Integer
- Dim query As String = "SELECT MAX(id) FROM HT_finish_rcp"
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- Using cmd As New SqlCommand(query, conn)
- Dim result As Object = cmd.ExecuteScalar()
- If result IsNot DBNull.Value AndAlso result IsNot Nothing Then
- Return Convert.ToInt32(result)
- Else
- Return 0 ' 如果没有记录,返回0
- End If
- End Using
- End Using
- End Function
- ' 删除指定配料名称的所有记录
- Private Sub DeleteRcpNameRecords(rcpName As String)
- Dim connectionString As String = connstring
- Dim query As String = "DELETE FROM HT_finish_rcp WHERE rcp_name = @rcp_name"
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- Using cmd As New SqlCommand(query, conn)
- cmd.Parameters.AddWithValue("@rcp_name", rcpName)
- ' 执行删除操作
- cmd.ExecuteNonQuery()
- End Using
- End Using
- End Sub
- Private Sub RefreshDgv1()
- Dim connectionString As String = connstring
- Dim query As String = "SELECT rcp_name as 配料名称,created_date as 创建日期 FROM HT_finish_rcp group by rcp_name,created_date order by id"
- Using conn As New SqlConnection(connectionString)
- conn.Open()
- ' 使用 DataAdapter 将数据库数据填充到 DataTable
- Using da As New SqlDataAdapter(query, conn)
- Dim dt As New DataTable()
- da.Fill(dt)
- ' 将填充的数据绑定到 dgv1
- 處方清單_dgv.DataSource = dt
- End Using
- End Using
- End Sub
- End Class
|