Compile Function obj_WM_Out(Method,Parms) /* Methods for WM_OUT table 05/01/2005 JCH - Initial Coding Properties: Methods: Create(WONo,ProcStep,CassNo,WfrQty) ;* Create new record NextEmptySlot(WONo,WOStep) ;* Returns list of CassNo:@VM:SlotNo, @FM'd for slot without an RDS or NCR number RemoveWafer(WONo,WOStep,CassNo,SlotNo,RDSNo,PocketNo,Zone,NCRNo) ;* Adds usage information from COMM_DIALOG_UNLOAD_EPI_PRO routine ReplaceWafer(WONo,WOStep,CassNo,SlotNo) ;* Removes usage information */ Declare Function Get_Status, Msg, Utility, obj_Tables, NextKey, obj_WO_Verify, obj_Prod_Spec, Send_Dyn, obj_RDS_Makeup Declare Function obj_RDS2, obj_WM_Out, Delete, Signature_Services, Environment_Services, Logging_Services Declare Function Database_Services Declare Subroutine Set_Status, Msg, obj_Tables, Send_Dyn, obj_WO_Step, obj_RDS_Layer, obj_RDS_Test, Btree.Extract Declare Subroutine Extract_SI_Keys, obj_WM_Out, obj_WO_Mat, obj_Post_Log, obj_WO_Mat_Log, ErrMsg, obj_WO_Wfr Declare Subroutine Logging_Services, Material_Services, Database_Services, Update_Index, Work_Order_Services Declare Subroutine Service_Services $Insert MSG_EQUATES $Insert APP_INSERTS $Insert WO_LOG_EQU $Insert WO_STEP_EQU $Insert WO_MAT_EQUATES $Insert EPI_SUSCEPTOR_EQUATES $Insert RDS_EQUATES $Insert WM_OUT_EQUATES $Insert PROD_SPEC_EQUATES $Insert QUOTE_SPEC_EQU $Insert SURFACE_SCAN_EQUATES $Insert CLEAN_INSP_EQUATES $Insert WMO_WFRS_EQUATES $Insert REACT_RUN_EQUATES ErrTitle = 'Error in Stored Procedure "obj_WM_Out"' ErrorMsg = '' ErrCode = '' LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WM_OUT' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' CurrStatus Log.csv' Headers = 'Logging DTM' : @FM : 'User' : @FM : 'WMOutKey' : @FM : 'Calculated Value' : @FM : 'Physical Value' objCurrStatusLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Release Error Log.csv' Headers = 'Logging DTM':@FM:'Error':@FM:'NumAttempts':@FM:'WONo':@FM:'WOStep':@FM:'CassNo' objReleaseLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) 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 = 'Create' ; GOSUB Create CASE Method = 'Delete' ; GOSUB Delete CASE Method = 'CurrStatus' ; GOSUB CurrStatus CASE Method = 'CRComp' ; GOSUB CRComp ;* Cleanroom complete flag CASE Method = 'NextOpenSlots' ; GOSUB NextOpenSlots CASE Method = 'SlotStatus' ; GOSUB SlotStatus CASE Method = 'AddWafer' ; GOSUB AddWafer CASE Method = 'RemoveWafer' ; GOSUB RemoveWafer CASE Method = 'AddShip' ; GOSUB AddShip CASE Method = 'RemShip' ; GOSUB RemShip CASE Method = 'ClearLoad' ; GOSUB ClearLoad CASE Method = 'RDSSlots' ; GOSUB RDSSlots CASE Method = 'InCassData' ; GOSUB InCassData CASE Method = 'AddMakeupWafers' ; GOSUB AddMakeupWafers CASE Method = 'SubMakeupWafers' ; GOSUB SubMakeupWafers CASE Method = 'RemMakeupWafers' ; GOSUB RemMakeupWafers CASE Method = 'RepMakeupWafers' ; GOSUB RepMakeupWafers CASE Method = 'CassRDSNos' ; GOSUB CassRDSNos CASE Method = 'CassRDSWfrCnts' ; GOSUB CassRDSWfrCnts CASE Method = 'GetPartNoQtys' ; GOSUB GetPartNoQtys CASE Method = 'GetLotNos' ; GOSUB GetLotNos CASE Method = 'GetOrderItems' ; GOSUB GetOrderItems CASE Method = 'NCRNos' ; GOSUB NCRNos CASE Method = 'RebuildLoad' ; GOSUB RebuildLoad CASE Method = 'RemSlots' ; GOSUB RemSlots CASE Method = 'ConvertCleanInsp' ; GOSUB ConvertCleanInsp CASE Method = 'WfrsOut' ; GOSUB WfrsOut CASE Method = 'EpiReactNo' ; GOSUB EpiReactNo CASE 1 NULL END CASE IF ErrorMsg NE '' THEN Set_Status(-1,ErrTitle:@SVM:ErrorMsg) END RETURN Result * * * * * * * Create: * * * * * * * WONo = Parms[1,@RM] WOStep = Parms[COL2()+1,@RM] NewCassNos = Parms[COL2()+1,@RM] CassLoadQty = Parms[COL2()+1,@RM] IF WONo = '' THEN ErrorMsg = 'Null Parameter "WONo" passed to routine. (':Method:')' IF WOStep = '' THEN ErrorMsg = 'Null Parameter "WOStep" passed to routine. (':Method:')' IF NewCassNos = '' THEN ErrorMsg = 'Null Parameter "NewCassNos" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN PSNo = XLATE('WO_STEP',WONo:'*':WOStep,1,'X') SubstrateSpec = XLATE('PROD_SPEC',PSNo,PROD_SPEC_SPEC_SUBSTRATE$,'X') ;********************************************************************************************* ReactorType = XLATE('PROD_SPEC',PSNo,PROD_SPEC_REACTOR_TYPE$,'X') ;* 9/2/2014 JCH Not used in this program PromiseShipDt = XLATE('WO_LOG',WONo,WO_LOG_PROMISE_SHIP_DT$,'X') SubPostClean = SubstrateSpec<1,QSSubPostClean$> ;*************************************************************************************** PSType = XLATE('PROD_SPEC',PSNo,'SPEC_TYPE','X') ;* Added 8/22/2012 JCH IF CassLoadQty = '' THEN IF PSType = 'Q' THEN SusceptorPockets = '' WaferSize = SubstrateSpec<1,QSSubWaferSize$> ;*Qual runs use the susceptor pocket count as the outbound wafer qty IF WaferSize = '125 mm 5 in' THEN SusceptorPockets = XLATE('EPI_SUSCEPTOR','5',EPI_SUSCEPTOR_POCKET_NO$,'X') END IF WaferSize = '150 mm 6 in' THEN SusceptorPockets = XLATE('EPI_SUSCEPTOR','6',EPI_SUSCEPTOR_POCKET_NO$,'X') END IF WaferSize = '200 mm 8 in' THEN SusceptorPockets = XLATE('EPI_SUSCEPTOR','8',EPI_SUSCEPTOR_POCKET_NO$,'X') END IF SusceptorPockets THEN CassLoadQty = SusceptorPockets[-1,'B':@VM] END ELSE CassLoadQty = 25 END END WORec = XLATE('WO_LOG',WONo,'','X') InboundWaferQty = 0 FOR I = 1 TO COUNT(NewCassNos,@VM) + (NewCassNos NE '') NewCassNo = NewCassNos<1,I> CassWfrQty = XLATE('WO_MAT',WONo:'*':NewCassNo,WO_MAT_WAFER_QTY$,'X') InboundWaferQty += CassWfrQty NEXT I WMOutKeys = XLATE('WO_STEP',WONo:'*':WOStep,WO_STEP_WM_OUT_KEYS$,'X') IF WMOutKeys = '' THEN WMOStartBox = 1 WMOStartSlot = 1 END ELSE LastBoxOut = WMOutKeys[-1,'B':@VM] LastWMORec = XLATE('WM_OUT',LastBoxOut,'','X') LastBoxLastSlot = LastWMORec[-1,'B':@VM] IF LastBoxLastSlot < CassLoadQty THEN WMOStartBox = FIELD(LastBoxOut,'*',3) ;* Start IN the last box WMOStartSlot = LastBoxLastSlot + 1 ;* Start with first slot past current and less than Load Qty END ELSE WMOStartBox = FIELD(LastBoxOut,'*',3) + 1 ;* Start with next box WMOStartSlot = 1 ;* Start with first slot END END WMOCassNo = WMOStartBox WMOSlotNo = WMOStartSlot OutOnlyCassIDs = '' ;* List of Outbound only Cassette IDs added 8/12/1011 JCH LOOP UNTIL InboundWaferQty = 0 WMOutKey = WONo:'*':WOStep:'*':WMOCassNo WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') ;* In case there is a partial box NewBoxFlag = '' IF WMOutRec = '' THEN NewBoxFlag = 1 ELSE NewBoxFlag = 0 IF NewBoxFlag THEN WMOutRec = PromiseShipDt WMOutRec = SubPostClean ;**************************************************** WMOutRec = 1 ;* Default InCleanRoom flag = 1 END FOR S = WMOSlotNo TO CassLoadQty IF WMOutRec = '' THEN WMOutRec = S InboundWaferQty -= 1 END UNTIL InboundWaferQty = 0 NEXT S LastSlotUsed = S ******** Added 4/23/2010 JCH ******** CheckWOMat = XLATE('WO_MAT',WONo:'*':WMOCassNo,'','X') IF CheckWOMat = '' THEN obj_WO_Mat('CreateWMO',WONo:@RM:WMOCassNo:@RM:LastSlotUsed) ;* Creates "shell" WO_MAT record with the signature profile in it. OutOnlyCassIDs<1,-1> = WONo:'*':WMOCassNo ;* Added 8/12/2011 JCH END Done = False$ NumAttempts = 0 Loop NumAttempts += 1 Database_Services('WriteDataRow', 'WM_OUT', WMOutKey, WMOutRec) If Error_Services('HasError') then // Log the error LogData = '' LogData<1> = LoggingDTM LogData<2> = Error_Services('GetMessage') LogData<3> = NumAttempts LogData<4> = WONo LogData<5> = WOStep LogData<6> = WMOCassNo Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM) end else LogData = '' LogData<1> = LoggingDTM LogData<2> = 'Success' LogData<3> = NumAttempts LogData<4> = WONo LogData<5> = WOStep LogData<6> = WMOCassNo Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM) Done = True$ end Until ( (NumAttempts EQ 10) or (Done EQ True$) ) Repeat WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey) If WMOutRec EQ '' then // Record did not write to the database LogData = '' LogData<1> = LoggingDTM LogData<2> = WMOutKey LogData<3> = WMOutRec LogData<4> = 'Record does not exist after obj_WM_OUT("Create") call.' Machine = Environment_Services('GetServer') If Machine NE 'MESSA01EC' then EmailAddr = 'dstieber@srpcs.com,6613649828@txt.att.net' EmailMsg = 'WM_OUT record ':WMOutKey:' does not exist after obj_WM_OUT("Create") call.' Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$, EmailAddr, EmailMsg) end else Logging_Services('AppendLog', objReleaseLog, LogData, @RM, @FM, False$) end end WMOCassNo += 1 WMOSlotNo = 1 REPEAT Result = OutOnlyCassIDs RETURN * * * * * * * Delete: * * * * * * * WMOutKeys = Parms[1,@RM] IF WMOutKeys = '' THEN RETURN Set_Status(0) WMoParms = 'WM_OUT' LockedWMOutKeys = '' FOR I = 1 TO COUNT(WMOutKeys,@VM) + (WMOutKeys NE '') WMOutKey = WMOutKeys<1,I> WMoParms = FieldStore(WMoParms, @RM, 2, 1, WMOutKey) obj_Tables('LockRec',WMoParms) IF Get_Status(errCode) THEN FOR N = 1 TO COUNT(LockedWMOutKeys,@VM) + (LockedWMOutKeys NE '') WMiParms = FieldStore(WMoParms, @RM, 2, 1, LockedWMOutKeys<1,N>) obj_Tables('UnlockRec',WMoParms) ;* Unlock everything locked up to here NEXT N ErrorMsg = 'Unable to lock WM_OUT ':QUOTE(WMOutKey):' for delete.' RETURN END ELSE LockedWMOutKeys<1,I> = WMOutKey END NEXT I TableVar = FIELD(WMoParms,@RM,3,1) FOR I = 1 TO COUNT(WMOutKeys,@VM) + (WMOutKeys NE '') WMOutKey = WMOutKeys<1,I> WMoParms = 'WM_OUT':@RM:WMOutKey:@RM:TableVar:@RM obj_Tables('DeleteRec',WMoParms) ;* Deletes and removes the lock NEXT I RETURN * * * * * * * CurrStatus: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] WOMatRec = Parms[COL2()+1,@RM] //IF WMOutKey EQ '170964*1*18' then debug IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') * Check for completion or abnormal condition IF WMOutRec = 1 THEN Result = 'VOID' RETURN END CurrLocation = '' IF WOMatRec = '' THEN WONo = WMOutKey[1,'*'] CassNo = WMOutKey[-1,'B*'] WOMatKey = WONo:'*':CassNo WOMatRec = XLATE('WO_MAT',WOMatKey,'','X') CurrLocation = XLATE('WO_MAT',WOMatKey,'CURR_LOCATION','X') END IF WOMatRec = 1 AND WOMatRec = 'WM_OUT' THEN Result = 'HOLD' ;* Box is on Hold RETURN END IF WMOutRec NE '' THEN Result = 'SHIP' RETURN END NCRStatuses = XLATE('NCR',WMOutRec,7,'X') IF INDEX(NCRStatuses,'O',1) THEN Result = 'NCR' ;* Open NCR associated with box RETURN End * Check for sequential status points SlotCount = 0 FillCount = 0 NCRCount = 0 FOR I = 1 TO COUNT(WMOutRec,@VM) + (WMOutRec NE '') SlotNo = WMOutRec RDSNo = WMOutRec SlotNCRNo = WMOutRec IF SlotNo NE '' THEN SlotCount += 1 IF RDSNo NE '' AND SlotNo NE '' THEN FillCount += 1 ;* 5/6/2010 JCH IF SlotNCRNo NE '' THEN NCRCount += 1 NEXT I IF NCRCount = SlotCount AND FillCount = 0 AND WMOutRec NE 1 THEN RejectFlag = 1 END ELSE RejectFlag = 0 END StepID = '' SigArray = Signature_Services('GetSigProfile', WOMatKey) SigProfile = SigArray<1> Signatures = SigArray<2> SigDtms = SigArray<3> ProfCnt = COUNT(SigProfile,@VM) + (SigProfile NE '') * Section new on 12/8/2011 JCH IF RejectFlag = 1 THEN IF Signatures<1,ProfCnt> NE '' THEN * This is the final QA signature - nothing else matters Result = 'REJ' END ELSE Result = 'RQA' END RETURN END FOR I = 1 TO ProfCnt Signature = Signatures<1,I> StepID = SigProfile<1,I> UNTIL Signature = '' NEXT I FinalQASig = '' PostCleanSig = '' PostInspSig = '' PostScanSig = '' BEGIN CASE CASE StepID[-2,2] = 'QA' ; FinalQASig = Signature CASE StepID[-4,4] = 'PSTC' ; PostCleanSig = Signature CASE StepID[-4,4] = 'PSTI' ; PostInspSig = Signature CASE StepID[-4,4] = 'PSTS' ; PostScanSig = Signature END CASE CutOffDtm = ICONV('11/17/2015 23:59:59','DT') ;* New status start at midnight on this day IF FinalQASig NE '' THEN IF WMOutRec = 1 THEN IF FillCount > 0 THEN Result = 'RTU' END ELSE Result = 'MT' END * This is a check to see if the box has been "Emptied" by the system admin so it can be disposed of. * Used to move obsolete M/U boxes out of the system * DKK & JCH 10/2/2014 IF Result = 'RTU' THEN LocCnt = COUNT(WOMatRec,@VM) + (WOMatRec NE '') FOR I = 1 TO LocCnt ChkLoc = WOMatRec ChkAction = WOMatRec IF ChkLoc = 'MU' AND ChkAction = 'EMPTY' THEN Result = 'MT' END NEXT I END END ELSE LastLoc = WOMatRec[-1,'B':@VM] LastWH = WOMatRec[-1,'B':@VM] CurrLoc = '' IF LastWH NE '' AND LastLoc NE '' THEN CurrLoc = LastWH:'*':LastLoc IF WMOutRec = 1 THEN Begin Case Case CurrLoc EQ 'CR*PKO' Result = 'PKO' Case CurrLoc EQ 'CR*PACK' Result = 'PACK' Case Otherwise$ Result = 'COMP' End Case END ELSE CurrDTM = ICONV(OCONV( Date(), 'D4/' ):' ':OCONV( Time(), 'MTS' ), 'DT' ) Result = 'RTS' END END RETURN END IF FillCount = SlotCount THEN Result = StepID[-1,'B':'_'] END IF FillCount = 0 THEN Result = 'RTB' ;* Ready to Build RETURN END IF FillCount < SlotCount THEN Result = 'BLD' ;* Building RETURN END RETURN * * * * * * * CRComp: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] WOMatRec = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') * Check for completion or abnormal condition IF WOMatRec = '' THEN WONo = WMOutKey[1,'*'] CassNo = WMOutKey[-1,'B*'] WOMatKey = WONo:'*':CassNo WOMatRec = XLATE('WO_MAT',WOMatKey,'','X') END SlotCount = 0 FillCount = 0 NCRCount = 0 RecSlotCnt = COUNT(WMOutRec,@VM) + (WMOutRec NE '') FOR I = 1 TO RecSlotCnt IF WMOutRec NE '' THEN SlotCount += 1 IF WMOutRec NE '' THEN FillCount += 1 IF WMOutRec NE '' THEN NCRCount += 1 NEXT I Result = 1 IF WMOutRec NE 1 AND (NCRCount NE SlotCount) THEN IF WOMatRec = 1 AND WOMatRec = 'WM_OUT' THEN Result = 0 ;* Box is on Hold NCRStatuses = XLATE('NCR',WMOutRec,7,'X') IF INDEX(NCRStatuses,'O',1) THEN Result = 0 ;* Open NCR associated with box IF WMOutRec = '' THEN Result = 0 IF WMOutRec = 1 THEN Result = 0 END RETURN * * * * * * * NextOpenSlots: * * * * * * * WONo = Parms[1,@RM] WOStep = Parms[COL2()+1,@RM] CassNos = Parms[COL2()+1,@RM] IF WONo = '' THEN ErrorMsg = 'Null Parameter "WONo" passed to routine. (':Method:')' IF WOStep = '' THEN ErrorMsg = 'Null Parameter "WOStep" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF CassNos = '' THEN OPEN 'DICT.WM_OUT' TO DictVar ELSE ErrorMsg = 'Unable to open "DICT.WM_OUT" in obj_WM_Out' RETURN END SearchString = 'WO_NO':@VM:WONo:@FM Flag = '' Btree.Extract(SearchString, 'WM_OUT', DictVar, WMOKeys, '', Flag) IF Get_Status(errCode) THEN RETURN END FOR I = 1 TO COUNT(WMOKeys,@VM) + (WMOKeys NE '') CassNo = WMOKeys<1,I>[-1,'B*'] If CassNo NE '' then LOCATE CassNo IN CassNos BY 'AR' USING @VM SETTING Pos ELSE CassNos = INSERT(CassNos,1,Pos,0,CassNo) END end NEXT I END CassCnt = COUNT(CassNos,@VM) + (CassNos NE '') * Start Counting at the last box and work backward FOR I = CassCnt TO 1 STEP -1 CassNo = CassNos<1,I> WMOutRec = XLATE('WM_Out',WONo:'*':WOStep:'*':CassNo,'','X') SlotCnt = COUNT(WMOutRec,@VM) + (WMOutRec NE '') IsMULot = WMOutRec EQ True$ IsFQASigned = WMOutRec NE '' IsVoided = WMOutRec If Not(IsMULot) AND Not(IsFQASigned) AND Not(IsVoided) then FOR N = SlotCnt TO 1 STEP -1 IF WMOutRec NE '' AND WMOutRec = '' AND WMOutRec = '' AND WMOutRec = '' THEN SlotNo = WMOutRec IF NOT(RowExists('WMO_WFRS',WONo:'*':WOStep:'*':CassNo:'*':SlotNo)) THEN ;* Check for 'LOCK' in WMO_WFRS table Result = INSERT(Result,1,0,0,I:@VM:N) ;* Plate-o-lator (LIFO) style END END NEXT N end NEXT I RETURN * * * * * * * SlotStatus: * * * * * * * WONo = Parms[1,@RM] WOStep = Parms[COL2()+1,@RM] CassNos = Parms[COL2()+1,@RM] IF WONo = '' THEN ErrorMsg = 'Null Parameter "WONo" passed to routine. (':Method:')' IF WOStep = '' THEN ErrorMsg = 'Null Parameter "WOStep" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF CassNos = '' THEN OPEN 'DICT.WM_OUT' TO DictVar ELSE ErrorMsg = 'Unable to open "DICT.WM_OUT" in obj_WM_Out' RETURN END SearchString = 'WO_NO':@VM:WONo:@FM Flag = '' Btree.Extract(SearchString, 'WM_OUT', DictVar, WMOKeys, '', Flag) IF Get_Status(errCode) THEN RETURN END FOR I = 1 TO COUNT(WMOKeys,@VM) + (WMOKeys NE '') CassNo = WMOKeys<1,I>[-1,'B*'] LOCATE CassNo IN CassNos BY 'AR' USING @VM SETTING Pos ELSE CassNos = INSERT(CassNos,1,Pos,0,CassNo) END NEXT I END CassCnt = COUNT(CassNos,@VM) + (CassNos NE '') * Start Counting at the last box and work backward FOR I = CassCnt TO 1 STEP -1 CassNo = CassNos<1,I> WMOutRec = XLATE('WM_Out',WONo:'*':WOStep:'*':CassNo,'','X') SlotCnt = COUNT(WMOutRec,@VM) + (WMOutRec NE '') FOR N = SlotCnt TO 1 STEP -1 IF WMOutRec NE '' AND WMOutRec = '' AND WMOutRec = '' AND WMOutRec = '' THEN SlotNo = WMOutRec IF NOT(RowExists('WMO_WFRS',WONo:'*':WOStep:'*':CassNo:'*':SlotNo)) THEN ;* Check for 'LOCK' in WMO_WFRS table Result = INSERT(Result,1,0,0,I:@VM:N:@VM:'Open') ;* Plate-o-lator (LIFO) style END ELSE LockRec = XLATE('WMO_WFRS',WONo:'*':WOStep:'*':CassNo:'*':SlotNo,'','X') LockBy = LockRec Workstation = LockRec LockedAt = OCONV(LockRec,'DT/2^S') Result = INSERT(Result,1,0,0,I:@VM:N:@VM:'Locked':@VM:LockBy:@VM:Workstation:@VM:LockedAt) END END ELSE Result = INSERT(Result,1,0,0,I:@VM:N:@VM:'Filled') END NEXT N NEXT I RETURN * * * * * * * AddWafer: * * * * * * * WONo = Parms[1,@RM] WOStep = Parms[COL2()+1,@RM] CassNo = Parms[COL2()+1,@RM] SlotNos = Parms[COL2()+1,@RM] RDSNos = Parms[COL2()+1,@RM] PocketNos = Parms[COL2()+1,@RM] Zones = Parms[COL2()+1,@RM] InCassNos = Parms[COL2()+1,@RM] InSlotNos = Parms[COL2()+1,@RM] PrevNCRs = Parms[COL2()+1,@RM] MUWONos = Parms[COL2()+1,@RM] MUSteps = Parms[COL2()+1,@RM] MUCassIDs = Parms[COL2()+1,@RM] MUSlots = Parms[COL2()+1,@RM] IF WONo = '' THEN ErrorMsg = 'Null Parameter "WONo" passed to routine. (':Method:')' IF WOStep = '' THEN ErrorMsg = 'Null Parameter "WOStep" passed to routine. (':Method:')' IF CassNo = '' THEN ErrorMsg = 'Null Parameter "CassNo" passed to routine. (':Method:')' IF SlotNos = '' THEN ErrorMsg = 'Null Parameter "SlotNos" passed to routine. (':Method:')' IF RDSNos = '' THEN ErrorMsg = 'Null Parameter "RDSNos" passed to routine. (':Method:')' IF PocketNos = '' THEN ErrorMsg = 'Null Parameter "PocketNos" passed to routine. (':Method:')' IF Zones = '' THEN ErrorMsg = 'Null Parameter "Zones" passed to routine. (':Method:')' IF InCassNos = '' THEN ErrorMsg = 'Null Parameter "InCassNos" passed to routine. (':Method:')' IF InSlotNos = '' THEN ErrorMsg = 'Null Parameter "InSlotNos" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:WONo:'*':WOStep:'*':CassNo WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WONo:'*':WOStep:'*':CassNo) IF Get_Status(errCode) THEN RETURN SlotCnt = COUNT(SlotNos,@VM) + (SlotNos NE '') NewFlag = 1 FOR I = 1 TO SlotCnt IF WMOutRec NE '' THEN NewFlag = 0 IF WMOutRec THEN NewFlag = 0 IF WMOutRec THEN NewFlag = 0 UNTIL NOT(NewFlag) NEXT I CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') IF NewFlag THEN obj_Post_Log('Create','WO_MAT':@RM:WONo:'*':CassNo:@RM:WO_MAT_WMO_LOAD_DTM$:@RM:ICONV(CurrDTM,'DT')) END LastSlotNo = WMOutRec[-1,'B':@VM] LastSlot = 0 LastRDSNo = '' LastReactNo = '' WfrIDs = '' NewSlotIDs = '' FOR I = 1 TO SlotCnt SlotNo = SlotNos<1,I> IF SlotNo = LastSlotNo THEN LastSlot = 1 LastRDSNo = RDSNos<1,I> LastReactNo = XLATE('REACT_RUN',LastRDSNo,REACT_RUN_REACTOR$,'X') END LOCATE SlotNo IN WMOutRec USING @VM SETTING Pos THEN ReactNo = XLATE('RDS',RDSNos<1,I>,RDS_REACTOR$,'X') WMOutRec = RDSNos<1,I> WMOutRec = PocketNos<1,I> WMOutRec = Zones<1,I> WMOutRec = InCassNos<1,I> WMOutRec = InSlotNos<1,I> WMOutRec = PrevNCRs<1,I> ;* Clears NCR number when called from the NCR delete event WMOutRec = MUWONos<1,I> WMOutRec = MUSteps<1,I> WMOutRec = MUCassIDs<1,I> WMOutRec = MUSlots<1,I> WfrIDs<1,-1> = WONo:'*':InCassNos<1,I>:'*':InSlotNos<1,I> NewSlotIDs<1,-1> = WONo:'*':CassNo:'*':SlotNo * * * * Added 3/22/2016 JCH - wafer history * * * * Parms = WONo:'*':InCassNos<1,I>:'*':InSlotNos<1,I>:@RM ;* WfrID Parms := CurrDTM:@RM ;* EventDtm Parms := @USER4:@RM ;* EventBy Parms := 'UNLOAD':@RM ;* Event Parms := WONo:'*':CassNo:'*':SlotNo:@RM ;* NewSlotID Parms := '':@RM ;* RunLoc Parms := '':@RM ;* NCRNo Parms := '':@RM ;* TWUse Parms := '':@RM ;* CurrSlotID Parms := '':@RM ;* NewToolID (Load Tool) Parms := 'R':ReactNo:@RM ;* CurrToolID (Unload Tool) Parms := '':@RM ;* NewInvLoc Parms := '':@RM ;* CurrInvLoc Parms := 'O' ;* Wfr Side obj_WO_Wfr('AddEvent',Parms) END NEXT I otParms = FieldStore(otParms,@RM,4,0,WMOutRec) ;* Put record in 4th field of OtParms Database_Services('WriteDataRow', 'WM_OUT', WONo:'*':WOStep:'*':CassNo, WMOutRec, True$, False$, True$) If Error_Services('NoError') then IF LastSlot = 1 THEN CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') EpiReactNo = obj_WM_Out('EpiReactNo',WONo:'*':WOStep:'*':CassNo:@RM:WMOutRec) IF EpiReactNo NE '' THEN ReactWH = XLATE('REACTOR',EpiReactNo,'TOOL_WH','X') ReactLoc = XLATE('REACTOR',EpiReactNo,'TOOL_LOC','X') END ELSE ReactWH = '' ReactLoc = '' END LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM LogDTM = CurrDTM ; WOMLParms := LogDTM:@RM Action = WOStep:'UNLOAD' ; WOMLParms := Action:@RM WhCd = ReactWH ; WOMLParms := WhCd:@RM LocCd = ReactLoc ; WOMLParms := LocCd:@RM WONos = WONo ; WOMLParms := WONos:@RM CassNos = CassNo ; WOMLParms := CassNos:@RM UserID = @USER4 ; WOMLParms := UserID:@RM Tags = '' ; WOMLParms := Tags:@RM ToolID = 'R':EpiReactNo ; WOMLParms := ToolID obj_WO_Mat_Log('Create',WOMLParms) ;* Stage PSTC log entry IF Get_Status(errCode) THEN RETURN END END ;* End of check for Box Full end RETURN * * * * * * * RemoveWafer: * * * * * * * WONo = Parms[1,@RM] WOStep = Parms[COL2()+1,@RM] CassNo = Parms[COL2()+1,@RM] SlotNos = Parms[COL2()+1,@RM] IF WONo = '' THEN ErrorMsg = 'Null Parameter "WONo" passed to routine. (':Method:')' IF WOStep = '' THEN ErrorMsg = 'Null Parameter "WOStep" passed to routine. (':Method:')' IF CassNo = '' THEN ErrorMsg = 'Null Parameter "CassNo" passed to routine. (':Method:')' IF SlotNos = '' THEN ErrorMsg = 'Null Parameter "SlotNos" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN WMOKey = WONo:'*':WOStep:'*':CassNo WMOutRec = Database_Services('ReadDataRow', 'WM_OUT', WMOKey) IF Get_Status(errCode) THEN RETURN ;* Added 2/24/2009 JCH FOR I = 1 TO COUNT(SlotNos,@VM) + (SlotNos NE '') SlotNo = SlotNos<1,I> LOCATE SlotNo IN WMOutRec USING @VM SETTING Pos THEN WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' END NEXT I Database_Services('WriteDataRow', 'WM_OUT', WMOkey, WMOutRec, True$, False$, True$) RETURN * * * * * * * AddShip: * * * * * * * WMOutKey = Parms[1,@RM] ShipNo = Parms[COL2()+1,@RM] Reship = Parms[COL2()+1,@RM] If Reship EQ '' then Reship = False$ end IF NOT(ASSIGNED(WMOutKey)) THEN ErrorMsg = 'Unassigned Parm "WMOutKey" passed to routine. (':Method:')' IF NOT(ASSIGNED(ShipNo)) THEN ErrorMsg = 'Unassigned Parm "ShipNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF WMOutKey = '' THEN ErrorMsg = 'Null Parm "WMOutKey" passed to routine. (':Method:')' IF ShipNo = '' THEN ErrorMsg = 'Null Parm "ShipNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock IF WMOutRec = '' OR WMOutRec = ShipNo or Reship EQ True$ THEN WMOutRec = ShipNo otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) END ELSE obj_Tables('UnlockRec',otParms) ErrorMsg = "WM_OUT Cassette was already shipped on shipment" :QUOTE(WMOutRec): ". (" :Method: ")" END // Update work order SHIP_QTY_STATIC WONo = Field(WMOutKey, '*', 1) Work_Order_Services('UpdateShippedQty', WONo) RETURN * * * * * * * RemShip: * * * * * * * WMOutKey = Parms[1,@RM] ShipNo = Parms[COL2()+1,@RM] IF NOT(ASSIGNED(WMOutKey)) THEN ErrorMsg = 'Unassigned Parm "WMOutKey" passed to routine. (':Method:')' IF NOT(ASSIGNED(ShipNo)) THEN ErrorMsg = 'Unassigned Parm "ShipNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF WMOutKey = '' THEN ErrorMsg = 'Null Parm "WMOutKey" passed to routine. (':Method:')' IF ShipNo = '' THEN ErrorMsg = 'Null Parm "ShipNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock IF WMOutRec = ShipNo OR WMOutRec = '' THEN WMOutRec = '' otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) END ELSE obj_Tables('UnlockRec',otParms) ErrorMsg = "Passed Ship No " :QUOTE(ShipNo): " doesn't match Ship No on WM_OUT record " :QUOTE(WMOutKey): ". (" :Method: ")" END RETURN * * * * * * * ClearLoad: * * * * * * * * The nuclear option for getting the RDS unload and WM_OUT load data back in sync. WMOutKey = Parms[1,@RM] IF NOT(ASSIGNED(WMOutKey)) THEN ErrorMsg = 'Unassigned Parm "WMOutKey" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock Makeups = WMOutRec NCRs = WMOutRec UMWs = WMOutRec CONVERT @VM TO '' IN Makeups CONVERT @VM TO '' IN NCRs CONVERT @VM TO '' IN UMWs IF Makeups NE '' THEN ErrorMsg = 'Cassette has makeup wafers in it.' IF NCRs NE '' THEN ErrorMsg = 'Cassette has NCR records attached.' IF UMWs NE '' THEN ErrorMsg = 'Cassette has wafers used for makeups removed from it.' IF ErrorMsg NE '' THEN obj_Tables('UnlockRec',otParms) RETURN END SlotCnt = COUNT(WMOutRec,@VM) + (WMOutRec NE '') FOR Slot = 1 TO SlotCnt WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' NEXT Slot otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) RETURN * * * * * * * RDSSlots: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') RDSNos = '' SlotRanges = '' FOR I = 1 TO COUNT(WMOutRec,@VM) + (WMOutRec NE '') RDSNo = WMOutRec SlotNo = WMOutRec IF RDSNo NE '' THEN LOCATE RDSNo IN RDSNos USING @VM SETTING Pos THEN SlotRange = SlotRanges<1,Pos> Start = SlotRange[1,'-'] SlotRanges<1,Pos> = Start:'-':SlotNo END ELSE RDSNos = INSERT(RDSNos,1,Pos,0,RDSNo) SlotRanges = INSERT(SlotRanges,1,Pos,0,SlotNo) END END NEXT I Result = RDSNos:@FM:SlotRanges RETURN * * * * * * * InCassData: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') WONo = WMOutKey[1,'*'] InWOCassettes = '' ;*Structure to hold WO*InCassNo pairs InLotNos = '' InPartNos = '' InSubPartNos = '' FOR I = 1 TO COUNT(WMOutRec,@VM) + (WMOutRec NE '') InCassette = WMOutRec IF InCassette NE '' THEN MUWONo = WMOutRec IF MUWONo = '' THEN ItemWONo = WONo END ELSE ItemWONo = MUWONo END WOMatRec = XLATE('WO_MAT',ItemWONo:'*':InCassette,'','X') LotNo = WOMatRec PartNo = WOMatRec SubPartNo = WOMatRec IF LotNo NE '' THEN SortKey = ItemWONo:'*':InCassette LOCATE SortKey IN InWOCassettes USING @VM SETTING Pos ELSE InWOCassettes = INSERT(InWOCassettes,1,Pos,0,SortKey) InLotNos = INSERT(InLotNos,1,Pos,0,LotNo) InPartNos = INSERT(InPartNos,1,Pos,0,PartNo) InSubPartNos = INSERT(InSubPartNos,1,Pos,0,SubPartNo) END END END NEXT I Result = InWOCassettes:@FM:InLotNos:@FM:InPartNos:@FM:InSubPartNos RETURN * * * * * * * AddMakeupWafers: * * * * * * * * Places makeup wafers into a production cassette WMOutKey = Parms[1,@RM] EmptySlots = Parms[COL2()+1,@RM] MakeupBox = Parms[COL2()+1,@RM] IF NOT(ASSIGNED(WMOutKey)) THEN ErrorMsg = 'Unassigned Parm "WMOutKey" passed to routine. (':Method:')' IF NOT(ASSIGNED(EmptySlots)) THEN ErrorMsg = 'Unassigned Parm "EmptySlots" passed to routine. (':Method:')' IF NOT(ASSIGNED(MakeupBox)) THEN ErrorMsg = 'Unassigned Parm "MakeupBox" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF WMOutKey = '' THEN ErrorMsg = 'Null Parm "WMOutKey" passed to routine. (':Method:')' IF EmptySlots = '' THEN ErrorMsg = 'Null Parm "EmptySlots" passed to routine. (':Method:')' IF MakeupBox = '' THEN ErrorMsg = 'Null Parm "MakeupBox" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock MakeupWaferData = obj_WM_Out('RemMakeupWafers',MakeUpBox:@RM:EmptySlots:@RM:WMOutKey) ;* Extracts and returns slot data from Makeup Box IF Get_Status(errCode) THEN RETURN IF MakeupWaferData = '' THEN RETURN MakeupWONo = MakeupBox[1,'*'] MakeupWOStep = MakeupBox[COL2()+1,'*'] MakeupCassNo = MakeupBox[COL2()+1,'*'] MakeupBy = @USER4 FOR I = 1 TO COUNT(EmptySlots,@VM) + (EmptySlots NE '') UNTIL MakeupWaferData = '' SlotNo = EmptySlots<1,I> WMOutRec = SlotNo WMOutRec = MakeupWONo WMOutRec = MakeupWOStep WMOutRec = MakeupCassNo WMOutRec = MakeupBy ;* Added 10/6/2010 JCH WMOutRec = MakeupWaferData WMOutRec = MakeupWaferData WMOutRec = MakeupWaferData WMOutRec = MakeupWaferData WMOutRec = MakeupWaferData WMOutRec = MakeupWaferData WMOutRec = MakeupWaferData NEXT I otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) RETURN * * * * * * * SubMakeupWafers: * * * * * * * * Subtracts makeup wafers from a production box for return to the makeup box WMOutKey = Parms[1,@RM] MadeupSlots = Parms[COL2()+1,@RM] IF NOT(ASSIGNED(WMOutKey)) THEN ErrorMsg = 'Unassigned Parm "WMOutKey" passed to routine. (':Method:')' IF NOT(ASSIGNED(MadeupSlots)) THEN ErrorMsg = 'Unassigned Parm "MadeupSlots" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF WMOutKey = '' THEN ErrorMsg = 'Null Parm "WMOutKey" passed to routine. (':Method:')' IF MadeupSlots = '' THEN ErrorMsg = 'Null Parm "MadeupSlots" passed to routine. (':Method:')' otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') WfrIDs = '' NewSlotIDs = '' CurrSlotIDs = '' SMData = '' FOR I = 1 TO COUNT(MadeupSlots,@VM) + (MadeupSlots NE '') MadeupSlot = MadeupSlots<1,I> SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec SMData = WMOutRec // KLUSA Timestamp Makeup Wafer Project // Delete most recent "added" DTM from WMOutRec AddedDTMS = WMOutRec AddedDTMS = Delete(AddedDTMS, 1, 1, 1) WMOutRec = AddedDTMS * * * * Added 5/11/2016 JCH - wafer history * * * * WfrID = WMOutRec:'*':WMOutRec:'*':WMOutRec NewSlotID = WMOutRec:'*':WMOutRec:'*':WMOutRec CurrSlotID = FIELD(WMOutKey,'*',1,1):'*':FIELD(WMOutKey,'*',3,1):'*':MadeupSlot WfrIDs<1,-1> = WfrID ;* Added 9/7/2016 JCH NewSlotIDs<1,-1> = NewSlotId ;* Added 9/7/2016 JCH CurrSlotIDs<1,-1> = CurrSlotId ;* Added 9/7/2016 JCH Parms = WfrID:@RM ;* WfrID Parms := CurrDTM:@RM ;* EventDtm Parms := @USER4:@RM ;* EventBy Parms := 'RMKUP':@RM ;* Event Parms := NewSlotID:@RM ;* NewSlotID Parms := '':@RM ;* RunLoc Parms := '':@RM ;* NCRNo Parms := '':@RM ;* TWUse Parms := CurrSlotID:@RM ;* CurrSlotID Parms := '':@RM ;* NewToolID Parms := '':@RM ;* CurrToolID Parms := '':@RM ;* NewInvLoc Parms := '':@RM ;* CurrInvLoc Parms := 'O' ;* Wfr Side obj_WO_Wfr('AddEvent',Parms) * * * * End of wafer history update * * * * WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' ;* Added 10/6/2010 JCH * WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' WMOutRec = '' ;* Added 03/14/2017 FDR * NEXT I otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) Result = SMData RETURN * * * * * * * RemMakeupWafers: * * * * * * * * Removes wafers from a makeup box for use as makeups in a production box MUBoxKey = Parms[1,@RM] EmptySlots = Parms[COL2()+1,@RM] TargetBoxKey = Parms[COL2()+1,@RM] IF NOT(ASSIGNED(MUBoxKey)) THEN ErrorMsg = 'Unassigned Parm "MUBoxKey" passed to routine. (':Method:')' IF NOT(ASSIGNED(EmptySlots)) THEN ErrorMsg = 'Unassigned Parm "EmptySlots" passed to routine. (':Method:')' IF NOT(ASSIGNED(TargetBoxKey)) THEN ErrorMsg = 'Unassigned Parm "TargetBoxKey" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF MUBoxKey = '' THEN ErrorMsg = 'Null Parm "MUBoxKey" passed to routine. (':Method:')' IF EmptySlots = '' THEN ErrorMsg = 'Null Parm "EmptySlot" passed to routine. (':Method:')' IF TargetBoxKey = '' THEN ErrorMsg = 'Null Parm "TargetBoxKey" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:MUBoxKey MU_WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock CONVERT '*' TO '.' IN TargetBoxKey ReqWfrCnt = COUNT(EmptySlots,@VM) + (EmptySlots NE '') ResCnt = 0 SlotCnt = COUNT(MU_WMOutRec,@VM) + (MU_WMOutRec NE '') CurrDate = OCONV(Date(),'D4/') CurrTime = OCONV(Time(),'MTHS') CurrDTM = CurrDate:' ':CurrTime WfrIDs = '' ;* Added 9/7/2016 JCH NewSlotIDs = '' ;* Added 9/7/2016 JCH CurrSlotIDs = '' ;* Added 9/7/2016 JCH FOR I = 1 TO SlotCnt IF MU_WMOutRec NE '' THEN ;* This line changed from WM_OUT_SLOT_NO$ to WM_OUT_RDS ResCnt += 1 * * * * Added 3/28/2016 JCH - wafer history * * * * WfrID = FIELD(MUBoxKey,'*',1,1):'*':MU_WMOutRec:'*':MU_WMOutRec NewSlotID = FIELD(TargetBoxKey,'.',1,1):'*':FIELD(TargetBoxKey,'.',3,1):'*':EmptySlots<1,ResCnt> CurrSlotID = FIELD(MUBoxKey,'*',1,1):'*':FIELD(MUBoxKey,'*',3,1):'*':MU_WMOutRec WfrIDs<1,-1> = WfrID ;* Added 9/7/2016 JCH NewSlotIDs<1,-1> = NewSlotID ;* Added 9/7/2016 JCH CurrSlotIDs<1,-1> = CurrSlotID ;* Added 9/7/2016 JCH Parms = WfrID:@RM ;* WfrID Parms := CurrDTM:@RM ;* EventDtm Parms := @USER4:@RM ;* EventBy Parms := 'MKUP':@RM ;* Event Parms := NewSlotID:@RM ;* NewSlotID Parms := '':@RM ;* RunLoc Parms := '':@RM ;* NCRNo Parms := '':@RM ;* TWUse Parms := CurrSlotID:@RM ;* CurrSlotID Parms := '':@RM ;* NewToolID Parms := '':@RM ;* CurrToolID Parms := '':@RM ;* NewInvLoc Parms := '':@RM ;* CurrInvLoc Parms := 'O' ;* Wfr Side obj_WO_Wfr('AddEvent',Parms) * * * * End of wafer history update * * * * Result = MU_WMOutRec ; *MU_WMOutRec = '' ;******* 4/16/2014 JCH ******* Leave Slot Nos in place Result = MU_WMOutRec ; MU_WMOutRec = '' Result = MU_WMOutRec ; MU_WMOutRec = '' Result = MU_WMOutRec ; MU_WMOutRec = '' Result = MU_WMOutRec ; MU_WMOutRec = '' Result = MU_WMOutRec ; MU_WMOutRec = '' MU_WMOutRec = TargetBoxKey MU_WMOutRec = EmptySlots<1,ResCnt> // Timestamp MU Wafer Project // Append makeup wafer removed datetime to the beginning of @VM for the available slot number. Dates will be // @SVM delimited. Note only the most recent datetime will be displayed on the form. DateTime = Date() : '.' : Time() // Grab previous removed dates. (e.g. makeup wafer that became a makeup wafer) AddedDTMS = MU_WMOutRec // Insert this datetime to result record to use in AddMakeupWafers routine Result = Insert(AddedDTMS, 0, 0, 1, DateTime) // Append "removed" datetime to MU wafer record RemovedDTMS = MU_WMOutRec RemovedDTMS = Insert(RemovedDTMS, 1, 1, 1, DateTime) MU_WMOutRec = RemovedDTMS END UNTIL ResCnt = ReqWfrCnt NEXT I otParms = FIELDSTORE(otParms,@RM,4,0,MU_WMOutRec) obj_Tables('WriteRec',otParms) WONo = FIELD(MUBoxKey,'*',1) CassNo = FIELD(MUBoxKey,'*',3) FillCnt = 0 FOR I = 1 TO SlotCnt SlotNo = MU_WMOutRec RDSNo = MU_WMOutRec IF RDSNo NE '' AND SlotNo NE '' THEN FillCnt += 1 NEXT I IF FillCnt = 0 THEN WOMatInvActions = XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_INV_ACTION$,'X') LOCATE 'EMPTY' IN WOMatInvActions USING @VM SETTING Dummy ELSE CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTHS') LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM LogDTM = CurrDTM ; WOMLParms := LogDTM:@RM Action = 'EMPTY' ; WOMLParms := Action:@RM WhCd = 'CR' ; WOMLParms := WhCd:@RM LocCd = 'MU' ; WOMLParms := LocCd:@RM WONos = WONo ; WOMLParms := WONos:@RM CassNos = CassNo ; WOMLParms := CassNos:@RM UserID = @USER4 ; WOMLParms := UserID:@RM Tags = '' ; WOMLParms := Tags:@RM ToolID = '' ; WOMLParms := ToolID obj_WO_Mat_Log('Create',WOMLParms) ;* Stage PSTC log entry IF Get_Status(errCode) THEN ErrMsg(errCode) END END END RETURN * * * * * * * RepMakeupWafers: * * * * * * * * Replaces makeup wafers into a makeup box. Used when returning makeups from a production box. WMOutKey = Parms[1,@RM] SMData = Parms[COL2()+1,@RM] ;* Data structure for wafers subtracted from production box IF NOT(ASSIGNED(WMOutKey)) THEN ErrorMsg = 'Unassigned Parm "WMOutKey" passed to routine. (':Method:')' IF NOT(ASSIGNED(SMData)) THEN ErrorMsg = 'Unassigned Parm "SMData" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN IF WMOutKey = '' THEN ErrorMsg = 'Null Parm "WMOutKey" passed to routine. (':Method:')' IF SMData = '' THEN ErrorMsg = 'Null Parm "SMData" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN MadeupBoxKey = WMOutKey CONVERT '*' TO '.' IN MadeupBoxKey FOR I = 1 TO COUNT(SMData,@FM) + (SMData NE '') MU_WONo = SMData MU_WOStep = SMData MU_WOCassNo = SMData MU_WOSlotNo = SMData MU_RDSNo = SMData MU_Pocket = SMData MU_Zone = SMData MU_InCassNo = SMData MU_InSlotNo = SMData MU_BoxKey = MU_WONo:'*':MU_WOStep:'*':MU_WOCassNo otParms = 'WM_OUT':@RM:MU_BoxKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) ELSE IF WMOutRec = MadeupBoxKey THEN WMOutRec = MU_WOSlotNo WMOutRec = MU_RDSNo WMOutRec = MU_Pocket WMOutRec = MU_Zone WMOutRec = MU_InCassNo WMOutRec = MU_InSlotNo WMOutRec = '' WMOutRec = '' // Delete most recent "removed" DTM RemovedDTMS = WMOutRec RemovedDTMS = Delete(RemovedDTMS, 1, 1, 1) WMOutRec = RemovedDTMS END otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) END NEXT I RETURN * * * * * * * CassRDSNos: * * * * * * * WMOutKeys = Parms[1,@RM] IF WMOutKeys = '' THEN RETURN RDSNos = XLATE('WM_OUT',WMOutKeys,WM_OUT_RDS$,'X') Result = '' FOR I = 1 TO COUNT(RDSNos,@VM) + (RDSNos NE '') LOCATE RDSNos<1,I> IN Result BY 'AR' USING @VM SETTING Pos ELSE Result = INSERT(Result,1,Pos,0,RDSNos<1,I>) END NEXT I RETURN * * * * * * * CassRDSWfrCnts: * * * * * * * WMOutKeys = Parms[1,@RM] IF WMOutKeys = '' THEN RETURN OutRDSNos = XLATE('WM_OUT',WMOutKeys,WM_OUT_RDS$,'X') RDSNos = '' Result = '' FOR I = 1 TO COUNT(OutRDSNos,@VM) + (OutRDSNos NE '') LOCATE OutRDSNos<1,I> IN RDSNos BY 'AR' USING @VM SETTING Pos THEN Result<1,Pos> = Result<1,Pos> + 1 END ELSE RDSNos = INSERT(RDSNos,1,Pos,0,OutRDSNos<1,I>) Result = INSERT(Result,1,Pos,0,1) END NEXT I RETURN * * * * * * * GetPartNoQtys: * * * * * * * WMOutKeys = Parms[1,@RM] IF WMOutKeys = '' THEN RETURN AllPartNos = '' AllPartQtys = '' PrevWONo = '' FOR I = 1 TO COUNT(WMOutKeys,@VM) + (WMOutKeys NE '') WMOutKey = WMOutKeys<1,I> WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') WONo = WMOutKey[1,'*'] InCassNos = WMOutRec FOR L = 1 TO COUNT(InCassNos,@VM) + (InCassNos NE '') InCassNo = InCassNos<1,L> MUWONo = WMOutRec MUCassNo = WMOutRec IF InCassNo NE '' THEN IF MUWONo NE '' THEN PartNo = XLATE('WO_MAT',MUWONo:'*':MUCassNo,WO_MAT_CUST_PART_NO$,'X') END ELSE PartNo = XLATE('WO_MAT',WONo:'*':InCassNo,WO_MAT_CUST_PART_NO$,'X') END LOCATE PartNo IN AllPartNos USING @VM SETTING PartPos THEN AllPartQtys<1,PartPos> = AllPartQtys<1,PartPos> + 1 END ELSE AllPartNos = INSERT(AllPartNos,1,PartPos,0,PartNo) AllPartQtys = INSERT(AllPartQtys,1,PartPos,0,1) END END NEXT L NEXT I Result = AllPartNos:@FM:AllPartQtys RETURN * * * * * * * GetLotNos: * * * * * * * WMOutKeys = Parms[1,@RM] IF WMOutKeys = '' THEN RETURN AllLotNos = '' FOR I = 1 TO COUNT(WMOutKeys,@VM) + (WMOutKeys NE '') WMOutKey = WMOutKeys<1,I> WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') WONo = WMOutKey[1,'*'] MUWONo = WMOutRec IF MUWONo = '' THEN ItemWONo = WONo ELSE ItemWONo = MUWONo InCassNos = WMOutRec FOR L = 1 TO COUNT(InCassNos,@VM) + (InCassNos NE '') InCassNo = InCassNos<1,L> MUWONo = WMOutRec IF MUWONo = '' THEN ItemWONo = WONo ELSE ItemWONo = MUWONo IF InCassNo NE '' THEN LotNo = XLATE('WO_MAT',ItemWONo:'*':InCassNo,WO_MAT_LOT_NO$,'X') LOCATE LotNo IN AllLotNos USING @VM SETTING LotPos ELSE AllLotNos = INSERT(AllLotNos,1,LotPos,0,LotNo) END END NEXT L NEXT I Result = AllLotNos RETURN * * * * * * * GetOrderItems: * * * * * * * WMOutKeys = Parms[1,@RM] IF WMOutKeys = '' THEN RETURN AllOrderItems = '' FOR I = 1 TO COUNT(WMOutKeys,@VM) + (WMOutKeys NE '') WMOutKey = WMOutKeys<1,I> WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') WONo = WMOutKey[1,'*'] InCassNos = WMOutRec FOR L = 1 TO COUNT(InCassNos,@VM) + (InCassNos NE '') InCassNo = InCassNos<1,L> MUWONo = WMOutRec IF InCassNo NE '' AND MUWONo = '' THEN OrderItem = XLATE('WO_MAT',WONo:'*':InCassNo,WO_MAT_ORDER_ITEM$,'X') LOCATE OrderItem IN AllOrderItems USING @VM SETTING InsPos ELSE AllOrderItems = INSERT(AllOrderItems,1,InsPos,0,OrderItem) END END NEXT L NEXT I Result = AllOrderItems RETURN * * * * * * * NCRNos: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') SlotNCRs = WMOutRec FOR I = 1 TO COUNT(SlotNCRs,@VM) + (SlotNCRs NE '') SlotNCR = SlotNCRs<1,I> IF SlotNCR NE '' THEN LOCATE SlotNCR IN Result BY 'AR' USING @VM SETTING Pos ELSE Result = INSERT(Result,1,Pos,0,SlotNCR) END END NEXT I RETURN * * * * * * * RebuildLoad: * * * * * * * WMOutID = Parms[1,@RM] IF WMOutID = '' THEN RETURN WONo = WMOutID[1,'*'] ProcStep = WMOutID[COL2()+1,'*'] OutCassNo = WMOutID[COL2()+1,'*'] Update_Index ("RDS", "WO", "") Extract_SI_Keys( 'RDS', 'WO', WONo, RDSNos ) ;* Original Code WOBoxCnt = COUNT( RDSNos, @VM ) + ( RDSNos NE '' ) FOR I = 1 TO WOBoxCnt RDSNo = RDSNos<1,I> RDSRec = XLATE('RDS',RDSNo,'','X') IF FIELD(WMOutID,'*',1,2) = RDSRec THEN A = RDSRec IF INDEX(RDSRec,OutCassNo,1) THEN otParms = 'WM_OUT':@RM:WMOutID WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock NCRKeys = WMOutRec FOR N = 1 TO COUNT(RDSRec,@VM) + (RDSRec NE '') IF RDSRec = OutCassNo THEN OutSlotNo = RDSRec WMOutRec = OutSlotNo WMOutRec = RDSNo WMOutRec = RDSRec WMOutRec = RDSRec WMOutRec = RDSRec WMOutRec = RDSRec END NEXT N WMOutRec = NCRKeys otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) END END NEXT I RETURN * * * * * * * RemSlots: * * * * * * * WMOutKey = Parms[1,@RM] RemSlots = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN ErrorMsg = 'Null Parm "WMOutKey" passed to routine. (':Method:')' IF RemSlots = '' THEN ErrorMsg = 'Null Parm "RemSlots" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN ErrorMsg = 'Unable to open WM_OUT Record for RemSlots' RETURN END RemCnt = COUNT(RemSlots,@VM) + (RemSlots NE '') FOR I = 1 TO RemCnt RemSlot = RemSlots<1,I> LOCATE RemSlot IN WMOutRec USING @VM SETTING Pos THEN WMOutRec = DELETE(WMOutRec,WM_OUT_SLOT_NO$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_RDS$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_POCKET$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_ZONE$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_IN_CASS_NO$ ,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_IN_SLOT_NO$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_MU_WO_NO$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_MU_WO_STEP$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_MU_CASS_NO$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_MU_SLOT_NO$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_UMW_CASS_ID$ ,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_UMW_SLOT_NO$,Pos,0) WMOutRec = DELETE(WMOutRec,WM_OUT_SLOT_NCR$,Pos,0) END NEXT I otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) RETURN * * * * * * * WfrsOut: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') RDSNos = WMOutRec SlotNos = WMOutRec MakeupBox = WMOutRec IF MakeupBox = 1 THEN Result = 0 END ELSE Result = '' END RDSCnt = COUNT(RDSNos,@VM) + (RDSNos NE '') FOR I = 1 TO RDSCnt IF RDSNos<1,I> NE '' AND SlotNos<1,I> NE '' THEN Result += 1 NEXT I RETURN * * * * * * * EpiReactNo: * * * * * * * WMOutKey = Parms[1,@RM] WMOutRec = Parms[COL2()+1,@RM] IF WMOutKey = '' THEN RETURN IF WMOutRec = '' THEN WMOutRec = XLATE('WM_OUT',WMOutKey,'','X') SlotCnt = COUNT(WMOutRec,@VM) + (WMOutRec NE '') AllRDSNos = '' AllRDSCnts = '' FOR I = 1 TO SlotCnt SlotRDS = WMOutRec IF SlotRDS NE '' AND WMOutRec = '' THEN LOCATE SlotRDS IN AllRDSNos USING @VM SETTING Pos THEN AllRdsCnts<1,Pos> = AllRdsCnts<1,Pos> + 1 END ELSE AllRdsNos = Insert(AllRdsNos,1,Pos,0,SlotRds) AllRdsCnts = Insert(AllRdsCnts,1,Pos,0,1) END END NEXT I AllCnt = COUNT(AllRdsCnts,@VM) + (AllRdsCnts NE '') BigRDS = '' BigCnt = '' FOR I = 1 TO AllCnt IF AllRdsCnts<1,I> > BigCnt THEN BigCnt = AllRdsCnts<1,I> BigRDS = AllRdsNos<1,I> END NEXT I Result = XLATE('REACT_RUN',BigRDS,REACT_RUN_REACTOR$,'X') RETURN Result * * * * * * * ConvertCleanInsp: * * * * * * * WONo = Parms[1,@RM] WOStep = Parms[COL2()+1,@RM] CassNo = Parms[COL2()+1,@RM] IF WONo = '' THEN ErrorMsg = 'Null Parm "WONo" passed to routine. (':Method:')' IF WOStep = '' THEN ErrorMsg = 'Null Parm "WOStep" passed to routine. (':Method:')' IF CassNo = '' THEN ErrorMsg = 'Null Parm "CassNo" passed to routine. (':Method:')' IF ErrorMsg NE '' THEN RETURN WMOutKey = WONo:'*':WOStep:'*':CassNo otParms = 'WM_OUT':@RM:WMOutKey WMOutRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock IF Get_Status(errCode) THEN ErrorMsg = 'Unable to open WM_OUT Record for update.(':Method:')' RETURN END CINo = XLATE('WO_MAT',WONo:'*':CassNo,WO_MAT_EPO_CI_NO$,'X') WMOutRec = CINo otParms = FIELDSTORE(otParms,@RM,4,0,WMOutRec) obj_Tables('WriteRec',otParms) IF Get_Status(errCode) THEN ErrorMsg = 'Unable to open WM_OUT Record for update.(':Method:')' RETURN END obj_Tables('UnlockRec',otParms) ;* Unlock the WM_OUT record cotParms = 'CLEAN_INSP':@RM:CINo CIRec = obj_Tables('ReadRec',cotParms) ;* Reads and sets lock IF Get_Status(errCode) THEN ErrorMsg = 'Unable to open CLEAN_INSP Record for update.(':Method:')' RETURN END CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec CIRec = WMOutRec SurfScanKey = WONO:'*':WOStep:'*':CassNo:'*':'PC' SurfScanRec = XLATE('SURFACE_SCAN',SurfScanKey,'','X') IF SurfScanRec NE '' THEN CIRec = SurfScanRec CIRec = SurfScanRec CIRec = SurfScanRec CIRec = SurfScanRec CIRec = SurfScanRec CIRec = SurfScanRec CIRec = SurfScanRec CIRec = SurfScanRec END cotParms = FIELDSTORE(cotParms,@RM,4,0,CIRec) obj_Tables('WriteRec',cotParms) IF Get_Status(errCode) THEN ErrorMsg = 'Unable to Write updated CLEAN_INSP record.(':Method:')' RETURN END RETURN