COMPILE FUNCTION obj_GaN_Test(Method,Parms) /* GaN Reports 7/26/2016 JCH Initial Coding Methods: GetStatus ;* Returns GaN processing overview status */ DECLARE SUBROUTINE Btree.Extract, Set_Status, Send_Dyn, Btree.Extract, V119, ErrMsg DECLARE FUNCTION obj_React_Run $INSERT POPUP_EQUATES $INSERT LOGICAL $INSERT WO_LOG_EQUATES $INSERT REACT_RUN_EQUATES $INSERT RUN_STAGE_EQUATES $INSERT RUN_STAGE_WFR_EQUATES $INSERT TOOL_EQUATES $INSERT TOOL_CLASS_EQUATES $INSERT TOOL_WFR_EQUATES $INSERT LOCATION_EQUATES EQU COL$STAGE TO 1 EQU COL$RDS_NO TO 2 EQU COL$WFR_ID TO 3 EQU COL$WAIT_HRS TO 4 EQU COL$EPI_PART_NO TO 5 EQU COL$GAN_RUN_ID TO 6 EQU COL$TOOL_TYPE TO 7 EQU COL$WAIT_WFR_QTY TO 8 EQU COL$TOOL_ID TO 9 EQU COL$RUN_WFR TO 10 EQU COL$RUN_HRS TO 11 /* EQU COL$ TO 8 EQU COL$ TO 9 EQU COL$ TO 10 EQU COL$ TO 11 EQU COL$ TO 12 */ EQU CRLF$ TO \0D0A\ EQU TAB$ TO \09\ ErrTitle = 'Error in Stored Procedure "obj_GaN"' 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 = 'GetStatus' ; GOSUB GetStatus CASE Method = 'ToolWIP' ; GOSUB ToolWIP CASE 1 * Put an error message here! END CASE IF ErrorMsg NE '' THEN Set_Status(-1,ErrTitle:@SVM:ErrorMsg) RETURN '' END RETURN Result * * * * * * * GetStatus: * * * * * * * PopupLiteral = XLATE('SYSREPOSPOPUPS', @APPID<1>:'**':'GAN_WIP_STAGES',PDISPLAY$,'X') CONVERT @VM:@SVM TO @FM:@VM IN PopupLiteral OPEN 'DICT.REACT_RUN' TO DictReactRun ELSE ErrorMsg = 'Unable to open "DICT.REACT_RUN" for Btree.Extract' RETURN END OPEN 'DICT.RUN_STAGE' TO DictRunStage ELSE ErrorMsg = 'Unable to open "DICT.RUN_STAGE" for Btree.Extract' RETURN END OPEN 'DICT.RUN_STAGE_WFR' TO DictRunStageWfr ELSE ErrorMsg = 'Unable to open "DICT.RUN_STAGE_WFR" for Btree.Extract' RETURN END LineCnt = 0 StageCnt = COUNT(PopupLiteral,@FM) + (PopupLiteral NE '') Header = 'Stage':@VM ;* Column headers for export Header := 'RDS No':@VM Header := 'Wait Wfr IDs':@VM Header := 'Wait Hrs':@VM Header := 'EPI Part No':@VM Header := 'Run ID':@VM Header := 'Tool Class':@VM Header := 'Wait Cnt':@VM Header := 'Tool ID':@VM Header := 'Run Cnt':@VM Header := 'Run Hrs':@VM Header := 'Run Wfr IDs' LineCnt += 1 Result = Header FOR S = 1 TO StageCnt Stage = PopupLiteral StageDesc = PopupLiteral CharFlag = PopupLiteral ToolClass = PopupLiteral ToolIDs = XLATE('TOOL_CLASS',ToolClass,TOOL_CLASS_TOOL$,'X') StageRdsNos = '' StageWaitWfrIDs = '' StageRunWfrIDs = '' StageToolIDs = '' StageWaitTms = '' StageRunTms = '' StageWaitWfrCnts = '' StageRunWfrCnts = '' BEGIN CASE CASE Stage = 'SPLIT' QInWfrIDs = XLATE('LOCATION','GCH*Q_SP',LOCATION_WFR_ID$,'X') ToolClass = 'GCH*Q_SP' CASE Stage = 'DISP' QInWfrIDs = XLATE('LOCATION','GGR*Q_DISP',LOCATION_WFR_ID$,'X') ToolClass = 'GGR*Q_DISP' CASE 1 QInWfrIDs = XLATE('TOOL_CLASS',ToolClass,'QIN_WFR_ID','X') END CASE * Collect data from places the wafers are stored in LOCATION (Queues), TOOL_WFR (On Tool * * * * * Wafer Queues (LOCATION table) * * * * * RDSNos = XLATE('WO_WFR',QInWfrIDs,'RDS_NO','X') ;* Wafers in the Queue ElapTms = XLATE('WO_WFR',QInWfrIDs,'ELAP_TM','X') ;* Times since last event rCnt = COUNT(RDSNos,@VM) + (RDSNos NE '') FOR R = 1 TO rCnt RDSNo = RDSNos<1,R> ElapTm = ElapTms<1,R> QInWfrID = QInWfrIDs<1,R> LOCATE RDSNo IN StageRdsNos BY 'AR' USING @VM SETTING Pos THEN StageWaitWfrCnts<1,Pos> = StageWaitWfrCnts<1,Pos> + 1 StageWaitWfrIDs = INSERT(StageWaitWfrIDs,1,Pos,-1,QInWfrID) END ELSE StageWaitWfrCnts = INSERT(StageWaitWfrCnts,1,Pos,0,1) StageRDSNos = INSERT(StageRDSNos,1,Pos,0,RDSNo) StageWaitWfrIDs = INSERT(StageWaitWfrIDs,1,Pos,0,QINWfrID) StageToolIDs = INSERT(StageToolIDs,1,Pos,0,'') ;* Not on a tool this is the Queues StageWaitTms = INSERT(StageWaitTms,1,Pos,0,ElapTm) StageRunTms = INSERT(StageRunTms,1,Pos,0,'') END NEXT R * * * * * Tool Queues * * * * * tCnt = COUNT(ToolIDs,@VM) + (ToolIDs NE '') FOR T = 1 TO tCnt ToolID = ToolIDs<1,T> RunWfrIDs = XLATE('TOOL_WFR',ToolID,TOOL_WFR_WFR_ID$,'X') RDSNos = XLATE('WO_WFR',RunWfrIDs,'RDS_NO','X') ElapTms = XLATE('WO_WFR',RunWfrIDs,'ELAP_TM','X') rCnt = COUNT(RDSNos,@VM) + (RDSNos NE '') FOR R = 1 TO rCnt RDSNo = RDSNos<1,R> ElapTm = ElapTms<1,R> ToolWfrID = RunWfrIDs<1,R> LOCATE RDSNo IN StageRDSNos BY 'AR' USING @VM SETTING Pos THEN StageRunWfrCnts<1,Pos> = StageRunWfrCnts<1,Pos> + 1 StageRunWfrIDs = INSERT(StageRunWfrIDs,1,Pos,-1,ToolWfrID) END ELSE StageRunWfrCnts = INSERT(StageRunWfrCnts,1,Pos,0,1) StageRDSNos = INSERT(StageRDSNos,1,Pos,0,RDSNo) StageRunWfrIDs = INSERT(StageRunWfrIDs,1,Pos,0,ToolWfrID) StageToolIDs = INSERT(StageToolIDs,1,Pos,0,ToolID) StageWaitTms = INSERT(StageWaitTms,1,Pos,0,'') StageRunTms = INSERT(StageRunTms,1,Pos,0,ElapTm) END NEXT R NEXT T * * * * * Sort by DSND StageWaitTms SortArray = '' slCnt = COUNT(StageRDSNos,@VM) + (StageRDSNos NE '') FOR M = 1 TO slCnt SortLine = StageWaitTms<1,M>:@FM SortLine := StageRDSNos<1,M>:@FM SortLine := StageWaitWfrIDs<1,M>:@FM SortLine := StageRunWfrIDs<1,M>:@FM SortLine := StageToolIDs<1,M>:@FM SortLine := StageRunTms<1,M>:@FM SortLine := StageWaitWfrCnts<1,M>:@FM SortLine := StageRunWfrCnts<1,M> SortArray := SortLine:@RM NEXT M a = LEN(SortArray) V119('S','','D','R',SortArray,'') IF Get_Status(errCode) THEN ErrMsg(errCode) END StageWaitTms = '' StageRDSNos = '' StageWaitWfrIDs = '' StargeRunWfrIDs = '' StageToolIDs = '' StageRunTms = '' StageWaitWfrCnts = '' StageRunWfrCnts = '' Line = 0 LOOP SortLine = SortArray[1,@RM] SortArray[1,COL2()] = '' UNTIL SortLine = '' Line += 1 StageWaitTms<1,Line> = SortLine<1> StageRDSNos<1,Line> = SortLine<2> StageWaitWfrIDs<1,Line> = SortLine<3> StageRunWfrIDs<1,Line> = SortLine<4> StageToolIDs<1,Line> = SortLine<5> StageRunTms<1,Line> = SortLine<6> StageWaitWfrCnts<1,Line> = SortLine<7> StageRunWfrCnts<1,Line> = SortLine<8> REPEAT * Build the stage lines StageLineCnt = COUNT(StageRDSNos,@VM) + (StageRDSNos NE '') ;* All the RDS Nos in this stage Line = Stage:@VM:@VM:@VM:@VM:@VM:@VM:@VM:@VM:@VM ;* Stage on a blank line for separator LineCnt += 1 Result = Line For N = 1 TO StageLineCnt RDSNo = StageRDSNos<1,N> RDSRec = XLATE('REACT_RUN',RDSNo,'','X') EpiPartNo = XLATE('WO_LOG',RDSRec,WO_LOG_EPI_PART_NO$,'X') GanRunID = RDSRec WaitWfrIDs = StageWaitWfrIDs<1,N> RunWfrIDs = StageRunWfrIDs<1,N> IF INDEX(WaitWfrIDs,@SVM,1) THEN WaitWfrIDs = 'Multi' IF INDEX(RunWfrIDs,@SVM,1) THEN RunWfrIDs = 'Multi' Line = @VM ;* Place holder Line := RDSNo:@VM ;* RDSNo Line := WaitWfrIDs:@VM ;* Wafer ID Line := StageWaitTms<1,N>:@VM ;* Wait Times Line := EpiPartNo:@VM ;* EpiPartNo Line := GanRunID:@VM ;* GanRunID Line := ToolClass:@VM ;* Tool Class Line := StageWaitWfrCnts<1,N>:@VM ;* Wait Wfr Cnts Line := StageToolIDs<1,N>:@VM ;* Tool ID Line := StageRunWfrCnts<1,N>:@VM ;* Run Wfr Cnts Line := StageRunTms<1,N>:@VM ;* Run Times Line := RunWfrIDs ;* Run Wfr IDs LineCnt += 1 Result = Line NEXT N NEXT S RETURN * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ToolWIP: * * * * * * * PopupLiteral = XLATE('SYSREPOSPOPUPS', @APPID<1>:'**':'GAN_WIP_STAGES',PDISPLAY$,'X') CONVERT @VM:@SVM TO @FM:@VM IN PopupLiteral OPEN 'DICT.REACT_RUN' TO DictReactRun ELSE ErrorMsg = 'Unable to open "DICT.REACT_RUN" for Btree.Extract' RETURN END OPEN 'DICT.RUN_STAGE' TO DictRunStage ELSE ErrorMsg = 'Unable to open "DICT.RUN_STAGE" for Btree.Extract' RETURN END OPEN 'DICT.RUN_STAGE_WFR' TO DictRunStageWfr ELSE ErrorMsg = 'Unable to open "DICT.RUN_STAGE_WFR" for Btree.Extract' RETURN END LineCnt = 0 StageCnt = COUNT(PopupLiteral,@FM) + (PopupLiteral NE '') Header = 'Stage':@VM ;* Column headers for export Header := 'Runs':@VM Header := 'Tot Runs':@VM Header := 'RDS No':@VM Header := 'EPI Part No':@VM Header := 'Run ID':@VM Header := 'State':@VM Header := 'Wfr Cnt':@VM Header := 'Tool Type':@VM Header := 'Tool ID' LineCnt += 1 Result = Header FOR S = 1 TO StageCnt Stage = PopupLiteral StageDesc = PopupLiteral CharFlag = PopupLiteral ToolClass = PopupLiteral QInWfrIDs = XLATE('TOOL_CLASS',ToolClass,'QIN_WFR_ID','X') RDSNos = XLATE('WO_WFR',QInWfrIDs,'RDS_NO','X') /* IF CharFlag = 1 THEN Search = 'GAN_WFR_STAGE':@VM:Stage:@FM Btree.Extract(Search,'RUN_STAGE_WFR',DictRunStageWfr,RunStageWfrKeys,'','') rskCnt = COUNT(RunStageWfrKeys,@VM) + (RunStageWfrKeys NE '') StageRdsNos = '' StageEpiPartNos = '' StageGanRunIDs = '' StageStates = '' StageToolIDs = '' RdsWfrCnts = '' StageWfrCnt = 0 FOR I = 1 TO rskCnt RunStageWfrKey = RunStageWfrKeys<1,I> RunStageWfrRec = XLATE('RUN_STAGE_WFR',RunStageWfrKey,'','X') ToolID = RunStageWfrRec RDSNo = RunStageWfrKey[1,'*'] CompBy = RunStageWfrRec SigProfs = RunStageWfrRec ;* Specified Inventory Actions Signatures = RunStageWfrRec ;* Inv Action Complete signature spCnt = COUNT(SigProfs,@VM) + (SigProfs NE '') sCnt = COUNT(Signatures,@VM) + (Signatures NE '') State = '' IF spCnt = 2 THEN StartSig = Signatures<1,1> EndSig = Signatures<1,2> BEGIN CASE CASE EndSig NE '' ; State = 'Comp' CASE StartSig NE '' ; State = 'Run' CASE 1 ; State = 'Wait' END CASE END QInWfrIDs = XLATE('RUN_STAGE_WFR',RunStageWfrKey,'QIN_WFR_ID','X') QInQty = COUNT(QInWfrIDs,@VM) + (QInWfrIDs NE '') RDSNo = RunStageWfrKey[1,'*'] RDSRec = XLATE('REACT_RUN',RDSNo,'','X') EpiPartNo = XLATE('WO_LOG',RDSRec,WO_LOG_EPI_PART_NO$,'X') GanRunID = RDSRec LOCATE RDSNo IN StageRdsNos BY 'AR' USING @VM SETTING Pos THEN RDSWfrCnts<1,Pos> = RDSWfrCnts<1,Pos> + 1 END ELSE StageRdsNos = INSERT(StageRdsNos,1,Pos,0,RDSNo) StageEpiPartNos = INSERT(StageEpiPartNos,1,Pos,0,EpiPartNo) StageGanRunIDs = INSERT(StageGanRunIDs,1,Pos,0,GanRunID) StageStates = INSERT(StageStates,1,Pos,0,State) StageToolIDs = INSERT(StageToolIDs,1,Pos,0,ToolID) RdsWfrCnts = INSERT(RdsWfrCnts,1,Pos,0,1) END StageWfrCnt += WfrCnt NEXT I StageWfrCnt = SUM(RdsWfrCnts) StageLineCnt = Count(StageRDSNos,@VM) + (StageRDSNos NE '') IF StageLineCnt = 0 THEN Line = Stage:@VM:@VM:@VM:@VM:@VM:@VM:@VM:@VM LineCnt += 1 Result = Line END ELSE For N = 1 TO StageLineCnt IF N = 1 THEN Line = Stage:@VM ;* Stage Line := '':@VM ;* Active Runs Line := StageLineCnt:@VM ;* Total Runs END ELSE Line = '':@VM Line := '':@VM Line := '':@VM END Line := StageRdsNos<1,N>:@VM ;* RDSNo Line := StageEpiPartNos<1,N>:@VM ;* EpiPartNo Line := StageGanRunIDs<1,N>:@VM ;* GanRunID Line := StageStates<1,N>:@VM ;* State Line := RdsWfrCnts<1,N>:@VM ;* RdsWfrCnt Line := ToolType:@VM ;* Tool Type for this stage Line := StageToolIDs<1,N> ;* Tool ID LineCnt += 1 Result = Line NEXT N END END ELSE IF Stage = 'DISP' THEN ToolType = '' Search = 'DISP_WFRS':@VM:1:@FM Btree.Extract(Search,'REACT_RUN',DictReactRun,RDSNos,'','') StageRdsNos = '' StageEpiPartNos = '' StageGanRunIDs = '' StageStates = '' StageToolIDs = '' RdsWfrCnts = '' StageWfrCnt = 0 rnCnt = COUNT(RDSNos,@VM) + (RDSNos NE '') FOR I = 1 TO rnCnt RDSNo = RDSNos<1,I> RDSRec = XLATE('REACT_RUN',RDSNo,'','X') EpiPartNo = XLATE('WO_LOG',RDSRec,WO_LOG_EPI_PART_NO$,'X') GanRunID = RDSRec CarrWfrs = RDSRec CONVERT @VM TO ' ' IN CarrWfrs CarrWfrs = TRIM(CarrWfrs) CONVERT ' ' TO @VM IN CarrWfrs WfrCnt = COUNT(CarrWfrs,@VM) + (CarrWfrs NE '') LOCATE RDSNo IN StageRdsNos BY 'AR' USING @VM SETTING Pos THEN RDSWfrCnts<1,Pos> = RDSWfrCnts<1,Pos> + WfrCnt END ELSE StageRdsNos = INSERT(StageRdsNos,1,Pos,0,RDSNo) StageEpiPartNos = INSERT(StageEpiPartNos,1,Pos,0,EpiPartNo) StageGanRunIDs = INSERT(StageGanRunIDs,1,Pos,0,GanRunID) StageStates = INSERT(StageStates,1,Pos,0,'') StageToolIDs = INSERT(StageToolIDs,1,Pos,0,'') RdsWfrCnts = INSERT(RdsWfrCnts,1,Pos,0,WfrCnt) END StageWfrCnt += WfrCnt NEXT I END ELSE Search = 'GAN_STAGE':@VM:Stage:@FM Btree.Extract(Search,'RUN_STAGE',DictRunStage,StageKeys,'','') StageRdsNos = '' StageEpiPartNos = '' StageGanRunIDs = '' StageStates = '' StageToolIDs = '' RdsWfrCnts = '' StageWfrCnt = 0 skCnt = COUNT(StageKeys,@VM) + (StageKeys NE '') FOR I = 1 TO skCnt StageKey = StageKeys<1,I> RunStageRec = XLATE('RUN_STAGE',StageKey,'','X') ToolType = RunStageRec ToolID = RunStageRec QInWfrIDs = XLATE('RUN_STAGE',StageKey,'QIN_WFR_ID','X') SigProfs = RunStageRec ;* Specified Inventory Actions Signatures = RunStageRec ;* Inv Action Complete signature spCnt = COUNT(SigProfs,@VM) + (SigProfs NE '') sCnt = COUNT(Signatures,@VM) + (Signatures NE '') State = '' IF spCnt = 2 THEN StartSig = Signatures<1,1> EndSig = Signatures<1,2> BEGIN CASE CASE EndSig NE '' ; State = 'Comp' CASE StartSig NE '' ; State = 'Run' CASE 1 ; State = 'Wait' END CASE END RDSNo = StageKey[1,'*'] RDSRec = XLATE('REACT_RUN',RDSNo,'','X') EpiPartNo = XLATE('WO_LOG',RDSRec,WO_LOG_EPI_PART_NO$,'X') GanRunID = RDSRec WfrCnt = COUNT(RDSRec,@VM) + (RDSRec NE '') LOCATE RDSNo IN StageRdsNos BY 'AR' USING @VM SETTING Pos THEN RDSWfrCnts<1,Pos> = RDSWfrCnts<1,Pos> + WfrCnt END ELSE StageRdsNos = INSERT(StageRdsNos,1,Pos,0,RDSNo) StageEpiPartNos = INSERT(StageEpiPartNos,1,Pos,0,EpiPartNo) StageGanRunIDs = INSERT(StageGanRunIDs,1,Pos,0,GanRunID) StageStates = INSERT(StageStates,1,Pos,0,State) StageToolIDs = INSERT(StageToolIDs,1,Pos,0,ToolID) RdsWfrCnts = INSERT(RdsWfrCnts,1,Pos,0,WfrCnt) END StageWfrCnt += WfrCnt NEXT I END ;* End of check for DISPO stage StageWfrCnt = SUM(RdsWfrCnts) StageLineCnt = Count(StageRDSNos,@VM) + (StageRDSNos NE '') IF StageLineCnt = 0 THEN Line = Stage:@VM:@VM:@VM:@VM:@VM:@VM:@VM:@VM LineCnt += 1 Result = Line END ELSE FOR N = 1 TO StageLineCnt IF N = 1 THEN Line = Stage:@VM ;* Stage Line := '':@VM ;* Active Runs Line := StageLineCnt:@VM ;* Total Runs END ELSE Line = '':@VM Line := '':@VM Line := '':@VM END Line := StageRdsNos<1,N>:@VM ;* RDSNo Line := StageEpiPartNos<1,N>:@VM ;* EpiPartNo Line := StageGanRunIDs<1,N>:@VM ;* GanRunID Line := StageStates<1,N>:@VM ;* State Line := RdsWfrCnts<1,N>:@VM ;* RdsWfrCnt Line := ToolType:@VM ;* Tool Type for this stage Line := StageToolIDs<1,N> LineCnt += 1 Result = Line NEXT N END ;* End of check for 0 StageLineCnt END */ NEXT S RETURN