Function NDW_QA_MET_RESULT_EVENTS(CtrlEntId, Event, @PARAMS) /*********************************************************************************************************************** This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written permission from Infineon. Name : NDW_QA_MET_RESULT_EVENTS Description : This function acts as a commuter module for all events related to this window. Notes : Commuter Modules are automatically called from the Promoted_Events function which is called by the application-specific promoted event handler. This makes it possible to add QuickEvents that need to execute Basic+ logic without having use the Form Designer to make the association, although this is limited to the events which are currently promoted. If the form needs to call the commuter module directly then the QuickEvent parameters should be formatted like this: '@SELF','@EVENT',['@PARAM1','@PARAMx'] Parameters : CtrlEntId [in] -- The fully qualified name of the control calling the promoted event Event [in] -- The event being executed. See the Notes section regarding "PRE" events Param1-15 [in] -- Additional event parameter holders EventFlow [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in EVENT_SETUP insert History : (Date, Initials, Notes) 06/08/18 djs Created initial commuter module. 07/30/18 djs Refactored form and commuter module to apply to the Unload stage only. Other stages will use the previous form, QA_MET_RESULT. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #Window NDW_QA_MET_RESULT DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, obj_WO_Mat, Btree.Extract DECLARE SUBROUTINE ErrMsg, Set_Property, obj_AppWindow, Send_Event, obj_WO_Mat_QA, obj_Tables DECLARE SUBROUTINE Start_Window, End_Window, Database_Services Declare subroutine SRP_EditTable_Manager, SRP_Show_Window, Rds_Services, Form_Services DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, obj_WM_Out, set_WinMsgVal, Form_Services, Memberof DECLARE FUNCTION Msg, obj_WO_Mat, Send_Message, obj_Tables, Start_Window, End_Window, QA_Services, Signature_Services DECLARE FUNCTION SRP_EditTable_Manager, Database_Services, Material_Services, Rds_Services, RGB $insert LOGICAL $insert EVENT_SETUP $insert WO_MAT_EQUATES $insert MSG_EQUATES $INSERT LSL_USERS_EQU $INSERT WM_OUT_EQUATES $INSERT WO_MAT_QA_EQUATES $INSERT POPUP_EQUATES $INSERT APPCOLORS $INSERT RDS_EQUATES $INSERT PRS_STAGE_EQUATES $INSERT TOOL_CLASS_EQUATES Equ Tab$ to \09\ Equ CRLF$ to \0D0A\ Equ LF$ to \0A\ Equ Comma$ to ',' ErrTitle = 'Error in NDW_QA_Met_Result_Events' ErrorMsg = '' Result = '' SubclassInfo = Form_Services('FindSubclassControl') Subclass = SubclassInfo<1> // Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler. If Event EQ 'OLE' then Transfer Event to OIEvent Transfer Param1 to Event Transfer Param2 to Param1 Transfer Param3 to Param2 * Transfer Param4 to Param3 * Transfer Param5 to Param4 * Transfer Param6 to Param5 * Transfer Param7 to Param6 * Transfer Param8 to Param7 end GoToEvent Event for CtrlEntID Return EventFlow else EVENT_CONTINUE$ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Events //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Event WINDOW.CREATE(CreateParam) ******************* * Read Parameters * ******************* CassID = CreateParam[1,@FM] Stage = CassID[-1, 'B*'] WONo = FIELD(CassID,'*',1) WOStepNo = FIELD(CassID,'*',2) CassNo = FIELD(CassID,'*',3) RDSNo = FIELD(CassID,'*',4) RunStep = FIELD(CassID,'*',5) CanEdit = (Memberof(@USER4, 'ENGINEERING') or Memberof(@USER4, 'LEAD') or Memberof(@USER4, 'SUPERVISOR')) If CanEdit then If Stage EQ 'UNLOAD' then //Check if UNLOAD stage is signed UnloadSigned = Signature_Services('GetStageSummary', WoMatKey, 'UNLOAD')<2> If UnloadSigned then Set_Property(@Window, '@CANEDIT', True$) end else Set_Property(@Window, '@CANEDIT', False$) end end end else Set_Property(@Window, '@CANEDIT', False$) end Set_Property(@Window : '.WO_NO', 'TEXT', WoNo) Set_Property(@Window : '.PROC_STEP_NO', 'TEXT', WOStepNo) Set_Property(@Window : '.OUT_CASS_NO', 'TEXT', CassNo) Set_Property(@Window : '.RDS_NO', 'TEXT', RDSNo) Set_Property(@Window : '.STAGE', 'TEXT', Stage) Set_Property(@Window : '.RUN_STEP', 'TEXT', RunStep) WOMatQAKey = WONo : '*' : CassNo WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) Profile = WOMatQARec ThickSpecMin = '' ThickSpecMax = '' HgCVSpecMin = '' HgCVSpecMax = '' HgCVSpecPhaseMin = '' Locate '1THICK_ONLY' in Profile using @VM setting vPos then ThickSpecMin = WOMatQARec ThickSpecMax = WOMatQARec end Locate '1CRES' in Profile using @VM setting vPos then HgCVSpecMin = WOMatQARec HgCVSpecMax = WOMatQARec HgCVSpecPhaseMin = WOMatQARec If HgCVSpecPhaseMin EQ '' then // Phase Min Spec was not added to WO_MAT_QA record when it should have been. // This bug should be fixed now, but in the meantime current records in production // may not have a phase min specification value. We need to add it here. - djs - 10/15/18 PSN = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') If PSN NE '' then PRSStageKey = PSN:'*UNLOAD' Database_Services('ActivateRecord', 'PRS_STAGE', PRSStageKey) MetProps = {MET_PROP} Locate 'CRES' in MetProps using @VM setting PropPos then SpecPhaseMinCol = {MET_PHASE_MIN} SpecPhaseMin = SpecPhaseMinCol<1, PropPos> WOMatQARec = SpecPhaseMin HgCVSpecPhaseMin = SpecPhaseMin Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, False$, False$) end end end end If ThickSpecMin NE '' then Set_Property(@Window : '.THICK_SPEC_MIN', 'TEXT', ThickSpecMin) Set_Property(@Window : '.THICK_SPEC_MIN', 'BACKCOLOR', GREEN$) end If ThickSpecMax NE '' then Set_Property(@Window : '.THICK_SPEC_MAX', 'TEXT', ThickSpecMax) Set_Property(@Window : '.THICK_SPEC_MAX', 'BACKCOLOR', GREEN$) end If HgCVSpecMin NE '' then Set_Property(@Window : '.HGCV_SPEC_MIN', 'TEXT', HgCVSpecMin) Set_Property(@Window : '.HGCV_SPEC_MIN', 'BACKCOLOR', GREEN$) end If HgCVSpecMax NE '' then Set_Property(@Window : '.HGCV_SPEC_MAX', 'TEXT', HgCVSpecMax) Set_Property(@Window : '.HGCV_SPEC_MAX', 'BACKCOLOR', GREEN$) end If HgCVSpecPhaseMin NE '' then Set_Property(@Window : '.HGCV_SPEC_PHASE_MIN', 'TEXT', HgCVSpecPhaseMin) Set_Property(@Window : '.HGCV_SPEC_PHASE_MIN', 'BACKCOLOR', GREEN$) end GoSub FillHgCVTable SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize) end event Event THICK_READINGS.GOTFOCUS(PrevFocusID) WO = Get_Property(@Window : '.WO_NO', 'TEXT') CassNo = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') WoMatKey = WO : '*' : CassNo Stage = Get_Property(@Window : '.STAGE', 'TEXT') If Stage EQ 'UNLOAD' then test = Signature_Services('GetStageSummary', WoMatKey, 'UNLOAD') UnloadSigned = Signature_Services('GetStageSummary', WoMatKey, 'UNLOAD')<2> If UnloadSigned then GoSub VerifyUser end else Message = 'Unload metrology data may only be entered after the UNLOAD signature has been signed.' Msg(@Window, Message) end end else GoSub VerifyUser end end event Event HGCV_READINGS.GOTFOCUS(PrevFocusID) WO = Get_Property(@Window : '.WO_NO', 'TEXT') CassNo = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') WoMatKey = WO : '*' : CassNo Stage = Get_Property(@Window : '.STAGE', 'TEXT') GoSub VerifyUser end event Event HGCV_PHASE_READINGS.GOTFOCUS(PrevFocusID) WO = Get_Property(@Window : '.WO_NO', 'TEXT') CassNo = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') WoMatKey = WO : '*' : CassNo Stage = Get_Property(@Window : '.STAGE', 'TEXT') GoSub VerifyUser end event Event THICK_AVG.GOTFOCUS(PrevFocusID) GoSub VerifyUser end event Event HGCV_AVG.GOTFOCUS(PrevFocusID) GoSub VerifyUser end event Event HGCV_PHASE_AVG.GOTFOCUS(PrevFocusID) GoSub VerifyUser end event Event SIGN.CLICK() WO = Get_Property(@Window : '.WO_NO', 'TEXT') CassNo = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') WoMatKey = WO : '*' : CassNo Stage = Get_Property(@Window : '.STAGE', 'TEXT') If Stage EQ 'UNLOAD' then UnloadSigned = Signature_Services('GetStageSummary', WoMatKey, 'UNLOAD')<2> If UnloadSigned then GoSub SaveQAData end else GoSub VerifyUser CanEdit = Get_Property(@Window, '@CANEDIT') If CanEdit then GoSub SaveQAData end else Message = 'Unload metrology data may only be entered after the UNLOAD signature has been signed.' Msg(@Window, Message) Return end end end else GoSub SaveQAData end SignatureReady = True$ WONo = Get_Property(@WINDOW:'.WO_NO','DEFPROP') CassNo = Get_Property(@WINDOW:'.OUT_CASS_NO','DEFPROP') WOMatQAKey = WONo : '*' : CassNo WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey, True$, 0, False$) UnloadOutOfSpec = 0 Stages = WOMatQARec TestAvgs = WOMatQARec For each Stage in Stages using @VM setting vPos If Stage EQ 'UNLOAD' then // Check if an average value (i.e. result) exists for the test. // If not, then skip if that test has failed. TestComp = (TestAvgs<0, vPos> NE '') If TestComp EQ True$ then StageOutOfSpec = WOMatQARec If StageOutOfSpec EQ True$ then StageFailReason = WOMatQARec // Ignore signature failures since user is attempting to sign the records. If (StageFailReason NE 'THICK_ONLY UNLOAD product measurement test has not been signed.') | and (StageFailReason NE 'CRES UNLOAD product measurement test has not been signed.') then UnloadOutOfSpec += 1 end end end end Next Stage OutOfSpec = Sum(UnloadOutOfSpec) If OutOfSpec GT 0 then FailReasons = WOMatQARec Msg = 'Unable to sign Unload QA Metrology for the followings reason(s).' For each FailReason in FailReasons using @VM If (FailReason NE 'THICK_ONLY UNLOAD product measurement test has not been signed.') | and (FailReason NE 'CRES UNLOAD product measurement test has not been signed.') then Msg := CRLF$ : FailReason end Next FailReason ErrMsg(Msg) SignatureReady = False$ end RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') IF (SignatureReady = True$) THEN Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW) Valid = Response<1> Username = Response<2> IF (Valid) THEN DTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTHS') OverrideUser = Get_Property(@Window, '@OVERRIDE_USER') If OverrideUser NE '' then Signature = OverrideUser end else Signature = Username end Profile = WOMatQARec Locate '1THICK_ONLY' in Profile setting vPos then Avg = WOMatQARec Sig = WOMatQARec If (Avg NE '') and (Sig EQ '') then WOMatQARec = Signature WOMatQARec = IConv(DTM, 'DT') end end Locate '1CRES' in Profile setting vPos then Avg = WOMatQARec Sig = WOMatQARec If (Avg NE '') and (Sig EQ '') then WOMatQARec = Signature WOMatQARec = IConv(DTM, 'DT') end end end Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, False$, True$) Send_Event('RDS_UNLOAD','WRITE') obj_Appwindow('LoadFormKeys','RDS_UNLOAD':@RM:RDSNo) End_Window(@WINDOW,'') END ELSE ;* End of check for Signature Ready Send_Event('RDS_UNLOAD','WRITE') obj_Appwindow('LoadFormKeys','RDS_UNLOAD':@RM:RDSNo) END end event Event TW_USE_BUTTON.CLICK() GoSub LaunchRDSMetrology end event Event EXIT.CLICK() End_Window(@Window, '') end event Event WINDOW.CLOSE(CancelFlag) End_Window(@WINDOW,'') end event Event OLE_SUBCLASS.OnComboClick(CtrlId, Sel, Value) Send_Event(CtrlId, 'LOSTFOCUS') end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Setup_OLE_Controls: Qualify = '' Qualify<1> = 1 Qualify<4> = 0 return FillHgCVTable: WorkOrderNo = Get_Property(@Window : '.WO_NO', 'DEFPROP') CassNo = Get_Property(@Window : '.OUT_CASS_NO', 'DEFPROP') WOMatQAKey = WorkOrderNo : '*' : CassNo WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) DataPoints = WOMatQARec Profiles = WOMatQARec ; // THICK_ONLY, CRES Result = WOMatQARec ; // Average of Data Points MinResult = WOMatQARec ; // Min of Data Points MaxResult = WOMatQARec ; // Max of Data Points RangePctResult = WOMatQARec ; // Range % of Data Points EdgeMeanResult = WOMatQARec ; // Edge Mean Delta of Data Points SpecMin = WOMatQARec SpecMax = WOMatQARec SpecPhaseMin = WOMatQARec ToolClasses = WOMatQARec Patterns = WOMatQARec RowLimit = Get_Property(@Window : '.TEST_POINTS', 'ROWLIMIT') ; //Default row limit. RowLimits = '' MaxRows = 0 For each Pattern in Patterns using @VM setting vPos ToolClass = ToolClasses<1, vPos> ToolClassRec = Database_Services('ReadDataRow', 'TOOL_CLASS', ToolClass) ToolPatterns = ToolClassRec ToolPatternSizes = ToolClassRec Locate Pattern in ToolPatterns using @VM setting PatternPos then PatternSize = ToolPatternSizes<1, PatternPos> If PatternSize GT MaxRows then MaxRows = PatternSize RowLimits<1, vPos> = PatternSize end else RowLimits<1, vPos> = RowLimit end Next Recipe BadColorArray = RED$:@FM:'':@FM:BRED$:@FM:'' GoodColorArray = GREEN$:@FM:'':@FM:'':@FM:'' List = '' HgCVData = '' PhaseData = '' For each Profile in Profiles using @VM setting ProfIndex If Profile EQ '1THICK_ONLY' then ThickEditCtrl = @Window:'.THICK_READINGS' List = DataPoints<1, ProfIndex> PatternSize = RowLimits<1, ProfIndex> If List NE '' then // Data points 11-14 are not to be used for statistical analysis within OpenInsight. We will display // them, but will not flag them as within/out of spec nor will we block signatures if they are out of // bounds. This means that the min, max, and average will be calculated using points 1-9. StopPoint = 10 SpecThickMin = SpecMin<1, ProfIndex> SpecThickMax = SpecMax<1, ProfIndex> Convert @SVM to @VM in List NumRows = DCount(List, @VM) // Fill out the edit table to RowLimit for clean display For CurrRow = NumRows to PatternSize List := @VM Next CurrRow Set_Property(@Window : '.THICK_READINGS', 'DEFPROP', List) For each ThickDataPoint in List using @VM setting vPos Until (vPos GT NumRows) or (vPos GT StopPoint) If ( ThickDataPoint LT SpecThickMin ) OR ( ThickDataPoint GT SpecThickMax ) then stat = Send_Message(ThickEditCtrl, 'COLOR_BY_POS', 0, vPos, BadColorArray) end else stat = Send_Message(ThickEditCtrl, 'COLOR_BY_POS', 0, vPos, GoodColorArray) end Next ThickDataPoint end else For Row = 1 to PatternSize stat = Send_Message(ThickEditCtrl, 'COLOR_BY_POS', 0, Row, BadColorArray) Next Row Set_Property(@Window : '.THICK_AVG', 'BACKCOLOR', RED$) Set_Property(@Window : '.THICK_MIN', 'BACKCOLOR', RED$) Set_Property(@Window : '.THICK_MAX', 'BACKCOLOR', RED$) end SpecThickMin = SpecMin<1, ProfIndex> SpecThickMax = SpecMax<1, ProfIndex> ResultThickAvg = Result<1, ProfIndex> ResultThickMin = MinResult<1, ProfIndex> ResultThickMax = MaxResult<1, ProfIndex> Set_Property(@Window : '.THICK_AVG', 'DEFPROP', ResultThickAvg) Set_Property(@Window : '.THICK_MIN', 'DEFPROP', ResultThickMin) Set_Property(@Window : '.THICK_MAX', 'DEFPROP', ResultThickMax) If ResultThickAvg NE '' and SpecThickMax NE '' and SpecThickMin NE '' then If (ResultThickAvg GT SpecThickMax) OR (ResultThickAvg LT SpecThickMin) then Set_Property(@Window : '.THICK_AVG', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.THICK_AVG', 'BACKCOLOR', GREEN$) end end If ResultThickMin NE '' and SpecThickMax NE '' and SpecThickMin NE '' then If (ResultThickMin GT SpecThickMax) OR (ResultThickMin LT SpecThickMin) then Set_Property(@Window : '.THICK_MIN', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.THICK_MIN', 'BACKCOLOR', GREEN$) end end If ResultThickMax NE '' and SpecThickMax NE '' and SpecThickMin NE '' then If (ResultThickMax GT SpecThickMax) OR (ResultThickMax LT SpecThickMin) then Set_Property(@Window : '.THICK_MAX', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.THICK_MAX', 'BACKCOLOR', GREEN$) end end end If Profile EQ '1CRES' then HgCVEditCtrl = @Window:'.HGCV_READINGS' PhaseEditCtrl = @Window:'.HGCV_PHASE_READINGS' List = DataPoints<1, ProfIndex> PatternSize = RowLimits<1, ProfIndex> CriticalPoints = '1,2,5,6,9' SpecHgCVMin = SpecMin<1, ProfIndex> SpecHgCVMax = SpecMax<1, ProfIndex> ThisSpecPhaseMin = SpecPhaseMin<1, ProfIndex> If List NE '' then For each DataPoint in List using @SVM setting SVPos HgCVData := DataPoint[1, 'F' : @TM] : @VM PhaseData := DataPoint[-1, 'B' : @TM] : @VM Next DataPoint HgCVData[-1, 1] = '' ; // Strip final @VM PhaseData[-1, 1] = '' NumRows = DCount(HgCVData, @VM) // Fill out the edit table to RowLimit for clean display For CurrRow = NumRows to PatternSize HgCVData := @VM PhaseData := @VM Next CurrRow HgCVRangePct = RangePctResult<1, ProfIndex, 1> PhaseRangePct = RangePctResult<1, ProfIndex, 2> HgCVEdgeMean = EdgeMeanResult<1, ProfIndex, 1> PhaseEdgeMean = EdgeMeanResult<1, ProfIndex, 2> Set_Property(@Window : '.HGCV_READINGS', 'DEFPROP', HgCVData) Set_Property(@Window : '.HGCV_PHASE_READINGS', 'DEFPROP', PhaseData) For each HgCVDataPoint in HgCVData using @VM setting vPos Until vPos GT NumRows If ( ( HgCVDataPoint LT SpecHgCVMin ) OR ( HgCVDataPoint GT SpecHgCVMax ) ) and Index(CriticalPoints, vPos, 1) then stat = Send_Message(HgCVEditCtrl, 'COLOR_BY_POS', 0, vPos, BadColorArray) end else stat = Send_Message(HgCVEditCtrl, 'COLOR_BY_POS', 0, vPos, GoodColorArray) end Next HgCVDataPoint For each PhaseDataPoint in PhaseData using @VM setting vPos Until vPos GT NumRows If ( PhaseDataPoint LT ThisSpecPhaseMin ) and Index(CriticalPoints, vPos, 1) then stat = Send_Message(PhaseEditCtrl, 'COLOR_BY_POS', 0, vPos, BadColorArray) end else stat = Send_Message(PhaseEditCtrl, 'COLOR_BY_POS', 0, vPos, GoodColorArray) end Next PhaseDataPoint Set_Property(@Window : '.HGCV_RANGE_PCT', 'TEXT', HgCVRangePct : '%') Set_Property(@Window : '.HGCV_PHASE_RANGE_PCT', 'TEXT', PhaseRangePct : '%') Set_Property(@Window : '.HGCV_EDGE_DELTA', 'DEFPROP', HgCVEdgeMean : '%') Set_Property(@Window : '.HGCV_PHASE_DELTA', 'DEFPROP', PhaseEdgeMean : '%') Set_Property(@Window : '.HGCV_RANGE_PCT', 'BACKCOLOR', GREEN$) Set_Property(@Window : '.HGCV_PHASE_RANGE_PCT', 'BACKCOLOR', GREEN$) Set_Property(@Window : '.HGCV_EDGE_DELTA', 'BACKCOLOR', GREEN$) Set_Property(@Window : '.HGCV_PHASE_DELTA', 'BACKCOLOR', GREEN$) end else For each CriticalPoint in CriticalPoints using ',' stat = Send_Message(HgCVEditCtrl, 'COLOR_BY_POS', 0, CriticalPoint, BadColorArray) stat = Send_Message(PhaseEditCtrl, 'COLOR_BY_POS', 0, CriticalPoint, BadColorArray) Next CriticalPoint Set_Property(@Window : '.HGCV_AVG', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_MIN', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_MAX', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_PHASE_AVG', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_PHASE_MIN', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_PHASE_MAX', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_RANGE_PCT', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_PHASE_RANGE_PCT', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_EDGE_DELTA', 'BACKCOLOR', RED$) Set_Property(@Window : '.HGCV_PHASE_DELTA', 'BACKCOLOR', RED$) end HgCVAvg = Result<1, ProfIndex, 1> PhaseAvg = Result<1, ProfIndex, 2> HgCVMin = MinResult<1, ProfIndex, 1> HgCVMax = MaxResult<1, ProfIndex, 1> PhaseMin = MinResult<1, ProfIndex, 2> PhaseMax = MaxResult<1, ProfIndex, 2> Set_Property(@Window, '@ORIG_HGCV_AVG', HgCVAvg) Set_Property(@Window : '.HGCV_AVG', 'DEFPROP', HgCVAvg) Set_Property(@Window : '.HGCV_PHASE_AVG', 'DEFPROP', PhaseAvg) Set_Property(@Window : '.HGCV_MIN', 'DEFPROP', HgCVMin) Set_Property(@Window : '.HGCV_MAX', 'DEFPROP', HgCVMax) Set_Property(@Window : '.HGCV_PHASE_MIN', 'DEFPROP', PhaseMin) Set_Property(@Window : '.HGCV_PHASE_MAX', 'DEFPROP', PhaseMax) If HgCVAvg NE '' and SpecHgCVMax NE '' and SpecHgCVMin NE '' then If (HgCVAvg GT SpecHgCVMax) OR (HgCVAvg LT SpecHgCVMin) then Set_Property(@Window : '.HGCV_AVG', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.HGCV_AVG', 'BACKCOLOR', GREEN$) end end If HgCVMin NE '' and SpecHgCVMax NE '' and SpecHgCVMin NE '' then If (HgCVMin GT SpecHgCVMax) OR (HgCVMin LT SpecHgCVMin) then Set_Property(@Window : '.HGCV_MIN', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.HGCV_MIN', 'BACKCOLOR', GREEN$) end end If HgCVMax NE '' and SpecHgCVMax NE '' and SpecHgCVMin NE '' then If (HgCVMax GT SpecHgCVMax) OR (HgCVMax LT SpecHgCVMin) then Set_Property(@Window : '.HGCV_MAX', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.HGCV_MAX', 'BACKCOLOR', GREEN$) end end If PhaseAvg NE '' and ThisSpecPhaseMin NE '' then If (PhaseAvg LT ThisSpecPhaseMin) then Set_Property(@Window : '.HGCV_PHASE_AVG', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.HGCV_PHASE_AVG', 'BACKCOLOR', GREEN$) end end If PhaseMin NE '' and ThisSpecPhaseMin NE '' then If (PhaseMin LT ThisSpecPhaseMin) then Set_Property(@Window : '.HGCV_PHASE_MIN', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.HGCV_PHASE_MIN', 'BACKCOLOR', GREEN$) end end If PhaseMax NE '' and ThisSpecPhaseMin NE '' then If (PhaseMax LT ThisSpecPhaseMin) then Set_Property(@Window : '.HGCV_PHASE_MAX', 'BACKCOLOR', RED$) end else Set_Property(@Window : '.HGCV_PHASE_MAX', 'BACKCOLOR', GREEN$) end end end Next Profile List = '' For Index = 1 to MaxRows List := Index : @VM Next Index List[-1, 1] = '' // Fill out the edit table to RowLimit for clean display For CurrRow = Index to RowLimit List := @VM Next CurrRow Set_Property(@Window : '.TEST_POINTS', 'DEFPROP', List) return SaveQAData: RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') WorkOrderNo = Get_Property(@Window : '.WO_NO', 'TEXT') CassNo = Get_Property(@Window : '.OUT_CASS_NO', 'TEXT') WOMatQAKey = WorkOrderNo : '*' : CassNo WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) DataPoints = WOMatQARec Profiles = WOMatQARec ; // THICK_ONLY, CRES Result = WOMatQARec ; // Average of Data Points ThicknessData = Get_Property(@Window : '.THICK_READINGS', 'LIST') HgCVData = Get_Property(@Window : '.HGCV_READINGS', 'LIST') PhaseData = Get_Property(@Window : '.HGCV_PHASE_READINGS', 'LIST') // The following average values are typically calculated in the WO_MAT_QA MFS, but can be manually // entered by leads/engineers/supervisors in order to override the typical workflow. ThickAvg = Get_Property(@Window : '.THICK_AVG', 'TEXT') HgCVAvg = Get_Property(@Window : '.HGCV_AVG', 'TEXT') PhaseAvg = Get_Property(@Window : '.HGCV_PHASE_AVG', 'TEXT') Profile = '' For each Profile in Profiles using @VM setting ProfileIndex Begin Case Case Profile EQ '1THICK_ONLY' SaveList = '' For each DataPoint in ThicknessData using @FM setting ThickIndex * Until DataPoint EQ '' SaveList<1, 1, ThickIndex> = DataPoint Next DataPoint If SaveList NE '' then // This is the typical path where data is read in through metrology services // and the min, max, and avg are calculated in the WO_MAT_QA MFS (WO_MAT_QA_ACTIONS). DataPoints<1, ProfileIndex> = SaveList end else // Lead/Supervisor/Engineer is overriding the typical workflow by entering the // Thickness average only. Result<1, ProfileIndex> = ThickAvg end Case Profile EQ '1CRES' SaveList = '' For each DataPoint in HgCVData using @FM setting CresIndex * Until DataPoint EQ '' PhaseDataPoint = PhaseData SaveList<1, 1, CresIndex> = DataPoint : @TM : PhaseDataPoint Next DataPoint If SaveList NE '' then // This is the typical path where data is read in through metrology services // and the min, max, avg, etc. are calculated in the WO_MAT_QA MFS (WO_MAT_QA_ACTIONS). DataPoints<1, ProfileIndex> = SaveList end else // Lead/Supervisor/Engineer is overriding the typical workflow by entering the // HgCV average and the Phase average only. Result<1, ProfileIndex, 1> = HgCVAvg Result<1, ProfileIndex, 2> = PhaseAvg end End Case Next Profile WOMatQARec = DataPoints WOMatQARec = Result Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAKey, WOMatQARec, True$, False$, True$) GoSub FillHgCVTable return LaunchRDSMetrology: Ctrls = @WINDOW:'.WO_NO':@RM ; Props = 'DEFPROP':@RM Ctrls := @WINDOW:'.PROC_STEP_NO':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.OUT_CASS_NO':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.RDS_NO':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.RUN_STEP':@RM ; Props := 'DEFPROP' Vals = Get_Property(Ctrls,Props) WONo = Vals[1,@RM] WOStep = Vals[COL2()+1,@RM] CassNo = Vals[COL2()+1,@RM] RDSNo = Vals[COL2()+1,@RM] RunStep = Vals[COL2()+1,@RM] // RDS_TEST is Metrology Data Open 'DICT.RDS_TEST' To DictRdsTest Else ErrMsg('Unable to open DICT.RDS_TEST for index lookup') Return End // Return Metrology key(s) associated with the RDSNo Search = 'RDS_NO':@VM:RDSNo:@FM RDSTestKeys = '' Btree.Extract(Search,'RDS_TEST',DictRdsTest,RDSTestKeys,'','') If Get_Status(errCode) Then ErrMsg(errCode) RETURN End // If there are multiple metrology records associated with the RDSNo, then // provide a popup of the metrology records for the user to select from. If Index(RDSTestKeys,@VM,1) Then TypeOver = '' TypeOver = RDSTestKeys RDSTestKey = Popup(@WINDOW,TypeOver,'RDS_TEST') End Else RDSTestKey = RDSTestKeys End oaParms = 'RDS_TEST':@RM oaParms := RDSTestKey:@RM oaParms := '' obj_AppWindow('ViewRelated',oaParms) return VerifyUser: CanEdit = Get_Property(@Window, '@CANEDIT') If Not(CanEdit) then Message = 'Only a member of lead, supervisor, or ':@SVM:'engineering can manually enter data.' Response = Msg(@Window, '', 'OVERRIDE', '', Message) Begin Case Case Response EQ 1 Response = True$ ; // User Clicked Override Case Response EQ 2 Response = False$ ; // User Clicked Cancel Case Response EQ char(27) Response = False$ ; // User Pressed Escape Key End Case If Response EQ True$ then Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : 'LEAD' : @VM : 'SUPERVISOR' : @VM : 'ENGINEERING') Valid = Response<1> Username = Response<2> If NOT(Valid) then Set_Property(@Window:'.EXIT', 'FOCUS', True$) end else // Store verified user's name so we can sign with it. Set_Property(@Window, '@OVERRIDE_USER', Username) Set_Property(@Window, '@CANEDIT', True$) end end else Set_Property(@Window:'.EXIT', 'FOCUS', True$) end end return