Compile function DBW_RDS_OVERVIEW_NEPP_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_RDS_Proc_Stat_Nepp_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) 09/29/21 djs Created initial commuter module. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #window DBW_RDS_OVERVIEW_NEPP $Insert EVENT_SETUP $Insert ACTION_SETUP $Insert APPCOLORS $Insert MSG_EQUATES $Insert WO_MAT_QA_EQUATES $Insert WO_MAT_EQUATES $Insert RDS_EQUATES $Insert POPUP_EQUATES $INSERT LOGICAL $INSERT LSL_USERS_EQU $INSERT SECURITY_RIGHTS_EQU $Insert REACT_RUN_EQUATES $Insert WM_IN_EQUATES $Insert WM_OUT_EQUATES $Insert WO_LOG_EQUATES $Insert NOTIFICATION_EQUATES Equ COL$LOG_FILE to 1 Equ COL$LOG_DTM to 2 Equ COL$ACTION to 3 Equ COL$WH_CD to 4 Equ COL$LOC_CD to 5 Equ COL$WO_NOS to 6 Equ COL$CASS_NOS to 7 Equ COL$USER_ID to 8 Equ COL$TAGS to 9 Equ COL$TOOL_ID to 10 Equ COL.MET_TEST$ To 1 Equ COL.TEST_DESC$ To 2 Equ COL.SLOT$ To 3 Equ COL.SLOT_DESC$ To 4 Equ COL.WFR_QTY$ To 5 Equ COL.MET_MIN$ To 6 Equ COL.MET_MAX$ To 7 Equ COL.MET_RESULT$ To 8 Equ COL.STD_DEV_MAX$ To 9 Equ COL.STD_DEV_RESULT$ To 10 Equ COL.SIG$ To 11 Equ COL.SIG_DTM$ To 12 Equ COL$MET_TEST to 1 ; // QA Metrology control on RDS_UNLOAD & RDS_POST_EPI windows Equ COL$MET_TEST_DESC to 2 Equ COL$MET_SLOT to 3 Equ COL$MET_SLOT_DESC to 4 Equ COL$MET_WFR_QTY to 5 Equ COL$MET_MIN to 6 Equ COL$MET_MAX to 7 Equ COL$MET_RESULT to 8 Equ COL$MET_STD_MAX to 9 Equ COL$MET_STD_RESULT to 10 Equ COL$MET_SIG to 11 Equ COL$MET_SIG_DTM to 12 EQU COL$TOP_LABEL TO 1 EQU COL$BOTTOM_LABEL TO 2 EQU COL$LOT_NO TO 3 EQU COL$IFX_LABEL TO 4 EQU COL$RESULT TO 5 EQU COL$WOLOGKEY TO 6 Equ CRLF$ to \0D0A\ Equ SS_STAGE$ To 1 Equ SS_PASS$ To 2 Equ SS_SIG$ To 3 Equ SS_DATA$ To 4 Equ SS_NA$ To 5 Declare subroutine SRP_Show_Window, Set_Property, Send_Message, ErrMsg, Msg, Start_Window, QA_Services, Post_Event Declare subroutine obj_Appwindow, Popup, Signature_Services, Set_Status, obj_WO_Mat, obj_WO_Mat_Log, Send_Event Declare subroutine obj_RDS, obj_Notes Declare function Database_Services, Form_Services, Signature_Services, Msg, SRP_Array, QA_Services, obj_Popup Declare function Error_Services, Popup_Services, Dialog_Box, MemberOf, obj_WO_Mat, obj_RDS, Send_Message, Utility 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$ //----------------------------------------------------------------------------- // EVENT HANDLERS //----------------------------------------------------------------------------- Event WINDOW.CREATE(CreateParam) GoSub SetupOLEControls If RowExists('RDS', CreateParam) then Set_Property(@Window:'.EDL_RDS_NO', 'TEXT', CreateParam) GoSub RefreshForm end GoSub EnableRefreshButton FormSize = '' SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize) End Event Event WINDOW.CLEAR(bSaveKey, bSuppressWarning, bMaintainFocus, CtrlIDFocus) GoSub ClearForm end event Event OLE_BTN_REFRESH.OnClick(Point, Button, Shift, Ctrl) GoSub RefreshForm end event Event EDL_RDS_NO.LOSTFOCUS(Flag, FocusID) GoSub EnableRefreshButton GoSub RefreshForm end event Event OLE_EDT_STAGES.OnButtonClick(Cell, Point, Button, Shift, Ctrl) // Open related form so the user can sign the stage/metrology test/NCR/etc... RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT') ErrorMsg = '' If RDSNo NE '' then StageIndex = Field(Cell, ';', 2) StageIDs = Get_Property(@Window, '@STAGE_ID_LIST') StageID = StageIDs Begin Case Case StageID EQ 'VER' Start_Window('RDS_PRE_EPI', @Window, RDSNo) Case StageID EQ 'SUPP' Start_Window('RDS', @Window, RDSNo) Case StageID EQ 'LOAD' Start_Window('RDS', @Window, RDSNo) Case StageID EQ 'UNLOAD' Start_Window('RDS_UNLOAD', @Window, RDSNo) Case StageID EQ 'POST' Start_Window('RDS_POST_EPI', @Window, RDSNo) Case StageID EQ 'QA' Start_Window('RDS_POST_EPI', @Window, RDSNo) Case StageID EQ 'RDS_TEST' MetKeys = Xlate('RDS', RDSNo, 'MET_KEYS', 'X') NumKeys = DCount(MetKeys, @VM) Begin Case Case NumKeys EQ 1 Start_Window('RDS_TEST', @Window, MetKeys) Case NumKeys GT 1 // Just display the Post-Epi RDS form so that users can select which RDS_TEST record // they would like to view. Start_Window('RDS_POST_EPI', @Window, RDSNo) Case NumKeys EQ 0 ErrorMsg = 'RDS_TEST record for RDS ':RDSNo:' does not exist!' End Case Case ( (StageID EQ 'PREI') or (StageID EQ 'PREC') or (StageID EQ 'PRES') ) CINo = Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X') If RowExists('CLEAN_INSP', CINo) then GoSub OpenCleanInsp end else ErrorMsg = 'PRE CLEAN_INSP record for RDS ':RDSNo:' does not exist!' end Case ( (StageID EQ 'FWII') or (StageID EQ 'FWIC') or (StageID EQ 'FWIS') ) CINo = Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X') If RowExists('CLEAN_INSP', CINo) then GoSub OpenCleanInsp end else ErrorMsg = 'FWI CLEAN_INSP record for RDS ':RDSNo:' does not exist!' end Case StageID EQ 'LOAD_QA_MET' WOMatQAKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') If RowExists('WO_MAT_QA', WOMatQAKey) then WOMatQAStages = Xlate('WO_MAT_QA', WOMatQAKey, 'STAGE', 'X') Locate 'FWI' in WOMatQAStages using @VM setting vPos then WONo = Field(WOMatQAKey, '*', 1) WOStep = 1 CassNo = Field(WOMatQAKey, '*', 2) RunStep = 'FWI' CassID = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep Start_Window('QA_MET_RESULT', @Window, CassID) end else ErrorMsg = 'LOAD/FWI QA metrology is not prescribed for RDS ':RDSNo:'!' end end else ErrorMsg = 'WO_MAT_QA record for RDS ':RDSNo:' does not exist!' end Case ( (StageID EQ 'LWII') or (StageID EQ 'LWIC') or (StageID EQ 'LWIS') or (StageID EQ 'ROTR') ) CINo = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X') If RowExists('CLEAN_INSP', CINo) then GoSub OpenCleanInsp end else ErrorMsg = 'LWI CLEAN_INSP record for RDS ':RDSNo:' does not exist!' end Case StageID EQ 'UNLOAD_QA_MET' WOMatQAKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') If RowExists('WO_MAT_QA', WOMatQAKey) then WONo = Field(WOMatQAKey, '*', 1) WOStep = 1 CassNo = Field(WOMatQAKey, '*', 2) RunStep = 'UNLOAD' CassID = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep Start_Window('NDW_QA_MET_RESULT', @Window, CassID) end else ErrorMsg = 'WO_MAT_QA record for RDS ':RDSNo:' does not exist!' end Case ( (StageID EQ 'PSTI') or (StageID EQ 'PSTC') or (StageID EQ 'PSTS') ) CINo = Xlate('RDS', RDSNo, 'POST_CI_NO', 'X') If RowExists('CLEAN_INSP', CINo) then GoSub OpenCleanInsp end else ErrorMsg = 'POST CLEAN_INSP record for RDS ':RDSNo:' does not exist!' end Case StageID EQ 'POST_QA_MET' WOMatQAKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') If RowExists('WO_MAT_QA', WOMatQAKey) then MetSlot = '' WONo = Field(WOMatQAKey, '*', 1) WOStep = 1 CassNo = Field(WOMatQAKey, '*', 2) RunStep = 'QA' CassID = WONo:'*':WOStep:'*':CassNo:'*':RDSNo:'*':RunStep TestStages = Xlate('WO_MAT_QA', WOMatQAKey, 'STAGE', 'X') NumTests = Count(TestStages, 'QA') If NumTests GT 1 then AllSlots = Xlate('WO_MAT_QA', WOMatQAKey, 'SLOT', 'X') QASlots = '' For each Stage in TestStages using @VM setting vPos If Stage EQ 'QA' then QASlots<0, -1> = AllSlots<0, vPos> Next Stage MetSlot = Popup_Services('DisplayPopupLiteral', 'Select QA Met Slot', 'Slot', QASlots, 1) end else For each Stage in TestStages using @VM setting vPos If Stage EQ 'QA' then MetSlot = AllSlots<0, vPos> Next Stage end If MetSlot NE '' then WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) Done = False$ For each Stage in TestStages using @VM setting vPos ThisSlot = AllSlots<0, vPos> If ( (Stage EQ 'QA') and (ThisSlot EQ MetSlot) ) then Done = True$ Until Done EQ True$ Next Stage MetTest = WOMatQARec TestLine = '' TestLine<0, COL.MET_TEST$> = MetTest TestLine<0, COL.TEST_DESC$> = obj_Popup('CodeDesc', 'QA_MET_TEST':@RM:MetTest) TestLine<0, COL.SLOT$> = MetSlot TestLine<0, COL.SLOT_DESC$> = obj_Popup('CodeDesc','TEST_SLOTS':@RM:MetSlot) TestLine<0, COL.WFR_QTY$> = WOMatQARec TestLine<0, COL.MET_MIN$> = WOMatQARec TestLine<0, COL.MET_MAX$> = WOMatQARec TestLine<0, COL.MET_RESULT$> = WOMatQARec TestLine<0, COL.STD_DEV_MAX$> = WOMatQARec TestLine<0, COL.STD_DEV_RESULT$> = WOMatQARec TestLine<0, COL.SIG$> = WOMatQARec TestLine<0, COL.SIG_DTM$> = WOMatQARec Start_Window('QA_MET_RESULT', @Window, CassID:@FM:TestLine) end end else ErrorMsg = 'WO_MAT_QA record for RDS ':RDSNo:' does not exist!' end Case StageID EQ 'LBLCHK' Start_Window('DIALOG_QA_LABEL_CHECK') Case StageID EQ 'NCR' WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') NCRKeys = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X') If NCRKeys NE '' then NumKeys = DCount(NCRKeys, @VM) If NumKeys GT 1 then NCRKey = Popup_Services('DisplayPopupLiteral', 'Select NCR', 'NCR No', NCRKeys, 1) end else NCRKey = NCRKeys end If NCRKey NE '' then Start_Window('NCR', @Window, NCRKey) end else ErrorMsg = 'No NCR records on file for RDS ':RDSNo:'!' end Case StageID EQ 'SAP_BATCH_ID' WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') WONo = Field(WOMatKey, '*', 1) CassNo = Field(WOMatKey, '*', 2) Start_Window('WO_MAT', @Window, WOMatKey) Set_Property('WO_MAT.WO_NO', 'TEXT', WONo) Set_Property('WO_MAT.CASS_NO', 'TEXT', CassNo) Post_Event('WO_MAT', 'READ') End Case end If ErrorMsg NE '' then ErrMsg(ErrorMsg) end event Event OLE_EDT_STAGES.OnCheckChanged(Cell, OldValue, NewValue) GoSub EnableAutoSignButton end event Event PUB_AUTO_SIGN.CLICK() If (Not(MemberOf(@User4, 'LEAD')) or Not(MemberOf(@User4, 'SUPERVISOR') ) ) then Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'LEAD':@VM:'SUPERVISOR') Valid = Response<1> end else Valid = True$ end If Valid then ErrorMsgs = '' RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT') WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') // Check all locks first RDSLock = Database_Services('IsKeyIDLocked', 'RDS', RDSNo) If RDSLock then ErrorMsgs<-1> = 'RDS record ':RDSNo:' is locked!' end WOMatLock = Database_Services('IsKeyIDLocked', 'WO_MAT', WOMatKey) If WOMatLock then ErrorMsgs<-1> = 'WO_MAT record ':WOMatKey:' is locked!' end WOMatQALock = Database_Services('IsKeyIDLocked', 'WO_MAT_QA', WOMatKey) If WOMatQALock then ErrorMsgs<-1> = 'WO_MAT_QA record ':WOMatKey:' is locked!' end NCRLock = False$ NCRKeys = Xlate('WO_MAT', WOMatKey, 'NCR_KEYS', 'X') If NCRKeys NE '' then For each NCRKey in NCRKeys using @VM setting vPos Locked = Database_Services('IsKeyIDLocked', 'NCR', NCRKey) If Locked then NCRLock = True$ Until Locked Next NCRKey If NCRLock then ErrorMsgs<-1> = 'NCR record ':NCRKey:' is locked!' end end PreCILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'PRE_CI_NO', 'X') ) If PreCILock then ErrorMsgs<-1> = 'PRE CLEAN_INSP record is locked!' end FWICILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'FWI_CI_NO', 'X') ) If FWICILock then ErrorMsgs<-1> = 'FWI CLEAN_INSP record is locked!' end LWICILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X') ) If LWICILock then ErrorMsgs<-1> = 'LWI CLEAN_INSP record is locked!' end QACILock = Database_Services('IsKeyIDLocked', 'CLEAN_INSP', Xlate('RDS', RDSNo, 'POST_CI_NO', 'X') ) If QACILock then ErrorMsgs<-1> = 'POST CLEAN_INSP record is locked!' end If ErrorMsgs EQ '' then If @User4 EQ 'DANIEL_ST' then Send_Event(@Window, 'WRITE') Def = "" Def = "Auto-signing stages. Please wait..." Def = "U" MsgUp = Msg(@Window, Def) ;* display the processing message // Procedurally sign all stages that have a checkmark ChkBoxList = Get_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]") Swap @RM with @FM in ChkBoxList StageIDs = Get_Property(@Window, '@STAGE_ID_LIST') NumRows = DCount(ChkBoxList, @FM) For RowIndex = 1 to NumRows ChkVal = ChkBoxList If ChkVal EQ True$ then StageID = StageIDs Begin Case Case StageID EQ 'VER' WaferQty = Xlate('RDS', RDSNo, 'VERIFY_QTY', 'X') Reactor = Xlate('RDS', RDSNo, 'REACTOR', 'X') SigReady = QA_Services('PreEpiSignatureReady', RDSNo, @User4, WaferQty, Reactor) If SigReady then QA_Services('SignPreEpiStage', RDSNo, @User4, WaferQty, Reactor, False$) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case StageID EQ 'SUPP' Signature_Services('SignSupplement', RDSNo, @User4) If Error_Services('HasError') then ErrorMsgs<-1> = Error_Services('GetMessage') end Case StageID EQ 'LOAD' WafersIn = Xlate('RDS', RDSNo, 'WAFERS_IN', 'X') Reactor = Xlate('RDS', RDSNo, 'REACTOR', 'X') LLSide = Xlate('RDS', RDSNo, 'LOAD_LOCK_SIDE', 'X') SigReady = QA_Services('LoadSignatureReady', RDSNo, @User4, WafersIn, LLSide, False$) If SigReady then QA_Services('SignLoadStage', RDSNo, @User4, WaferQty, LLSide, False$) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case StageID EQ 'UNLOAD' Reactor = Xlate('RDS', RDSNo, 'REACTOR', 'X') SigReady = QA_Services('UnloadSignatureReady', RDSNo, @User4, Reactor) If SigReady then QA_Services('SignUnloadStage', RDSNo, @User4, False$) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case StageID EQ 'POST' PSNo = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') VerInst = XLATE('PRS_STAGE', PSNo:'*POST', 'INST', 'X') InstructionsVerified = True$ If VerInst NE '' then InstructionsVerified = Dialog_Box('RDS_VER', @Window, VerInst) If InstructionsVerified then SigReady = Signature_Services('PostEpiSigReady', RDSNo) If SigReady then Signature_Services('SignPostEpiStage', RDSNo, @User4) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = 'You must acknowledge RDS_VER instructions in order to sign POST-EPI stage.' end Case StageID EQ 'QA' SigReady = Signature_Services('QASigReady', RDSNo) If SigReady then Signature_Services('SignQAStage', RDSNo, @User4) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case StageID EQ 'RDS_TEST' // No signature for RDS_TEST records Null Case ( (StageID EQ 'PREI') or (StageID EQ 'PREC') or (StageID EQ 'PRES') or (StageID EQ 'FWII') | or (StageID EQ 'FWIC') or (StageID EQ 'FWIS') or (StageID EQ 'LWII') or (StageID EQ 'LWIC') | or (StageID EQ 'LWIS') or (StageID EQ 'PSTI') or (StageID EQ 'PSTC') or (StageID EQ 'PSTS') ) SigReady = Signature_Services('CleanInspSigReady', RDSNo, StageID) If SigReady then Signature_Services('SignCleanInsp', RDSNo, StageID, @User4) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case ( (StageID EQ 'LOAD_QA_MET') or (StageID EQ 'UNLOAD_QA_MET') or (StageID EQ 'POST_QA_MET') ) Begin Case Case StageID EQ 'LOAD_QA_MET' QAStage = 'LOAD' Case StageID EQ 'UNLOAD_QA_MET' QAStage = 'UNLOAD' Case StageID EQ 'POST_QA_MET' QAStage = 'QA' End Case WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatKey) TestStages = WOMatQARec TestSlots = WOMatQARec For each TestStage in TestStages using @VM setting vPos If TestStage EQ QAStage then TestSlot = TestSlots<0, vPos> SigReady = Signature_Services('QAMetSigReady', RDSNo, QAStage, TestSlot) If SigReady then Signature_Services('SignQAMet', RDSNo, QAStage, @User4, TestSlot) If Error_Services('HasError') then ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end end Next TestStage If ErrorMsgs EQ '' then ChkBoxList = False$ Case StageID EQ 'ROTR' SigReady = Signature_Services('ROTRSigReady', RDSNo) If SigReady then // Collect ROTR reason from user MsgParms = 'ROTR Acceptance' : @FM : 'ROTR Acceptance Reason' : @FM : '' Reason = Msg(@Window, '', 'MESSAGE_INPUT', '', MsgParms) If Reason NE '' then Signature_Services('SignROTR', RDSNo, @User4, Reason) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = 'An ROTR acceptance reason must be provided in order to sign ROTR' end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case StageID EQ 'LBLCHK' // No signature for LBLCHK. Users must use the UI and barcode scanner. Null Case StageID EQ 'NCR' SigReady = Signature_Services('NCRSigReady', RDSNo) If SigReady then Signature_Services('SignNCRs', RDSNo, @User4) If Error_Services('NoError') then ChkBoxList = False$ end else ErrorMsgs<-1> = Error_Services('GetMessage') end end else ErrorMsgs<-1> = Error_Services('GetMessage') end Case Otherwise$ End Case end Next RowIndex Msg(@Window, MsgUp) ;* Take message down Set_Property(@Window, '@CHK_BOX_LIST', ChkBoxList) GoSub RefreshForm end end else ErrorMsgs<-1> = 'Only a LEAD or SUPERVISOR may auto-sign.' end If ErrorMsgs NE '' then Swap @FM with CRLF$ in ErrorMsgs ErrMsg(ErrorMsgs) end end event Event SIGN_BUTTON.CLICK() Valid = '' RDSNo = Get_Property(@WINDOW:'.EDL_RDS_NO', 'DEFPROP') WONo = Xlate('RDS', RDSNo, 'WO', 'X') CassNo = Xlate('RDS', RDSNo, 'CASS_NO', 'X') WOStep = Xlate('RDS', RDSNo, 'WO_STEP', 'X') ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X') PSNo = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') ****************************************** * Update the form with signature, if any * ****************************************** CurrSig = '' CurrDTM = '' CurrDate = '' CurrTime = '' ********************************************* * Verify if the FQA has already been signed * ********************************************* IF Not(MemberOf(@USER4,'BYPASS')) THEN IF (CurrSig NE '') THEN ErrMsg('Supervisor Verification for this material has already been signed.') RETURN END END ****************************************** * Verify if the Post-EPI has been signed * ****************************************** PostEpiSig = Xlate('RDS', RDSNo, 'POST_EPI_SIG', 'X') IF (PostEpiSig = '') THEN ErrorMesg = 'Process Error':@SVM:'Technician Signature Required before Final QA Verification.' ErrMsg(ErrorMesg) RETURN END ************************************************************************** ************************************************************************** IF Not(MemberOf(@USER4,'BYPASS')) THEN ;* Bypass requirement for a different signer for post-epi and FQA -dkk 10/9/14 IF (PostEpiSig = @USER4) THEN ErrorMesg = 'Process Error':@SVM:'User ':QUOTE(PostEpiSig):' has signed this RDS for Post-Epi.':CRLF$:CRLF$ ErrorMesg := 'Another qualified user must sign FQA verification' ErrMsg(ErrorMesg) RETURN END END *************************************** * Verify Metrology has been completed * *************************************** Set_Status(0) obj_WO_Mat('MQAComp',WONo:'*':CassNo:@RM:WOStep:@RM:'QA') errCode = '' IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END *********************************************** * Verify RDS_TEST record has measurement data * *********************************************** ThickAvg = Xlate('RDS', RDSNo, 'TTHICK_AVG_ALL', 'X') If ThickAvg EQ '' then ErrMsg('RDS metrology measurement data is missing. FQA cannot be signed.') Return end ResAvg = Xlate('RDS', RDSNo, 'TRES_AVG_ALL', 'X') If ResAvg EQ '' then ErrMsg('RDS Resistivity measurement data is missing. FQA cannot be signed.') Recipients = XLATE('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X') SentFrom = 'OI Admin' Subject = 'Missing Resistivity Avg data' Message = RDSNo: ' failed FQA due to missing resistivity average data.' AttachWindow = '' AttachKey = '' SendToGroup = '' Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) Return end ************************************************ * Verify Signatures Profile has been fulfilled * ************************************************ WOMatKey = WONo:'*':CassNo Signature_Services('CheckSigOrder', WOMatKey, 'QA') If Error_Services('HasError') then ErrMsg(Error_Services('GetMessage')) return 0 end Signature_Services('FQAReady', WOMatKey) If Error_Services('HasError') then ErrMsg(Error_Services('GetMessage')) Return 0 end ************************* * Verify Wafer Quantity * ************************* CassSchedWafers = Get_Property(@Window : '.WAFERS_SCHEDULED', 'TEXT') WafersOut = Get_Property(@Window : '.WAFERS_OUT', 'TEXT') If CassSchedWafers NE WafersOut then Message = 'Unable to sign FQA because the Scheduled' : CRLF$ : 'Qty does not equal the ' Message := 'Wafers Out Qty.' : CRLF$ : 'Lead or supervisor must override.' LeadMessage = 'Scheduled Wafers Quantity does not equal the Wafers Out Quantity.' If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message) end else Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage) end 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') Valid = Response<1> Username = Response<2> If NOT(Valid) then Return end else Set_Property(@Window : '.FINAL_QA_WAFER_OUT_SIG', 'DEFPROP', Username) Set_Property(@Window : '.FINAL_QA_WAFER_OUT_NAME', 'TEXT', OConv(Username, '[XLATE_CONV,LSL_USERS*FIRST_LAST]')) Set_Property(@Window : '.FINAL_QA_WAFER_OUT_DATE', 'DEFPROP', Oconv(Date(), 'D2/')) Set_Property(@Window : '.FINAL_QA_WAFER_OUT_TIME', 'DEFPROP', Oconv(Time(), 'MTS')) end end else Return end end ********************************* * Verify NCR total >= USL Fails * ********************************* ReactorNo = Xlate('RDS', RDSNo, 'REACTOR', 'X') ROTREnabled = Xlate('REACTOR', ReactorNo, 'ENABLE_ROTR', 'X') If (ROTREnabled EQ True$) then LWICIKey = Xlate('RDS', RDSNo, 'LWI_CI_NO', 'X') NumUSLFailValues = Xlate('CLEAN_INSP', LWICIKey, 'NUM_FAILED_WAFERS', 'X') NumUSLFailCount = COUNT(NumUSLFailValues,@VM) + (NumUSLFailValues NE '') NumUSLFail = NumUSLFailValues<1,NumUSLFailCount> If NumUSLFail EQ '' then NumUSLFail = 0 TotalNCR = Xlate('RDS', RDSNo, 'TOT_REJ', 'X') If TotalNCR EQ '' then TotalNCR = 0 If NumUSLFail GT TotalNCR then Message = 'Unable to sign FQA because the total quantity of NCR wafers':CRLF$:'is less than the '| : 'number of wafers above the USL threshold.' : CRLF$ : 'A lead or supervisor must override.' LeadMessage = 'Total quantity of NCR wafers is less than the number of wafers above the USL threshold.' If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message) end else Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage) end 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:'ENGINEER') Valid = Response<1> If NOT(Valid) then Return end else Return end end end ******************************************** * Verify NCR wafer qty >= Failed wafer qty * ******************************************** NCRReq = QA_Services('GetNCRRequired', WOMatKey) If NCRReq then Message = 'Unable to sign FQA because the total quantity of NCR wafers':CRLF$:'is less than the '| : 'number of wafers that failed surfscan.' : CRLF$ : 'A lead or supervisor must override.' LeadMessage = 'Total quantity of NCR wafers is less than the number of wafers that failed surfscan.' If NOT( MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') ) then Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', Message) end else Response = Msg(@Window, '', 'POST_EPI_WAFER_OUT', '', LeadMessage) end 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:'ENGINEER') Valid = Response<1> If NOT(Valid) then Return 0 end else Return end end ************************* * Verify if Shift exist * ************************* Shift = Xlate('RDS', RDSNo, 'SHIFT', 'X') IF (Shift EQ '') THEN ErrMsg('Process Error':@SVM:'Shift is required before signing.') RETURN END **************************** * Verify if lot is on Hold * **************************** WOMatCurrStatus = obj_WO_Mat('CurrStatus',WONo:'*':CassNo) IF WOMatCurrStatus = 'HOLD' THEN ErrMsg('Process Error':@SVM:'Cassette is on Hold and may not be signed off.':CRLF$:CRLF$) RETURN END ********************** * Check ROTR Failure * ********************** ROTRAction = Get_Property(@Window : '.ROTR_ACTION', 'INVALUE') If (ROTRAction NE 'Passed') AND (ROTRAction NE 'Accepted') AND (ROTRAction NE '') then ErrMsg('Process Error':@SVM:'ROTR does not meet all requirements.':CRLF$:CRLF$) return end *************************************** * Verify Metrology has been completed * *************************************** CtrlName = @WINDOW:'.MET_TEST' MetList = Get_Property(CtrlName,'LIST') MLCnt = COUNT(MetList,@FM) + (MetList NE '') FOR Line = 1 TO MLCnt IF MetList NE '' THEN BEGIN CASE CASE ((MetList = '') AND (MetList = '')) NULL CASE (MetList = '') ErrMsg('Process Error':@SVM:'Required QA Metrology results have not been entered.') RETURN CASE ((MetList < MetList) OR (MetList > MetList)) ErrMsg('Process Error':@SVM:'One or more QA Metrology results is out of specification.') RETURN CASE ((MetList NE '') AND (MetList = '')) ErrMsg('Process Error':@SVM:'One or more QA Metrology results are not signed off.') RETURN END CASE END ;* End of check for a test requirement on the line NEXT Line ****************************************** * Verify Unload Stage QA Metrology Tests * ****************************************** DevelopmentFlag = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') If (DevelopmentFlag EQ True$) then WOMatQAKey = WONo : '*' : CassNo WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAKey) OutOfSpec = WOMatQARec OutOfSpec = Sum(OutOfSpec) If OutOfSpec GT 0 then FailReasons = WOMatQARec ErrorMsg = 'Process Error':@SVM For each FailReason in FailReasons using @VM ErrorMsg := FailReason:CRLF$ Next FailReason ErrMsg(ErrorMsg) Return end end ******************************************* * Verify if all steps have been completed * ******************************************* WOMatRec = XLATE('WO_MAT',WONo:'*':CassNo,'','X') RDSNos = WOMatRec MakeupBox = WOMatRec LOCATE RDSNo IN RDSNos USING @VM SETTING Pos THEN NextRDS = RDSNos<1,Pos+1> END ELSE NextRDS = '' END IF (WOMatCurrStatus NE 'QA' AND WOMatCurrStatus NE 'PSTI' AND WOMatCurrStatus NE 'COMP') AND (NextRDS NE '' AND WOMatCurrStatus NE 'VER') THEN ErrorMessage = 'Process Error':@SVM:'Run is not ready for final QA.':CRLF$:CRLF$ ErrorMessage := 'The ':OCONV(WOMatCurrStatus,'[WO_MAT_CURR_STATUS_CONV]'):' step is not complete.' ErrMsg(ErrorMessage) RETURN END IF NOT(MemberOF( @USER4, 'SUPERVISOR' ) OR MemberOf( @user4, 'LEAD' ) OR MemberOf( @USER4, 'FINAL_QA' ) ) THEN ErrMsg('Process Error':@SVM:'You must be a supervisor to verify this RDS.') RETURN END ************************************************************************ * Prompt user to validate the Process Specification Stage Instructions * ************************************************************************ VerInst = XLATE('PRS_STAGE',PSNo:'*QA',PRS_STAGE_INST$,'X') VerInst = TRIM(VerInst) IF LEN(VerInst) > 5 THEN Yes = Dialog_Box( 'RDS_VER', @WINDOW, VerInst ) IF NOT(Yes) THEN RETURN END END ************************** * Verify user's password * ************************** // Check if user has already been verified above to avoid prompting for password twice If Valid EQ '' Then Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW) Valid = Response<1> end IF (Valid) THEN SigDt = OCONV( Date(), 'D2/' ) SigTm = Time() SigTmPlusOne = OCONV(SigTm + 1, 'MTS' ) SigTmPlusTwo = OCONV(SigTm + 2, 'MTS' ) SigTmPlusFive = OCONV(SigTm + 5, 'MTS' ) SigTmPlusTen = OCONV(SigTm + 10, 'MTS' ) SigTm = OCONV(SigTm,'MTS') SigBy = @USER4 EventParms = '' EventCnt = 1 IF ReactorType NE 'EPP' THEN ToolID = '' WHCd = 'CR' LocCD = 'QA' Tag = '' EventParms = 'WO_MAT' EventParms = SigDt:' ':SigTm EventParms = WOStep:'QA' EventParms = 'CR' EventParms = 'QA' EventParms = WONo EventParms = CassNo EventParms = @USER4 EventParms = '' EventParms = '' CONVERT @FM TO @RM IN EventParms obj_WO_Mat_Log('Create',EventParms) ;* * * * * INV EVENT LOG * * * * * IF Get_Status(errCode) THEN CALL ErrMsg(ErrCode) RETURN END IF MakeupBox = 1 THEN EventParms = 'WO_MAT' EventParms = SigDt:' ':SigTmPlusTwo EventParms = 'RTU' EventParms = 'CR' EventParms = 'MU' EventParms = WONo EventParms = CassNo EventParms = @USER4 EventParms = '' EventParms = '' CONVERT @FM TO @RM IN EventParms obj_WO_Mat_Log('Create',EventParms) ;* * * * * INV EVENT LOG * * * * * IF Get_Status(errCode) THEN CALL ErrMsg(ErrCode) RETURN END END END ;* End of check for non EpiPRO reactor Set_Property(@Window : '.POST_EPI_SUP_SIG', 'TEXT', @User4) Set_Property(@Window : '.POST_EPI_SUP_SIG_NAME', 'TEXT', OConv(@User4, '[XLATE_CONV,LSL_USERS*FIRST_LAST]')) Set_Property(@Window : '.POST_EPI_SUP_SIG_DATE', 'TEXT', SigDt) Set_Property(@Window : '.POST_EPI_SUP_SIG_TIME', 'TEXT', SigTmPlusOne) /* Sync up the RDS record with WO_MAT */ IOOptions = Get_Property(@Window, 'IOOPTIONS') IOOptions<6> = True$ Set_Property(@Window, 'IOOPTIONS', IOOptions) Send_Event(@Window, 'WRITE') IOOptions<6> = False$ Set_Property(@Window, 'IOOPTIONS', IOOptions) WOMatKey = WONo:'*':CassNo WOMatRec = XLATE('WO_MAT',WOMatKey,'','X') WMRDSNos = WOMatRec LOCATE RDSNo IN WMRDSNos USING @VM SETTING Pos THEN NextRDSNo = WMRDSNos<1,Pos+1> IF NextRDSNo NE '' THEN CurrWfrQty = obj_WO_Mat('CurrWaferCnt',WOMatKey:@RM:WOMatRec) Set_Status(0) obj_RDS('SetSchedWfrQty',NextRDSNo:@RM:CurrWfrQty) IF Get_Status(errCode) THEN ErrMsg(errCode) END END * Added 08/05/2013 JCH WOMatKey = WONo:'*':CassNo OrgMUPart = XLATE('WO_MAT',WOMatKey,'MU_PART_NO','X') NewMUPart = XLATE('WO_MAT',WOMatKey,'MU_PART_NO','X') IF NewMUPart NE OrgMUPart THEN IndexTransactionRow = 'MU_PART_NO':@FM:WOMatKey:@FM:OrgMUPart:@FM:NewMUPart:@FM OPEN "!WO_MAT" TO BangTable THEN LOCK BangTable, 0 THEN READ PendingTrans FROM BangTable, 0 ELSE PendingTrans = '0':@FM PendingTrans := IndexTransactionRow WRITE PendingTrans ON BangTable, 0 ELSE ErrMsg('Unable to write index transaction to !WO_MAT. ':WOMatKey) END UNLOCK BangTable, 0 ELSE ErrMsg('Unable to Open !WO_MAT to add index transaction. ':WOMatKey) END ELSE ErrMsg('Unable to Lock !WO_MAT to add index transaction. ':WOMatKey) END END ELSE ErrMsg('Unable to Open !WO_MAT to add index transaction. ':WOMatKey) END END ;* End of check for changed index value END ;* End of check for valid signature end event Event SIG_PROFILE.CLICK() RDSNo = Get_Property(@WINDOW:'.EDL_RDS_NO','TEXT') WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') If WOMatKey NE '' then SigData = Signature_Services('GetSigProfile', WOMatKey) Display = '' RowCnt = COUNT(SigData<1>,@VM) + (SigData<1> NE '') FOR I = 1 TO RowCnt Display<1,I,1> = SigData<1,I> Display<1,I,2> = SigData<2,I> Display<1,I,3> = SigData<3,I> Display<1,I,4> = SigData<4,I> NEXT I TypeOver = '' TypeOver = Display void = Popup(@WINDOW,TypeOver,'SIG_PROFILE') end end event Event CASS_IDS.POSCHANGED(NextColumn, NextRow) CtrlEntID = @WINDOW:'.CASS_IDS' PrevSelPos = Get_Property(CtrlEntId,"PREVSELPOS") PrevCol = PrevSelPos<1> PrevRow = PrevSelPos<2> CurrPos = Get_Property(CtrlEntId,"SELPOS") CurrCol = CurrPos<1> CurrRow = CurrPos<2> ListData = Get_Property(CtrlEntId,'LIST') ArrayData = Get_Property(CtrlEntId,'ARRAY') MismatchDetected = False$ /* No mismatch */ CellValue = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", CurrCol, CurrRow)) IF (CellValue = '') THEN ColPointer = CurrCol LinePointer = CurrRow ColCnt = 5 /* Find the first non-empty cell */ LOOP Test = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", ColPointer, LinePointer)) UNTIL Test NE '' OR (LinePointer = 0 AND ColPointer = 1) ColPointer = ColPointer - 1 IF ColPointer = 0 THEN ColPointer = ColCnt LinePointer = LinePointer - 1 END REPEAT /* Move to the next empty cell */ BEGIN CASE CASE LinePointer = 0 * Empty Table LinePointer = 1 ColPointer = 1 CASE ColPointer = ColCnt LinePointer = LinePointer + 1 ColPointer = 1 CASE 1 ColPointer = ColPointer + 1 END CASE Set_Property("SYSTEM", "BLOCK_EVENTS", True$) Set_Property(CtrlEntId, "SELPOS", ColPointer:@FM:LinePointer) Set_Property("SYSTEM", "BLOCK_EVENTS", False$) END ***************************** * Post Prompt for Top Label * ***************************** TopLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$TOP_LABEL, PrevRow)) IF TopLabel[1,2] = '1T' THEN TopLabel = TopLabel[3,99] Set_Property(CtrlEntId,"CELLPOS",TopLabel,PrevSelPos) END IF ((TopLabel NE '') AND (PrevCol = COL$TOP_LABEL)) THEN Set_Property(@WINDOW,'@EPIPRO_FLAG',0) BEGIN CASE CASE TopLabel[1,1] = 'I' * WM_IN table TopLabel = TopLabel[2,99] WOMatKey = FIELD(TopLabel,'.',1):'*':FIELD(TopLabel,'.',3) Set_Property(CtrlEntID, "CELLPOS", TopLabel, PrevSelPos) Set_Property(@WINDOW,'@EPIPRO_FLAG',1) CASE TopLabel[1,1] = 'O' * EpiPro Silicon or GaN TopLabel = TopLabel[2,99] WONo = TopLabel[1, 'F.'] CassNo = TopLabel[-1, 'B.'] WOMatKey = WONo:'*':CassNo Set_Property(CtrlEntID, "CELLPOS", TopLabel, PrevSelPos) If (Count(TopLabel, '.') EQ 2) then // EpiPro Set_Property(@WINDOW,'@EPIPRO_FLAG',1) end else // GaN Set_Property(@WINDOW,'@GAN_FLAG',1) end CASE INDEX(TopLabel,'.',1) AND NOT(INDEX(TopLabel,'.',2)) * This is a WO_MAT format label WOMatKey = TopLabel Convert '.' To '*' In WOMatKey CASE INDEX(TopLabel,'.',2) * EpiPRO material indeterminate direction WOMatKey = FIELD(TopLabel,'.',1):'*':Field(TopLabel,'.',3) Set_Property(@WINDOW,'@EPIPRO_FLAG',1) CASE 1 ReactRunRec = XLATE('REACT_RUN', TopLabel, '', 'X') IF ReactRunRec = '' THEN RDSRec = XLATE('RDS',TopLabel,'','X') TestWO = RDSRec CassNo = RDSRec END ELSE TestWO = ReactRunRec CassNo = ReactRunRec End WOMatKey = TestWO:'*':CassNo END CASE WOMatRec = XLATE('WO_MAT', WOMatKey, '', 'X') IF (WOMatRec = '') THEN Set_Property(CtrlEntID, "CELLPOS", '', PrevSelPos) ;* No corresponding data record found for label scanned bad read or wrong thing scanned Set_Property("SYSTEM", "BLOCK_EVENTS", True$) Set_Property(CtrlEntID, "SELPOS", PrevSelPos) Set_Property("SYSTEM", "BLOCK_EVENTS", False$) RETURN END ELSE Set_Property(CtrlEntID, "CELLPOS", FIELD(WOMatKey,'*',1), COL$WOLOGKEY:@FM:PrevRow) * * Check for FQA signature completed * * FQASigned = '' WorkOrdNo = Field(WOMatKey, '*', 1) ReactorType = XLATE('WO_LOG', WorkOrdNo, 'REACT_TYPE', 'X') QAStage = '' Begin Case Case ReactorType EQ 'EPP' QAStage = 'MO_QA' Case ReactorType EQ 'GAN' QAStage = 'G_FQA' Case Otherwise$ QAStage = 'QA' End Case FQASigned = Signature_Services('CheckSignature', WOMatKey, QAStage) IF NOT(FQASigned) THEN Msg(@WINDOW, '', 'UNSIGNED_CASSETTE') Set_Property(CtrlEntID, "CELLPOS", '', PrevSelPos) ;* No corresponding data record found for label scanned bad read or wrong thing scanned Set_Property("SYSTEM", "BLOCK_EVENTS", True$) Set_Property(CtrlEntID, "SELPOS", PrevSelPos) Set_Property("SYSTEM", "BLOCK_EVENTS", False$) RETURN END Set_Property(@WINDOW,'@WO_MAT_KEY',WOMatKey) Set_Property(@WINDOW,'@WO_MAT_LOT',WOMatRec) END END ******************************** * Post Prompt for Bottom Label * ******************************** TopLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$TOP_LABEL, PrevRow)) BottomLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$BOTTOM_LABEL, PrevRow)) IF BottomLabel[1,2] = '1T' THEN BottomLabel = BottomLabel[3,99] Set_Property(CtrlEntId,"CELLPOS",BottomLabel,PrevSelPos) END IF ((BottomLabel NE '') AND (PrevCol = COL$BOTTOM_LABEL)) Then BEGIN CASE CASE BottomLabel[1,1] = 'I' * WM_IN table BottomLabel = BottomLabel[2,99] Set_Property(CtrlEntID, "CELLPOS", BottomLabel, PrevSelPos) CASE BottomLabel[1,1] = 'O' * WM_OUT table BottomLabel = BottomLabel[2,99] Set_Property(CtrlEntID, "CELLPOS", BottomLabel, PrevSelPos) CASE INDEX(BottomLabel,'.',1) AND NOT(INDEX(BottomLabel,'.',2)) * This is a WO_MAT format label NULL CASE INDEX(BottomLabel,'.',2) * EpiPRO material indeterminate direction NULL CASE 1 NULL END CASE ************************************ * Validate the Top & Bottom Labels * ************************************ IF (TopLabel NE BottomLabel) THEN MismatchDetected = True$ /* Mismatch Detected */ void = Utility('BEEP') Set_Property(CtrlEntID, "CELLPOS", 'Mismatch', COL$RESULT:@FM:PrevRow) /* Load Current Location */ stat = Send_Message(CtrlEntID, 'COLOR_BY_POS', 0, PrevRow, RED$) Set_Property("SYSTEM", "BLOCK_EVENTS", True$) Set_Property(CtrlEntID, "SELPOS", COL$TOP_LABEL:@FM:PrevRow+1) /* Move to the next line ready to scan */ Set_Property("SYSTEM", "BLOCK_EVENTS", False$) InsertedPosition = Send_Message(CtrlEntID, "INSERT", -1, '') TypeOver = '' TypeOver = 'FQA Label Mismatch' TypeOver = CRLF$:'Label ID Mismatch!':CRLF$ OK = Msg(@WINDOW,TypeOver,'LABEL_MISMATCH') * Inform Quality Insurance that a mismatch has occurred * Recipients = '' OtherRecipients = XLATE('NOTIFICATION','LABEL_CHECK_FQA',NOTIFICATION_USER_ID$,'X') ;* Added 10/03/2005 JCH - J.C. Henry & Co., Inc Changed from LABEL_MISMATCH by dkk 11/6/15 FOR N = 1 TO COUNT(OtherRecipients,@VM) + (OtherRecipients NE '') OtherRecip = OtherRecipients<1,N> LOCATE OtherRecip IN Recipients USING @VM SETTING Pos ELSE Recipients = INSERT(Recipients,1,Pos,0,OtherRecip) END NEXT N SentFrom = @USER4 Subject = 'Final QA Label Check Mismatch' Message = 'Cassette Top ID ':QUOTE(TopLabel):' has mismatched Bottom ID ':QUOTE(BottomLabel)'.' AttachWindow = '' AttachKey = '' SendToGroup = '' Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) If Count(TopLabel, '.') then // EpiPro Silicon or GaN IF TopLabel[1,1] = 'O' THEN TopLabel[1,1] = '' IF TopLabel[1,1] = 'I' THEN TopLabel[1,1] = '' WONo = TopLabel[1, 'F.'] StepNo = 1 CassNo = TopLabel[-1, 'B.'] RDSNo = '' end else // Non-EpiPro Silicon RDSNo = TopLabel ReactRunRec = XLATE('REACT_RUN', RDSNo, '', 'X') WONo = ReactRunRec StepNo = ReactRunRec CassNo = ReactRunRec end * Setup parameters to WO_Mat_Log method * CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS') UserID = @USER4 LogFile = 'WO_MAT' ;* Changed so all scans are logged in the WO_MAT table 12/3/2006 Action = 'LBLCHK' ;* Final label check for same top and bottom and correct Lot Number on WO_MAT record WHCd = 'CR' ;* Clean room @ final QA LocCd = 'QA' ;* MisMatch - keep the cassette location at Final QA Set_Status(0) obj_WO_Mat_Log('Create',LogFile:@RM:CurrDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONo:@RM:CassNo:@RM:UserID:@RM:'Mismatch') IF Get_Status(errCode) THEN Errmsg(errCode) END END /* End of check for top & bottom labels check */ END /* End of check for bottom label available */ ********************** * Process Lot Number * ********************** IF (MismatchDetected = False$) THEN LotNumber = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$LOT_NO, PrevRow)) IF ((TopLabel NE '') AND (BottomLabel NE '') AND (LotNumber = '')) THEN EpiProFlag = Get_Property(@WINDOW, '@EPIPRO_FLAG') GaNFlag = Get_Property(@WINDOW, '@GAN_FLAG') Begin Case Case EpiProFlag EQ True$ LotNumber = 'EpiPRO' Set_Property(CtrlEntID, "CELLPOS", LotNumber, COL$LOT_NO:@FM:PrevRow) Case GaNFlag EQ True$ LotNumber = 'GaN' Set_Property(CtrlEntID, "CELLPOS", LotNumber, COL$LOT_NO:@FM:PrevRow) End Case END IF ((LotNumber NE '') AND (PrevCol = COL$LOT_NO)) THEN *************************** * Validate the Lot Number * *************************** IF (LotNumber NE 'EpiPRO' and LotNumber NE 'GaN') THEN IF ((LotNumber[1,2] = '1T') OR (LotNumber[1,2] = '2T')) THEN /* Trim off field identifiers (1T) or (2T) if present - changed by dkk 12/13/16 */ LotNumber[1,2] = '' Set_Property(CtrlEntID, "CELLPOS", LotNumber, COL$LOT_NO:@FM:PrevRow) END WOMatKey = Get_Property(@WINDOW,'@WO_MAT_KEY') WONo = WOMatKey[1,'*'] CassNo = WOMatKey[COL2()+1,'*'] WOMatLot = Get_Property(@WINDOW,'@WO_MAT_LOT') * * * Check for Wales added suffix "-BB" on implant wafers coming back * * * IF (WOMatLot[-3,1] = '-') AND (WOMatLot[-2,1] = WOMatLot[-1,1]) And WOMatLot[-2,2] Matches "2A" THEN IF LotNumber = WOMatLot[1,Len(WOMatLot) - 3] THEN LotNumber := WOMatLot[-3,3] END END ;* End of check for "-AA" type lot suffix added by Wales IF (LotNumber NE WOMatLot) THEN MismatchDetected = True$ /* Mismatch Detected */ void = Utility('BEEP') Set_Property(CtrlEntID, "CELLPOS", 'Mismatch',COL$RESULT:@FM:PrevRow) /* Load Current Location */ stat = Send_Message(CtrlEntID, 'COLOR_BY_POS', 0, PrevRow,RED$) Set_Property("SYSTEM", "BLOCK_EVENTS", True$) Set_Property(CtrlEntID, "SELPOS", COL$TOP_LABEL:@FM:PrevRow+1) /* Move to the next line ready to scan */ Set_Property("SYSTEM", "BLOCK_EVENTS", False$) InsertedPosition = Send_Message(CtrlEntID, "INSERT", -1, '') TypeOver = '' TypeOver = 'FQA Label Mismatch' TypeOver = CRLF$:'Lot No. Mismatch!':CRLF$ OK = Msg(@WINDOW,TypeOver,'LABEL_MISMATCH') /* Inform Quality Insurance that a mismatch has occurred */ Recipients = '' OtherRecipients = XLATE('NOTIFICATION','LABEL_CHECK_FQA',NOTIFICATION_USER_ID$,'X') ;* Added 10/03/2005 JCH - J.C. Henry & Co., Inc Changed from LABEL_MISMATCH by dkk 11/6/15 FOR N = 1 TO COUNT(OtherRecipients,@VM) + (OtherRecipients NE '') OtherRecip = OtherRecipients<1,N> LOCATE OtherRecip IN Recipients USING @VM SETTING Pos ELSE Recipients = INSERT(Recipients,1,Pos,0,OtherRecip) END NEXT N SentFrom = @USER4 Subject = 'Final QA Label Check Mismatch' Message = 'Cassette ':QUOTE(TopLabel):' has incorrect Lot No ':QUOTE(LotNumber)'.' AttachWindow = '' AttachKey = '' SendToGroup = '' Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS') UserID = @USER4 LogFile = 'WO_MAT' ;* Changed so all scans are logged in the WO_MAT table 12/3/2006 Action = 'LBLCHK' ;* Final label check for same top and bottom and correct Lot Number on WO_MAT record WHCd = 'CR' ;* Clean room @ final QA LocCd = 'QA' ;* MisMatch - keep the cassette location at Final QA Set_Status(0) obj_WO_Mat_Log('Create',LogFile:@RM:CurrDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONo:@RM:CassNo:@RM:UserID:@RM:'Mismatch') IF Get_Status(errCode) THEN Errmsg(errCode) END END ELSE NULL END /* End of check for LotNumber and WOMatLot matching */ END ELSE NULL END /* End of check for EpiPro lot */ END /* End of check for lot number validation */ END ******************************** * Validate Scanned Information * ******************************** IF (MismatchDetected = False$) THEN /* Read scanned information from edit table */ TopLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$TOP_LABEL, PrevRow)) BottomLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$BOTTOM_LABEL, PrevRow)) LotNumber = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$LOT_NO, PrevRow)) //IFXLabel = TRIM(Send_Message(CtrlEntID, "TEXT_BY_POS", COL$IFX_LABEL, PrevRow)) IF ((TopLabel NE '') AND (BottomLabel NE '') AND (LotNumber NE '')) THEN ;//AND (IFXValid = 1) AND (IFXLabel NE '')) THEN ******************************** * FQA Labels Validation = GOOD * ******************************** Set_Property(CtrlEntID, "CELLPOS", 'OK', COL$RESULT:@FM:PrevRow) stat = Send_Message(CtrlEntID, "COLOR_BY_POS", 0, PrevRow,GREEN$) Set_Property("SYSTEM", "BLOCK_EVENTS", True$) Set_Property(CtrlEntID, "SELPOS", COL$TOP_LABEL:@FM:PrevRow+1) /* Move to the next line ready to scan */ Set_Property("SYSTEM", "BLOCK_EVENTS", False$) InsertedPosition = Send_Message(CtrlEntID, "INSERT", -1, '') * Add transaction to Posting system to time-stamp WO_MAT record ! 10/28/2019 - DJS & Dan Crisp ! This transaction is moving to Packaging_Services and is triggered by ! the NDW_PACKAGING form upon a successful scan sequence. IF Count(TopLabel, '.') THEN IF TopLabel[1,1] = 'O' THEN TopLabel[1,1] = '' IF TopLabel[1,1] = 'I' THEN TopLabel[1,1] = '' WONo = TopLabel[1, 'F.'] StepNo = 1 CassNo = TopLabel[-1, 'B.'] RDSNo = '' end else RDSNo = TopLabel ReactRunRec = XLATE('REACT_RUN',RDSNo,'','X') WONo = ReactRunRec StepNo = ReactRunRec CassNo = ReactRunRec END CurrDTM = OCONV(Date(),'D2/'):' ':OCONV(Time(),'MTS') UserID = @USER4 LogFile = 'WO_MAT' ;* Changed so all scans are logged in the WO_MAT table 12/3/2006 Action = 'LBLCHK' ;* Final label check for same top and bottom and correct Lot Number on WO_MAT record WHCd = 'CR' ;* Clean room @ final QA LocCd = 'PKO' ;* QA wants this to "place" the cassette into the outbound passthrough Set_Status(0) obj_WO_Mat_Log('Create',LogFile:@RM:CurrDTM:@RM:Action:@RM:WhCd:@RM:LocCd:@RM:WONo:@RM:CassNo:@RM:UserID:@RM:'Match') IF Get_Status(errCode) THEN Errmsg(errCode) END END /* End of check for all information available to be checked*/ END If NextRow EQ 2 then GoSub RefreshForm end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SetupOLEControls: NumCols = 4 NumRows = 26 StageIDs = Database_Services('ReadDataRow', 'APP_INFO', 'SILICON_STAGE_LIST') CtrlList = Xlate('STAGE', StageIDs, 'DESC', 'X') StageCtrl = @Window:'.OLE_EDT_STAGES' HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 HeaderColArray = 40:@FM:False$:@FM:False$:@FM:False$ HeaderAlignArray = 'Center':@FM:'Center':@FM:'Center' DimArray = NumCols:@FM:NumRows HeaderTitles = 'Stage':@VM:'Data':@VM:'Signature':@VM:'Sign' DataColArray = 120:@FM:True$:@FM:True$:@FM:True$:@FM:False$ Set_Property(StageCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8) Set_Property(StageCtrl, "OLE.Dimension", DimArray) Set_Property(StageCtrl, "OLE.CellFont[1;All]", HeaderFontArray) Set_Property(StageCtrl, "OLE.LIST", CtrlList) Set_Property(StageCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray) Set_Property(StageCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray) Set_Property(StageCtrl, "OLE.TitleList", HeaderTitles) Set_Property(StageCtrl, "OLE.AllowDeletions", False$) Set_Property(StageCtrl, "OLE.AllowInserts", False$) Set_Property(StageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(StageCtrl, "OLE.HeaderAlignment[All; 1]", HeaderAlignArray) Set_Property(StageCtrl, "OLE.DataColumn[1]", DataColArray) DataColArray<1> = 60 DataColArray<4> = False$ Set_Property(StageCtrl, "OLE.DataColumn[2-4]", DataColArray) CellAlignArray = 'Center':@FM:'Center':@FM:'Center' Set_Property(StageCtrl, "OLE.CellAlignment[4; All]", CellAlignArray) // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(StageCtrl, 'QUALIFY_EVENT', 'OLE.OnButtonClick', Qualifier) Send_Message(StageCtrl, 'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier) Send_Message(@Window:'.OLE_BTN_REFRESH', 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier) // Stage cell button style setup ButtonTypeArray = '' ButtonTypeArray<1> = 'Push Button' ButtonTypeArray<2> = '' ButtonTypeArray<2, 1> = False$ ButtonTypeArray<2, 2> = True$ ButtonTypeArray<2, 3> = True$ ButtonTypeArray<3> = 'None' ButtonTypeArray<4> = "Vertical(Gradient(":OI_HOT_BLUE$:", ":OI_HOT_BLUE$:"), Border(":OI_BLUE$:"))" ButtonTypeArray<5> = "Vertical(Gradient(":OI_CLICK_BLUE$:", ":OI_CLICK_BLUE$:"), Border(":OI_BLUE$:"))" ButtonTypeArray<6> = 'OD' ButtonTypeArray<7> = 'None' Set_Property(StageCtrl, "OLE.CellType[1; All]", ButtonTypeArray) return EnableRefreshButton: RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT') If RDSNo[1, 2] EQ '1T' then RDSNo = RDSNo[3, 999] Set_Property(@Window:'.EDL_RDS_NO', 'TEXT', RDSNo) end If RDSNo NE '' then Enabled = RowExists('RDS', RDSNo) end else Enabled = False$ end Set_Property(@Window:'.OLE_BTN_REFRESH', 'ENABLED', Enabled) return EnableAutoSignButton: ChkVals = Get_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]") Enabled = Sum(ChkVals) Set_Property(@Window:'.PUB_AUTO_SIGN', 'ENABLED', Enabled) return EnableOtherButtons: RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT') Enabled = (RDSNo NE '') Set_Property(@Window:'.CTRL_PLAN', 'ENABLED', Enabled) Set_Property(@Window:'.PUB_SAVE', 'ENABLED', Enabled) Set_Property(@Window:'.PUB_CLEAR_FORM', 'ENABLED', Enabled) return RefreshForm: RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT') If RDSNo NE '' then If RDSNo[1,2] EQ '1T' then RDSNo[1,2] = '' Set_Property(@Window:'.EDL_RDS_NO', 'TEXT', RDSNo) ReactorType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X') Begin Case Case ReactorType EQ 'EPP' ErrMsg('EpiPro runs are not supported by this form at this time!') Set_Property(@Window:'.EDL_RDS_NO', 'FOCUS', True$) Set_Property(@Window:'.EDL_RDS_NO', 'SELECTION', 1:@FM:999) Case ReactorType EQ 'GAN' ErrMsg('GaN runs are not supported by this form!') Set_Property(@Window:'.EDL_RDS_NO', 'FOCUS', True$) Set_Property(@Window:'.EDL_RDS_NO', 'SELECTION', 1:@FM:999) Case RowExists('RDS', RDSNo) GoSub ClearLblChkEDT Def = "" Def = "Loading stage data. Please wait..." Def = "U" MsgUp = Msg(@Window, Def) ;* display the processing message WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') CassSummary = Signature_Services('GetCassSummary', WOMatKey) CassSummaryPrime = SRP_Array('Rotate', CassSummary, @FM, @VM) ArrayData = Get_Property(@Window:'.OLE_EDT_STAGES', 'OLE.ARRAY') StageIDs = Database_Services('ReadDataRow', 'APP_INFO', 'SILICON_STAGE_LIST') StageDescs = Xlate('STAGE', StageIDs, 'DESC', 'X') ColorArray = '' DataList = '' ChkBoxList = '' Set_Property(@Window, '@STAGE_ID_LIST', StageIDs) Set_Property(@Window, '@STAGE_DESC_LIST', StageDescs) For each Row in CassSummary using @FM setting fPos StageID = Row<0, SS_STAGE$> StageDesc = StageDescs<0, fPos> StagePass = Row<0, SS_PASS$> StageSigComp = Row<0, SS_SIG$> StageDataComp = Row<0, SS_DATA$> StageNA = Row<0, SS_NA$> ChkBoxList = False$ Begin Case Case StagePass ColorArray = GREEN$ ColorArray = BGREEN$ Case StageDataComp and Not(StageSigComp) ColorArray = YELLOW$ ColorArray = BYELLOW$ ChkBoxList = True$ Case Not(StagePass) and Not(StageNA) ColorArray = RED$ ColorArray = BRED$ Case Otherwise$ ColorArray = GREY$ ColorArray = LTGREY$ End Case Begin Case Case StageDataComp DataList = 'Complete' ColorArray = GREEN$ Case Not(StageDataComp) and Not(StageNA) DataList = 'Missing' ColorArray = YELLOW$ Case Otherwise$ DataList = 'N/A' ColorArray = 'None' End Case Begin Case Case StageSigComp DataList = 'Complete' ColorArray = GREEN$ Case Not(StageSigComp) and Not(StageNA) DataList = 'Missing' ColorArray = YELLOW$ Case Otherwise$ DataList = 'N/A' ColorArray = 'None' End Case Next Row Set_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]", False$) Set_Property(@Window, '@CHK_BOX_LIST', ChkBoxList) Set_Property(@Window, '@DATA_LIST', DataList) Set_Property(@Window, '@COLOR_ARRAY', ColorArray) GoSub PopulateCells GoSub ColorCells GoSub EnableChkBoxes GoSub EnableAutoSignButton GoSub EnableOtherButtons GoSub UpdateHoldLabel GoSub ColorControls Send_Event(@Window, 'READ') Msg(@Window, MsgUp) ;* Take message down Case Otherwise$ ErrMsg('RDS ':RDSNo:' does not exist!.') Set_Property(@Window:'.EDL_RDS_NO', 'FOCUS', True$) Set_Property(@Window:'.EDL_RDS_NO', 'SELECTION', 1:@FM:999) End Case end return ColorCells: ColorArray = Get_Property(@Window, '@COLOR_ARRAY') If ColorArray NE '' then StageCtrl = @Window:'.OLE_EDT_STAGES' For each Row in ColorArray using @FM setting fPos // Column 1 - Stage Name BackColor = Row<0, 1> If BackColor EQ '' then BackColor = 'None' HotBackColor = Row<0, 2> If HotBackColor EQ '' then HotBackColor = 'None' CellTypeArray = Get_Property(StageCtrl, 'OLE.CellType[1;':fPos:']') CellTypeArray<3> = BackColor CellTypeArray<4> = HotBackColor Set_Property(StageCtrl, 'OLE.CellType[1;':fPos:']', CellTypeArray) For Col = 2 to 3 BackColor = Row<0, Col + 1> CellColorArray = Get_Property(StageCtrl, 'OLE.CellColors[':Col:';':fPos:']') CellColorArray<2> = BackColor Set_Property(StageCtrl, 'OLE.CellColors[':Col:';':fPos:']', CellColorArray) Next Col Next Row end return ColorControls: WafersOut = Get_Property(@Window:'.WAFERS_OUT', 'TEXT') WafersScheduled = Get_Property(@Window:'.WAFERS_SCHEDULED', 'TEXT') If WafersScheduled NE WafersOut then BackColor = RED$ end else BackColor = GREEN$ end Set_Property(@Window:'.WAFERS_SCHEDULED','BACKCOLOR',BackColor) Set_Property(@Window:'.WAFERS_OUT','BACKCOLOR',BackColor) ROTRAction = Get_Property(@WINDOW:'.ROTR_ACTION','TEXT') BEGIN CASE CASE ROTRAction[1,1] = 'P' BackColor = GREEN$ CASE ROTRAction[1,1] = 'F' BackColor = RED$ CASE ROTRAction[1,1] = 'W' BackColor = YELLOW$ CASE ROTRAction[1,1] = 'A' BackColor = ORANGE$ CASE 1 BackColor = Get_Property(@WINDOW,'BACKCOLOR') END CASE Set_Property(@WINDOW:'.ROTR_ACTION','BACKCOLOR',BackColor) return PopulateCells: DataList = Get_Property(@Window, '@DATA_LIST') If DataList NE '' then StageCtrl = @Window:'.OLE_EDT_STAGES' For each Row in DataList using @FM setting fPos For Col = 2 to 3 CellText = DataList Set_Property(StageCtrl, 'OLE.CellText[':Col:';':fPos:']', CellText) Next Col Next Row end return EnableChkBoxes: ChkBoxList = Get_Property(@Window, '@CHK_BOX_LIST') If ChkBoxList NE '' then StageCtrl = @Window:'.OLE_EDT_STAGES' For each Row in ChkBoxList using @FM setting fPos ChkBoxEnabled = Row<0, 1> If ChkBoxEnabled then CellColorArray = Get_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']') CellColorArray<2> = 'None' Set_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']', CellColorArray) CellTypeArray = 'CHB':@FM:True$ Set_Property(StageCtrl, "OLE.CellType[4;":fPos:"]", CellTypeArray) Set_Property(StageCtrl, "OLE.CellProtection[4;":fPos:"]", 'None') end else CellColorArray = Get_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']') CellColorArray<2> = GREY$ Set_Property(StageCtrl, 'OLE.CellColors[4;':fPos:']', CellColorArray) Set_Property(StageCtrl, "OLE.CellType[4;":fPos:"]", 'TEXT') Set_Property(StageCtrl, "OLE.CellProtection[4;":fPos:"]", 'Full') end Next Row end return UpdateHoldLabel: Ctrl = @Window:'.LBL_HOLD' RDSNo = Get_Property(@Window:'.EDL_RDS_NO', 'TEXT') OnHold = Xlate('RDS', RDSNo, 'HOLD', 'X') If OnHold then // Set label to "On Hold" and set text color to red Set_Property(Ctrl, 'TEXT', 'On Hold') Set_Property(Ctrl, 'FORECOLOR', BRED$) end else // Set label to "Off Hold" and set text color to green Set_Property(Ctrl, 'TEXT', 'Off Hold') Set_Property(Ctrl, 'FORECOLOR', BGREEN$) end return OpenCleanInsp: DetWindow = 'CLEAN_INSP' DetKeys = CINo DefaultRec = '' RetKey = RDSNo RetWin = CtrlEntID RetPage = 1 RetCtrl = 'OLE_EDT_STAGES' RetPos = '' obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos) Set_Property(DetWindow, '@SKIP_RETURN', True$) return OpenWOMatWfr: DetWindow = 'WO_MAT_WFR' DetKeys = WOMatKey DefaultRec = '' RetKey = RDSNo RetWin = '' RetPage = 1 RetCtrl = '' RetPos = '' obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos) Set_Property(DetWindow, '@SKIP_RETURN', True$) Set_Property(DetWindow, 'VISIBLE', True$) return ClearLblChkEDT: List = '' List<3, 4> = '' Set_Property(@Window:'.CASS_IDS', 'LIST', List) return ClearForm: NumCols = 4 NumRows = 26 DataList = '' For Row = 1 to NumRows DataList = '' Next Row ColorList = '' For Row = 1 to NumRows For Col = 1 to NumCols ColorList = 'None' Next Col Next Row ChkList = '' For Row = 1 to NumRows For Col = 1 to NumCols ChkList = False$ Next Col Next Row Set_Property(@Window:'.OLE_EDT_STAGES', "OLE.CellCheck[4; All]", False$) Set_Property(@Window, '@CHK_BOX_LIST', ChkList) Set_Property(@Window, '@DATA_LIST', DataList) Set_Property(@Window, '@COLOR_ARRAY', ColorList) GoSub PopulateCells GoSub ColorCells GoSub EnableChkBoxes GoSub EnableAutoSignButton GoSub UpdateHoldLabel GoSub ColorControls GoSub ClearLblChkEDT GoSub EnableRefreshButton GoSub EnableOtherButtons return