Imports System.ComponentModel Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Text Imports System.Threading Imports System.Windows.Forms Imports UTS_Core.DebugLog Imports UTS_Core.UTSModule.DbConnect Imports UTS_Core.UTSModule.DbTableModel.Customer Imports UTS_Core.UTSModule.Production Imports UTS_Core.UTSModule.Station Imports UTS_Core.UTSModule.Station.StationTestPlan Imports UTS_Core.UTSModule.Test.Command.SystemCommand Imports UTS_Core.UTSModule.Test.Controls Imports UTS_Core.UTSModule.Test.StatusMonitor Imports UTS_Core.UTSModule.Test.StatusMonitor.TestStatusMonitor Namespace UTSModule.Test Public Class FrmStationTest Implements IUtsTest Implements IProcessStation Implements IProductionLine Private _utsApp As UtsAppForm ''' 测试错误代码管理器 Private _errCodeManager As ErrCodeManager ''' 测试线程 Private _testThread As Thread ''' 测试站信息 Public TestProcessStation As ProcessStation ''' 测试记录表格 Private _recordGrid As TestRecordGrid #Region "UTS窗体公共模块" Public Sub ShowForm(parentControl As Control) FormBorderStyle = FormBorderStyle.None TopLevel = False Dock = DockStyle.Fill Parent = parentControl Show() End Sub ''' ''' 产线变化 ''' Public Sub ProductionLineChanged() Implements IProductionLine.ProductionLineChanged 'Todo:产线变化代码 ApplicationLog.WriteInfoLog($"测试页面生产线变更中。") ApplicationLog.WriteInfoLog($"测试页面生产线变更完成。") End Sub ''' ''' 站位变化 ''' Public Sub Station_Changed() Implements IProcessStation.StationChanged ApplicationLog.WriteInfoLog($"测试页面站位变更中,PN:{_utsApp.ProcessStation.ParentProject.Name} - SN:{_utsApp.ProcessStation.Name} - TP:{_utsApp.ProcessStation.Packet.Name}!") TestProcessStation = _utsApp.ProcessStation _tester.ProcessStation = TestProcessStation '绑定测试器的流程 _recordGrid.StationPlan = CType(TestProcessStation.Packet.StationPlan, StationTestPlan) LblStation.Text = $"{TestProcessStation.ParentProject.Name} : {TestProcessStation.Name}" PicStepTip.Image = TestProcessStation.Packet.StationImage '重置提示图 '初始化提示信息图执行类中耦合变量 ShowTipImageExecutor.TipImageControl = PicStepTip ShowTipsExecutor.TipControl = LblTipString DbConnector.UtsCreateTestLogTableToLocal(TestProcessStation.ParentProject.Index, TestProcessStation.StationID) '创建本地记录表 InitChartData(TestProcessStation.ParentProject.Index, TestProcessStation.StationID) '更新本地图表数据 UpdateTestLogToCsv(_tester.GetFixedModule(FixedModuleEnum.Main).RowList.ToArray()) '更新CSV文件 ApplicationLog.WriteInfoLog($"测试页面站位变更完成!") End Sub #End Region #Region "Form Event" Dim gRunFlag As Int16 = 0 Private Sub FrmStationTest_Load(sender As Object, e As EventArgs) Handles Me.Load ApplicationLog.WriteInfoLog($"测试页面加载中。") '初始化UTS窗体信息,失败则关闭窗体 If InitializeUtsApp() = False Then Return gRunFlag = 1 '初始化错误代码 _errCodeManager = ErrCodeManager.CreateManager() gRunFlag = 2 '初始化窗体页面 InitializeForm() gRunFlag = 3 '初始化测试器 InitTester() gRunFlag = 4 AddHandler UtsKeyValueMonitor.UtsKeyDown, AddressOf UtsKeyDownCallback '按键检测 AddHandler StationEditStatusMonitor.StationEditStatusChanged, AddressOf StationEditStatusChanged '流程编辑检测 ApplicationLog.WriteInfoLog($"测试页面加载完成。") gRunFlag = 5 End Sub Private Function InitializeUtsApp() As Boolean _utsApp = UtsAppForm.CreateSingleton() _utsApp.AddStatisticsObserver(Me) Try If _utsApp.IsInitialized = False Then _utsApp.Initialize() 'Todo:可根据需要限定可选站位 End If Catch ex As Exception ApplicationLog.WriteErrorLog($"初始化窗体失败,原因:{ex.Message}!") MsgBox($"初始化窗体失败,原因:{ex.Message}") Close() Return False End Try Return True End Function Private Sub InitializeForm() InitBarChart() InitPieChart() InitRecordGrid() End Sub Private Sub Btn_StartTest_Click(sender As Object, e As EventArgs) Handles BtnStartTest.Click Static waitStop As Boolean = False If waitStop = True Then Return waitStop = True StartTestEvent() waitStop = False End Sub Private Sub StationEditStatusChanged(sender As Object, e As StationEditStatusChangedEventArgs) If e.Status <> StationEditStatusMonitor.StationEditStatusEnum.Saved Then Return If GrdStepTestRecord.InvokeRequired Then '判断是否需要开委托 GrdStepTestRecord.Invoke(New Action(Of Object, StationEditStatusChangedEventArgs)(AddressOf StationEditStatusChanged), New Object() {sender, e}) Return End If _recordGrid.UpdateStepTestRecord() End Sub #End Region #Region "外部按键事件" Private Sub UtsKeyDownCallback(sender As Object, e As UtsKeyDownEventArgs) If BtnStartTest.InvokeRequired Then BtnStartTest.Invoke(New Action(Of UtsKeyValueMonitor.UtsKeyValueEnum)(AddressOf UpdateKey), New Object() {e.KeyValue}) Else UpdateKey(e.KeyValue) End If End Sub Private Sub UpdateKey(key As UtsKeyValueMonitor.UtsKeyValueEnum) Static waitStop As Boolean = False If key = UtsKeyValueMonitor.UtsKeyValueEnum.Start Then If waitStop = True Then Return waitStop = True StartTestEvent() waitStop = False End If End Sub #End Region #Region "CSV测试记录" Private Sub UpdateTestLogToCsv(nodes() As RowNode) Dim dirPath As String = $"{Application.StartupPath}\LocalTestLog" Dim filePath As String = $"{dirPath}\TestLog_{Now:yyyyMMdd}.csv" If IO.Directory.Exists(dirPath) = False Then IO.Directory.CreateDirectory(dirPath) Dim str As New StringBuilder str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Start{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Load,{TestProcessStation.Packet.FileName}{vbCrLf}") Dim testItems As New StringBuilder Dim testSteps As New StringBuilder Dim testCmdTypes As New StringBuilder Dim testCmdNames As New StringBuilder Dim param1 As New StringBuilder Dim param2 As New StringBuilder Dim param3 As New StringBuilder Dim param4 As New StringBuilder Dim param5 As New StringBuilder Dim param6 As New StringBuilder Dim param7 As New StringBuilder Dim param8 As New StringBuilder For Each node As RowNode In nodes If String.IsNullOrWhiteSpace(node.RecordName) Then Continue For End If testItems.Append(","c) testItems.Append(node.RecordName) testSteps.Append(","c) testSteps.Append(node.RowListIndex) testCmdTypes.Append(","c) testCmdTypes.Append(node.CommandType) testCmdNames.Append(","c) testCmdNames.Append(node.Command) param1.Append(","c) If node.Parameters.Count > 0 Then param1.Append(node.Parameters(0).Value) param2.Append(","c) If node.Parameters.Count > 1 Then param2.Append(node.Parameters(1).Value) param3.Append(","c) If node.Parameters.Count > 2 Then param3.Append(node.Parameters(2).Value) param4.Append(","c) If node.Parameters.Count > 3 Then param4.Append(node.Parameters(3).Value) param5.Append(","c) If node.Parameters.Count > 4 Then param5.Append(node.Parameters(4).Value) param6.Append(","c) If node.Parameters.Count > 5 Then param6.Append(node.Parameters(5).Value) param7.Append(","c) If node.Parameters.Count > 6 Then param7.Append(node.Parameters(6).Value) param8.Append(","c) If node.Parameters.Count > 7 Then param8.Append(node.Parameters(7).Value) Next str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},TestStep,{testSteps}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},TestItem,{testItems}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},CmdType,{testCmdTypes}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Command,{testCmdNames}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_1,{param1}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_2,{param2}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_3,{param3}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_4,{param4}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_5,{param5}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_6,{param6}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_7,{param7}{vbCrLf}") str.Append($",{Now:yyyyMMdd},{Now:HH:mm:ss},Parameter_8,{param8}{vbCrLf}") Try IO.File.AppendAllText(filePath, str.ToString()) Catch ex As Exception ApplicationLog.WriteErrorLog($"更新CSV文件失败,原因:{ex.Message}") UtsMsgBox.ShowDialog($"更新CSV文件失败,原因:{ex.Message}") End Try End Sub ''' ''' 存储单笔测试记录至CSV文件 ''' Private Sub SaveTestLogToCsv(result As TestResult) Dim dirPath As String = $"{Application.StartupPath}\LocalTestLog" Dim filePath As String = $"{dirPath}\TestLog_{Now:yyyyMMdd}.csv" '设置写入内容 Dim str As New StringBuilder str.Append($"{result.DUT_SN},{Now:yyyyMMdd},{Now:HH:mm:ss},{result.TestResult}") If result.FailSteps.Count > 0 Then str.Append($",{result.FailSteps(0).RowListIndex}") Else str.Append($",") End If str.Append($",{result.DUT_SN}") For Each keyValuePair As KeyValuePair(Of String, String) In result.CustomRecord str.Append($",{keyValuePair.Value}") Next str.Append(vbCrLf) Try IO.File.AppendAllText(filePath, str.ToString()) Catch ex As Exception ApplicationLog.WriteErrorLog($"保存测试结果至CSV文件失败:{ex.Message}") UtsMsgBox.ShowDialog($"保存测试结果至CSV文件失败:{ex.Message}") End Try End Sub #End Region #Region "统一查询图表数据" Private ReadOnly _pieResults As New List(Of PieChartResult) Private ReadOnly _barResults As New List(Of BarChartResult) Private ReadOnly _pointResults As New List(Of PointChartResult) Private Sub InitChartData(pid As Integer, sid As Integer) ApplicationLog.WriteInfoLog($"测试页面统计图表绘制中。") _pieResults.Clear() _barResults.Clear() _pointResults.Clear() Dim dtTable As DataTable = DbConnector.GetTodayTestResult(pid, sid) Dim result As New TestResult For Each row As DataRow In dtTable.Rows Dim a As String = row($"{TestLogTable.ColNames.StartTime}").ToString() If Date.TryParse(a, result.StartTime) = False Then Continue For Dim c As String = row($"{TestLogTable.ColNames.TestResult}").ToString() If String.Compare(c, "1") = 0 Then result.TestResult = TestResult.TestResultEnum.Pass Else result.TestResult = TestResult.TestResultEnum.Fail End If result.DUT_SN = row($"{TestLogTable.ColNames.DUT_SN}").ToString() If String.IsNullOrWhiteSpace(result.DUT_SN) Then Continue For result.ErrCode = row($"{TestLogTable.ColNames.ErrCode}").ToString() AddPieChart(result) AddBarChart(result) AddPointChart(result) Next RedrawPointChart() ApplicationLog.WriteInfoLog($"测试页面统计图表绘制完成。") End Sub #End Region #Region "良率统计" Private Sub InitPieChart() ChartPie.Header.Text = "良率统计" '标题 ChartPie.Header.Visible = False '隐藏标题 ChartPie.Legend.Alignment = Steema.TeeChart.LegendAlignments.Right ChartPie.Legend.Font.Brush.Color = Color.Gray ChartPie.Legend.Font.SizeFloat = 8.0! ChartPie.Legend.Transparent = True ChartPie.Walls.Back.Visible = False ChartPie.Walls.Back.Transparent = True ' TcPie.ExplodeBiggest = 10 '最大饼块与饼图分割位置 TcPie.ExplodedSlice.Add(10) TcPie.Circled = True '饼图圆形 TcPie.Transparency = 10 TcPie.UniqueCustomRadius = True TcPie.UseExtendedNumRange = False TcPie.Frame.Circled = True TcPie.Pen.Visible = False '取消绘制边框 TcPie.Marks.Font.Brush.Color = Color.White '标签内容字体颜色 TcPie.Marks.Font.Name = $"Consolas" '标签内容字体名 TcPie.Marks.Shadow.Visible = False TcPie.Marks.Transparent = True TcPie.Marks.Visible = True TcPie.Marks.Style = Steema.TeeChart.Styles.MarksStyles.Percent '百分比 TcPie.MarksPie.InsideSlice = True TcPie.YValues.Order = Steema.TeeChart.Styles.ValueListOrder.Descending '倒序排序 End Sub Private Sub AddPieChart(result As TestResult) Dim code As String Dim msg As String Dim color As Color If result.TestResult = TestResult.TestResultEnum.Pass Then code = "PASS" msg = "测试通过" color = _errCodeManager("9002").Color Else If _errCodeManager.IndexOf(result.ErrCode) <> -1 Then code = result.ErrCode msg = _errCodeManager(result.ErrCode).Msg color = _errCodeManager(result.ErrCode).Color Else code = "9001" msg = _errCodeManager(code).Msg color = _errCodeManager(code).Color End If End If Dim addPie As Boolean = True For i As Integer = 0 To _pieResults.Count - 1 If _pieResults(i).CodeEqual(code) Then _pieResults(i).AddResult() addPie = False Exit For End If Next If addPie Then Dim pieResult As New PieChartResult(code, msg, color) pieResult.AddResult() _pieResults.Add(pieResult) End If ReDrawPie() End Sub Private Sub ReDrawPie() TcPie.BeginUpdate() TcPie.Clear() For i As Integer = 0 To _pieResults.Count - 1 TcPie.Add(_pieResults(i).Count, _pieResults(i).Code & " : " & _pieResults(i).Msg, _pieResults(i).Color) Next TcPie.EndUpdate() End Sub Class PieChartResult Sub New(code As String, msg As String, color As Color) Me.Code = code Me.Msg = msg Me.Color = color End Sub Property Code() As String Property Msg() As String Property Color() As Color Property Count() As Integer Public Function CodeEqual(srcCode As String) As Boolean If String.Compare(Code, srcCode) = 0 Then Return True End If Return False End Function Public Sub AddResult() Count += 1 End Sub End Class #End Region #Region "图表生产统计" Private Sub InitBarChart() ChartBar.Header.Text = "生产统计" '标题 ChartBar.Header.Visible = False '隐藏标题 ChartBar.Legend.Transparent = True '刻印说明 ChartBar.Legend.Alignment = Steema.TeeChart.LegendAlignments.Top TcBarPass.Pen.Visible = False TcBarPass.Brush.Color = _errCodeManager("9002").Color TcBarPass.Brush.Transparency = 40 TcBarPass.MultiBar = Steema.TeeChart.Styles.MultiBars.Stacked '与其他柱状图并列显示 TcBarPass.Marks.Transparent = True '标记提示边框透明 TcBarPass.Marks.Style = Steema.TeeChart.Styles.MarksStyles.Value '提示标签类型为数值 TcBarPass.Marks.AutoPosition = False TcBarPass.MarksLocation = Steema.TeeChart.Styles.MarksLocation.Start '标签文本在柱状图上面显示 TcBarPass.Legend.Text = "Pass" TcBarFail.Pen.Visible = False TcBarFail.Brush.Color = _errCodeManager("9003").Color TcBarFail.Brush.Transparency = 40 TcBarFail.MultiBar = Steema.TeeChart.Styles.MultiBars.Stacked '与其他柱状图并列显示 TcBarFail.Marks.Transparent = True '标记提示边框透明 TcBarFail.Marks.Style = Steema.TeeChart.Styles.MarksStyles.Value '提示标签类型为数值 TcBarFail.Marks.AutoPosition = False TcBarFail.MarksLocation = Steema.TeeChart.Styles.MarksLocation.Start '标签文本在柱状图上面显示 TcBarFail.Legend.Text = "Fail" End Sub Dim gAllCount As Integer = 0 Dim gPassCount As Integer = 0 Dim gFailCount As Integer = 0 Private Sub AddBarChart(result As TestResult) '填充内存 Dim addBar As Boolean Dim tmp As BarChartResult If _barResults.Count > 0 Then If _barResults(_barResults.Count - 1).TimeEqual(result.StartTime) Then tmp = _barResults(_barResults.Count - 1) Else If result.StartTime.Hour = 0 Then _barResults.Clear() '过零点则清空 TcBarPass.Clear() TcBarFail.Clear() End If tmp = New BarChartResult(result.StartTime) _barResults.Add(tmp) If _barResults.Count > 8 Then '超过八个小时,移除前一小时数据 _barResults.RemoveAt(0) addBar = False Else addBar = True End If End If Else tmp = New BarChartResult(result.StartTime) _barResults.Add(tmp) addBar = True End If tmp.AddResult(result.TestResult = TestResult.TestResultEnum.Pass) '填充图表 If addBar Then TcBarPass.Add(tmp.RecordTime, tmp.PassCount) TcBarFail.Add(tmp.RecordTime, tmp.FailCount) Else RedrawBarChart() End If '更新测试计数 Momo 2023-11-14 gAllCount += 1 If result.TestResult = TestResult.TestResultEnum.Pass Then gPassCount += 1 Else gFailCount += 1 End If Try TssLblTestCount.Text = "Count:" & gAllCount TssLblPassCount.Text = "Pass:" & gPassCount TssLblFailCount.Text = "Fail:" & gFailCount Catch ex As Exception End Try End Sub Private Sub RedrawBarChart() TcBarPass.Clear() TcBarFail.Clear() For i As Integer = 0 To _barResults.Count - 1 TcBarPass.Add(_barResults(i).RecordTime, _barResults(i).PassCount) TcBarFail.Add(_barResults(i).RecordTime, _barResults(i).FailCount) Next End Sub Class BarChartResult Sub New(time As Date) RecordTime = New DateTime(time.Year, time.Month, time.Day, time.Hour, 0, 0) PassCount = 0 FailCount = 0 AllCount = 0 End Sub Property RecordTime() As DateTime Property PassCount As Integer Property FailCount As Integer Property AllCount As Integer Public Function TimeEqual(srcTime As DateTime) As Boolean If RecordTime.Day = srcTime.Day AndAlso RecordTime.Hour = srcTime.Hour Then Return True End If Return False End Function Public Sub AddResult(passed As Boolean) If passed Then PassCount += 1 Else FailCount += 1 End If AllCount += 1 End Sub End Class #End Region #Region "点阵生产统计" ''' 当前绘制图形宽度 Private _drawW As Integer ''' 当前绘制图形坐标点X Private _drawX As Integer ''' 当前绘制图形坐标点Y Private _drawY As Integer ''' 当前绘制图形单行最大上限 Private _drawLineMaxCount As Integer ''' ''' 添加绘制测试结果 ''' ''' Private Sub AddPointChart(result As TestResult) Dim a As New PointChartResult With {.BarCode = result.DUT_SN} If result.TestResult = TestResult.TestResultEnum.Pass Then a.Result = True a.Color = _errCodeManager("9002").Color Else a.Result = False If _errCodeManager.IndexOf(result.ErrCode) <> -1 Then a.Color = _errCodeManager(result.ErrCode).Color Else a.Color = _errCodeManager("9001").Color End If End If _pointResults.Add(a) DrawPointChart(_pointResults.Count - 1) '从0开始 End Sub Private Sub DrawPointChart(index As Integer) If PnlPoint.InvokeRequired Then PnlPoint.Invoke(New Action(Of Integer)(AddressOf DrawPointChart), New Object() {index}) Return End If Using g As Graphics = PnlPoint.CreateGraphics() g.SmoothingMode = SmoothingMode.HighQuality '抗锯齿 If index = 0 Then ResetPointChart() ElseIf index Mod _drawLineMaxCount = 0 Then _drawY += _drawW + 2 _drawX = 2 Else _drawX += _drawW + 2 End If g.FillEllipse(New SolidBrush(_pointResults(index).Color), New Rectangle(_drawX, _drawY, _drawW, _drawW)) End Using End Sub Private Sub ResetPointChart() _drawW = 6 _drawX = 2 _drawY = 2 _drawLineMaxCount = PnlPoint.Width \ (2 + _drawW) End Sub Private Sub RedrawPointChart() Using g As Graphics = PnlPoint.CreateGraphics() g.SmoothingMode = SmoothingMode.HighQuality '抗锯齿 For index As Integer = 0 To _pointResults.Count - 1 If index = 0 Then ResetPointChart() ElseIf index Mod _drawLineMaxCount = 0 Then _drawY += _drawW + 2 _drawX = 2 Else _drawX += _drawW + 2 End If g.FillEllipse(New SolidBrush(_pointResults(index).Color), New Rectangle(_drawX, _drawY, _drawW, _drawW)) Next End Using End Sub Private Sub PnlProduct_SizeChanged(sender As Object, e As EventArgs) Handles PnlPoint.SizeChanged End Sub Class PointChartResult Property BarCode() As String Property Result() As Boolean Property Color() As Color End Class Private Sub PnlPoint_Paint(sender As Object, e As PaintEventArgs) Handles PnlPoint.Paint RedrawPointChart() End Sub #End Region #Region "测试执行" Private Sub StartTestEvent() '检测 If TestStatus = TestStatusEnum.Testing Then If UtsMsgBox.ShowDialog("当前已处于测试状态中,是否结束测试!", UtsMsgBox.UtsMsgBoxTypeEnum.YesNo, "测试已开启") = DialogResult.OK Then StopTest() End If Return End If If TestProcessStation Is Nothing Then UtsMsgBox.ShowDialog("请选择测试站再尝试进行测试!") Return End If If CheckValidDate(TestProcessStation.Packet.ValidDate) = False Then UtsMsgBox.ShowDialog("测试功能已超过使用期限,请联系管理员!") Return End If If _testThread IsNot Nothing AndAlso _testThread.IsAlive Then UtsMsgBox.ShowDialog("测试线程未完全退出,请稍后开始测试!") Return End If StartTest() '开始测试 End Sub ''' ''' 校验测试流程有效日期 ''' ''' Private Function CheckValidDate(validDate As Date) As Boolean Return Now.CompareTo(validDate) < 0 End Function ''' ''' 开始测试 ''' Private Sub StartTest() _testThread = New Thread(AddressOf _tester.StartTest) _testThread.Start() '开启测试线程 End Sub ''' ''' 终止测试 ''' Private Sub StopTest() _tester.ExitTest() End Sub #End Region #Region "统一测试模块" Private _tester As UtsTester Private Sub InitTester() ApplicationLog.WriteInfoLog($"测试器初始化中。") _tester = UtsTester.CreateTester() '_tester.TestFailMode = UtsTester.TestFailModeEnum.StepFail AddHandler _tester.TestStart, AddressOf IUtsTest_TestStart AddHandler _tester.TestPass, AddressOf IUtsTest_TestPass AddHandler _tester.TestFail, AddressOf IUtsTest_TestFail AddHandler _tester.TestPause, AddressOf IUtsTest_TestPause AddHandler _tester.TestEnd, AddressOf IUtsTest_TestEnd AddHandler _tester.TestStatusChanged, AddressOf IUtsTest_TestStatusChanged AddHandler _tester.TestNodeChanged, AddressOf IUtsTest_TestNodeChanged AddHandler _tester.TestNodeCompleted, AddressOf IUtsTest_TestNodeCompleted AddHandler _tester.TestProgressChanged, AddressOf IUtsTest_TestProgressChanged AddHandler _tester.RetryProgressChanged, AddressOf IUtsTest_RetryProgressChanged AddHandler _tester.TestTimeChanged, AddressOf IUtsTest_TestTimeChanged AddHandler StationEditStatusMonitor.StationEditStatusChanged, AddressOf _tester.StationEditStatusChanged ApplicationLog.WriteInfoLog($"测试器初始化完成。") End Sub Private Sub IUtsTest_TestStart(sender As Object, e As EventArgs) Implements IUtsTest.TestStart If _tester.DebugMode Then Return If PicStepTip.InvokeRequired Then '判断是否需要开委托 PicStepTip.Invoke(New Action(Of Object, EventArgs)(AddressOf IUtsTest_TestStart), New Object() {sender, e}) Return End If PicStepTip.Image = TestProcessStation.Packet.StationImage '重置提示图 _recordGrid.ClearRecode() '清空测试记录项 ApplicationLog.WriteInfoLog($"测试页面测试开始。") End Sub Private Sub IUtsTest_TestPass(sender As Object, e As EventArgs) Implements IUtsTest.TestPass If _tester.DebugMode Then Return ApplicationLog.WriteInfoLog($"测试页面测试成功。") End Sub Private Sub IUtsTest_TestFail(sender As Object, e As TestFailEventArgs) Implements IUtsTest.TestFail If _tester.DebugMode Then Return '调试模式不处理 UpdateTestNode(e.Node) ApplicationLog.WriteInfoLog($"测试页面测试失败。") End Sub Private Sub IUtsTest_TestPause(sender As Object, e As TestPauseEventArgs) Implements IUtsTest.TestPause If _tester.DebugMode Then Return '调试模式不处理 UpdateTestNode(e.Node) ApplicationLog.WriteInfoLog($"测试页面测试暂停。") End Sub Private Sub IUtsTest_TestEnd(sender As Object, e As TestEndEventArgs) Implements IUtsTest.TestEnd If _tester.DebugMode Then Return '调试模式不处理 If String.IsNullOrWhiteSpace(e.TestResult.DUT_SN) Then ApplicationLog.WriteWarningLog($"测试页面测试结束,无SN号不予入库。") Return End If If e.TestResult.DUT_SN.Length > 32 Then ApplicationLog.WriteWarningLog($"测试页面测试结束,过长的SN号[{e.TestResult.DUT_SN}]不予入库。") MsgBox($"当前SN号[{e.TestResult.DUT_SN}]超过设定长度上限32,不予录入数据库。") Return End If ApplicationLog.WriteInfoLog($"测试页面测试结束处理中,SN:{e.TestResult.DUT_SN},Result:{e.TestResult.TestResult}。") SaveTestLogToCsv(e.TestResult) '保存至CSV SaveTestLogToDatabase(e.TestResult) '存储数据至数据库 AddBarChart(e.TestResult) '当前时测试总数绘制至图表 AddPointChart(e.TestResult) '测试结果绘制至点阵图 AddPieChart(e.TestResult) '测试结果绘制至饼状图 ApplicationLog.WriteInfoLog($"测试页面测试结束。") End Sub ''' ''' 存储单笔测试记录至数据库 ''' Private Sub SaveTestLogToDatabase(result As TestResult) If String.IsNullOrWhiteSpace(result.DUT_SN) Then Return '无SN不处理 Try Dim tbName As String = TestLogTable.TableName(TestProcessStation.ParentProject.Index, TestProcessStation.StationID) DbConnector.SaveTestLog(tbName, TestProcessStation, result) Catch ex As Exception ApplicationLog.WriteErrorLog($"保存测试结果至数据库失败:{ex.Message}") UtsMsgBox.ShowDialog($"保存测试结果至数据库失败:{ex.Message}") End Try End Sub Private Sub IUtsTest_TestNodeChanged(sender As Object, e As TestNodeChangedEventArgs) Implements IUtsTest.TestNodeChanged If _tester.DebugMode Then Return UpdateTestNode(e.Node) End Sub Private Sub UpdateTestNode(node As RowNode) If _tester.DebugMode Then Return If _tester.TestFiexdModule <> FixedModuleEnum.Main Then Return If node.Action = False Then Return If LblTestStep.InvokeRequired Then '判断是否需要开委托 LblTestStep.Invoke(New Action(Of RowNode)(AddressOf UpdateTestNode), New Object() {node}) Return End If LblTestStep.Text = $"Step : [{node.RowListIndex}] - [{_recordGrid.GetRowByNode(node)}]" LblStepTip.Text = $"[{node.RowListIndex}]-{node.ParentNode.Label}:{node.Description}" _recordGrid.UpdateTestRow(node) End Sub Public Sub IUtsTest_TestNodeCompleted(sender As Object, e As TestNodeCompletedEventArgs) Implements IUtsTest.TestNodeCompleted If _tester.DebugMode Then Return _recordGrid.UpdateTestRecord(e.Node, e.TestReturn) End Sub Public Sub IUtsTest_TestStatusChanged(sender As Object, e As TestStatusChangedEventArgs) Implements IUtsTest.TestStatusChanged If _tester.DebugMode Then Return UpdateTestStatus(e.Status) End Sub ''' ''' 根据测试状态,更新界面UI显示 ''' ''' Private Sub UpdateTestStatus(status As TestStatusEnum) If _tester.DebugMode Then Return If LblTestStatus.InvokeRequired Then '判断是否需要开委托 LblTestStatus.Invoke(New Action(Of TestStatusEnum)(AddressOf UpdateTestStatus), New Object() {status}) Return End If Select Case status Case TestStatusEnum.WaitForTest LblTestStatus.ForeColor = _errCodeManager("9002").Color LblTestStatus.Text = $"Wait" ApplicationLog.WriteInfoLog($"测试页面测试状态变更,等待测试。") Case TestStatusEnum.Testing LblTestStatus.ForeColor = _errCodeManager("9004").Color LblTestStatus.Text = $"Testing" ApplicationLog.WriteInfoLog($"测试页面测试状态变更,测试中。") Case TestStatusEnum.TestPass LblTestStatus.ForeColor = _errCodeManager("9002").Color LblTestStatus.Text = $"Pass" ApplicationLog.WriteInfoLog($"测试页面测试状态变更,测试成功。") Case TestStatusEnum.TestFail LblTestStatus.ForeColor = _errCodeManager("9003").Color LblTestStatus.Text = $"Fail" ApplicationLog.WriteInfoLog($"测试页面测试状态变更,测试失败。") Case TestStatusEnum.DeviceError LblTestStatus.ForeColor = _errCodeManager("9003").Color LblTestStatus.Text = $"Error" ApplicationLog.WriteErrorLog($"测试页面测试状态变更,设备错误。") Case Else Console.WriteLine($"测试页面测试状态变更,未知状态:{status}。") ApplicationLog.WriteErrorLog($"测试页面测试状态变更,未知状态:{status}。") End Select LblTestStep.ForeColor = LblTestStatus.ForeColor LblStepTip.ForeColor = LblTestStatus.ForeColor If status = TestStatusEnum.Testing Then BtnStartTest.Text = $"Stop(&S)" '更新测试按键 BtnStartTest.ForeColor = Color.OrangeRed Else BtnStartTest.Text = $"Start(&S)" '更新测试按键 BtnStartTest.ForeColor = Color.Green End If End Sub Private Sub IUtsTest_TestTimeChanged(sender As Object, e As TestTimeEventArgs) Implements IUtsTest.TestTimeChanged If _tester.DebugMode Then Return UpdateTestTime(e.TimeElapsed) End Sub ''' ''' 更新测试时间 ''' ''' Private Sub UpdateTestTime(elapsed As TimeSpan) If StuState.InvokeRequired Then '判断是否需要开委托 StuState.Invoke(New Action(Of TimeSpan)(AddressOf UpdateTestTime), New Object() {elapsed}) Return End If TssLblTestTime.Text = $"Time:{elapsed.Hours:D2}:{elapsed.Minutes:D2}:{elapsed.Seconds:D2}:{elapsed.Milliseconds:D3}" End Sub Private Sub IUtsTest_TestProgressChanged(sender As Object, e As TestProgressChangedEventArgs) Implements IUtsTest.TestProgressChanged If _tester.DebugMode Then Return UpdateTestProgress(CInt(e.Percent)) End Sub Private Sub UpdateTestProgress(progress As Integer) Try If _tester.DebugMode Then Return If PrgStepTip.InvokeRequired Then '判断是否需要开委托 PrgStepTip.Invoke(New Action(Of Integer)(AddressOf UpdateTestProgress), New Object() {progress}) Return End If If progress < TssBarTestProgress.Minimum Then progress = TssBarTestProgress.Minimum If progress > TssBarTestProgress.Maximum Then progress = TssBarTestProgress.Maximum TssBarTestProgress.Value = progress Catch ex As Exception End Try End Sub Private Sub IUtsTest_RetryProgressChanged(sender As Object, e As TestProgressChangedEventArgs) Implements IUtsTest.RetryProgressChanged If _tester.DebugMode Then Return UpdateRetryProgress(CInt(e.Percent)) End Sub Private Sub UpdateRetryProgress(progress As Integer) If _tester.DebugMode Then Return If PrgStepTip.InvokeRequired Then '判断是否需要开委托 PrgStepTip.Invoke(New Action(Of Integer)(AddressOf UpdateRetryProgress), New Object() {progress}) Return End If PrgStepTip.Value = progress End Sub Private Sub IUtsTest_TestCountChanged(sender As Object, e As TestCountChangedEventArgs) Implements IUtsTest.TestCountChanged If _tester.DebugMode Then Return UpdateTestCount(e.PassCount, e.FailCount) End Sub Private Sub UpdateTestCount(pass As Integer, fail As Integer) If StuState.InvokeRequired Then '判断是否需要开委托 StuState.Invoke(New Action(Of Integer, Integer)(AddressOf UpdateTestCount), New Object() {pass, fail}) Return End If TssLblFailCount.Text = $"Fail:{fail}" TssLblPassCount.Text = $"Pass:{pass}" TssLblTestCount.Text = $"Count:{pass + fail}" End Sub #End Region #Region "表格相关操作" Private Sub InitRecordGrid() _recordGrid = New TestRecordGrid() With {.Grid = GrdStepTestRecord} End Sub Private Sub TsmiShowAllRows_Click(sender As Object, e As EventArgs) Handles TsmiShowAllRows.Click _recordGrid.ShowAllRows() End Sub Private Sub TsmiShowRecordRows_Click(sender As Object, e As EventArgs) Handles TsmiShowRecordRows.Click _recordGrid.ShowRecordRows() End Sub Private Sub TsmiTestSetupNode_Click(sender As Object, e As EventArgs) Handles TsmiTestSetupNode.Click If _tester.ExecuteFixedModule(FixedModuleEnum.Setup).ExecuteResult Then UtsMsgBox.ShowDialog($"测试 {FixedModuleEnum.Setup} 模块执行完成!") Else UtsMsgBox.ShowDialog($"测试 {FixedModuleEnum.Setup} 模块执行失败!") End If End Sub Private Sub TsmiTestCleanupNode_Click(sender As Object, e As EventArgs) Handles TsmiTestCleanupNode.Click If _tester.ExecuteFixedModule(FixedModuleEnum.Cleanup).ExecuteResult Then UtsMsgBox.ShowDialog($"测试 {FixedModuleEnum.Cleanup} 模块执行完成!") Else UtsMsgBox.ShowDialog($"测试 {FixedModuleEnum.Cleanup} 模块执行失败!") End If End Sub Private Sub TsmiRetryTestNode_Click(sender As Object, e As EventArgs) Handles TsmiTestNode.Click Dim node As RowNode = _recordGrid.ActiveNode If node Is Nothing Then Return _tester.ExecutePlan(node, Nothing) End Sub Private Sub TsmiStartTestWithNode_Click(sender As Object, e As EventArgs) Handles TsmiStartTestWithNode.Click Dim node As RowNode = _recordGrid.ActiveNode If node Is Nothing Then Return While node IsNot Nothing _tester.ExecutePlan(node, Nothing) If node.NextNode Is Nothing Then If node.RowLever = 1 Then Exit While node = node.ParentNode Else node = node.NextNode End If End While End Sub Public Sub SetSpcSplitterDistance(Distance As Integer) SpcMain.SplitterDistance = Distance End Sub Public Function GetSpcSplitterDistance() As Integer Return SpcMain.SplitterDistance End Function #End Region End Class End Namespace