Imports System.IO Imports System.Threading Imports System.Globalization Imports EgtUILib Imports EgtWPFLib5 Imports EgtBEAMWALL.Core.ConstBeam Imports EgtBEAMWALL.Core Public Class CalcIntegration Private _thread As System.Threading.Thread Public Enum CmdType As Integer GENERATE = 0 MODIFY = 1 SIMULATE = 2 CHECK = 3 CHECKGEN = 4 POINT_CLOUD = 5 RAWPART = 6 End Enum Public Class Bar 'Public piInfo As PatternInfo Public nBarState As Integer Public nBarId As Integer Public sBarPath As String Public bBarOk As Boolean Public nCmdType As Integer Public nBarType As ProjectType End Class Private Structure MyProc Public bEnable As Boolean Public Proc As Process Public nBar As Integer End Structure Public Sub New() End Sub Delegate Sub CallbackDlg(dProgress As Double, sProgress As String, ByRef bCancel As Boolean) Public Sub Run(vBar As Bar(), sProjDirPath As String, callback As CallbackDlg) _thread = New Thread(Sub() DoJob(vBar, sProjDirPath, callback) End Sub) _thread.Start() End Sub Private Shared Sub DoJob(vBar As Bar(), sProjDirPath As String, callback As CallbackDlg) Dim bCancel As Boolean = False callback(0, "Init", bCancel) ' creo progetti a seconda del tipo For Each Bar In vBar If Bar.nBarType = ProjectType.PROJ Then Bar.sBarPath = CreateNewProjectFromPart(Bar.nBarId, sProjDirPath) ElseIf Bar.nBarType = ProjectType.PROD Then Bar.sBarPath = CreateNewProjectFromMachGroup(Bar.nBarId, sProjDirPath) End If Next Dim bIsSimulation As Boolean = False ' se sono in simulazione If vBar.Count > 0 AndAlso vBar(0).nCmdType = CmdType.SIMULATE Then bIsSimulation = True callback(0, "Simulation opened", bCancel) Else callback(0.1, "", bCancel) End If Dim ExePath As String = String.Empty GetMainPrivateProfileString(S_BEAM, K_CALCPATH, "", ExePath) ' Numero di barre Dim numBars As Integer = vBar.Count If numBars = 0 Then Return ' Numero di core logici da utilizzare (minimo tra presenti sul PC e imposti da INI) Dim nMaxThread As Integer = Math.Min(Environment.ProcessorCount, Map.refMainWindowVM.MainWindowM.GetMaxCamInstances()) ' Frazione di avanzamento del lavoro (in piu) Dim dProgress As Double = 0 'indice incremento progress durante calcolo barra Dim nPgsCurrBar As Integer = 0 Dim nPgsClock As Integer = 0 ' Lancio in parallelo più processi (senza superare il numero di core logici presenti) Dim vProc As MyProc() = New MyProc(nMaxThread - 1) {} For j As Integer = 0 To nMaxThread - 1 vProc(j).nBar = -1 vProc(j).bEnable = True Next ' Processo i Btl in parallelo Dim nCurrBar As Integer = 0 Dim nDoneBar As Integer = 0 Dim nShiftBar As Integer = 0 Dim nActProc As Integer = 0 While nCurrBar < numBars + nShiftBar OrElse nActProc > 0 For j As Integer = 0 To nMaxThread - 1 If Not vProc(j).bEnable Then Continue For Dim bDone As Boolean = False If vProc(j).nBar = -1 Then If nCurrBar < numBars + nShiftBar Then If vBar(nCurrBar).bBarOk Then vProc(j).Proc = New Process() vProc(j).Proc.StartInfo.FileName = ExePath vProc(j).Proc.StartInfo.Arguments = """" & vBar(nCurrBar).sBarPath & """ " & """" & Map.refProjectVM.BTLStructureVM.nPROJTYPE & """ " & """" & CurrentMachine.sMachineName & """ " & vBar(nCurrBar).nCmdType vProc(j).Proc.StartInfo.UseShellExecute = False If vProc(j).Proc.Start() Then vProc(j).nBar = nCurrBar nCurrBar += 1 nActProc += 1 End If Else If vBar(nCurrBar).nCmdType = CmdType.CHECK OrElse vBar(nCurrBar).nCmdType = CmdType.CHECKGEN Then ProcessResults(vBar(nCurrBar)) bDone = True nCurrBar += 1 End If End If Else If vProc(j).Proc.HasExited Then ' se terminato con successo If vProc(j).Proc.ExitCode = 0 Then ' salvo il risultato If vBar(vProc(j).nBar).nCmdType = CmdType.CHECK OrElse vBar(vProc(j).nBar).nCmdType = CmdType.CHECKGEN Then ProcessResults(vBar(vProc(j).nBar)) bDone = True vProc(j).nBar = -1 nActProc -= 1 ' se superato il numero di processi eseguibili in parallelo ElseIf vProc(j).Proc.ExitCode = 1 Then ' aggiungo il pezzo in coda If numBars + nShiftBar < numBars + nMaxThread Then vBar(numBars + nShiftBar) = vBar(vProc(j).nBar) nShiftBar += 1 End If ' disabilito il processo vProc(j).bEnable = False vProc(j).nBar = -1 nActProc -= 1 ' altrimenti (errore generico di esecuzione) Else ' salvo il risultato If vBar(vProc(j).nBar).nCmdType = CmdType.CHECK OrElse vBar(vProc(j).nBar).nCmdType = CmdType.CHECKGEN Then ProcessResults(vBar(vProc(j).nBar)) bDone = True vProc(j).nBar = -1 nActProc -= 1 End If Else vProc(j).Proc.Refresh() End If End If If bDone Then ' se non sono in simulazione If bIsSimulation Then callback(0, "Simulation closing", bCancel) Else ' Dialog con Progress Bar nDoneBar += 1 dProgress = 1 / numBars * nDoneBar Dim sProg As String = (dProgress * 100).ToString("F1", CultureInfo.InvariantCulture) callback(dProgress, " Progress: " & sProg & "% Count: " & nDoneBar & " / " & numBars, bCancel) End If If bCancel Then ' fine callback(1, "", bCancel) ' riabilito interfaccia Map.refProjectVM.ManageIsEnabled(True) Map.refMyStatusBarVM.ResetStopProgress() Return End If nPgsCurrBar = 0 nPgsClock = 0 Else ' se non sono in simulazione If Not bIsSimulation Then ' aggiorno conteggio If nPgsClock >= 100 AndAlso nPgsCurrBar < 149 Then nPgsCurrBar += 1 dProgress = 1 / numBars * nDoneBar + 1 / numBars / 150 * nPgsCurrBar Dim sProg As String = (dProgress * 100).ToString("F1", CultureInfo.InvariantCulture) callback(dProgress, " Progress: " & sProg & "% Count: " & nDoneBar & " / " & numBars, bCancel) nPgsClock = 0 End If End If End If nPgsClock += 1 Thread.Sleep(1) Next ' Verifico che i processi non siano andati tutti in errore Dim bAllKO As Boolean = True For j As Integer = 0 To nMaxThread - 1 If vProc(j).bEnable Then bAllKO = False Next If bAllKO Then MessageBox.Show("Execution error (all processes are disabled)") Exit While End If Thread.Sleep(10) End While Thread.Sleep(300) ' se sono in simulazione If bIsSimulation Then callback(1, "Simulation closed", bCancel) Else callback(1, "Done", bCancel) End If ' riabilito interfaccia Map.refProjectVM.ManageIsEnabled(True) Map.refMyStatusBarVM.ResetStopProgress() End Sub Private Shared Function CreateNewProjectFromPart(nPartId As Integer, sProjDirPath As String) As String ' Aggiorno identificativi per segnalazione errori UpdateCutIdAndTaskId(nPartId) ' Disabilito segnalazione modificato Dim DisableMgr As New DisableModifiedMgr ' Recupero visibilita' pezzo e lo imposto a visibile Dim nOldPartMode As Integer EgtGetMode(nPartId, nOldPartMode) EgtSetMode(nPartId, GDB_MD.STD) ' Salvo pezzo nel suo progetto Dim bOk As Boolean = False Dim nPDN As Integer = 0 EgtGetInfo(nPartId, BTL_PRT_PDN, nPDN) Dim sPartFilePath As String = sProjDirPath & "\" & nPDN.ToString() & ".bwe" bOk = EgtSaveObjToFile(nPartId, sPartFilePath, NGE.CMPTEXT) ' Ripristino visibilita' pezzo EgtSetMode(nPartId, nOldPartMode) ' Ripristino stato segnalazione modifica DisableMgr.ReEnable() Return If(bOk, sPartFilePath, String.Empty) End Function Private Shared Function CreateNewProjectFromMachGroup(nMachGroupId As Integer, sProjDirPath As String) As String ' Aggiorno identificativi per segnalazione errori Dim nOldMachGroup As Integer = EgtGetCurrMachGroup() If nMachGroupId <> nOldMachGroup Then EgtSetCurrMachGroup(nMachGroupId) Dim nRawId As Integer = EgtGetFirstRawPart() While nRawId <> GDB_ID.NULL If EgtVerifyRawPartPhase(nRawId, 1) Then Dim nPartId As Integer = EgtGetFirstPartInRawPart(nRawId) While nPartId <> GDB_ID.NULL UpdateCutIdAndTaskId(nPartId) nPartId = EgtGetNextPartInRawPart(nPartId) End While End If nRawId = EgtGetNextRawPart(nRawId) End While If nMachGroupId <> nOldMachGroup Then If nOldMachGroup <> GDB_ID.NULL Then EgtSetCurrMachGroup(nOldMachGroup) Else EgtResetCurrMachGroup() End If End If ' Salvo gruppo di lavorazione nel suo progetto Dim sMachGroupName As String = "" EgtGetMachGroupName(nMachGroupId, sMachGroupName) Dim sMachGroupFilePath As String = sProjDirPath & "\" & sMachGroupName & ".bwe" If EgtSaveObjToFile(nMachGroupId, sMachGroupFilePath, NGE.CMPTEXT) Then Return sMachGroupFilePath End If Return String.Empty End Function Private Shared Function UpdateCutIdAndTaskId(nPartId As Integer) As Boolean ' Assegno Id a CutId per calcoli EgtSetInfo(nPartId, "CUTID", nPartId, True) ' Assegno TASKID agli outline per calcoli Dim nOutLayerId As Integer = EgtGetFirstNameInGroup(nPartId, OUTLINE) Dim nOutlineId As Integer = EgtGetFirstInGroup(nOutLayerId) While nOutlineId <> GDB_ID.NULL ' verifico che sia una feature Dim nGRP As Integer If EgtGetInfo(nOutlineId, BTL_FTR_GRP, nGRP) Then ' verifico se ha un principale Dim nMainOffsId As Integer If EgtGetInfo(nOutlineId, BTL_FTR_MAINID, nMainOffsId) Then ' assegno TASKID alla feature per calcoli EgtSetInfo(nOutlineId, "TASKID", nOutlineId + nMainOffsId, True) Else ' assegno TASKID alla feature per calcoli EgtSetInfo(nOutlineId, "TASKID", nOutlineId, True) End If End If nOutlineId = EgtGetNext(nOutlineId) End While ' Assegno TASKID alle feature per calcoli Dim nProcessingId As Integer = EgtGetFirstNameInGroup(nPartId, PROCESSINGS) Dim nFeatureId As Integer = EgtGetFirstInGroup(nProcessingId) While nFeatureId <> GDB_ID.NULL ' verifico che sia una feature Dim nGRP As Integer If EgtGetInfo(nFeatureId, BTL_FTR_GRP, nGRP) Then ' verifico se ha un principale Dim nMainOffsId As Integer If EgtGetInfo(nFeatureId, BTL_FTR_MAINID, nMainOffsId) Then ' assegno TASKID alla feature per calcoli EgtSetInfo(nFeatureId, "TASKID", nFeatureId + nMainOffsId, True) Else ' assegno TASKID alla feature per calcoli EgtSetInfo(nFeatureId, "TASKID", nFeatureId, True) End If End If nFeatureId = EgtGetNext(nFeatureId) End While Return True End Function Private Shared Sub ProcessResults(Bar As Bar) Dim BtlPath As String = Bar.sBarPath Dim ResPath As String = Path.ChangeExtension(BtlPath, ".txt") Dim bErrors As Boolean = False Dim nLastErr As Integer = 0 Dim sLastMsg As String = "" Dim nCurrCutId As Integer = 0 Dim nTotTime As Integer = 0 If File.Exists(ResPath) Then Dim ProcessResultList As New List(Of ProcessResult) Dim nErr As Integer = 0 Dim sMsg As String = "" Dim dRot As Double = 0 Dim nFall As Integer = 0 Dim dPartRot As Double = 0 Dim dTotRot As Double = 0 Dim cutId As Integer = 0 Dim taskId As Integer = 0 Dim prevCutId As Integer = GDB_ID.NULL Dim currBTLPart As BTLPartVM = Nothing Dim currPart As PartVM Dim lines As String() = System.IO.File.ReadAllLines(ResPath) For Each line As String In lines If line.StartsWith("ERR=") Then Dim nVal As Integer? = GetVal(line, "ERR") nErr = (If(nVal IsNot Nothing, nVal.Value, 0)) sMsg = "" dRot = 0 nFall = 0 cutId = 0 taskId = 0 ElseIf line.StartsWith("ROT=") Then Dim nVal As Integer? = GetVal(line, "ROT") Dim nRot As Integer = (If(nVal IsNot Nothing, nVal.Value, 0)) dRot = Math.Abs(((4 - nRot) Mod 4) * 90) dPartRot = Math.Max(dPartRot, dRot) dTotRot = Math.Max(dTotRot, dRot) ElseIf line.StartsWith("CUTID=") Then Dim nVal As Integer? = GetVal(line, "CUTID") cutId = If(nVal IsNot Nothing, nVal.Value, 0) ElseIf line.StartsWith("TASKID=") Then Dim nVal As Integer? = GetVal(line, "TASKID") taskId = (If(nVal IsNot Nothing, nVal.Value, 0)) ProcessResultAdd(ProcessResultList, ProcessResult.CreateTaskResult(cutId, taskId, nErr, sMsg, dRot), Bar) ElseIf line.StartsWith("FALL=") Then Dim nVal As Integer? = GetVal(line, "FALL") nFall = (If(nVal IsNot Nothing, nVal.Value, 0)) ProcessResultList.Add(ProcessResult.CreateFallResult(cutId, nErr, sMsg, nFall)) ElseIf line.StartsWith("TIME=") Then Dim nVal As Integer? = GetVal(line, "TIME") nTotTime = (If(nVal IsNot Nothing, nVal.Value, 0)) ProcessResultList.Add(ProcessResult.CreateTimeResult(cutId, nTotTime)) 'If Bar.nBarType = ProjectType.PROJ AndAlso Not IsNothing(currBTLPart) Then ' EgtSetInfo(currBTLPart.nPartId, If(Bar.nBarType = ProjectType.PROJ, ITG_PROJ_TIME, ITG_PROD_TIME), nTotTime, True) 'End If ElseIf Not String.IsNullOrWhiteSpace(line) AndAlso line <> "---" Then sMsg = line End If Next If ProcessResultList.Count > 0 Then If Bar.nBarType = ProjectType.PROJ Then ' Inizializzo il pezzo in verifica Dim BTLPart As BTLPartVM = GetBTLPartVMFromPartId(Bar.nBarId) BTLPart.CalcPartUpdate(0, 0, "") Else ' Inizializzo i pezzi del gruppo di lavoro in verifica Dim Machgroup As MyMachGroupVM = GetMachgroupVMFromMachgroupId(Bar.nBarId) For Each Part In Machgroup.PartVMList Part.CalcPartUpdate(0, 0, "") Next Machgroup.CalcMachGroupUpdate(0, 0, "") End If ' Ciclo ... Dim nCUTID As Integer = -1 Dim CurrBTLPartVM As BTLPartVM Dim CurrPartVM As PartVM Dim CurrMachgroupVM As MyMachGroupVM Dim CurrBTLFeatureVM As BTLFeatureVM For Each Line In ProcessResultList ' se necessario recupero part If Line.nCUTID <> 0 Then If Line.nCUTID <> nCUTID Then nCUTID = Line.nCUTID If Bar.nBarType = ProjectType.PROJ Then ' aggiorno nuovo pezzo CurrBTLPartVM = GetBTLPartVMFromPartId(Line.nCUTID) Else ' aggiorno nuovo pezzo CurrPartVM = GetPartVMFromPartId(Line.nCUTID) End If End If Else ' se CutId = 0 If Bar.nBarType = ProjectType.PROJ Then ' imposto unico pezzo presente CurrBTLPartVM = GetBTLPartVMFromPartId(Bar.nBarId) Else ' riporto errore barra CurrMachgroupVM = GetMachgroupVMFromMachgroupId(Bar.nBarId) End If End If ' se necessario recupero feature If Line.nTASKID <> 0 Then If Bar.nBarType = ProjectType.PROJ Then CurrBTLFeatureVM = GetBTLFeatureVMFromBTLPartId(CurrBTLPartVM, Line.nTASKID) Else CurrBTLFeatureVM = GetFeatureVMFromPartId(CurrPartVM, Line.nTASKID) End If Else CurrBTLFeatureVM = Nothing End If Select Case Line.Type Case ProcessResult.ProcessResultTypes.BAR If Bar.nBarType = ProjectType.PROJ Then CurrBTLPartVM.CalcPartUpdate(Line.nERR, Line.dROT, Line.sMSG) Else CurrMachgroupVM.CalcMachGroupUpdate(Line.nERR, Line.dROT, Line.sMSG) End If Case ProcessResult.ProcessResultTypes.PART If Bar.nBarType = ProjectType.PROJ Then CurrBTLPartVM.CalcPartUpdate(Line.nERR, Line.dROT, Line.sMSG) Else CurrPartVM.CalcPartUpdate(Line.nERR, Line.dROT, Line.sMSG) End If Case ProcessResult.ProcessResultTypes.TASKID CurrBTLFeatureVM.CalcFeatureUpdate(Line.nERR, Line.dROT, Line.sMSG) Case ProcessResult.ProcessResultTypes.FALL If Bar.nBarType = ProjectType.PROJ Then CurrBTLPartVM.CalcFallUpdate(Line.nFALL) Else CurrPartVM.CalcFallUpdate(Line.nFALL) End If Case ProcessResult.ProcessResultTypes.TIME If Bar.nBarType = ProjectType.PROJ Then CurrBTLPartVM.CalcTimeUpdate(Line.nTIME) Else If IsNothing(CurrMachgroupVM) Then CurrMachgroupVM = GetMachgroupVMFromMachgroupId(Bar.nBarId) CurrMachgroupVM.CalcTimeUpdate(Line.nTIME) End If End Select Next If Bar.nBarType = ProjectType.PROJ Then ' aggiorno il pezzo Dim BTLPart As BTLPartVM = GetBTLPartVMFromPartId(Bar.nBarId) BTLPart.CalcGlobalUpdate() ' lancio aggiornamento tempo su BTL Map.refProjectVM.BTLStructureVM.CalcGlobalTime() Else Dim Machgroup As MyMachGroupVM = GetMachgroupVMFromMachgroupId(Bar.nBarId) For Each Part In Machgroup.PartVMList Part.CalcGlobalUpdate() Next Machgroup.CalcGlobalUpdate() ' lancio aggiornamento tempo su MachgroupPanel Map.refProjectVM.MachGroupPanelVM.CalcGlobalTime() End If End If Else bErrors = True nLastErr = 25 sLastMsg = "Execution Error" End If End Sub Private Shared Function GetVal(sText As String, sKey As String) As Integer? Dim sParts As String() = sText.Split("="c) If String.Compare(sParts(0), sKey) <> 0 Then Return Nothing Dim nVal As Integer = Nothing If Not Integer.TryParse(sParts(1), nVal) Then Return Nothing Else Return nVal End If End Function Private Shared Sub ProcessResultAdd(PRList As List(Of ProcessResult), NewPR As ProcessResult, Bar As Bar) Dim Prev As ProcessResult Select Case NewPR.Type Case ProcessResult.ProcessResultTypes.BAR If Bar.nBarType = ProjectType.PROJ Then Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.PART) Else Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.BAR) End If Case ProcessResult.ProcessResultTypes.PART Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.PART AndAlso x.nCUTID = NewPR.nCUTID) Case ProcessResult.ProcessResultTypes.TASKID Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.TASKID AndAlso x.nCUTID = NewPR.nCUTID AndAlso x.nTASKID = NewPR.nTASKID) End Select If IsNothing(Prev) Then PRList.Add(NewPR) ElseIf NewPR.nERR = 22 Or (NewPR.nERR > 0 And Prev.nERR <= 0) Or (NewPR.nERR < 0 And Prev.nERR = 0) Then If NewPR.dROT = 0 And Prev.dROT <> NewPR.dROT Then NewPR.SetROT(Prev.dROT) End If PRList.Remove(Prev) PRList.Add(NewPR) ElseIf Prev.dROT = 0 And Prev.dROT <> NewPR.dROT Then Prev.SetROT(NewPR.dROT) End If End Sub Private Shared Function GetBTLPartVMFromPartId(nPartId As Integer) As BTLPartVM Return Map.refProjectVM.BTLStructureVM.BTLPartVMList.FirstOrDefault(Function(x) x.nPartId = nPartId) End Function Private Shared Function GetPartVMFromPartId(nPartId As Integer) As PartVM For Each MachGroupVM As MyMachGroupVM In Map.refProjectVM.MachGroupPanelVM.MachGroupVMList Dim PartVM As PartVM = MachGroupVM.PartVMList.FirstOrDefault(Function(x) x.nPartId = nPartId) If Not IsNothing(PartVM) Then Return PartVM Next End Function Private Shared Function GetMachgroupVMFromMachgroupId(nMachGroupId As Integer) As MyMachGroupVM Return Map.refProjectVM.MachGroupPanelVM.MachGroupVMList.FirstOrDefault(Function(x) x.Id = nMachGroupId) End Function Private Shared Function GetBTLFeatureVMFromBTLPartId(BTLPartVM As BTLPartVM, nFeatureId As Integer) As BTLFeatureVM Return BTLPartVM.BTLFeatureVMList.FirstOrDefault(Function(x) x.nFeatureId = nFeatureId) End Function Private Shared Function GetFeatureVMFromPartId(PartVM As PartVM, nFeatureId As Integer) As BTLFeatureVM Return PartVM.FeatureVMList.FirstOrDefault(Function(x) x.nFeatureId = nFeatureId) End Function End Class Public Class ProcessResult Public Enum ProcessResultTypes As Integer BAR = 1 PART = 2 TASKID = 3 FALL = 4 TIME = 5 End Enum Private m_Type As ProcessResultTypes Public ReadOnly Property Type As ProcessResultTypes Get Return m_Type End Get End Property Private m_nCUTID As Integer Public ReadOnly Property nCUTID As Integer Get Return m_nCUTID End Get End Property Private m_nTASKID As Integer Public ReadOnly Property nTASKID As Integer Get Return m_nTASKID End Get End Property Private m_nERR As Integer Public ReadOnly Property nERR As Integer Get Return m_nERR End Get End Property Private m_sMSG As String Public ReadOnly Property sMSG As String Get Return m_sMSG End Get End Property Private m_dROT As Double Public ReadOnly Property dROT As Double Get Return m_dROT End Get End Property Friend Sub SetROT(value As Double) m_dROT = value End Sub Private m_nFALL As Integer Public ReadOnly Property nFALL As Integer Get Return m_nFALL End Get End Property Private m_nTIME As Integer Public ReadOnly Property nTIME As Integer Get Return m_nTIME End Get End Property Public Shared Function CreateTaskResult(CUTID As Integer, TASKID As Integer, ERR As Integer, MSG As String, ROT As Double) As ProcessResult If CUTID <> 0 Then If TASKID = 0 Then Return New ProcessResult(ProcessResultTypes.PART, CUTID, TASKID, ERR, MSG, ROT, 0, 0) End If Return New ProcessResult(ProcessResultTypes.TASKID, CUTID, TASKID, ERR, MSG, ROT, 0, 0) End If Return New ProcessResult(ProcessResultTypes.BAR, CUTID, TASKID, ERR, MSG, ROT, 0, 0) End Function Public Shared Function CreateFallResult(CUTID As Integer, ERR As Integer, MSG As String, FALL As Integer) As ProcessResult Return New ProcessResult(ProcessResultTypes.FALL, CUTID, 0, ERR, MSG, 0, FALL, 0) End Function Public Shared Function CreateTimeResult(CUTID As Integer, TIME As Integer) As ProcessResult Return New ProcessResult(ProcessResultTypes.TIME, CUTID, 0, 0, "", 0, 0, TIME) End Function Protected Sub New(Type As ProcessResultTypes, CUTID As Integer, TASKID As Integer, ERR As Integer, MSG As String, ROT As Double, FALL As Integer, TIME As Integer) m_Type = Type m_nCUTID = CUTID m_nTASKID = TASKID m_nERR = ERR m_sMSG = MSG m_dROT = ROT m_nFALL = FALL m_nTIME = TIME End Sub End Class