COMPILE FUNCTION obj_WO_Wfr(Method,Parms) #pragma precomp SRP_PreCompiler /* Methods for the WO_WFR (Wafer) Tables 3/1/2016 JCH - Initial coding */ DECLARE FUNCTION Get_Status, Msg, obj_Tables, Send_Dyn, ErrMsg, obj_Tables, Reconcile_Epi_WO, obj_WO_Mat_Wfr, RetStack DECLARE SUBROUTINE ErrMsg, Set_Status, Send_Dyn, FieldStore, obj_Tables, obj_WO_Wfr, Clear_Table, obj_WO_Mat_Wfr, Set_Property DECLARE SUBROUTINE Rlist, obj_Tool_Wfr, obj_Location, obj_Notes DECLARE FUNCTION Environment_Services $INSERT WO_LOG_EQUATES $INSERT WO_MAT_EQUATES $INSERT WM_IN_EQUATES $INSERT WM_OUT_EQUATES $INSERT RDS_EQUATES $INSERT WO_WFR_EQUATES $Insert WO_MAT_WFR_EQUATES $Insert TW_USE_EQUATES $Insert NCR_EQUATES $Insert RLIST_Equates EQU CRLF$ TO \0D0A\ EQU TAB$ TO \09\ EQU WAFER_ID$ TO 1 ;* Columns in data structure returned by Reconcile_Epi_Pro EQU LOT_NO$ TO 2 EQU LOADED_INTO$ TO 3 EQU RAN_IN$ TO 4 EQU POCKET_CHAR$ TO 5 EQU UNLOADED_INTO$ TO 6 EQU WAFER_DISP$ TO 7 EQU TRACE_DTM$ TO 1 EQU TRACE_BY$ TO 2 EQU TRACE_EVENT$ TO 3 EQU TRACE_SLOT_ID$ TO 4 EQU TRACE_RUN_LOC$ TO 5 EQU TRACE_CARR_SLOT$ TO 6 EQU TRACE_INV_LOC$ TO 7 EQU TRACE_TOOL_ID$ TO 8 EQU TRACE_TW_USE$ TO 9 EQU TRACE_NCR_NO$ TO 10 ErrTitle = 'Error in Stored Procedure "obj_WO_Wfr"' ErrorMsg = '' ErrCode = '' IF NOT(ASSIGNED(Method)) THEN ErrorMsg = 'Unassigned parameter "Method" passed to subroutine' IF NOT(ASSIGNED(Parms)) THEN Parms = '' IF ErrorMsg NE '' THEN Set_Status(-1,ErrTitle:@SVM:ErrorMsg) RETURN '' END Result = '' BEGIN CASE CASE Method = 'SetProp' ; Gosub SetProp CASE Method = 'CassRel' ; Gosub CassRel Case Method = 'AddEvent' ; Gosub AddEvent Case Method = 'RemEvent' ; Gosub RemEvent Case Method = 'CurrLoc' ; Gosub CurrLoc Case Method = 'GetET' ; Gosub GetET CASE Method = 'Convert' ; Gosub Convert CASE Method = 'Disp' ; Gosub Disp Case Method = 'CassDel' ; Gosub CassDel CASE Method = 'LoadFromSlot' ; Gosub LoadFromSlot CASE Method = 'UnloadIntoSlot' ; Gosub UnloadIntoSlot CASE Method = 'InSlotDisp' ; Gosub InSlotDisp CASE Method = 'OutSlotDisp' ; Gosub OutSlotDisp CASE Method = 'TestAddEvent' ; Gosub TestAddEvent CASE Method = 'TraceData' ; Gosub TraceData CASE 1 NULL END CASE IF ErrorMsg NE '' THEN Set_Status(-1,ErrTitle:@SVM:ErrorMsg) END RETURN Result * * * * * * * SetProp: * * * * * * * **** NO MULTIVALUE FIELDS HERE **** WOWfrKey = Parms[1,@RM] FieldNos = Parms[COL2()+1,@RM] FieldValues = Parms[COL2()+1,@RM] IF WOWfrKey = '' THEN ErrorMsg = 'Null parameter "WOMWfrKey" passed to routine. (':Method:')' IF FieldNos = '' THEN ErrorMsg = 'Null parameter "FieldNos" passed to routine. (':Method:')' If ErrorMsg NE '' Then RETURN otParms = 'WO_WFR':@RM:WOWfrKey WOWfrRec = obj_Tables('ReadRec',otParms) fCnt = COUNT(FieldNos,@VM) + (FieldNos NE '') FOR I = 1 TO fCnt FieldNo = FieldNos<1,I> FieldValue = FieldValues<1,I> WOWfrRec = FieldValue ;* No check for any ICONV stuff so pass it in converted NEXT I otParms = FIELDSTORE(otParms,@RM,4,0,WOWfrRec) obj_Tables('WriteRec',otParms) RETURN * * * * * * * CassRel: * * * * * * * WOMatKey = Parms[1,@RM] If WOMatKey = '' Then Return WfrQty = Xlate('WO_MAT',WOMatKey,WO_MAT_WAFER_QTY$,'X') CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') WfrIDs = '' ;* Added 9/7/2016 JCH NewSlotIDs = '' ;* Added 9/7/2016 JCH For I = 1 To WfrQty WfrIDs<1,-1> = WOMatKey:'*':I ;* Added 9/7/2016 JCH NewSlotIDs<1,-1> = WOMatKey:'*':I ;* Added 9/7/2016 JCH owwParms = WOMatKey:'*':I:@RM ;* WfrID owwParms := CurrDTM:@RM ;* EventDtm owwParms := @USER4:@RM ;* EventBy owwParms := 'REL':@RM ;* Event owwParms := WOMatKey:'*':I:@RM ;* New Slot ID owwParms := '':@RM ;* RPZ (RDSNo*Pocket*Zone) owwParms := '':@RM ;* NCRNo owwParms := '':@RM ;* TWUse ID owwParms := '':@RM ;* Current Slot ID owwParms := '':@RM ;* New ToolID owwParms := '':@RM ;* Curr Tool ID owwParms := '':@RM ;* NewInvLoc owwParms := '':@RM ;* CurrInvLoc owwParms := 'I' ;* Wfr Side obj_WO_Wfr('AddEvent',owwParms) Next I Return * * * * * * * AddEvent: * * * * * * * WfrID = Parms[1,@RM] ;* mv EventDtm = Parms[COL2()+1,@RM] EventBy = Parms[COL2()+1,@RM] Event = Parms[COL2()+1,@RM] NewSlotID = Parms[COL2()+1,@RM] ;* mv RunLoc = Parms[COL2()+1,@RM] ;* mv NCRNo = Parms[COL2()+1,@RM] TWUse = Parms[COL2()+1,@RM] CurrSlotID = Parms[COL2()+1,@RM] ;* mv NewToolID = Parms[COL2()+1,@RM] CurrToolID = Parms[COL2()+1,@RM] NewInvLoc = Parms[COL2()+1,@RM] CurrInvLoc = Parms[COL2()+1,@RM] WfrSide = Parms[COL2()+1,@RM] NewCarrLoc = Parms[COL2()+1,@RM] ;* mv Added 6/20/2016 JCH CurrCarrLoc = Parms[COL2()+1,@RM] ;* mv Added 6/20/2016 JCH Scribe = Parms[COL2()+1,@RM] ;* mv Added 6/20/2016 JCH If WfrID = '' THEN ErrorMsg = 'Null Parameter "WfrID" passed to routine. (':Method:')' If Event = '' THEN ErrorMsg = 'Null Parameter "EventEvent" passed to routine. (':Method:')' If EventDTM NE '' THEN thisEventDTM = ICONV(EventDTM,'DT') If thisEventDTM = '' THEN ErrorMsg = 'Invalid Parameter EventDTM ':Quote(EventDTM):' passed to routine. (':Method:')' If ErrorMsg NE '' Then RETURN End * REL - Release is the initial entry into the Wafer history so no check for a Current location IF Event NE 'REL' THEN IF CurrSlotID = '' AND CurrToolID = '' AND CurrInvLoc = '' AND CurrCarrLoc = '' AND TWUse = '' AND NCRNo = '' THEN ErrorMsg = 'Wafer has been dispositioned.' Recipients = Xlate('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X') SentFrom = @USER4 Subject = 'Wafer has been dispositioned.' Message = "WfrID":TAB$:WfrID:CRLF$ Message := 'EventDTM:':TAB$:EventDTM:CRLF$ Message := 'Event:':TAB$:Event:CRLF$ Message := 'NewSlotID:':TAB$:NewSlotID:CRLF$ Message := 'RunLoc:':TAB$:RunLoc:CRLF$ Message := 'NCRNo:':TAB$:NCRNo:CRLF$ Message := 'TWUse:':TAB$:TWUse:CRLF$ Message := 'CurrSlotID:':TAB$:CurrSlotID:CRLF$ Message := 'NewToolID:':TAB$:NewToolID:CRLF$ Message := 'CurrToolID:':TAB$:CurrToolID:CRLF$ Message := 'NewInvLoc:':TAB$:NewInvLoc:CRLF$ Message := 'CurrInvLoc:':TAB$:CurrInvLoc:CRLF$ Message := 'WfrSide:':TAB$:WfrSide:CRLF$ Message := 'NewCarrLoc:':TAB$:NewCarrLoc:CRLF$ Message := 'CurrCarrLoc:':TAB$:CurrCarrLoc:CRLF$ Message := 'Scribe:':TAB$:Scribe:CRLF$ AttachWindow = '' AttachKey = '' SendToGroup = '' Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup obj_Notes('Create',Parms) RETURN END END * * * Added 9/21/2016 JCH * * * - Troubleshooting WIP problem "%$((!" AuditWfrID = WfrID CONVERT '*' TO '.' IN AuditWfrID AuditDTM = ICONV(EventDTM,'DT') AuditKey = AuditWfrID:'*':AuditDTM:'*':EventBy:'*':Event AuditRec = NewSlotID:@FM AuditRec := RunLoc:@FM AuditRec := NCRNo:@FM AuditRec := TWUse:@FM AuditRec := CurrSlotID:@FM AuditRec := NewToolID:@FM AuditRec := CurrToolID:@FM AuditRec := NewInvLoc:@FM AuditRec := CurrInvLoc:@FM AuditRec := WfrSide:@FM AuditRec := NewCarrLoc:@FM AuditRec := CurrCarrLoc:@FM AuditRec := Scribe aotParms = 'WO_WFR_AUDIT':@RM:AuditKey:@RM:'':@RM:AuditRec obj_Tables('WriteRec',aotParms) * * * * * * * CONVERT '.' TO '*' IN WfrID CONVERT '.' TO '*' IN NewSlotID CONVERT '.' TO '*' IN CurrSlotID IF NewSlotID NE '' THEN NewSlotIDCassNo = FIELD(NewSlotID,'*',2) IF NewSlotIDCassNo = '' THEN RETURN END END otParms = 'WO_WFR':@RM:WfrID WfrRec = obj_Tables('ReadRec',otParms) IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END If EventDTM = '' Then ExistDTMs = WfrRec IF ExistDTMs = '' THEN thisEventDTM = ICONV( OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS'),'DT' ) END ELSE Loop TestChar = ExistDTMs[-1,1] Until TestChar NE @VM Or ExistDTMs = '' ExistDTMs[-1,1] = '' Repeat LastDTM = ExistDTMs[-1,'B':@VM] thisEventDTM = LastDTM + ( 1/24 ) ;* Fake a time for this 1 hour after last transaction. END ;* End check for Existing DTMs End If EventBy = '' Then EventBy = 'OI' ;* Admin user End Locate thisEventDTM In WfrRec BY 'AR' SETTING Pos THEN obj_Tables('UnlockRec',otParms) IF Get_Status(ErrCode) THEN ErrMsg(errCode) END END ELSE * IF Scribe NE '' AND WfrRec = '' THEN * WfrRec = Scribe ;* Added 9/7/2016 JCH * END DestTest = XLATE('TOOL',NewToolID,'DEST_TEST','X') ;* Tool Start on destructive test IF DestTest AND WfrRec = '' THEN WfrRec = 1 END WfrRec = Insert(WfrRec,WO_WFR_LOC_DTM$,Pos,0,thisEventDTM) WfrRec = Insert(WfrRec,WO_WFR_LOC_BY$,Pos,0,EventBy) WfrRec = Insert(WfrRec,WO_WFR_LOC_EVENT$,Pos,0,Event) WfrRec = Insert(WfrRec,WO_WFR_SLOT_ID$,Pos,0,NewSlotID) WfrRec = Insert(WfrRec,WO_WFR_RUN_LOC$,Pos,0,RunLoc) WfrRec = Insert(WfrRec,WO_WFR_WMI_NCR_NO$,Pos,0,NCRNo) WfrRec = Insert(WfrRec,WO_WFR_TW_USE$,Pos,0,TWUse) WfrRec = Insert(WfrRec,WO_WFR_TOOL_ID$,Pos,0,NewToolID) WfrRec = Insert(WfrRec,WO_WFR_INV_LOC$,Pos,0,NewInvLoc) WfrRec = Insert(WfrRec,WO_WFR_WFR_SIDE$,Pos,0,WfrSide) ;* Added 5/28/2016 JCH WfrRec = Insert(WfrRec,WO_WFR_CARR_SLOT$,Pos,0,NewCarrLoc) ;* Added 6/20/2016 JCH otParms = FieldStore(otParms,@RM,4,0,WfrRec) obj_Tables('WriteRec',otParms) IF Get_Status(ErrCode) THEN ErrMsg(errCode) END BEGIN CASE CASE NewSlotID = '' AND CurrSlotID NE '' obj_WO_Mat_Wfr('ClearWfrID',CurrSlotID:@RM:@RM:WfrSide) ;* Removes wafer from slot in WO_MAT_WFR record CASE NewSlotID NE '' AND CurrSlotID NE '' obj_WO_Mat_Wfr('SetWfrID',NewSlotID:@RM:WfrID:@RM:WfrSide) ;* Adds Wafer ID to NewSlotID in WO_MAT_WFR table obj_WO_Mat_Wfr('ClearWfrID',CurrSlotID:@RM:@RM:WfrSide) ;* Removes wafer from CurrSlotIDin WO_MAT_WFR record CASE NewSlotID NE '' AND CurrSlotID = '' obj_WO_Mat_Wfr('SetWfrID',NewSlotID:@RM:WfrID:@RM:WfrSide) ;* Adds Wafer ID to NewSlotID in WO_MAT_WFR table CASE 1 NULL END Case BEGIN CASE CASE NewToolID = '' AND CurrToolID NE '' obj_Tool_Wfr('ClearWfrID',CurrToolID:@RM:WfrID) ;* Removes wafer from Tool_WFR record CASE NewToolID NE '' AND CurrToolID NE '' obj_Tool_Wfr('SetWfrID',NewToolID:@RM:WfrID) ;* Adds Wafer ID to NewToolID IN TOOL_WFR table obj_Tool_Wfr('ClearWfrID',CurrToolID) ;* Removes wafer from CurrToolID in TOOL_WFR record CASE NewToolID NE '' AND CurrToolID = '' obj_Tool_Wfr('SetWfrID',NewToolID:@RM:WfrID) ;* Adds Wafer ID to NewTOOLID IN TOOL_WFR table CASE 1 NULL END Case BEGIN CASE CASE NewInvLoc = '' AND CurrInvLoc NE '' obj_Location('ClearWfrID',CurrInvLoc:@RM:WfrID) ;* Removes wafer from Location record CASE NewInvLoc NE '' AND CurrInvLoc NE '' obj_Location('SetWfrID',NewInvLoc:@RM:WfrID) ;* Adds Wafer ID to WFR_ID field IN LOCATION table obj_Location('ClearWfrID',CurrInvLoc:@RM:WfrID) ;* Removes wafer from WFR_ID field in LOCATION record CASE NewInvLoc NE '' AND CurrInvLoc = '' obj_Location('SetWfrID',NewInvLoc:@RM:WfrID) ;* Adds Wafer ID to WFR_ID field IN LOCATION table CASE 1 NULL END Case END Return ********************************************************************************************************************** * * * * * * * TestAddEvent: * * * * * * * WfrIDs = Parms[1,@RM] ;* mv EventDtm = Parms[COL2()+1,@RM] EventBy = Parms[COL2()+1,@RM] Event = Parms[COL2()+1,@RM] NewSlotIDs = Parms[COL2()+1,@RM] ;* mv RunLocs = Parms[COL2()+1,@RM] ;* mv NCRNo = Parms[COL2()+1,@RM] TWUse = Parms[COL2()+1,@RM] CurrSlotIDs = Parms[COL2()+1,@RM] ;* mv NewToolID = Parms[COL2()+1,@RM] CurrToolID = Parms[COL2()+1,@RM] NewInvLoc = Parms[COL2()+1,@RM] CurrInvLoc = Parms[COL2()+1,@RM] WfrSide = Parms[COL2()+1,@RM] NewCarrLocs = Parms[COL2()+1,@RM] ;* mv Added 6/20/2016 JCH CurrCarrLocs = Parms[COL2()+1,@RM] ;* mv Added 6/20/2016 JCH Scribes = Parms[COL2()+1,@RM] ;* Added 6/20/2016 JCH If WfrIDs = '' THEN ErrorMsg = 'Null Parameter "WfrID" passed to routine. (':Method:')' If Event = '' THEN ErrorMsg = 'Null Parameter "EventEvent" passed to routine. (':Method:')' If EventDTM NE '' THEN thisEventDTM = ICONV(EventDTM,'DT') If thisEventDTM = '' THEN ErrorMsg = 'Invalid Parameter EventDTM ':Quote(EventDTM):' passed to routine. (':Method:')' If ErrorMsg NE '' Then RETURN End CONVERT '.' TO '*' IN WfrIDs CONVERT '.' TO '*' IN NewSlotIDs CONVERT '.' TO '*' IN CurrSlotIDs IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END * * * Added 9/21/2016 JCH * * * - Troubleshooting WIP problem "%$((!" OPEN 'WO_WFR_AUDIT' TO AuditFile THEN AuditWfrID = WfrIDs<1,1> CONVERT '*' TO '.' IN AuditWfrID AuditDTM = ICONV(EventDTM,'DT') AuditKey = AuditWfrID:'*':AuditDTM:'*':EventBy:'*':Event AuditRec = NewSlotIDs:@FM AuditRec := RunLocs:@FM AuditRec := NCRNo:@FM AuditRec := TWUse:@FM AuditRec := CurrSlotIDs:@FM AuditRec := NewToolID:@FM AuditRec := CurrToolID:@FM AuditRec := NewInvLoc:@FM AuditRec := CurrInvLoc:@FM AuditRec := WfrSide:@FM AuditRec := NewCarrLocs:@FM AuditRec := CurrCarrLocs:@FM AuditRec := Scribes:@FM AuditRec := WfrIDs WRITE AuditRec ON AuditFile,AuditKey ELSE ErrMsg(ErrCode) END END * * * * * * * If EventDTM = '' Then ExistDTMs = WfrRec IF ExistDTMs = '' THEN thisEventDTM = ICONV( OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS'),'DT' ) END ELSE Loop TestChar = ExistDTMs[-1,1] Until TestChar NE @VM Or ExistDTMs = '' ExistDTMs[-1,1] = '' Repeat LastDTM = ExistDTMs[-1,'B':@VM] thisEventDTM = LastDTM + ( 1/24 ) ;* Fake a time for this 1 hour after last transaction. END ;* End check for Existing DTMs End If EventBy = '' Then EventBy = 'OI' ;* Admin user End * * * * * Process Wafers * * * * * WOMatWfrKeys = '' WOMatWfrIDs = '' WOMatWfrCnts = '' WOMatNewSlotIDs = '' WOMatCurrSlotIDs = '' ToolNewWfrIDs = '' ToolCurrWfrIDs = '' LocNewWfrIDs = '' LocCurrWfrIDs = '' wCnt = COUNT(WfrIDs,@VM) + (WfrIDs NE '') * * * * * Build Key Lists for calls to obj_WO_Mat_Wfr('SetWfrIDs' and 'ClearWfrIDs' FOR I = 1 TO wCnt WfrID = WfrIDs<1,I> NewSlotID = NewSlotIDs<1,I> CurrSlotID = CurrSlotIDs<1,I> RunLoc = RunLocs<1,I> NewCarrLoc = NewCarrLocs<1,I> ;* Doesn't seem to be used! CurrCarrLoc = CurrCarrLocs<1,I> ;* Doesn't seem to be used! Scribe = Scribes<1,I> IF NewSlotID NE '' OR CurrSlotID NE '' THEN WOMatKey = FIELD(WfrID,'*',1,2) LOCATE WOMatKey IN WOMatWfrKeys USING @FM SETTING Pos THEN LineCnt = WOMatWfrCnts + 1 WOMatWfrCnts = LineCnt WOMatWfrIDs = INSERT(WOMatWfrIDs,Pos,LineCnt,0,WfrID) IF NewSlotID NE '' THEN WOMatNewSlotIDs = INSERT(WOMatNewSlotIDs,Pos,-1,0,NewSlotID) END IF CurrSlotID NE '' THEN WOMatCurrSlotIDs = INSERT(WOMatCurrSlotIDs,Pos,-1,0,CurrSlotID) END END ELSE WOMatWfrKeys = INSERT(WOMatWfrKeys,Pos,0,0,WOMatKey) WOMatWfrIDs = INSERT(WOMatWfrIDs,Pos,1,0,WfrID) WOMatWfrCnts = INSERT(WOMatWfrCnts,Pos,0,0,1) IF NewSlotId NE '' THEN WOMatNewSlotIDs = INSERT(WOMatNewSlotIDs,Pos,-1,0,NewSlotID) END IF CurrSlotId NE '' THEN WOMatCurrSlotIDs = INSERT(WOMatCurrSlotIDs,Pos,-1,0,CurrSlotID) END END END ;* End of check for slot changes IF NewToolID NE '' THEN ToolNewWfrIds<1,-1> = WfrID IF CurrToolID NE '' THEN ToolCurrWfrIDs<1,-1> = WfrID IF NewInvLoc NE '' THEN LocNewWfrIDs<1,-1> = WfrID IF CurrInvLoc NE '' THEN LocCurrWfrIDs<1,-1> = WfrID * Update individual WO_WFR records otParms = 'WO_WFR':@RM:WfrID WfrRec = obj_Tables('ReadRec',otParms) LOCATE thisEventDTM In WfrRec BY 'AR' SETTING Pos ELSE NULL END * IF Scribe NE '' AND WfrRec = '' THEN * WfrRec = Scribe ;* Added 9/7/2016 JCH * END DestTest = XLATE('TOOl',NewToolID,'DEST_TEST','X') ;* Tool Start on destructive test IF DestTest THEN IF WfrRec = 1 THEN obj_Tables('UnlockRec',otParms) ;* Wafer already flagged as broken END ELSE WfrRec = 1 ;* Flag the wafer as broken WfrRec = Insert(WfrRec,WO_WFR_LOC_DTM$,Pos,0,thisEventDTM) WfrRec = Insert(WfrRec,WO_WFR_LOC_BY$,Pos,0,EventBy) WfrRec = Insert(WfrRec,WO_WFR_LOC_EVENT$,Pos,0,'DEST') ;* Wafer flagged as destroyed WfrRec = Insert(WfrRec,WO_WFR_SLOT_ID$,Pos,0,NewSlotID) WfrRec = Insert(WfrRec,WO_WFR_RUN_LOC$,Pos,0,RunLoc) WfrRec = Insert(WfrRec,WO_WFR_WMI_NCR_NO$,Pos,0,NCRNo) WfrRec = Insert(WfrRec,WO_WFR_TW_USE$,Pos,0,TWUse) WfrRec = Insert(WfrRec,WO_WFR_TOOL_ID$,Pos,0,'') ;* Wafer not logged WfrRec = Insert(WfrRec,WO_WFR_INV_LOC$,Pos,0,NewInvLoc) ;* This is blank in this case WfrRec = Insert(WfrRec,WO_WFR_WFR_SIDE$,Pos,0,WfrSide) ;* Added 5/28/2016 JCH WfrRec = Insert(WfrRec,WO_WFR_CARR_SLOT$,Pos,0,NewCarrLoc) ;* Added 6/20/2016 JCH otParms = FieldStore(otParms,@RM,4,0,WfrRec) obj_Tables('WriteRec',otParms) IF Get_Status(ErrCode) THEN ErrMsg(errCode) END END END ELSE WfrRec = Insert(WfrRec,WO_WFR_LOC_DTM$,Pos,0,thisEventDTM) WfrRec = Insert(WfrRec,WO_WFR_LOC_BY$,Pos,0,EventBy) WfrRec = Insert(WfrRec,WO_WFR_LOC_EVENT$,Pos,0,Event) WfrRec = Insert(WfrRec,WO_WFR_SLOT_ID$,Pos,0,NewSlotID) WfrRec = Insert(WfrRec,WO_WFR_RUN_LOC$,Pos,0,RunLoc) WfrRec = Insert(WfrRec,WO_WFR_WMI_NCR_NO$,Pos,0,NCRNo) WfrRec = Insert(WfrRec,WO_WFR_TW_USE$,Pos,0,TWUse) WfrRec = Insert(WfrRec,WO_WFR_TOOL_ID$,Pos,0,NewToolID) WfrRec = Insert(WfrRec,WO_WFR_INV_LOC$,Pos,0,NewInvLoc) WfrRec = Insert(WfrRec,WO_WFR_WFR_SIDE$,Pos,0,WfrSide) ;* Added 5/28/2016 JCH WfrRec = Insert(WfrRec,WO_WFR_CARR_SLOT$,Pos,0,NewCarrLoc) ;* Added 6/20/2016 JCH otParms = FieldStore(otParms,@RM,4,0,WfrRec) obj_Tables('WriteRec',otParms) IF Get_Status(ErrCode) THEN ErrMsg(errCode) END END ; * end of check for destructive test NEXT I IF WOMatWfrKeys NE '' THEN wmCnt = COUNT(WOMatWfrKeys,@FM) + (WOMatWfrKeys NE '') FOR I = 1 TO wmCnt WOMatKey = WOMatWfrKeys WfrIDs = WOMatWfrIDs NewSlotIDs = WOMatNewSlotIDs CurrSlotIDs = WOMatCurrSlotIDs IF CurrSlotIDs NE '' THEN obj_WO_Mat_Wfr('ClearWfrIDS',WOMatKey:@RM:CurrSlotIDs:@RMWfrIDs:@RM:WfrSide) IF NewSlotIDs NE '' THEN obj_WO_Mat_Wfr('SetWfrIDS',WOMatKey:@RM:NewSlotIDs:@RMWfrIDs:@RM:WfrSide) NEXT I END ;* End of check for WO_Mat keys IF ToolCurrWfrIDs NE '' THEN obj_Tool_Wfr('ClearWfrID',CurrToolID:@RM:ToolCurrWfrIDs) IF ToolNewWfrIDs NE '' THEN obj_Tool_Wfr('SetWfrID',NewToolID:@RM:ToolNewWfrIDs) IF LocCurrWfrIDs NE '' THEN obj_Location('ClearWfrID',CurrInvLoc:@RM:LocCurrWfrIDs) IF LocNewWfrIDs NE '' THEN obj_Location('SetWfrID',NewInvLoc:@RM:LocNewWfrIDs) RETURN * * * * * * * RemEvent: * * * * * * * * * * Removes NCR or TEST from history if they are the last event recorded * * * WfrID = Parms[1,@RM] Event = Parms[COL2()+1,@RM] EventID = Parms[COL2()+1,@RM] If WfrID = '' THEN ErrorMsg = 'Null Parameter "WfrID" passed to routine. (':Method:')' If Event = '' THEN ErrorMsg = 'Null Parameter "Event" passed to routine. (':Method:')' If ErrorMsg NE '' Then Return If Event NE 'NCR' And Event NE 'TEST' Then ErrorMsg = 'Only NCR or TEST events may be removed. Event = ':QUOTE(Event) Return END otParms = 'WO_WFR':@RM:WfrID WfrRec = obj_Tables('ReadRec',otParms) IF WfrRec = '' THEN obj_Tables('UnlockRec',otParms) RETURN END BEGIN CASE CASE Event = 'NCR' ; EventFieldNo = WO_WFR_WMI_NCR_NO$ CASE Event = 'TEST' ; EventFieldNo = WO_WFR_TW_USE$ CASE Event = '' obj_Tables('UnlockRec',otParms) RETURN END CASE Locate EventID In WfrRec USING @VM SETTING Pos Then NewSlotID = WfrRec If NewSlotID NE '' THEN obj_WO_Mat_Wfr('SetWfrID',NewSlotID:@RM:WfrID) ;* Adds Wafer ID to NewSlotID in WO_MAT_WFR table End WfrRec = Delete(WfrRec,WO_WFR_LOC_DTM$,Pos,0) WfrRec = Delete(WfrRec,WO_WFR_LOC_BY$,Pos,0) WfrRec = Delete(WfrRec,WO_WFR_LOC_EVENT$,Pos,0) WfrRec = Delete(WfrRec,WO_WFR_SLOT_ID$,Pos,0) WfrRec = Delete(WfrRec,WO_WFR_RUN_LOC$,Pos,0) WfrRec = Delete(WfrRec,WO_WFR_WMI_NCR_NO$,Pos,0) WfrRec = Delete(WfrRec,WO_WFR_TW_USE$,Pos,0) otParms = FieldStore(otParms,@RM,4,1,WfrRec) obj_Tables('WriteRec',otParms) End Else obj_Tables('UnlockRec',otParms) End Return * * * * * * * CurrLoc: * * * * * * * IF NOT(ASSIGNED(WfrID)) THEN WfrID = Parms[1,@RM] IF NOT(ASSIGNED(WfrRec)) THEN WfrRec = Parms[COL2()+1,@RM] IF WfrID = '' THEN RETURN ;* This is used in the dictionary -> don't throw an error for a null parmeter IF WfrRec = '' THEN WfrRec = XLATE('WO_WFR',WfrID,'','X') NcrNos = WfrRec TWNos = WfrRec CONVERT @VM TO '' IN NcrNos CONVERT @VM TO '' IN TWNos IF NcrNos NE '' OR TWNos NE '' THEN RETURN ;* Wafer is no longer in the active tracking system WfrEvents = WfrRec CurrLoc = '' weCnt = Count(WfrEvents,@VM) + (WfrEvents NE '') For M = WeCnt To 1 STEP -1 WfrEvent = WfrEvents<1,M> SlotLoc = WfrRec CassID = FIELD(SlotLoc,'*',1,2) ToolLoc = WfrRec InvIDLoc = WfrRec If CassID NE '' Then CurrLoc<1,1> = CassID IF SlotLoc NE '' Then CurrLoc<1,2> = SlotLoc If ToolLoc NE '' Then CurrLoc<1,3> = ToolLoc If InvIDLoc NE '' Then CurrLoc<1,4> = InvIDLoc While CurrLoc = '' Next M Result = CurrLoc RETURN * * * * * * * GetET: * * * * * * * * Returns time in Hours since last event happened WfrID = Parms[1,@RM] WfrRec = Parms[COL2()+1,@RM] IF WfrID = '' THEN RETURN ;* This is used in the dictionary -> don't throw an error for a null parmeter IF WfrRec = '' THEN WfrRec = XLATE('WO_WFR',WfrID,'','X') LocDTMs = WfrRec LocCnt = COUNT(LocDTMs,@VM) + (LocDTMs NE '') LastDTM = LocDTMs<1,LocCnt> IF LastDTM = '' THEN RETURN ;* Bail CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTH') CurrDTM = ICONV(CurrDTM , 'DT' ) IF CurrDTM > LastDTM THEN Result = OCONV(ICONV( (CurrDTM - LastDTM)*24 , 'MD1'), 'MD1') ;* Elapsed time in hours to 1 decimal precision END RETURN * * * * * * * Disp: * * * * * * * IF NOT(ASSIGNED(WfrID)) THEN WfrID = Parms[1,@RM] IF NOT(ASSIGNED(WfrRec)) THEN WfrRec = Parms[COL2()+1,@RM] IF WfrID = '' THEN RETURN ;* This is used in the dictionary -> don't throw an error for a null parmeter IF WfrRec = '' THEN WfrRec = XLATE('WO_WFR',WfrID,'','X') WfrEvents = WfrRec evCnt = COUNT(WfrEvents,@VM) + ( WfrEvents NE '' ) Loaded = INDEX(WfrEvents,'LOAD',1) Unloaded = INDEX(WfrEvents,'UNLOAD',1) BEGIN CASE CASE NOT(Loaded) EpiStage = 'Pre' CASE Loaded AND NOT(Unloaded) EpiStage ='React' CASE Loaded AND Unloaded EpiStage = 'Post' END CASE LastEvent = WfrRec BEGIN CASE CASE LastEvent = 'TEST' TWKey = WfrRec IF TWKey = '' THEN TWKey = '***' Disp = 'TEST -> ':TWKey CASE LastEvent = 'NCR' Disp = 'NCR':' - ':WfrRec:' ':WfrRec CASE LastEvent = 'UNLOAD' Disp = 'UNLOAD -> ':WfrRec CASE LastEvent = 'LOAD' Disp = 'LOAD -> ':WfrRec CASE LastEvent = 'MKUP' Disp = 'MKUP -> ':WfrRec CASE LastEvent = 'MOVE' Disp = 'MOVE -> ':WfrRec CASE LastEvent = 'REPLACE' Disp = 'REPLACE -> ':WfrRec CASE LastEvent = 'RETURN' Disp = 'RETURN -> ':WfrRec CASE 1 Disp = 'PROD - ':WfrID END CASE Result = Disp RETURN * * * * * * * CassDel: * * * * * * * WOMatKey = Parms[1,@RM] If WOMatKey = '' Then Return WfrQty = Xlate('WO_MAT',WOMatKey,WO_MAT_WAFER_QTY$,'X') otParms = 'WO_MAT_WFR':@RM:WOMatKey obj_Tables('DeleteRec',otParms) For I = 1 To WfrQty otParms = 'WO_WFR':@RM:WOMatKey:'*':I obj_Tables('DeleteRec',otParms) Next I Return * * * * * * * InSlotDisp: * * * * * * * WOWfrKey = Parms[1,@RM] WOWfrRec = Parms[COL2()+1,@RM] IF WOWfrKey = '' THEN RETURN ;* Called from dictionary -> no messages IF WOWfrRec = '' THEN WOWfrRec = XLATE('WO_WFR',WOWfrKey,'','X') END IF WOWfrRec = '' THEN RETURN eCnt = COUNT(WOWfrRec,@VM) + (WOWfrRec NE '') LoadPOs = '' NCRPos = '' TestPos = '' UnloadPos = '' FOR I = eCnt TO 1 STEP -1 Event = WOWfrRec IF Event = 'LOAD' AND LoadPos = '' THEN LoadPos = I IF Event = 'NCR' AND NCRPos = '' THEN NCRPos = I IF Event = 'TEST' AND TestPos = '' THEN TestPos = I IF Event = 'UNLOAD' AND UnloadPos = '' THEN UnloadPos = I UNTIL LoadPos AND NCRPos AND TestPos AND UnloadPos NEXT I BEGIN CASE CASE NCRPos AND LoadPos = '' ; Result = 'PreEpi NCR - ':WOWfrRec CASE TestPos NE '' ; Result = 'Prod Test - ':WOWfrRec CASE LoadPos NE '' ; Result = 'Load - ':WOWfrREc:' ':WOWfrRec CASE 1 NULL END CASE RETURN * * * * * * * OutSlotDisp: * * * * * * * WOWfrKey = Parms[1,@RM] WOWfrRec = Parms[COL2()+1,@RM] IF WOWfrKey = '' THEN RETURN ;* Called from dictionary -> no messages IF WOWfrRec = '' THEN WOWfrRec = XLATE('WO_WFR',WOWfrKey,'','X') END IF WOWfrRec = '' THEN RETURN eCnt = COUNT(WOWfrRec,@VM) + (WOWfrRec NE '') MkupPos = '' NCRPos = '' UnloadPos = '' FOR I = eCnt TO 1 STEP -1 Event = WOWfrRec IF Event = 'MKUP' AND MkupPos = '' THEN MkupPos = I IF Event = 'NCR' AND NCRPos = '' THEN NCRPos = I IF Event = 'UNLOAD' AND UnloadPos = '' THEN UnloadPos = I UNTIL UnloadPos AND NCRPos AND MkupPos NEXT I BEGIN CASE CASE NCRPos AND UnLoadPos NE '' ; Result = 'NCR Post Epi - ':WOWfrRec CASE MkupPos NE '' ; Result = 'UMW - ':WOWfrRec CASE 1 NULL END CASE RETURN * * * * * * * TraceData: * * * * * * * WOWfrKey = Parms[1,@RM] WOWfrRec = Parms[COL2()+1,@RM] IF WOWfrKey = '' THEN RETURN ;* Called from dictionary -> no messages IF WOWfrRec = '' THEN WOWfrRec = XLATE('WO_WFR',WOWfrKey,'','X') END IF WOWfrRec = '' THEN RETURN lCnt = COUNT(WOWfrRec,@VM) + (WOWfrRec NE '') FOR I = 1 to lCnt Result<1,I,TRACE_DTM$> = OCONV(WOWfrRec,'DT4/^S') Result<1,I,TRACE_BY$> = WOWfrRec Result<1,I,TRACE_EVENT$> = WOWfrRec Result<1,I,TRACE_SLOT_ID$> = WOWfrRec Result<1,I,TRACE_RUN_LOC$> = WOWfrRec Result<1,I,TRACE_CARR_SLOT$> = WOWfrRec Result<1,I,TRACE_INV_LOC$> = WOWfrRec Result<1,I,TRACE_TOOL_ID$> = WOWfrRec Result<1,I,TRACE_TW_USE$> = WOWfrRec Result<1,I,TRACE_NCR_NO$> = WOWfrRec NEXT I RETURN * * * * * * * Convert: * * * * * * * *CLEAR_TABLE('WO_WFR') *CLEAR_TABLE('WO_MAT_WFR') WONos = '161854' wCnt = COUNT(WONos,@VM) + (WONos NE '') FOR I = 1 TO wCnt WONo = WONos<1,I> EpiProFlag = Xlate('WO_LOG',WONo,'EPI_PRO_FLAG','X') If EpiProFlag THEN CALL Convert_Epi_WO(WONo) End Else Gosub ConvertASM End NEXT I RETURN * * * * * * * ConvertASM: * * * * * * * * * * * * NOT setup for calls to obj_wo_Wfr with MV'd paramters Open 'WO_MAT' To WOMatTable Else ErrMsg(ErrorMsg) Return End SelectSent = 'SELECT WO_MAT WITH WO_NO = ':QUOTE(WONo):' BY CASS_NO' Set_Status(0) RList(SelectSent,TARGET_ACTIVELIST$,'','','') IF Get_Status(errCode) THEN ErrMsg(errCode) Return END Done = 0 LOOP READNEXT WOMatKey ELSE Done = 1 UNTIL Done WOMatRec = Xlate('WO_MAT',WOMatKey,'','X') WONo = WOMatKey[1,'*'] CassNo = WOMatKey[COL2()+1,'*'] SlotNos = WOMatRec sCnt = Count( SlotNos,@VM ) + ( SlotNos NE '' ) For I = 1 To sCnt SlotNo = SlotNos<1,I> NCRNo = WOMatRec TWUseKey = WOMatRec RepWfrID = WOMatRec WfrID = WONo:'*':CassNo:'*':SlotNo CurrWfrRec = Xlate('WO_WFR',WfrID,'','X') If NCRNo NE '' Then Locate NCRNo In WOMatRec BY 'AR' SETTING NPos Then NCRBy = WOMatRec NCRDTM = WOMatRec CurrWfrRec = XLATE('WO_WFR',WfrID,'','X') LOCATE NCRNo IN CurrWfrRec SETTING cwPos ELSE owwParms = WfrID:@RM ;* WfrID owwParms := Oconv(NCRDtm,'DT4/^S'):@RM ;* Event Dtm owwParms := NCRBy:@RM ;* Event By owwParms := 'NCR':@RM ;* Event owwParms := '':@RM ;* NewSlotID owwParms := '':@RM ;* RunID (RPZ) owwParms := NCRNo:@RM ;* NCRNo owwParms := '':@RM ;* TwID owwParms := WfrID ;* CurrSlotID obj_WO_Wfr('AddEvent',owwParms) END ;* End of check for NCRNo already in WO_WFR record End ;* End of locating NCRNo IN WOMatRec field End ;* End of check for NCR No If TWUseKey NE '' Then LOCATE 'TEST' IN CurrWfrRec SETTING twPos ELSE TWUseRec = XLATE('TW_USE',TWUseKey,'','X') TWSig = TWUseRec TWSigDtm = TWUseRec owwParms = WfrID:@RM ;* WfrID owwParms := Oconv(TWSigDTM,'DT4/^S'):@RM ;* Event Dtm owwParms := TWSig:@RM ;* Event By owwParms := 'TEST':@RM ;* Event owwParms := '':@RM ;* NewSlotID owwParms := '':@RM ;* RunID (RPZ) owwParms := '':@RM ;* NCRNo owwParms := TWUseKey:@RM ;* TWUseKey owwParms := WfrID ;* CurrSlotID obj_WO_Wfr('AddEvent',owwParms) END ;* End of check for 'TEST' Event already in WO_WFR Record End ;* End of check for TWUseKey If RepWfrID NE '' Then Convert '.' To '*' In RepWfrID LOCATE WfrID IN CurrWfrRec SETTING Dummy ELSE owwParms = RepWfrID:@RM ;* WfrID owwParms := '':@RM ;* Event Dtm owwParms := '':@RM ;* Event By owwParms := 'MKUP':@RM ;* Event owwParms := WfrID:@RM ;* NewSlotID owwParms := '':@RM ;* RunID (RPZ) owwParms := '':@RM ;* NCRNo owwParms := '':@RM ;* TwID owwParms := RepWfrID ;* CurrSlotID obj_WO_Wfr('AddEvent',owwParms) END ;* End of new Slot ID already in the existing WO_WFR Rec End ;* End of check for RepWfrID Next I REPEAT RETURN * * * * * * * LoadFromSlot: * * * * * * * RETURN * * * * * * * UnloadIntoSlot: * * * * * * * RETURN