Compile function NDW_GAN_RDS_PROD_DEMO_EVENTS(CtrlEntId, Event, @PARAMS) /*********************************************************************************************************************** Name : NDW_GAN_RDS_PROD_DEMO_EVENTS Description : Commuter module for the NDW_GAN_RDS_PROD_DEMO form. Notes : Application errors should be logged using the Error Services module. There are a few methodological assumptions built into way errors are managed which are important to understand in order to properly work with Error Services: - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger this will appear backwards since the originating procedure always appears at the bottom of the list and the current routine appears at the top of the list. We are using this orientation because it is common to refer to the process of calling other procedures as 'drilling down'. - The reason for defining the orientation of the call stack is because Error_Services allows for multiple error conditions to be appended to an original error. In most cases this will happen when a procedure at the bottom of the stack generates an error condition and then returns to its calling procedure. This higher level procedure can optionally add more information relevant to itself. This continues as the call stack 'bubbles' its way back to the top to where the originating procedure is waiting. - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus) preserve their error state until explicitly cleared. This can hinder the normal execution of code since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists. Our philosophy is that error conditions should automatically be cleared before a new procedure is executed to avoid this problem. However, the nature of Basic+ does not make this easy to automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our philosophy then it should include a call into the 'Clear' service request at the top of the program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.) - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any error conditions that were set before. Parameters : Service [in] -- Name of the service being requested Param1-10 [in/out] -- Additional request parameter holders Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure Metadata : History : (Date, Initials, Notes) 01/19/21 djs Original programmer. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #window NDW_GAN_RDS_PROD_DEMO DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, Center_Window, Post_Event, SRP_EditTable_Manager DECLARE SUBROUTINE ErrMsg, Send_Message, Set_Property, Send_Event, Btree.Extract, obj_AppWindow, SRP_Show_Window DECLARE SUBROUTINE obj_Notes, Security_Err_Msg, End_Window, Forward_Event, Start_Window, Create_Note, Excel_Services DECLARE SUBROUTINE obj_RDS_Test, Print_Control_Plan, Print_RDS_Instruction, Send_Info, Post_Event, Database_Services DECLARE SUBROUTINE obj_Run_Stage_Wfr, obj_WO_Wfr, obj_Run_Stage, GaN_Services, Utility, SRP_Stopwatch, COMM_NCR DECLARE SUBROUTINE Dialog_Box, Get_Status, Logging_Services, Unlock, Error_Services, Disposition_Services DECLARE SUBROUTINE Engineering_Services DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, Utility, Center_Window, Popup, Collect.Ixvals, Security_Services DECLARE FUNCTION Send_Message, Msg, Security_Check, RowExists, NextKey, obj_React_Esc, obj_React_Run, Form_Services DECLARE FUNCTION obj_RDS_Test, MemberOf, Create_Dialog, obj_Popup, obj_WO_Wfr, SRP_EditTable_Manager, Database_Services DECLARE FUNCTION Obj_Run_Stage, Obj_Run_Stage_Wfr, Gan_Services, SRP_Array, DateTime, Error_Services, Obj_NCR DECLARE FUNCTION Memory_Services, SRP_Get_Window_Rect, Excel_Services, Environment_Services, Logging_Services DECLARE FUNCTION SRP_Date $INSERT APPCOLORS $INSERT RTI_STYLE_EQUATES $INSERT EVENT_SETUP $INSERT MSG_EQUATES $INSERT LSL_USERS_EQU $INSERT SECURITY_RIGHTS_EQU $INSERT REACT_EVENT_EQUATES $INSERT REACT_RUN_EQUATES $INSERT WO_STEP_EQU $INSERT WO_MAT_EQUATES $INSERT WO_WFR_WIP_EQUATES $INSERT EPI_SUSCEPTOR_EQUATES $INSERT REACTOR_EQUATES $INSERT POPUP_EQUATES $INSERT TOOL_CLASS_EQUATES $INSERT RUN_STAGE_EQUATES $INSERT LOCATION_EQUATES $INSERT RUN_STAGE_WFR_EQUATES $INSERT WO_WFR_EQUATES $INSERT SRP_POPUP_EQUATES $INSERT LOGICAL $INSERT WO_LOG_EQUATES $INSERT GAN_PARAMS_EQUATES $INSERT GAN_PARAM_CONFIG_EQUATES $INSERT NCR_EQUATES // Cassette / Wafer Action Combo Box Selections EQU COMBO_X$ TO 1 EQU COMBO_START$ TO 2 EQU COMBO_STOP$ TO 3 EQU COMBO_COMP$ TO 4 EQU COMBO_PART$ TO 5 EQU COL$CHAR_WFR_ID TO 1 EQU COL$SCRIBE TO 2 EQU COL$SPLIT_BY TO 3 EQU COL$SPLIT_DTM TO 4 EQU COL$CURR_STAGE TO 5 EQU COL$CHAR_DEST TO 6 EQU COL$CHAR_TW_NO TO 7 EQU COL$CHAR_WFR_STATUS TO 8 EQU COL$CARR_SLOG_NO TO 1 EQU COL$CARR_WFR_ID TO 2 EQU COL$CARR_SCRIBE TO 3 EQU COL$CARR_CHAR_FLAG TO 4 EQU COL$CARR_NCR TO 5 EQU COL$CARR_GRADE TO 6 EQU COL$SIG_PROF TO 1 EQU COL$SIGNATURE TO 2 EQU COL$SIG_DTM TO 3 EQU COL$STAGE_COMMENT TO 4 EQU COL$STAGE_STATUS TO 5 EQU COL$MET_STAGE TO 1 EQU COL$MET_TOOL_ID TO 2 // Disposition OLE Edit Table EQU COL$DISP_SLOT TO 1 EQU COL$DISP_WFR_ID TO 2 EQU COL$DISP_SCRIBE TO 3 EQU COL$DISP_GRADE TO 4 EQU COL$DISP_REASON TO 5 EQU COL$DISP_ROOT_CAUSE TO 6 EQU COL$DISP_RDS_NCR TO 7 EQU COL$DISP_WMO_NCR TO 8 EQU COL$DISP_SHIP_ID TO 9 EQU COL$DISP_RETAIN_BOX TO 10 EQU COL$DISP_RETAIN_SLOT TO 11 // NCR OLE Edit Table EQU COL$NCR_NO TO 1 EQU COL$NCR_STATUS TO 2 EQU COL$NCR_REJ_QTY TO 3 EQU COL$NCR_RESP TO 4 EQU COL$NCR_STAGE TO 5 EQU COL$NCR_LOSS_DESC TO 6 EQU COL$NCR_LOSS_COMM TO 7 EQU COL$NCR_FIN_SIG TO 8 EQU COL$NCR_FIN_SIG_DTM TO 9 EQU COL$SUSC_LOAD_WFR_ID TO 6 ;* SUSC_LOAD control EQU COL$SUSC_LOAD_WFR_SCRIBE TO 7 EQU EDITABLE$ TO 4 EQU PROTECTED$ TO 8 ;* Protected - Edittable COLSTYLE constants EQU MULTILINE_STYLE$ TO 512 ;* MultiLine Select EQU LOCKED$ TO 8192 EQU DROPDOWN_STYLE$ TO 131072 LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\GaNWIP' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' GaN WIP Log.csv' Headers = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'Username' : @FM : 'Notes' objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM 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 else // Event not implemented end Return EventFlow or 1 //----------------------------------------------------------------------------- // EVENT HANDLERS //----------------------------------------------------------------------------- Event WINDOW.CREATE(CreateParam) GoSub PopulateControls SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, '', 1) End Event Event WINDOW.CLOSE(CancelFlag) obj_Notes('Inbox',@USER4) ;* Checks for any new messages end event Event WINDOW.OMNIEVENT(Message, Param1, Param2, Param3, Param4) Begin Case Case Message _EQC 'FillDispEditTable' GoSub FillDispEditTable Case Message _EQC 'FillNCREditTable' GoSub FillNCREditTable End Case end event Event CMB_GAN_RUN_ID.CHANGED(NewData) If NewData NE '' then GaNRunID = NewData ReactorNo = Get_Property(@Window, '@REACTOR') GaNRunInfo = Gan_Services('GetRunInfo', GaNRunID) Recipe = GaNRunInfo<1,1> SuscSerialNo = GaNRunInfo<2,1> SPCWaferTrackPart = GaNRunInfo<6,1> Set_Property(@Window:'.EDL_WAFER_TRACK_PART', 'TEXT', SPCWaferTrackPart) Set_Property(@Window:'.OLE_REACTOR_EDT', "OLE.HeaderText[1; 2]", 'Reactor ':ReactorNo) WOLogOpenInsightPart = Get_Property(@Window:'.EPI_PART_NO', 'TEXT') Convert @Lower.Case to @Upper.Case in GaNRunID SchedWaferTrackPart = Xlate('GAN_SCHEDULE', GaNRunID, 'WAFER_TRACK_PART', 'X') SchedOpenInsightPart = Xlate('GAN_SCHEDULE', GaNRunID, 'OPENINSIGHT_PART', 'X') // OpenInsightPart Verification If SchedOpenInsightPart NE WOLogOpenInsightPart then Set_Property(@Window:'.EPI_PART_NO', 'BACKCOLOR', RED$) end else Set_Property(@Window:'.EPI_PART_NO', 'BACKCOLOR', GREEN$) end // WaferTrackPart Verification If SchedWaferTrackPart NE SPCWaferTrackPart then Set_Property(@Window:'.EDL_WAFER_TRACK_PART', 'BACKCOLOR', RED$) end else Set_Property(@Window:'.EDL_WAFER_TRACK_PART', 'BACKCOLOR', GREEN$) end Set_Property(@Window, '@GANRUNINFO', GaNRunInfo) Set_Property(@Window : '.GAN_RECIPE', 'TEXT', Recipe) Set_Property(@Window : '.GAN_SUSC_SERIAL', 'TEXT', SuscSerialNo) GoSub VerifyRecipe end end event Event CMB_GAN_ETCH_ID.CHANGED(NewData) ExternalEtchID = NewData Begin Case Case (ExternalEtchID _EQC 'No Etch Required') Set_Property(@Window : '.ETCH_RECIPE', 'TEXT', 'Not Applicable') Case (ExternalEtchID NE '') and (ExternalEtchID _NEC 'No Etch Required') GaNEtchInfo = Gan_Services('GetRunInfo', ExternalEtchID) Recipe = GaNEtchInfo<1,1> Set_Property(@Window : '.ETCH_RECIPE', 'TEXT', Recipe) End Case end event Event CTRL_PLAN.CLICK() PSNo = Get_Property(@WINDOW:'.PS_NO','DEFPROP') IF PSNo NE '' THEN Print_Control_Plan(PSNo) END end event Event WONO_BUTTON.CLICK() WONo = Get_Property(@WINDOW:'.WO_NO','DEFPROP') IF WONo NE '' THEN Start_Window('WO_LOG2',@WINDOW, WONo:'*CENTER', '', '' ) ;* Added (copied from ViewPSN) -dkk 10/23/14 END end event Event SEND_MSG.CLICK() CurrWindow = @WINDOW CurrKey = Get_Property(CurrWindow,'ID') IF CurrKey = '' THEN MsgInfo = '' MsgInfo = 'You must have a record present...' MsgInfo = 'H' Msg( '', MsgInfo ) RETURN END IF RowExists('REACT_RUN',CurrKey) THEN NoteID = NextKey('NOTES') obj_AppWindow('ViewRelated','NOTE_MESSAGE':@RM:NoteID:@RM:@WINDOW:@FM:CurrKey) END ELSE MsgInfo = '' MsgInfo = 'You must save this run data sheet first...' MsgInfo = 'H' Msg( '', MsgInfo ) END end event Event PSNO_BUTTON.CLICK() PSNo = Get_Property(@WINDOW:'.PS_NO','DEFPROP') IF PSNo NE '' THEN Start_Window('PROD_SPEC',@WINDOW, PSNo:'*CENTER', '', '' ) ;* Old style call to old style window END end event Event EDB_CASS_COMMENTS.CHANGED(NewData) NewComments = NewData OrigComments = Get_Property(@Window, '@COMMENTS') If NewComments NE OrigComments then Set_Property(@Window:'.PUB_SAVE_COMMENTS', 'ENABLED', True$) end else Set_Property(@Window:'.PUB_SAVE_COMMENTS', 'ENABLED', True$) end end event Event PUB_SAVE_COMMENTS.CLICK() RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') CassComments = Get_Property(@Window:'.EDB_CASS_COMMENTS', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) ReactRunRec = CassComments Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) Set_Property(CtrlEntID, 'ENABLED', False$) Set_Property(@Window, '@COMMENTS', CassComments) end event Event PUB_UPDATE_EA_DATA.CLICK() RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') Engineering_Services('UpdateAll', RDSNo) end event Event PUB_CLOSE_RDS.CLICK() RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') AllWfrsComp = GaN_Services('ReadyToClose', RDSNo) If AllWfrsComp EQ True$ then MsgText = 'Are you sure you want to close this RDS? Once closed an RDS cannot be re-opened.' MsgHead = 'Warning' Response = Msg(@WINDOW,'','YESNO','',MsgHead:@FM:MsgText) If Response EQ Yes$ then GaN_Services('CloseRDS', RDSNo) GoSub FillDispEditTable GoSub EnableCloseRDSButton GoSub UpdateRDSStatus // Refresh the WO_PROD_GAN form if it is open to reflect possible updates to outbound cassettes. GaNProdVis = Get_Property('WO_PROD_GAN', 'VISIBLE') If GaNProdVis EQ True$ then Send_Event('WO_PROD_GAN', 'READ') end end else Dialog_Box('NDW_WAFER_STATUS', @Window, RDSNo) end end event Event PUB_CREATE_NCR.CLICK() DispEDTCtrl = @Window:".OLE_DISP_EDT" CarrSlotList = Get_Property(DispEDTCtrl, 'OLE.List') SelectedRows = Get_Property(DispEDTCtrl, "OLE.ColumnData[":COL$DISP_RDS_NCR:"]") CONVERT @VM TO @FM in SelectedRows NumWfrs = DCount(SelectedRows, @FM) WONo = Get_Property(@Window:'.WO_NO', 'TEXT') RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') Reactor = Get_Property(@Window, '@REACTOR') RejWfrIDs = '' RejSlotIDs = '' GoodLines = 0 FOR WfrIndex = 1 TO NumWfrs RowSelected = SelectedRows If RowSelected EQ True$ then SlotNo = CarrSlotList IF CarrSlotList NE '' Then GoodLines += 1 RejWfrIDs<1,GoodLines> = CarrSlotList RejSlotIDs<1,GoodLines> = RDSNo:'*':SlotNo END end NEXT I ncrParms = WONo:@RM ncrParms := '1':@RM ncrParms := '':@RM ;* Place holder for WO_MAT_CASS_NO ncrParms := RDSNo:@RM ;* Single RDS field ncrParms := Reactor:@RM ;* Reactor No ncrParms := '':@RM ;* Loss Stage ncrParms := RejWfrIDs:@RM ;* WfrIDs ;* CarrWafer IDs ncrParms := RejSlotIDs:@RM ;* CarrSlotIDs ;* GaN PostEpi Carrier Slot ID -> GaN non-characterization wafers ncrParms := '':@RM ;* CassSlotIDs ;* WOMat Cassette Slot ID -> Rej from cassette ncrParms := '' ;* RunPocketZone ;* RPZ -> Rej from susceptor Set_Status(0) NCRNo = obj_NCR('CreateWfr',ncrParms) ;* Create new NCR for this wafer/group of wafers IF Get_Status(errCode) THEN ErrMsg(errCode) end else // Mark wafers as scrap ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) Grades = Xlate('REACT_RUN', RDSNo, 'WFR_GRADES', 'X') WfrIDs = ReactRunRec OutSlotIDs = ReactRunRec For each RejWfrID in RejWfrIDs using @VM setting vPos Locate RejWfrID in WfrIDs using @VM setting wPos then Grades<0, wPos> = 'Scrap' // Check if this wafer is in an outbound cassette. If so, // then remove it. Wafers cannot be shipped and scrapped at the same time. OutSlotID = OutSlotIDs<0, wPos> If OutSlotID NE '' then // Remove wafer from outbound cassette OutCass = Field(OutSlotID, '*', 1, 2) GaN_Services('RemoveWfrsFromOutCass', OutCass, RejWfrID) end end WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', RejWfrID) WOWfrRec = 'Scrap' WOWfrRec = NCRNo Database_Services('WriteDataRow', 'WO_WFR', RejWfrID, WOWfrRec, True$, False$, True$) Next RejWfrID Dialog_Box('NCR', @Window, NCRNo) PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'H') Def = "" Def = "Loading..." Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) Disposition_Services('AutoDispositionRun', RDSNo) Msg(@Window, MsgUp, 20, MSGINSTUPDATE$) GoSub FillMetEditTable Msg(@Window, MsgUp, 40, MSGINSTUPDATE$) GoSub FillDispEditTable Msg(@Window, MsgUp, 60, MSGINSTUPDATE$) GoSub FillNCREditTable Msg(@Window, MsgUp, 80, MSGINSTUPDATE$) GoSub EnableCloseRDSButton Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'A') end GoSub EnableNCRButton end event Event PUB_LOT_ABORT.CLICK() RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') For each WfrID in WfrIDs using @VM setting vPos FormattedWfrID = WfrID Convert '*' to '.' in FormattedWfrID CurrStage = Gan_Services('GetCurrStage', WfrID) Begin Case Case ( (CurrStage EQ 'UV') or (CurrStage EQ 'UV_PRE') or (CurrStage EQ 'UV_PST') or (CurrStage EQ 'WARP') or (CurrStage EQ 'CAN') or (CurrStage EQ 'CAN_PRE') or (CurrStage EQ 'CAN_PST') ) // Pre-SPLIT wafer // a) Skip any pre-SPLIT stages // b) Mark all wafers as "Disposition" at SPLIT stage Loop StageKey = RDSNo:'*':CurrStage:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', StageKey, 'STATUS', 'X') Begin Case Case StageStatus _EQC 'INIT' // Skip stage - Moves wafer to next stage Gan_Services('SkipWaferStage', RDSNo, WfrID, CurrStage) Case StageStatus _EQC 'START' // Stop wafer - Moves wafer to next stage Gan_Services('StopWaferStage', RDSNo, WfrID, CurrStage) Case StageStatus _EQC 'COMP' Null Case Otherwise$ Null End Case CurrStage = Gan_Services('GetCurrStage', WfrID) Until CurrStage _EQC 'SPLIT' Repeat If CurrStage _EQC 'SPLIT' then Gan_Services('DispositionWfr', RDSNo, WfrID) Case CurrStage _EQC 'SPLIT' // SPLIT wafer - Simply disposition the wafer Gan_Services('DispositionWfr', RDSNo, WfrID) Case (CurrStage _EQC 'XRD') or (CurrStage _EQC 'AFM') | or (CurrStage _EQC 'RPM') or (CurrStage _EQC 'PR') or (CurrStage _EQC 'SCOPE') | or (CurrStage _EQC 'HALL') or (CurrStage _EQC 'EBEAM') or (CurrStage _EQC 'RTA_HALL') | or (CurrStage _EQC 'RTA') or (CurrStage _EQC 'HALL_PGAN') | or (CurrStage _EQC 'BV') or (CurrStage _EQC 'JV_XRD') // Post-SPLIT wafer // a) Currently running wafers will need to be stopped // b) All subsequent stages will need to be auto-skipped including unprescribed stages Loop CurrQ = Gan_Services('GetWfrQueue', WfrID) QType = Gan_Services('GetQueueType', CurrQ) Begin Case Case QType _EQC 'Location' // Wafer not running on a tool. Skip the stage. Gan_Services('SkipWaferStage', RDSNo, WfrID, CurrStage) Case QType _EQC 'Tool' // Wafer running on tool. Stop the stage. Gan_Services('StopWaferStage', RDSNo, WfrID, CurrStage) End Case CurrStage = Gan_Services('GetCurrStage', WfrID) Until CurrStage _EQC 'DISP' Repeat Case CurrStage _EQC 'DISP' // Wafer is where it needs to be. Nothing needed to do. Null Case Otherwise$ ErrorMsg = 'Error aborting wafer ':WfrID:'. Contact FI team for assistance.' ErrMsg(ErrorMsg) End Case Disposition_Services('AutoDispositionWfr', WfrID) Next WfrID GoSub FillMetEditTable GoSub FillDispEditTable end event Event OLE_METROLOGY_EDT.OnButtonClick(Cell, Point, Button, Shift, Ctrl) Row = Field(Cell, ';', 2) Col = Field(Cell, ';', 1) SelStage = Get_Property(CtrlEntID, "OLE.CellText[":Col:";":Row:"]") SelStageID = GaN_Services('GetStageID', SelStage) If ( (SelStageID EQ 'UV') or (SelStageID EQ 'UV_PRE') or (SelStageID EQ 'UV_PST') or (SelStageID EQ 'WARP') or (SelStageID EQ 'WET_CLEAN') or (SelStageID EQ 'CAN_PRE') or (SelStageID EQ 'CAN_PST') ) then RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') ToolID = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[2; ':Row:']') IsSplit = Gan_Services('IsCassSplit', RDSNo) Menu = "" // Initialize menu options StartStatus = False$ StopStatus = False$ CompStatus = False$ SkipStatus = False$ UnskipStatus = False$ WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') WfrStages = Xlate('REACT_RUN', RDSNo, 'WFR_STAGE', 'X') CanPreStartCnt = 0 CanPstStartCnt = 0 WetCleanStartCnt = 0 NumWfrs = Get_Property(@Window, '@NUMWFRS') // Check each wafer in the selected stage to determine which menu options should be enabled. For each WfrID in WfrIDs using @VM setting wPos Convert '*' to '.' in WfrID Begin Case Case SelStageID EQ 'UV_PRE' // Check if UV stage exists UVStageWfrKey = RDSNo:'*UV*':WfrID If RowExists('RUN_STAGE_WFR', UVStageWfrKey) then // Display this on the UV_PRE line RunStageWfrKey = UVStageWfrKey end else RunStageWfrKey = RDSNo:'*':SelStageID:'*':WfrID end Case SelStageID EQ 'CAN_PRE' // Check if CAN stage exists CanStageWfrKey = RDSNo:'*CAN*':WfrID If RowExists('RUN_STAGE_WFR', CanStageWfrKey) then // Display this on the CAN_PRE line RunStageWfrKey = CanStageWfrKey end else RunStageWfrKey = RDSNo:'*':SelStageID:'*':WfrID end Case Otherwise$ RunStageWfrKey = RDSNo:'*':SelStageID:'*':WfrID End Case WfrStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') Begin Case Case WfrStatus EQ 'INIT' and ToolID NE 'Select' StartStatus = True$ SkipStatus = True$ Case WfrStatus EQ 'INIT' SkipStatus = True$ Case WfrStatus EQ 'START' StopStatus = True$ Case WfrStatus EQ 'STOP' CompStatus = True$ Case WfrStatus EQ 'SKIP' If IsSplit EQ False$ then UnskipStatus = True$ End Case Next WfrID Menu<-1> = "START" :@VM:"Start" :@VM:StartStatus Menu<-1> = "STOP" :@VM:"Stop" :@VM:StopStatus Menu<-1> = "COMP" :@VM:"Complete" :@VM:CompStatus Menu<-1> = "SKIP" :@VM:"Skip" :@VM:SkipStatus Menu<-1> = "UNSKIP" :@VM:"Unskip" :@VM:UnskipStatus Send_Message(CtrlEntID, "OLE.ShowContextMenu", Point, Menu, Cell) end end event Event OLE_REACTOR_EDT.OnButtonClick(Cell, Point, Button, Shift, Ctrl) RecipeMismatch = Get_Property(@Window, '@RECIPEMISMATCH') RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') Row = Field(Cell, ';', 2) Col = Field(Cell, ';', 1) Stage = Get_Property(CtrlEntID, "OLE.CellText[":Col:";":Row:"]") StageID = Gan_Services('GetStageID', Stage) If StageID NE 'ETCH' then Menu = "" // Initialize all menu options to false until we deem they need to be turned on StartStatus = False$ StopStatus = False$ LoadStatus = False$ UnloadStatus = False$ CompStatus = False$ // Get inventory actions associated with this particular stage RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') RunStageKey = RDSNo:'*':StageID InvActions = Xlate('RUN_STAGE', RunStageKey, 'SPEC_INV_ACTION', 'X') CurrStatus = Xlate('RUN_STAGE', RunStageKey, 'STATUS', 'X') Begin Case Case StageID EQ 'G_RDS' // Need to check if GaN Run ID has been selected and if the GaN Recipe is populated. GaNRunID = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') GaNRecipe = Get_Property(@Window:'.GAN_RECIPE', 'TEXT') EtchKey = RDSNo:'*ETCH' EtchStageComp = Xlate('RUN_STAGE', EtchKey, 'STATUS', 'X') If (GaNRunID NE '') and (GaNRecipe NE '') and (EtchStageComp _EQC 'COMP') and (CurrStatus NE 'COMP') then CompStatus = True$ end Case StageID EQ 'GROWTH' PrevStageKey = RDSNo:'*':'ETCH' PrevStageStatus = Xlate('RUN_STAGE', PrevStageKey, 'STATUS', 'X') If PrevStageStatus EQ 'COMP' then Begin Case Case CurrStatus EQ 'START' UnloadStatus = True$ Case CurrStatus EQ 'COMP' Null Case Otherwise$ LoadStatus = True$ End Case end Case StageID EQ 'G_RATE' PrevStageKey = RDSNo:'*':'GROWTH' PrevStageStatus = Xlate('RUN_STAGE', PrevStageKey, 'STATUS', 'X') If PrevStageStatus EQ 'COMP' and CurrStatus NE 'COMP' then CompStatus = True$ End Case For each Action in InvActions using @VM Begin Case Case Action EQ "START" Menu<-1> = "START" :@VM:"Start" :@VM:StartStatus Case Action EQ "STOP" Menu<-1> = "STOP" :@VM:"Stop" :@VM:StopStatus Case Action EQ "LOAD" Menu<-1> = "LOAD" :@VM:"Load" :@VM:LoadStatus Case Action EQ "UNLOAD" Menu<-1> = "UNLOAD" :@VM:"Unload" :@VM:UnloadStatus End Case Next Action If RecipeMismatch EQ True$ then CompStatus = False$ If StageID NE 'GROWTH' then Menu<-1> = "COMP" :@VM:"Complete" :@VM:CompStatus Send_Message(CtrlEntID, "OLE.ShowContextMenu", Point, Menu, Cell) end end event Event OLE_REACTOR_EDT.OnContextMenuClick(Item, UserData) Set_Property(@Window:'.OLE_METROLOGY_EDT' , "OLE.Redraw", False$) Set_Property(@Window:'.OLE_DISP_STAGE_EDT' , "OLE.Redraw", False$) CurrDTM = DateTime() SelCell = UserData Row = Field(SelCell, ';', 2) RowData = Get_Property(CtrlEntID, "OLE.RecordData[":Row:"]") ReactorStageCtrl = @Window:'.OLE_REACTOR_EDT' RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') PSNo = Xlate('REACT_RUN', RDSNo, 'PS_NO', 'X') NumWfrs = DCount(InWfrIDs, @VM) StartCol = 3 EndCol = StartCol + (NumWfrs - 1) WfrActions = '' WfrStage = RowData<1, 1> For Col = StartCol to EndCol WfrActions<1, -1> = RowData<1, Col> Next Col StageName = Get_Property(CtrlEntID, 'OLE.CellText[1; ':Row:']') StageID = Gan_Services('GetStageID', StageName) PRSStageKey = PSNo :'*': StageID CurrAction = Item RunStageKey = RDSNo:'*':StageID RunStageRec = Database_Services('ReadDataRow', 'RUN_STAGE', RunStageKey) WONo = Get_Property(@Window:'.WO_NO', 'TEXT') CassNo = Get_Property(@Window:'.CASS_NO', 'TEXT') WOMatKey = WONo:'*':CassNo WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey) ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) Begin Case Case CurrAction EQ 'UNLOAD' Begin Case Case StageID EQ 'GROWTH' GaN_Services('UnloadSusceptor', RDSNo) If Error_Services('NoError') then Set_Property(ReactorStageCtrl, "OLE.CellText[2; ":Row:"]", 'Complete') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) CarrSlotIDs = ReactRunRec Scribes = Xlate('REACT_RUN', RDSNo, 'WFR_SCRIBES', 'X') Set_Property(@Window, '@CARRSLOTIDS', CarrSlotIDs) Set_Property(@Window, '@SCRIBES', Scribes) Engineering_Services('PostEARequest', RDSNo, 'GROWTH') GaN_Services('GetGaNMetrologyData', RDSNo, 'GROWTH') GaN_Services('GetGaNMetrologyData', RDSNo, 'TEMP') end else ErrorMessages = Error_Services('GetMessages') Convert @FM to CRLF$ in ErrorMessages ErrMsg(ErrorMesssages) end End Case Case CurrAction EQ 'LOAD' Begin Case Case StageID EQ 'GROWTH' RunStageKey = RDSNo:'*':StageID Reactor = Get_Property(@Window, '@REACTOR') // Need to sign 'LOAD' inventory action LoadComplete = Dialog_Box('DIALOG_LOAD_SUSCEPTOR', @WINDOW, RDSNo:@FM:StageName:@FM:Reactor) If LoadComplete EQ True$ then // Update the UI Set_Property(ReactorStageCtrl, "OLE.CellText[2; ":Row:"]", 'Load') Scribes = Xlate('REACT_RUN', RDSNo, 'WFR_SCRIBES', 'X') WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') Set_Property(@Window, '@WFRIDS', WfrIDs) HeaderTitles = "Stage":@VM:"Tool ID":@VM:Scribes Set_Property(MetStageCtrl, "OLE.TitleList", HeaderTitles) GaNProdVis = Get_Property('WO_PROD_GAN', 'VISIBLE') If GaNProdVis EQ True$ then Send_Event('WO_PROD_GAN', 'READ') GoSub FillDispEditTable GoSub FillNCREditTable GoSub ReadCurrParams GoSub FillDispStageCtrl GoSub ColorTabs GoSub EnableTabs end End Case Case CurrAction EQ 'COMP' // 1. Save REACT_RUN record (Bind REACT_RUN (RDS) key id to GaN Run ID and to GaN Etch ID). Remove GaN Run ID and GaN Etch ID from their respective lists. // 2. Remove all wafers from previous Location/Tool ID queue if applicable // 3. Insert all wafers into Location/Tool ID queue (e.g. LOCATION*GCH*Q_ETCH/TOOL_WFR*R69) // 4. Add COMP_BY and COMP_DTM to RUN_STAGE record // 5. Update UI // 6. Refresh GaN Work Order status form Begin Case Case StageID EQ 'G_RDS' GaNRunID = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') GanSuscSerial = Get_Property(@Window:'.GAN_SUSC_SERIAL', 'TEXT') GaNRunRecipe = Get_Property(@Window:'.GAN_RECIPE', 'TEXT') SPCWaferTrackPart = Get_Property(@Window:'.EDL_WAFER_TRACK_PART', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) RunInfo = Gan_Services('GetRunInfo', GaNRunID) PocketNos = RunInfo<3> Scribes = RunInfo<4> SatSerialNos = RunInfo<5> // Save the Wafer Track Part from SPC into the WO_LOG record. WOLogRec = Database_Services('ReadDataRow', 'WO_LOG', WONo) WOLogRec = SPCWaferTrackPart Database_Services('WriteDataRow', 'WO_LOG', WONo, WOLogRec, True$, False$, True$) // Just get the first reator in the list InWfrIDs = ReactRunRec Reactor = Get_Property(@Window, '@REACTOR') ReactRunRec = GaNRunID ReactRunRec = GaNRunRecipe ReactRunRec = GanSuscSerial ReactRunRec = SatSerialNos ReactRunRec = Reactor GaN_Services('RemoveRunID', GaNRunID) Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) // 2 - N/A // 3 - Move cassette to GROWTH queue. GrowthQ = 'GCH*Q_GROWTH' GaN_Services('MoveCassToQueue', WOMatKey, GrowthQ) WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WOMatKey) WOMatRec = CurrDTM WOMatRec = @User4 WOMatRec = GrowthQ Database_Services('WriteDataRow', 'WO_MAT', WOMatKey, WOMatRec, True$, False$, True$) // 4 RunStageRec = @User4 RunStageRec = CurrDTM RunStageRec = 'COMP' Database_Services('WriteDataRow', 'RUN_STAGE', RunStageKey, RunStageRec, True$, False$, True$) // 5 Set_Property(ReactorStageCtrl, "OLE.CellText[2; ":Row:"]", 'Complete') // 6 GaNProdVis = Get_Property('WO_PROD_GAN', 'VISIBLE') If GaNProdVis EQ True$ then Send_Event('WO_PROD_GAN', 'READ') Case StageID EQ 'G_RATE' GaNRunID = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') RunInfo = Gan_Services('GetRunInfo', GaNRunID) PocketNos = RunInfo<3> Scribes = RunInfo<4> // 1. Remove all wafers from current Location queue // 2. Lookup next Location queue // 3. Insert all wafers into next Location queue CurrLocQID = 'GCH*Q_RATE' NextLocQID = 'GCH*UV_PRE_Q' InWfrIDs = ReactRunRec For each WOWfrID in InWfrIDs using @VM setting vPos If WOWfrID NE '' then GaN_Services('RemoveWfrFromWIP', WOWfrID) WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WOWfrID) LocDTMs = WOWfrRec NextIndex = DCount(LocDTMs, @VM) + 1 WOWfrRec = CurrDTM WOWfrRec = @User4 WOWfrRec = NextLocQID WOWfrRec = 'COMP' WOWfrRec = PocketNos<0, vPos> WOWfrRec = Scribes<0, vPos> Database_Services('WriteDataRow', 'WO_WFR', WOWfrID, WOWfrRec, True$, False$, True$) Gan_Services('MoveWfrToQueue', WOWfrID, NextLocQID) end Next WOWfrID // 3. Add COMP_BY and COMP_DTM to RUN_STAGE record RunStageRec = @User4 RunStageRec = CurrDTM RunStageRec = 'COMP' Database_Services('WriteDataRow', 'RUN_STAGE', RunStageKey, RunStageRec, True$, False$, True$) // 4. Create prescribed RUN_STAGE_WFR records Gan_Services('CreateAllRunStageWfr', RDSNo, 'SPLIT') // 5. Update REACT_RUN form Set_Property(ReactorStageCtrl, "OLE.CellText[2; ":Row:"]", 'Complete') GoSub EnableRows GoSub FillMetEditTable GoSub FillMetHeader GoSub FillDispStageHeader // 6. Refresh GaN Work Order status form if it is open GaNProdVis = Get_Property('WO_PROD_GAN', 'VISIBLE') If GaNProdVis EQ True$ then Send_Event('WO_PROD_GAN', 'READ') End Case End Case Set_Property(@Window:'.OLE_METROLOGY_EDT' , "OLE.Redraw", True$) Set_Property(@Window:'.OLE_DISP_STAGE_EDT' , "OLE.Redraw", True$) end event Event OLE_METROLOGY_EDT.OnContextMenuClick(Item, UserData) PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'H') // Suppress redraw until all properties are set Set_Property(@Window:'.OLE_METROLOGY_EDT', "OLE.Redraw", False$) Set_Property(@Window:'.OLE_DISP_STAGE_EDT', "OLE.Redraw", False$) Set_Property(@Window:'.OLE_DISP_EDT', "OLE.Redraw", False$) Set_Property(@Window:'.OLE_NCR_EDT', "OLE.Redraw", False$) SelCell = UserData Row = Field(SelCell, ';', 2) RowData = Get_Property(CtrlEntID, "OLE.RecordData[":Row:"]") RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') InWfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') PSNo = Xlate('REACT_RUN', RDSNo, 'PS_NO', 'X') NumWfrs = DCount(InWfrIDs, @VM) StartCol = 3 EndCol = StartCol + (NumWfrs - 1) WfrActions = '' WfrStage = RowData<1, 1> For Col = StartCol to EndCol WfrActions<1, -1> = RowData<1, Col> Next Col StageName = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[1; ':Row:']') StageID = Gan_Services('GetStageID', StageName) ToolID = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[2; ':Row:']') If ToolID EQ 'Select' then ToolID = '' PRSStageKey = PSNo :'*': StageName Action = Item SpecToolClass = Xlate('PRS_STAGE', PRSStageKey, 'PROC_TOOL_CLASS', 'X') ToolClassRec = Database_Services('ReadDataRow', 'TOOL_CLASS', SpecToolClass) CurrDTM = DateTime() NextStage = Gan_Services('GetNextRxStage', RDSNo, StageID) Begin Case Case Action _EQC 'START' For each WfrID in InWfrIDs using @VM setting WaferIndex FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') ReadyToStart = GaN_Services('ReadyToStart', RDSNo, WfrID) If ( (StageStatus EQ 'INIT') and (ReadyToStart EQ True$) ) then GaN_Services('StartWaferStage', RDSNo, WfrID, StageID, ToolID) Next WfrID Case Action _EQC 'STOP' Def = "" If StageID NE 'WET_CLEAN' then Def = "Stopping Stage and Retrieving SPC Data..." end else Def = "Stopping Stage..." end Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) NumWfrs = Get_Property(@Window, '@NUMWFRS') Increment = Int(100 / NumWfrs) + 1 AutoComplete = False$ For each WfrID in InWfrIDs using @VM setting WaferIndex FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'START' then GaN_Services('StopWaferStage', RDSNo, WfrID, StageID) If StageID NE 'WET_CLEAN' then GaN_Services('GetGaNMetrologyData', RDSNo, StageID, ToolID, WfrID) If Error_Services('NoError') then AutoComplete = True$ end * update the gauge Msg(@Window, MsgUp, (Increment * WaferIndex), MSGINSTUPDATE$) Next WfrID Msg(@Window, MsgUp, 90, MSGINSTUPDATE$) Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) ;* take down the gauge If AutoComplete EQ True$ then Def = "" Def = "Auto-Completing Stage..." Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) For each WfrID in InWfrIDs using @VM setting vPos FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'STOP' then GaN_Services('CompleteWaferStage', RDSNo, WfrID, StageID) * update the gauge Msg(@Window, MsgUp, (Increment * vPos), MSGINSTUPDATE$) Next WfrID Msg(@Window, MsgUp, 90, MSGINSTUPDATE$) Engineering_Services('PostEARequest', RDSNo, StageID) If NextStage EQ 'SPLIT' then GaN_Services('SplitSelection', RDSNo) Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) ;* take down the gauge end else ErrorMsg = 'Warning: Auto-complete failed. Unable to find ':StageID:' data in SPC.':CRLF$ ErrorMsg := 'Verify metrology data, then attempt to complete the stage again.' Error_Services('Add', ErrorMsg) ErrMsg(ErrorMsg) end If Error_Services('NoError') then Disposition_Services('AutoDispositionRun', RDSNo) GoSub ReadCurrParams GoSub FillDispStageCtrl GoSub ColorTabs GoSub FillDispEditTable Case Action _EQC 'COMP' NumWfrs = Get_Property(@Window, '@NUMWFRS') Increment = Int(100 / NumWfrs) + 1 OkToComplete = False$ If StageID NE 'WET_CLEAN' then Def = "" Def = "Retrieving SPC Data..." Def = "G" Def = 100 Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) For each WfrID in InWfrIDs using @VM setting WaferIndex FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'STOP' then GaN_Services('GetGaNMetrologyData', RDSNo, StageID, ToolID, WfrID) If Error_Services('NoError') then OkToComplete = True$ end * update the gauge Msg(@Window, MsgUp, (Increment * WaferIndex), MSGINSTUPDATE$) Next WfrID Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) ;* take down the gauge end else OkToComplete = True$ end If OkToComplete EQ True$ then Def = "" Def = "Completing Stage..." Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) For each WfrID in InWfrIDs using @VM setting vPos FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'STOP' then GaN_Services('CompleteWaferStage', RDSNo, WfrID, StageID) * update the gauge Msg(@Window, MsgUp, (Increment * vPos), MSGINSTUPDATE$) Next WfrID If NextStage EQ 'SPLIT' then GaN_Services('SplitSelection', RDSNo) Msg(@Window, MsgUp, 90, MSGINSTUPDATE$) If Error_Services('NoError') then Disposition_Services('AutoDispositionRun', RDSNo) GoSub ReadCurrParams GoSub FillDispStageCtrl GoSub ColorTabs GoSub FillDispEditTable end Engineering_Services('PostEARequest', RDSNo, StageID) Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) ;* take down the gauge end else ErrorMsg = 'Warning: Complete stage failed. Unable to find ':StageID:' data in SPC.':CRLF$ ErrorMsg := 'Verify metrology data, then attempt to complete the stage again.' Error_Services('Add', ErrorMsg) ErrMsg(ErrorMsg) end Case Action _EQC 'SKIP' For each WfrID in InWfrIDs using @VM setting vPos FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'INIT' then GaN_Services('SkipWaferStage', RDSNo, WfrID, StageID) Next WfrID If NextStage EQ 'SPLIT' then Gan_Services('SplitSelection', RDSNo) If Error_Services('NoError') then Disposition_Services('AutoDispositionRun', RDSNo) GoSub ReadCurrParams GoSub FillDispStageCtrl GoSub ColorTabs GoSub FillDispEditTable end end Case Action _EQC 'UNSKIP' For each WfrID in InWfrIDs using @VM setting vPos FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'SKIP' then GaN_Services('UnskipWaferStage', RDSNo, WfrID, StageID) Next WfrID End Case GoSub FillMetEditTable // Re-enable redraw now that all properties are set Set_Property(@Window:'.OLE_METROLOGY_EDT', "OLE.Redraw", True$) Set_Property(@Window:'.OLE_DISP_STAGE_EDT', "OLE.Redraw", True$) Set_Property(@Window:'.OLE_DISP_EDT', "OLE.Redraw", True$) Set_Property(@Window:'.OLE_NCR_EDT', "OLE.Redraw", True$) PrevCursor = Set_Property('SYSTEM', 'CURSOR', PrevCursor) end event Event OLE_METROLOGY_EDT.OnClick(Cell, Point, Button, Shift, Ctrl) If Button _EQC 'Right' then Column = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) PopupCtrl = @Window : '.OLE_POPUP' AllowPopup = False$ PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup end GoSub DisplayPopup end end event Event OLE_METROLOGY_EDT.OnHeaderDblClick(Cell, Point, Button, Shift, Ctrl) Col = Field(Cell, ';', 1, 1) If Col GT 3 then RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') WfrIndex = Col - 3 WfrID = WfrIDs<0, WfrIndex> WfrComments = '' WfrComments = Xlate('WO_WFR', WfrID, 'COMMENTS', 'X') // Display wafer comments and allow user to edit/erase comments. Response = Dialog_Box('NDW_WFR_COMMENTS', @WINDOW, WfrComments) Save = Response<1> NewComments = Response<2> If Save EQ True$ then // Insert comments into WO_WFR record WOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WfrID) WOWfrRec = NewComments Database_Services('WriteDataRow', 'WO_WFR', WfrID, WOWfrRec, True$, False$, True$) ColNo = WfrIndex + 3 Set_Property(CtrlEntID, "OLE.HeaderToolTip[":ColNo:";1]", NewComments) HeaderColors = Get_Property(CtrlEntID, "OLE.HeaderColors[":ColNo:";1]") If NewComments NE '' then // Set header to cyan so the user knows there's a comment HeaderColors<2> = 'LightCyan' HeaderColors<4> = 'LightCyan' end else // Comment has been removed, so reset header colors back to default colors HeaderColors<2> = 'None' HeaderColors<4> = OI_HOT_BLUE$ end Set_Property(CtrlEntID, "OLE.HeaderColors[":ColNo:";1]", HeaderColors) end end end event Event OLE_REACTOR_EDT.OnClick(Cell, Point, Button, Shift, Ctrl) If Button _EQC 'Right' then Column = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) PopupCtrl = @Window : '.OLE_POPUP' AllowPopup = False$ PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup end GoSub DisplayPopup end end event Event PUB_IMPORT_MET_DATA.CLICK() Def = "" Def = "Importing..." Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' GaNParamKeys = Xlate('REACT_RUN', RDSNo, 'GAN_PARAM_KEYS', 'X') MetStageList = '' AllStageList = Database_Services('ReadDataRow', 'APP_INFO', 'GAN_MET_STAGES') For each GaNParamKey in GaNParamKeys using @VM Stage = Field(GaNParamKey, '*', 2, 1) MetStageList<0, -1> = Stage Next GaNParamKey InWfrIDs = Get_Property(@Window, '@WFRIDS') For each Stage in MetStageList using @VM If ( (Stage EQ 'GROWTH') or (Stage EQ 'TEMP') ) then Gan_Services('GetGaNMetrologyData', RDSNo, Stage) end else Locate Stage in AllStageList using @FM setting Row then Msg(@Window, MsgUp, (Row * 5), MSGINSTUPDATE$) ToolType = GaN_Services('GetStageID', Stage) Tool = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[2; ':Row:']') WaferIndex = 1 ; // Just use the first wafer's status to determine if the stage is complete. StageStatus = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[':(WaferIndex + 2):'; ':Row:']') If ( ( (ToolType EQ 'UV') or (ToolType EQ 'UV_PRE') or (ToolType EQ 'UV_PST') or (ToolType EQ 'WARP') or (ToolType EQ 'CAN') or (ToolType EQ 'CAN_PRE') or (ToolType EQ 'CAN_PST') ) and (StageStatus EQ 'Complete') ) then Gan_Services('GetGaNMetrologyData', RDSNo, ToolType, Tool) end else For each WfrID in InWfrIDs using @VM setting WaferIndex StageStatus = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[':(WaferIndex + 2):'; ':Row:']') If StageStatus EQ 'Complete' then Gan_Services('GetGaNMetrologyData', RDSNo, ToolType, Tool, WfrID) Next WfrID end end end Next Stage Disposition_Services('AutoDispositionRun', RDSNo) Msg(@Window, MsgUp, 90, MSGINSTUPDATE$) GoSub ReadCurrParams GoSub FillDispStageCtrl Msg(@Window, MsgUp, 95, MSGINSTUPDATE$) GoSub ColorTabs GoSub FillDispEditTable GoSub EnableCloseRDSButton Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) ;* take down the gauge end event Event OLE_METROLOGY_EDT.OnComboClicked(Cell, SelPos, Value) PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'H') Column = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' MetStageList = Get_Property(MetStageCtrl, "OLE.ColumnData[1]") StageDesc = MetStageList<0, Row> StageID = GaN_Services('GetStageID', StageDesc) RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') MetRowsEnabled = Get_Property(@Window, '@METROWSENABLED') ColorArray = 'None':@FM:'None':@FM:'None':@FM:'None':@FM:'None' ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) WfrStages = ReactRunRec UnRxStages = ReactRunRec ToolID = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[2; ':Row:']') CurrDTM = DateTime() WfrIndex = Column - 2 PartNo = Get_Property(@Window:'.EPI_PART_NO', 'TEXT') Reactor = Get_Property(@Window, '@REACTOR') RunID = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') SelStage = Get_Property(CtrlEntID, "OLE.CellText[":Column:";":Row:"]") ToolType = GaN_Services('GetStageID', SelStage) Tool = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[2; ':Row:']') MetParameter = '' Abort = False$ If Column EQ COL$MET_TOOL_ID then ToolID = Value // A tool ID has been selected. Need to check all RUN_STAGE_WFR statuses. Tool IDs can only be updated if the // status is 'INIT' or if the stage is CAN. For each WfrID in WfrIDs using @VM setting vPos If WfrID NE '' then WfrIDFormatted = WfrID Swap '*' with '.' in WfrIDFormatted RunStageWfrKey = RDSNo:'*':StageID:'*':WfrIDFormatted If RowExists('RUN_STAGE_WFR', RunStageWfrKey) then WfrStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If ( (WfrStatus EQ 'INIT') or (StageID EQ 'CAN') or (StageID EQ 'CAN_PRE') or (StageID EQ 'CAN_PST') ) then Set_Property(MetStageCtrl, "OLE.CellProtection[":Column:";":Row:"]", "None") RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey) RunStageWfrRec = ToolID Database_Services('WriteDataRow','RUN_STAGE_WFR',RunStageWfrKey,RunStageWfrRec,True$,False$,True$) end end end Next WfrID MetRowsEnabled = True$ Set_Property(@Window, '@METROWSENABLED', MetRowsEnabled) end else Action = Value WfrID = WfrIDs<0, WfrIndex> Begin Case Case Action _EQC 'START' Gan_Services('StartWaferStage', RDSNo, WfrID, StageID, ToolID) Case Action _EQC 'STOP' AutoComplete = False$ FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'START' then GaN_Services('StopWaferStage', RDSNo, WfrID, StageID) If StageID NE 'WET_CLEAN' then GaN_Services('GetGaNMetrologyData', RDSNo, StageID, ToolID, WfrID) If Error_Services('NoError') then AutoComplete = True$ end If AutoComplete EQ True$ then FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'STOP' then GaN_Services('CompleteWaferStage', RDSNo, WfrID, StageID) Engineering_Services('PostEARequest', RDSNo, StageID) If NextStage EQ 'SPLIT' then GaN_Services('SplitSelection', RDSNo) end Case Action _EQC 'Complete' OkToComplete = False$ If StageID NE 'WET_CLEAN' then FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'STOP' then GaN_Services('GetGaNMetrologyData', RDSNo, StageID, ToolID, WfrID) If Error_Services('NoError') then OkToComplete = True$ end end else OkToComplete = True$ end If OkToComplete EQ True$ then FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrKey = RDSNo:'*':StageID:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrKey, 'STATUS', 'X') If StageStatus EQ 'STOP' then GaN_Services('CompleteWaferStage', RDSNo, WfrID, StageID) Engineering_Services('PostEARequest', RDSNo, StageID) end else ErrorMsg = 'Warning: Complete stage failed. Unable to find ':StageID:' data in SPC.':CRLF$ ErrorMsg := 'Verify metrology data, then attempt to complete the stage again.' Error_Services('Add', ErrorMsg) ErrMsg(ErrorMsg) end Case Action _EQC 'SKIP' Gan_Services('SkipWaferStage', RDSNo, WfrID, StageID) Case Action _EQC 'UNSKIP' Gan_Services('UnskipWaferStage', RDSNo, WFrID, StageID) Case Action _EQC 'ADD' Gan_Services('AddWaferStage', RDSNo, WfrID, StageID, ToolID) Case Action _EQC 'REMOVE' Gan_Services('RemoveWaferStage', RDSNo, WfrID, StageID) Case Action _EQC 'CHARACTERIZE' If Not( Memberof(@User4, 'GAN_WIP_SUPERVISOR') ) then Response = Dialog_Box('NDW_VERIFY_USER', @Window, @User4 : @FM : 'GAN_WIP_SUPERVISOR') Valid = Response<1> end else Valid = True$ end If Valid EQ True$ then Gan_Services('CharacterizeWafer', RDSNo, WfrID) end else Abort = True$ end Case Action _EQC 'DISPOSITION' If Not( Memberof(@User4, 'GAN_WIP_SUPERVISOR') ) then Response = Dialog_Box('NDW_VERIFY_USER', @Window, @User4 : @FM : 'GAN_WIP_SUPERVISOR') Valid = Response<1> end else Valid = True$ end If Valid EQ True$ then Gan_Services('DispositionWfr', RDSNo, WfrID) end else Abort = True$ end Case Action _EQC 'WITHDRAW' If Not( Memberof(@User4, 'GAN_WIP_SUPERVISOR') ) then Response = Dialog_Box('NDW_VERIFY_USER', @Window, @User4 : @FM : 'GAN_WIP_SUPERVISOR') Valid = Response<1> end else Valid = True$ end If Valid EQ True$ then Gan_Services('WithdrawWfr', RDSNo, WfrID) end else Abort = True$ end Case Otherwise$ End Case end If Error_Services('HasError') then Errmsg(Error_Services('GetMessage')) end else If Abort EQ False$ then CurrStage = Gan_Services('GetCurrStage', WfrID) If CurrStage _EQC 'DISP' then // Update the Disposition DTM for all wafers that have been through or are at disposition ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) InWfrIDs = ReactRunRec For each WOWfrID in InWfrIDs using @VM setting vPos ThisWOWfrRec = Database_Services('ReadDataRow', 'WO_WFR', WOWfrID) LocDTMs = ThisWOWfrRec LocQs = ThisWOWfrRec Locate 'GGR*Q_DISP' in LocQs using @VM setting vPos then // Wafer has been dispositioned at some point, so update the disposition DTM LocDTMs<0, vPos> = CurrDTM ThisWOWfrRec = LocDTMs Database_Services('WriteDataRow', 'WO_WFR', WOWfrID, ThisWOWfrRec, True$, False$, True$) end Next WOWfrID Set_Property(@Window:'.PUB_UPDATE_DISP', 'ENABLED', True$) end Disposition_Services('AutoDispositionRun', RDSNo) GoSub ReadCurrParams GoSub FillDispEditTable GoSub FillMetEditTable GoSub ColorTabs GoSub EnableCloseRDSButton end end PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'A') end event Event OLE_DISP_EDT.OnCheckChanged(Cell, OldValue, NewValue) Col = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) NCRButton = '' Begin Case Case Col EQ COL$DISP_RDS_NCR // The checkbox is only used for creating NCRs. We don't need to save anything at this time. // Check (no pun intended) if any of the checkboxes in this column are True$. If so, then enable // the "Create NCR" button, otherwise disable it. GoSub EnableNCRButton End Case end event Event COMBO_PRIORITY.CHANGED(NewData) Priority = NewData RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) ReactRunRec = Priority Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) end event Event CMB_GAN_ETCH_ID.DROPDOWN(EditLineText) /* If ETCH stage complete, then display dropdown of all external etch IDs bound to this RDS. If ETCH stage is not complete, then provide a popup of all available etch IDs and allow the user to select multiple external etch IDs to bind to the RDS */ RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') LogData = '' LogData<1> = OConv(Datetime(), 'DT') LogData<2> = RDSNo LogData<3> = @User4 LogData<4> = 'Begin dropdown event.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) EtchStageKey = RDSNo:'*ETCH' EtchStageStatus = Xlate('RUN_STAGE', EtchStageKey, 'STATUS', 'X') LogData<4> = 'Etch Stage Status: ':EtchStageStatus Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) If EtchStageStatus _NEC 'COMP' then // Open the External Etch Manager so that users can select one or more internal and external etch ID(s) to // bind to this RDS (REACT_RUN) record. Reactor = Get_Property(@Window, '@REACTOR') LogData<4> = 'Reactor: ':Reactor Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) If (Reactor NE '') then SelEtchIDs = '' SelEtchIDs = Dialog_Box('NDW_EXTERNAL_ETCH_MANAGER', @Window, Reactor) LogEtchIDs = SelEtchIDs Convert @FM to ',' in LogEtchIDs LogData<4> = 'Selected etch IDs: ':LogEtchIDs Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) // If SelEtchIDs is equal to False$ (0) then the user canceled the external etch selection process. If SelEtchIDs NE False$ then SelIntEtchIDs = SelEtchIDs<1> SelExtEtchIDs = SelEtchIDs<2> // Update RUN_STAGE record RunStageKey = RDSNo:'*ETCH' RunStageRec = Database_Services('ReadDataRow', 'RUN_STAGE', RunStageKey) If Error_Services('NoError') then CurrDTM = DateTime() RunStageRec = @User4 RunStageRec = CurrDTM RunStageRec = 'COMP' RunStageRec = SelIntEtchIDs Database_Services('WriteDataRow', 'RUN_STAGE', RunStageKey, RunStageRec, True$, False$, True$) If Error_Services('NoError') then // Update REACT_RUN record NumExtEtchIDs = DCount(SelExtEtchIDs, @VM) LastExtEtchID = SelExtEtchIDs<0, NumExtEtchIDs> ExtEtchRecipes = '' Set_Property(@Window:'.CMB_GAN_ETCH_ID', 'LIST', SelExtEtchIDs) Set_Property(@Window:'.CMB_GAN_ETCH_ID', 'SELPOS', -1) Set_Property(@Window:'.CMB_GAN_RUN_ID', 'ENABLED', True$) For each ExtEtchID in SelExtEtchIDs using @VM setting vPos If ExtEtchID _NEC 'No Etch Required' then LogData<4> = 'Calling Gan_Services("GetRunInfo", ':ExtEtchID:').' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) GaNEtchInfo = Gan_Services('GetRunInfo', ExtEtchID) If Error_Services('NoError') then LogData<4> = 'Call to Gan_Services("GetRunInfo", ':ExtEtchID:') was successful.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end else LogData<4> = 'Error Calling Gan_Services("GetRunInfo", ':ExtEtchID:').' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end ExtEtchRecipes<0, -1> = GaNEtchInfo<1,1> LogData<4> = 'Calling Gan_Services("ConsumeExtEtchID", ':ExtEtchID:').' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) GaN_Services('ConsumeExtEtchID', ExtEtchID) If Error_Services('NoError') then LogData<4> = 'Call to Gan_Services("ConsumeExtEtchID", ':ExtEtchID:') was successful.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end else ErrorMessage = Error_Services('GetMessage') LogData<4> = 'Error Calling Gan_Services("ConsumeExtEtchID", ':ExtEtchID:'). Error message: ':ErrorMessage Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end end else ExtEtchRecipes = 'Not Applicable' end Next ExtEtchID LastExtEtchRecipe = ExtEtchRecipes<0, NumExtEtchIDs> Set_Property(@Window:'.ETCH_RECIPE', 'TEXT', LastExtEtchRecipe) ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then ReactRunRec = SelExtEtchIDs ReactRunRec = ExtEtchRecipes Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) If Error_Services('NoError') then For each IntEtchID in SelIntEtchIDs using @VM setting vPos LogData<4> = 'Calling Gan_Services("ConsumeIntEtchID", ':IntEtchID:').' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) GaN_Services('ConsumeIntEtchID', IntEtchID) If Error_Services('NoError') then LogData<4> = 'Call to Gan_Services("ConsumeIntEtchID", ':IntEtchID:') was successful.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end else ErrorMessage = Error_Services('GetMessage') LogData<4> = 'Error Calling Gan_Services("ConsumeIntEtchID", ':IntEtchID:'). Error message: ':ErrorMessage Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end Next IntEtchID // Update the UI Row = 1 ; // Etch Configuration Row Set_Property(@Window:'.OLE_REACTOR_EDT', "OLE.CellText[2; ":Row:"]", 'Complete') Set_Property(@Window:'.CMB_GAN_RUN_ID', 'ENABLED', True$) end else ErrorMessage = Error_Services('GetMessage') LogData<4> = 'Error writing REACT_RUN record: ':RDSNo:'. Error message: ':ErrorMessage:'.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end end else ErrorMessage = Error_Services('GetMessage') LogData<4> = 'Error reading REACT_RUN record: ':RDSNo:'. Error message: ':ErrorMessage:'.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end end else ErrorMessage = Error_Services('GetMessage') LogData<4> = 'Error writing RUN_STAGE record: ':RunStageKey:'. Error message: ':ErrorMessage:'.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end end else ErrorMessage = Error_Services('GetMessage') LogData<4> = 'Error reading RUN_STAGE record: ':RunStageKey:'. Error message: ':ErrorMessage:'.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end end end else ErrorMsg = 'Reactor number is missing. Unable to complete ETCH stage.' ErrMsg(ErrorMsg) end end If Error_Services('NoError') then LogData<4> = 'Dropdown event successful.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end else LogData<4> = 'Error in dropdown event.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end LogData<4> = 'End dropdown event.' Logging_Services('AppendLog', objLog, LogData, @RM, @FM, True$) end event Event OLE_TAB.SelChanged(Index, PrevIndex) GoSub FillDispStageCtrl end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Setup_OLE_Controls: NumReactorCols = 2 NumReactorRows = 4 NumMetCols = 10 NumMetRows = 20 NumDispCols = 11 NumDispRows = 8 NumNCRCols = 9 NumNCRRows = 5 ReactorCtrlList = '' MetCtrlList = '' DispCtrlList = '' DispParamCtrlList = 'LSL':@FM:'USL' ReactorToolIDArray = '' MetToolIDArray = '' GaNStageArray = Database_Services('ReadDataRow', 'APP_INFO', 'GAN_STAGES_DEMO') Set_Property(@Window, '@GAN_STAGES', GaNStageArray) ReactorStageIndex = 1 MetStageIndex = 1 For each Row in GaNStageArray using @FM setting fPos StageDesc = Row<0,2> ToolClassIDs = Row<0,3> RunType = Row<0,5> Begin Case Case RunType EQ 'Reactor' ReactorCtrlList = StageDesc ReactorStageIndex += 1 Case RunType EQ 'Metrology' MetCtrlList = StageDesc TempArray = '' MetCtrlList = 'Select' For each ToolClassID in ToolClassIDs using @SVM setting svPos ProdTools = 'Tool1':@VM:'Tool2' Convert @VM to @STM in ProdTools TempArray = SRP_Array('Join', TempArray, ProdTools, 'OR', @STM) Next ToolClassID If TempArray[-1, 1] EQ @STM then TempArray[-1, 1] = '' MetToolIDArray = TempArray MetStageIndex += 1 End Case Next Row CarrSlotIDs = 23:@VM:20:@VM:17:@VM:14:@VM:11:@VM:8:@VM:5:@VM:2 Slots = CarrSlotIDs NumWfrs = DCount(Scribes, @VM) debug Set_Property(@Window, '@SCRIBES', Scribes) Set_Property(@Window, '@CARRSLOTIDS', CarrSlotIDs) Set_Property(@Window, '@NUMWFRS', NumWfrs) Set_Property(@Window, '@WFRIDS', WfrIDs) Set_Property(@Window, '@SLOTS', Slots) NumDummyWfrs = 0 DummyPockets = '' NumEmptyWfrs = 0 EmptyPockets = '' For each Scribe in Scribes using @VM setting vPos DummyID = GanRunID[1,7]:'D' EmptyID = GaNRunID[1,7]:'E' If Scribe[1,8] EQ DummyID then NumDummyWfrs += 1 DummyPockets<1, vPos> = True$ end If Scribe[1,8] EQ EmptyID then NumEmptyWfrs += 1 EmptyPockets<1, vPos> = True$ end Next Scribe Set_Property(@Window, '@DUMMYPOCKETS', DummyPockets) Set_Property(@Window, '@EMPTYPOCKETS', EmptyPockets) SuscUnloaded = False$ If NumWfrs GT 0 then // Wafers have not yet been unloaded from the susceptor. We will use this flag to // deactivate various control elements. SuscUnloaded = True$ end ReactorStageCtrl = @Window:'.OLE_REACTOR_EDT' MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' DispCtrl = @Window:'.OLE_DISP_EDT' NCRCtrl = @Window:'.OLE_NCR_EDT' DispParamCtrl = @Window:'.OLE_DISP_PARAM_EDT' HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 ReactorDimArray = NumReactorCols :@FM: NumReactorRows MetDimArray = NumMetCols :@FM: NumMetRows DispDimArray = NumDispCols :@FM: NumDispRows NCRDimArray = NumNCRCols :@FM: NumNCRRows Set_Property(@Window, '@METDIMARRAY', MetDimArray) Set_Property(@Window, '@DISPDIMARRAY', DispDimArray) Set_Property(@Window, '@NCRDIMARRAY', NCRDimArray) Set_Property(ReactorStageCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8) Set_Property(ReactorStageCtrl, "OLE.Dimension", ReactorDimArray) Set_Property(ReactorStageCtrl, "OLE.CellFont[1;All]", HeaderFontArray) Set_Property(ReactorStageCtrl, "OLE.LIST", ReactorCtrlList) Set_Property(ReactorStageCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray) Set_Property(ReactorStageCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray) Set_Property(MetStageCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8) Set_Property(MetStageCtrl, "OLE.Dimension", MetDimArray) Set_Property(MetStageCtrl, "OLE.CellFont[1;All]", HeaderFontArray) Set_Property(MetStageCtrl, "OLE.LIST", MetCtrlList) Set_Property(MetStageCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray) Set_Property(MetStageCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray) Set_Property(DispCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8) Set_Property(DispCtrl, "OLE.Dimension", DispDimArray) Set_Property(DispCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray) Set_Property(DispCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray) Set_Property(NCRCtrl, "OLE.CellFont[All; All]", 'Segoe UI':@SVM:8) Set_Property(NCRCtrl, "OLE.Dimension", NCRDimArray) Set_Property(NCRCtrl, "OLE.HeaderFont[All; 1]", HeaderFontArray) Set_Property(NCRCtrl, "OLE.HeaderFont[1; All]", HeaderFontArray) ScribesCopy = Scribes Convert @VM to '' in ScribesCopy HeaderTitles = "Stage":@VM:"Tool ID" ScribeHeaderTitles = '' If ScribesCopy NE '' then For each Scribe in Scribes using @VM setting vPos SlotID = CarrSlotIDs<0, vPos> ScribeHeaderTitles<0, -1> = Scribe:' (':SlotID:')' Next Scribe HeaderTitles<0, -1> = ScribeHeaderTitles Set_Property(@Window, '@SCRIBE_HEADER_TITLES', ScribeHeaderTitles) end else DefWfrTitles = '' For WfrIndex = 1 to NumWfrs DefWfrTitles<1, -1> = 'Wafer ':WfrIndex Next WfrIndex HeaderTitles = "Stage":@VM:"Tool ID":@VM:DefWfrTitles end ReactorNo = Get_Property(@Window, '@REACTOR') ReactorHeaderTitles = "Stage":@VM:"Status" Set_Property(ReactorStageCtrl, "OLE.TitleList", ReactorHeaderTitles) Set_Property(ReactorStageCtrl, "OLE.HeaderMerge[1; 2]", 1:@FM:NumReactorRows) Set_Property(ReactorStageCtrl, "OLE.HeaderText[1; 2]", 'Reactor ':ReactorNo) Set_Property(ReactorStageCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') Set_Property(ReactorStageCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L') Set_Property(ReactorStageCtrl, "OLE.CellAlignment[1; All]", 'C':@FM:'L':@FM:'L') Set_Property(ReactorStageCtrl, "OLE.AllowDeletions", False$) Set_Property(ReactorStageCtrl, "OLE.AllowInserts", False$) Set_Property(MetStageCtrl, "OLE.TitleList", HeaderTitles) Set_Property(MetStageCtrl, "OLE.HeaderMerge[1; 2]", 1:@FM:NumMetRows) Set_Property(MetStageCtrl, "OLE.HeaderText[1; 2]", 'Metrology') Set_Property(MetStageCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') Set_Property(MetStageCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L') Set_Property(MetStageCtrl, "OLE.CellAlignment[1; All]", 'C':@FM:'L':@FM:'L') Set_Property(MetStageCtrl, "OLE.AllowDeletions", False$) Set_Property(MetStageCtrl, "OLE.AllowInserts", False$) DispHeaderTitles = 'Slot':@VM:'Inbound':@VM:'Scribe':@VM:'Grade':@VM:'Reason':@VM:'Root Cause':@VM:'RDS NCR':@VM:'WMO NCR':@VM DispHeaderTitles := 'Outbound':@VM:'Retain Box':@VM:'Retain Slot' Set_Property(DispCtrl, "OLE.TitleList", DispHeaderTitles) Set_Property(DispCtrl, "OLE.HeaderText[1; 2]", 'Disposition') Set_Property(DispCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') Set_Property(DispCtrl, "OLE.CellAlignment[":COL$DISP_SLOT:"-":COL$DISP_GRADE:"; All]", 'C':@FM:'C':@FM:'L') Set_Property(DispCtrl, "OLE.CellAlignment[":COL$DISP_REASON:"-":COL$DISP_ROOT_CAUSE:"; All]", 'C':@FM:'L':@FM:'L') Set_Property(DispCtrl, "OLE.CellAlignment[":COL$DISP_RDS_NCR:"-":COL$DISP_RETAIN_SLOT:"; All]", 'C':@FM:'C':@FM:'L') Set_Property(DispCtrl, "OLE.AllowDeletions", False$) Set_Property(DispCtrl, "OLE.AllowInserts", False$) NCRHeaderTitles = 'NCR':@VM:'Status':@VM:'Qty':@VM:'Responsible':@VM:'Stage':@VM:'Loss Desc':@VM:'Loss Comments' | :@VM:'Signature':@VM:'Date & Time' Set_Property(NCRCtrl, "OLE.TitleList", NCRHeaderTitles) Set_Property(NCRCtrl, "OLE.HeaderMerge[1; 2]", 1:@FM:NumNCRRows) Set_Property(NCRCtrl, "OLE.HeaderText[1; 2]", 'Scrap') Set_Property(NCRCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') Set_Property(NCRCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'C':@FM:'L') Set_Property(NCRCtrl, "OLE.AllowDeletions", False$) Set_Property(NCRCtrl, "OLE.AllowInserts", False$) // Set default header colors HeaderColorArray = '' HeaderColorArray<1> = 'Auto' HeaderColorArray<2> = 'None' HeaderColorArray<3> = 'None' HeaderColorArray<4> = OI_HOT_BLUE$ HeaderColorArray<5> = False$ Set_Property(ReactorStageCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray) Set_Property(MetStageCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray) Set_Property(DispCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray) Set_Property(NCRCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray) Set_Property(DispParamCtrl, "OLE.HeaderColors[All; All]", HeaderColorArray) // Set header tooltips (wafer comments) For each WfrID in WfrIDs using @VM setting WfrIndex WfrComments = '' WfrComments = Xlate('WO_WFR', WfrID, 'COMMENTS', 'X') ColNo = WfrIndex + 3 If WfrComments NE '' then Set_Property(MetStageCtrl, "OLE.HeaderToolTip[":ColNo:";1]", WfrComments) // Set header to light cyan so the user knows there's a comment HeaderColors = Get_Property(MetStageCtrl, "OLE.HeaderColors[":ColNo:";1]") HeaderColors<2> = 'LightCyan' HeaderColors<4> = 'LightCyan' Set_Property(MetStageCtrl, "OLE.HeaderColors[":ColNo:";1]", HeaderColors) end Next WfrID // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(ReactorStageCtrl, 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier) Send_Message(ReactorStageCtrl, 'QUALIFY_EVENT', 'OLE.OnButtonClick', Qualifier) Send_Message(ReactorStageCtrl, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualifier) Send_Message(MetStageCtrl, 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier) Send_Message(MetStageCtrl, 'QUALIFY_EVENT', 'OLE.PosChanged', Qualifier) Send_Message(MetStageCtrl, 'QUALIFY_EVENT', 'OLE.OnButtonClick', Qualifier) Send_Message(MetStageCtrl, 'QUALIFY_EVENT', 'OLE.OnComboClicked', Qualifier) Send_Message(MetStageCtrl, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualifier) Send_Message(MetStageCtrl, 'QUALIFY_EVENT', 'OLE.OnHeaderDblClick', Qualifier) Send_Message(DispCtrl, 'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier) Send_Message(DispCtrl, 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier) Send_Message(DispCtrl, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualifier) Send_Message(DispCtrl, 'QUALIFY_EVENT', 'OLE.OnComboClicked', Qualifier) Send_Message(NCRCtrl, 'QUALIFY_EVENT', 'OLE.OnDblClick', Qualifier) // Process BeforeUpdate event synchronously Qualifier<4> = 1 Send_Message(DispCtrl, 'QUALIFY_EVENT', 'OLE.BeforeUpdate', Qualifier) // Setup Tool ID and Wafer status/action combo boxes CellTypeArray = "" CellTypeArray<1> = "Combo" CellTypeArray<2, 1> = "" CellTypeArray<2, 2> = "L" CellTypeArray<2, 3> = '' CellTypeArray<2, 4> = 1 ;// Column 1 contains the values we care about CellTypeArray<2, 5> = 1 ;// Auto fill on CellTypeArray<2, 6> = 0 ;// Case sensitive on CellTypeArray<2, 7> = 10 ;// 10 visible rows max CellTypeArray<2, 8> = 0 ;// Don't fire the OnOptionClick CellTypeArray<2, 9> = 1 ;// Reduce the list to partial matches CellTypeArray<2, 10> = 0 ;// Only show the drop down when the user types CellTypeArray<2, 11> = 0 ;// Do not use LIST Format CellTypeArray<2, 12> = 1 ;// Autofill on Tool ID name CellTypeArray<2, 13> = 1 ;// Hide dropdown when user clears cell CellTypeArray<2, 14> = 0 ;// Let navigation keys show the drop down CellTypeArray<2, 15> = 0 ;// Show the drop down regardless of the cell's contents CellTypeArray<2, 16> = 0 ;// Show the drop down during autofill CellTypeArray<2, 17> = 1 ;// Remove selection when user backspaces/deletes CellTypeArray<2, 18> = 0 ;// Show Popup while in read only mode CellTypeArray<2, 19> = 1 ;// Show Popup When Navigating CellTypeArray<2, 20> = 1 ;// Always Tab Out on Enter CellTypeArray<2, 21> = -1 ;// Always show the dropdown above when close to the screen bottom CellTypeArray<2, 23> = 1 ;// Limit possible values to those in dropdown // Store this for later use elsewhere Set_Property(@Window, '@COMBOBOX', CellTypeArray) * For RowIndex = 1 to NumMetRows * ThisComboArray = CellTypeArray * ThisComboArray<2, 3> = MetToolIDArray * Set_Property(MetStageCtrl, "OLE.CellType[2; ":RowIndex:"]", ThisComboArray) * Next RowIndex // Cell selection style setup Set_Property(ReactorStageCtrl, "OLE.ResetSelPos", False$) ;// Prevent cell selection from being reset upon lost focus event Set_Property(MetStageCtrl, "OLE.ResetSelPos", False$) Set_Property(DispCtrl, "OLE.ResetSelPos", False$) Set_Property(NCRCtrl, "OLE.ResetSelPos", False$) ReactorSelStyleArray = Get_Property(ReactorStageCtrl, "OLE.SelectionStyle") ReactorSelStyleArray<8> = True$ MetSelStyleArray = Get_Property(MetStageCtrl, "OLE.SelectionStyle") MetSelStyleArray<8> = True$ ;// Keep cell highlighted when table loses focus DispSelStyleArray = Get_Property(DispCtrl, "OLE.SelectionStyle") DispSelStyleArray<8> = True$ ;// Keep cell highlighted when table loses focus NCRSelStyleArray = Get_Property(NCRCtrl, "OLE.SelectionStyle") NCRSelStyleArray<8> = True$ ;// Keep cell highlighted when table loses focus Set_Property(ReactorStageCtrl, 'OLE.SelectionStyle', ReactorSelStyleArray) Set_Property(MetStageCtrl, 'OLE.SelectionStyle', MetSelStyleArray) Set_Property(DispCtrl, 'OLE.SelectionStyle', DispSelStyleArray) Set_Property(NCRCtrl, 'OLE.SelectionStyle', MCRSelStyleArray) CellSelStyleArray = '' CellSelStyleArray<1> = 'White' ;// Selected cell foreground color CellSelStyleArray<2> = OI_BLUE$ ;// Selected cell background color CellSelStyleArray<3> = 'None' ;// Selected record (row) foreground color - none = default CellSelStyleArray<4> = OI_HOT_BLUE$ ;// Selected record (row) background color CellSelStyleArray<5> = 'None' ;// Selected field (column) foreground color - none = default CellSelStyleArray<6> = OI_HOT_BLUE$ ;// Selected field (column) background color Set_Property(ReactorStageCtrl, 'OLE.CellSelColors[2; All]', CellSelStyleArray) Set_Property(MetStageCtrl, 'OLE.CellSelColors[2-':NumDummyWfrs+2:'; All]', CellSelStyleArray) Set_Property(NCRCtrl, 'OLE.CellSelColors[All; All]', CellSelStyleArray) // 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(ReactorStageCtrl, "OLE.CellType[1; All]", ButtonTypeArray) Set_Property(MetStageCtrl, "OLE.CellType[1; All]", ButtonTypeArray) MetRowsEnabled = '' For RowIndex = 1 to NumMetRows MetRowsEnabled = False$ Next RowIndex // Get associated run stage keys and check them for assigned Tool IDs. If Tool ID is // set, then set the Tool ID combo box selection accordingly. ReactorStageList = Get_Property(ReactorStageCtrl, "OLE.ColumnData[1]") MetStageList = Get_Property(MetStageCtrl, "OLE.ColumnData[1]") ReactorStageIDList = '' MetStageIDList = '' For each StageDesc in ReactorStageList using @VM setting vPos ReactorStageIDList<1, vPos> = 'R-STAGE0':vPos Next StageDesc For each StageDesc in MetStageList using @VM setting vPos MetStageIDList<1, vPos> = Gan_Services('GetStageID', StageDesc) Next StageDesc Set_Property(@Window, '@METSTAGEIDLIST', MetStageIDList) * RunStageKeys = ReactRunRec * MetStages = ReactRunRec Set_Property(@Window, '@METTOOLIDARRAY', MetToolIDArray) // Protect and color dummy and empty wafer columns ColorArray = @FM:'OD' CellColorArray = 'None':@FM:'None':@FM:'None':@FM:'None':@FM:'None' For each Pocket in DummyPockets using @VM setting vPos If Pocket EQ True$ then ColNo = vPos + 2 Set_Property(MetStageCtrl,"OLE.CellProtection[":ColNo:"; All]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":ColNo:"; All]", ColorArray) Set_Property(MetStageCtrl,"OLE.ColumnData[":ColNo:"]", '') Set_Property(MetStageCtrl,"OLE.HeaderColors[":ColNo+1:"; 1]", ColorArray) end Next Pocket For each Pocket in EmptyPockets using @VM setting vPos If Pocket EQ True$ then ColNo = vPos + 2 Set_Property(MetStageCtrl,"OLE.CellProtection[":ColNo:"; All]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":ColNo:"; All]", ColorArray) Set_Property(MetStageCtrl,"OLE.ColumnData[":ColNo:"]", '') Set_Property(MetStageCtrl,"OLE.HeaderColors[":ColNo+1:"; 1]", ColorArray) end Next Pocket // Protect and color N/A wafer columns If NumWfrs LT 8 then ; // 8 wafers make a full cassette in GaN StartCol = NumWfrs + 3 ; // Must add the three columns before the wafer columns Set_Property(MetStageCtrl,"OLE.CellProtection[":StartCol:"-":NumMetCols:"; All]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":StartCol:"-":NumMetCols:"; All]", ColorArray) Set_Property(MetStageCtrl,"OLE.ColumnData[":StartCol:"-":NumMetCols:"]", '') Set_Property(MetStageCtrl,"OLE.HeaderColors[":StartCol+1:"-":NumMetCols+1:"; 1]", ColorArray) end else StartCol = 3 Set_Property(MetStageCtrl,"OLE.CellProtection[":StartCol:"-":NumMetCols:"; All]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":StartCol:"-":NumMetCols:"; All]", CellColorArray) Set_Property(MetStageCtrl,"OLE.ColumnData[":StartCol:"-":NumMetCols:"]", '') Set_Property(MetStageCtrl,"OLE.HeaderColors[":StartCol+1:"-":NumMetCols+1:"; 1]", CellColorArray) end // Get and set each cassette's current status for each reactor stage // Cassette level (RUN_STAGE) For each Stage in ReactorStageIDList using @VM setting StageIndex DispStatus = 'Complete' Set_Property(ReactorStageCtrl, "OLE.CellText[2; ":StageIndex:"]", DispStatus) Set_Property(ReactorStageCtrl, "OLE.CellProtection[2; ":StageIndex:"]", "None") Next Stage // Get and set each wafer's current status for each stage within the Metrology and Disposition edit tables. GoSub FillMetEditTable GoSub SetupDispEDT GoSub SetupTabCtrl GoSub SetupDispStageCtrl GoSub ReadCurrParams GoSub FillDispStageCtrl GoSub ColorTabs GoSub EnableTabs //////////////////////////////////// Code below here only runs once ////////////////////////////////////////// FirstPassComp = Get_Property(@Window, '@FIRSTPASS') If FirstPassComp EQ '' or FirstPassComp EQ False$ then // Color headers Set_Property(MetStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") Set_Property(@Window, '@FIRSTPASS', True$) // Disable resizing of the header row and header column // Resize header column to fit contents HeaderRowArray = Get_Property(MetStageCtrl, "OLE.HeaderRow[1]") HeaderColArray = Get_Property(MetStageCtrl, "OLE.HeaderColumn[1]") HeaderRowArray<3> = False$ HeaderColArray<1> = 80 HeaderColArray<3> = False$ Set_Property(MetStageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(MetStageCtrl, "OLE.HeaderRow[1]", HeaderRowArray) // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(MetStageCtrl, "OLE.DataColumn[1]") StageColSize<3> = False$ Set_Property(MetStageCtrl, "OLE.DataColumn[All]", StageColSize) // Resize the stage column to fit stage descriptions StageColSize<1> = 186 Set_Property(MetStageCtrl, "OLE.DataColumn[1]", StageColSize) WfrColSize = Get_Property(MetStageCtrl, "OLE.DataColumn[3]") WfrColSize<1> = 96 Set_Property(MetStageCtrl, "OLE.DataColumn[3-10]", WfrColSize) // Disable resizing of rows as there is no need for this on this form RowSizeProps = Get_Property(MetStageCtrl, "OLE.DataRow[1]") RowSizeProps<3> = False$ Set_Property(MetStageCtrl, "OLE.DataRow[All]", RowSizeProps) // Disable resizing of the header row and header column // Resize header column to fit contents HeaderRowArray = Get_Property(ReactorStageCtrl, "OLE.HeaderRow[1]") HeaderColArray = Get_Property(ReactorStageCtrl, "OLE.HeaderColumn[1]") HeaderRowArray<3> = False$ HeaderColArray<1> = 80 HeaderColArray<3> = False$ Set_Property(ReactorStageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(ReactorStageCtrl, "OLE.HeaderRow[1]", HeaderRowArray) // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(ReactorStageCtrl, "OLE.DataColumn[1]") StageColSize<3> = False$ Set_Property(ReactorStageCtrl, "OLE.DataColumn[All]", StageColSize) // Resize the stage column to fit stage descriptions StageColSize<1> = 186 Set_Property(ReactorStageCtrl, "OLE.DataColumn[1]", StageColSize) // Disable resizing of rows as there is no need for this on this form RowSizeProps = Get_Property(ReactorStageCtrl, "OLE.DataRow[1]") RowSizeProps<3> = False$ Set_Property(ReactorStageCtrl, "OLE.DataRow[All]", RowSizeProps) // Color headers Set_Property(ReactorStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") //////////////////////////////////// Setup NCR OLE Edit Table ////////////////////////////////////////////// // Disable resizing of the header row and header column // Resize header column to fit contents HeaderRowArray = Get_Property(NCRCtrl, "OLE.HeaderRow[1]") HeaderColArray = Get_Property(NCRCtrl, "OLE.HeaderColumn[1]") HeaderRowArray<3> = False$ HeaderColArray<1> = 80 HeaderColArray<3> = False$ Set_Property(NCRCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(NCRCtrl, "OLE.HeaderRow[1]", HeaderRowArray) // Disable resizing of columns as there is no need for this on this form ColSize = Get_Property(NCRCtrl, "OLE.DataColumn[1]") ColSize<3> = False$ ColSize<1> = 56 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_NO:"]", ColSize) ColSize<1> = 45 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_STATUS:"]", ColSize) ColSize<1> = 35 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_REJ_QTY:"]", ColSize) ColSize<1> = 90 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_RESP:"]", ColSize) ColSize<1> = 58 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_STAGE:"]", ColSize) ColSize<1> = 140 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_LOSS_DESC:"]", ColSize) ColSize<1> = 173 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_LOSS_COMM:"]", ColSize) ColSize<1> = 100 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_FIN_SIG:"]", ColSize) ColSize<1> = 120 Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_FIN_SIG_DTM:"]", ColSize) // Disable resizing of rows as there is no need for this on this form RowSizeProps = Get_Property(NCRCtrl, "OLE.DataRow[1]") RowSizeProps<3> = False$ Set_Property(NCRCtrl, "OLE.DataRow[All]", RowSizeProps) Set_Property(NCRCtrl, "OLE.CellProtection[":COL$NCR_NO:"-":COL$NCR_FIN_SIG_DTM:"; All]", 'None') // Color headers Set_Property(NCRCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") // Set Loss Comments column to autosized so that the table resizes when scrollbars are necessary ColArray = Get_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_LOSS_COMM:"]") ColArray<4> = True$ Set_Property(NCRCtrl, "OLE.DataColumn[":COL$NCR_LOSS_COMM:"]", ColArray) end return FillMetEditTable: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') WfrIDs = Get_Property(@Window, '@WFRIDS') NumWfrs = Get_Property(@Window, '@NUMWFRS') MetStageIDList = Get_Property(@Window, '@METSTAGEIDLIST') * If WfrIDs EQ '' then * WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') * Set_Property(@Window, '@WFRIDS', WfrIDs) * end * If NumWfrs EQ '' then * NumWfrs = DCount(WfrIDs, @VM) * Set_Property(@Window, '@NUMWFRS') * end GoSub AutoSelectToolID MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' MetRowsEnabled = Get_Property(@Window, '@METROWSENABLED') CellTypeArray = Get_Property(@Window, '@COMBOBOX') ColorArray = @FM:'OD' CellColorArray = 'None':@FM:'None':@FM:'None':@FM:'None':@FM:'None' EnabledColorArray = CellColorArray // Get and set each wafer's current status for each stage within the Metrology edit table. EndCol = NumWfrs + 2 For each Stage in MetStageIDList using @VM setting StageIndex For each WfrID in WfrIDs using @VM setting WfrIndex BackgroundColor = 'None' CurrWfrRow = StageIndex CurrWfrCol = WfrIndex + 2 ThisComboArray = CellTypeArray DispStatus = '' CurrStatus = 'COMP' Begin Case Case CurrStatus _EQC 'COMP' DispStatus = 'Complete' MetActionArray = 'Complete' Case CurrStatus _EQC 'START' DispStatus = 'Start' MetActionArray = 'Stop' Case CurrStatus _EQC 'STOP' DispStatus = 'Stop' MetActionArray = 'Complete' Case CurrStatus _EQC 'SKIP' DispStatus = 'Skip' MetActionArray = 'Unskip' Case CurrStatus _EQC 'CHAR' DispStatus = 'Characterize' MetActionArray = '' // If any metrology stages after split have been started and/or completed, then withdraw // will not be an option. Case CurrStatus _EQC 'DISP' DispStatus = 'Disposition' MetActionArray = '' Case CurrStatus _EQC 'INIT' DispStatus = 'X' End Case Convert @FM to @STM in MetActionArray ThisComboArray<2, 3> = MetActionArray * Set_Property(MetStageCtrl, "OLE.CellType[":CurrWfrCol:";":CurrWfrRow:"]", ThisComboArray) Destructive = (StageIndex GT 13) RowEnabled = True$ If (Destructive EQ True$) then // Set row text color to red If (RowEnabled EQ True$) then DestEditArray = 'Red':@FM:BackgroundColor:@FM:'White':@FM:OI_BLUE$:@FM:'None' Set_Property(MetStageCtrl,"OLE.CellProtection[":CurrWfrCol:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":CurrWfrCol:";":CurrWfrRow:"]", DestEditArray) Set_Property(MetStageCtrl,"OLE.CellProtection[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", DestEditArray) end else DestEditArray = 'Red':@FM:'OD':@FM:'None':@FM:'None':@FM:'None' Set_Property(MetStageCtrl,"OLE.CellProtection[":CurrWfrCol:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":CurrWfrCol:";":CurrWfrRow:"]", DestEditArray) Set_Property(MetStageCtrl,"OLE.CellProtection[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", DestEditArray) end end else // Set row text color to default (i.e. 'None') If (RowEnabled EQ True$) then ColorArray = 'None':@FM:BackgroundColor:@FM:'White':@FM:OI_BLUE$:@FM:'None' Set_Property(MetStageCtrl,"OLE.CellProtection[":CurrWfrCol:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":CurrWfrCol:";":CurrWfrRow:"]", ColorArray) Set_Property(MetStageCtrl,"OLE.CellProtection[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", ColorArray) end else ColorArray = 'None':@FM:'OD':@FM:'None':@FM:'None':@FM:'None' Set_Property(MetStageCtrl,"OLE.CellProtection[":CurrWfrCol:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":CurrWfrCol:";":CurrWfrRow:"]", ColorArray) Set_Property(MetStageCtrl,"OLE.CellProtection[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":COL$MET_STAGE:'-':COL$MET_TOOL_ID:";":CurrWfrRow:"]", ColorArray) end end Next WfrID Next Stage Set_Property(@Window, '@METROWSENABLED', MetRowsEnabled) return AutoSelectToolID: EnabledColorArray = 'None':@FM:'None':@FM:'None':@FM:'None':@FM:'None' MetStageIDList = Get_Property(@Window, '@METSTAGEIDLIST') WfrIDs = Get_Property(@Window, '@WFRIDS') MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' MetRowsEnabled = Get_Property(@Window, '@METROWSENABLED') MetToolIDArray = Get_Property(@Window, '@METTOOLIDARRAY') For each MetStage in MetStageIDList using @VM setting mPos If MetStage _NEC 'SPLIT' then RunStageWfrKey = '' For each WfrID in WfrIDs using @VM setting wPos If WfrID NE '' then CurrWfrCol = wPos + 2 Convert '*' to '.' in WfrID Begin Case Case MetStage EQ 'UV_PRE' // Check if UV stage exists UVStageWfrKey = RDSNo:'*UV*':WfrID If RowExists('RUN_STAGE_WFR', UVStageWfrKey) then // Display this on the UV_PRE line RunStageWfrKey = UVStageWfrKey end else RunStageWfrKey = RDSNo:'*':MetStage:'*':WfrID end Case MetStage EQ 'CAN_PRE' // Check if CAN stage exists CanStageWfrKey = RDSNo:'*CAN*':WfrID If RowExists('RUN_STAGE_WFR', CanStageWfrKey) then // Display this on the CAN_PRE line RunStageWfrKey = CanStageWfrKey end else RunStageWfrKey = RDSNo:'*':MetStage:'*':WfrID end Case Otherwise$ RunStageWfrKey = RDSNo:'*':MetStage:'*':WfrID End Case KeyFound = RowExists('RUN_STAGE_WFR', RunStageWfrKey) If KeyFound EQ True$ then RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey) ToolID = RunStageWfrRec If ToolID EQ '' then // Check to see how many tools exist for the current stage. If only one exists, then // auto-select it for convenience. ToolIDs = Gan_Services('GetToolIDs', MetStage, 'PROD') NumTools = DCount(ToolIDs, @VM) If NumTools EQ 1 then ToolID = ToolIDs<0, 1> RunStageWfrRec = ToolID Database_Services('WriteDataRow', 'RUN_STAGE_WFR', RunStageWfrKey, RunStageWfrRec, True$, False$, True$) end end If ToolID NE '' then Locate MetStage in MetStageIDList using @VM setting RowIndex then ThisComboArray = MetToolIDArray Convert @STM to @VM in ThisComboArray Locate ToolID in ThisComboArray using @VM setting vPos then Set_Property(MetStageCtrl, "OLE.CellComboSelPos[2; ":RowIndex:"]", vPos) end else Set_Property(MetStageCtrl, "OLE.CellText[2;":RowIndex:"]", ToolID) end // Tool ID is set, so enable wafer action dropdown menus. If ( (MetStage NE 'UV') and (MetStage NE 'UV_PRE') and (MetStage NE 'UV_PST') and (MetStage NE 'WARP') and (MetStage NE 'CAN') and (MetStage NE 'CAN_PRE') and (MetStage NE 'CAN_PST') and (MetStage NE 'WET_CLEAN') ) then Set_Property(MetStageCtrl,"OLE.CellProtection[":CurrWfrCol:"; ":RowIndex:"]","None") end MetRowsEnabled = True$ end end end end Next WfrID end Next MetStage Set_Property(@Window, '@METROWSENABLED', MetRowsEnabled) return FillDispStageHeader: DispStageCtrl = @Window:'.OLE_DISP_STAGE_EDT' ScribeHeaderTitles = Get_Property(@Window, '@SCRIBE_HEADER_TITLES') HeaderRowTitles = 'LSL':@VM:'Target':@VM:'USL':@VM:ScribeHeaderTitles Set_Property(DispStageCtrl, "OLE.TitleList", HeaderRowTitles) Set_Property(DispStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") return FillMetHeader: Scribes = Xlate('REACT_RUN', RDSNo, 'WFR_SCRIBES', 'X') CarrSlotIDs = Xlate('REACT_RUN', RDSNo, 'CARR_SLOT_NO', 'X') Set_Property(@Window, '@SCRIBES', Scribes) Set_Property(@Window, '@CARRSLOTIDS', CarrSlotIDs) MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' ScribesCopy = Scribes Convert @VM to '' in ScribesCopy HeaderTitles = "Stage":@VM:"Tool ID" ScribeHeaderTitles = '' If ScribesCopy NE '' then For each Scribe in Scribes using @VM setting vPos SlotID = CarrSlotIDs<0, vPos> ScribeHeaderTitles<0, -1> = Scribe:' (':SlotID:')' Next Scribe HeaderTitles<0, -1> = ScribeHeaderTitles Set_Property(@Window, '@SCRIBE_HEADER_TITLES', ScribeHeaderTitles) end else DefWfrTitles = '' For WfrIndex = 1 to NumWfrs DefWfrTitles<1, -1> = 'Wafer ':WfrIndex Next WfrIndex HeaderTitles = "Stage":@VM:"Tool ID":@VM:DefWfrTitles end Set_Property(MetStageCtrl, "OLE.TitleList", HeaderTitles) Set_Property(MetStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") return EnableRows: // Enable rows and columns now that RUN_STAGE_WFR records have been created GaNRunID = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' Scribes = Xlate('REACT_RUN', RDSNo, 'PKT_SAT_ID', 'X') DummyPockets = '' NumDummyWfrs = 0 For each Scribe in Scribes using @VM setting vPos DummyID = GanRunID[1,7]:'D' If Scribe[1,8] EQ DummyID then NumDummyWfrs += 1 DummyPockets<1, vPos> = True$ end else DummyPockets<1, vPos> = False$ end Next Scribe NumWfrs = DCount(Scribes, @VM) Set_Property(@Window, '@DUMMYPOCKETS', DummyPockets) Set_Property(@Window, '@NUMWFRS', NumWfrs) MetDimArray = Get_Property(@Window, '@METDIMARRAY') NumMetCols = MetDimArray<1> DispDimArray = Get_Property(@Window, '@DISPDIMARRAY') NumDispCols = DispDimArray<1> EnabledColorArray = 'None':@FM:'None':@FM:'None':@FM:'None':@FM:'None' For each Pocket in DummyPockets using @VM setting vPos If Pocket EQ True$ then ColNo = vPos + 2 Set_Property(MetStageCtrl,"OLE.CellProtection[":ColNo:"; All]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":ColNo:"; All]", EnabledColorArray) Set_Property(MetStageCtrl,"OLE.ColumnData[":ColNo:"]", '') Set_Property(MetStageCtrl,"OLE.HeaderColors[":ColNo+1:"; 1]", EnabledColorArray) end Next Pocket // Protect and color empty wafer columns If NumWfrs GT 0 then ColOffset = 3 StartCol = ColOffset EndCol = NumWfrs + ColOffset Set_Property(MetStageCtrl,"OLE.CellProtection[":StartCol:"-":EndCol:"; 1-6]", "None") Set_Property(MetStageCtrl,"OLE.CellColors[":StartCol:"-":EndCol:"; 1-6]", EnabledColorArray) Set_Property(MetStageCtrl,"OLE.ColumnData[":StartCol:"-":EndCol:"]", '') Set_Property(MetStageCtrl,"OLE.HeaderColors[":StartCol+1:"-":EndCol+1:"; 1]", EnabledColorArray) end return FillDispEditTable: InWfrIDs = '' Scribes = '' For WfrIndex = 1 to 8 InWfrIDs<0, WfrIndex> = '123456*1*':WfrIndex Scribes<0, WfrIndex> = 'Scribe0':WfrIndex Next WfrIndex RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') DispCtrl = @Window:'.OLE_DISP_EDT' DispDimArray = Get_Property(@Window, '@DISPDIMARRAY') NumDispRows = DispDimArray<2> Set_Property(DispCtrl, "OLE.HeaderMerge[1; 2]", 1:@FM:NumDispRows) DispCtrlArray = '' Slots = Get_Property(@Window, '@SLOTS') NumWfrs = DCount(InWfrIDs, @VM) RDSClosed = False$ For WfrIndex = 1 to NumWfrs Row = WfrIndex WfrID = InWfrIDs<0, WfrIndex> DispCtrlArray = Slots<0, WfrIndex> DispCtrlArray = WfrID DispCtrlArray = Scribes<0, WfrIndex> DispCtrlArray = '' DispCtrlArray = '' DispCtrlArray = '' DispCtrlArray = 'Prod' Next WfrIndex Set_Property(DispCtrl, "OLE.ARRAY", DispCtrlArray) GoSub EnableNCRButton return Event OLE_NCR_EDT.OnDblClick(Cell, Point, Button, Shift, Ctrl) DispCtrlArray = Get_Property(@Window:'.OLE_DISP_EDT', "OLE.ARRAY") Row = Field(Cell, ';', 2, 1) RDSNCRNos = DispCtrlArray WMONCRNos = DispCtrlArray NCRNos = SRP_Array('Join', RDSNCRNos, WMONCRNos, 'OR', @VM) NCRNo = Get_Property(CtrlEntID, "OLE.CellText[":COL$NCR_NO:";":Row:"]") If RowExists('NCR', NCRNo) then PreNCRRec = Database_Services('ReadDataRow', 'NCR', NCRNo) PostNCRRec = '' Dialog_Box('NCR', @Window, NCRNo) If RowExists('NCR', NCRNo) then PostNCRRec = Database_Services('ReadDataRow', 'NCR', NCRNo) If PreNCRRec NE PostNCRRec then RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'H') Def = "" Def = "Loading..." Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) Disposition_Services('AutoDispositionRun', RDSNo) Msg(@Window, MsgUp, 20, MSGINSTUPDATE$) Msg(@Window, MsgUp, 40, MSGINSTUPDATE$) GoSub FillDispEditTable Msg(@Window, MsgUp, 60, MSGINSTUPDATE$) GoSub FillNCREditTable Msg(@Window, MsgUp, 80, MSGINSTUPDATE$) GoSub EnableCloseRDSButton Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) GoSub EnableNCRButton Msg(@Window, MsgUp) PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'A') end end end event Event OLE_DISP_STAGE_EDT.OnClick(Cell, Point, Button, Shift, Ctrl) If Button EQ 'Right' then Col = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) CellColorArray = Get_Property(@Window, '@COLOR_ARRAY') SelTabIndex = Get_Property(@Window:".OLE_TAB", "OLE.SelectedTab") CaptionList = Get_Property(@Window:".OLE_TAB", "OLE.CaptionList") StageID = Field(CaptionList, ',', SelTabIndex, 1) BackColor = CellColorArray CellText = Get_Property(CtrlEntID, "OLE.CellText[":Col:";":Row:"]") Begin Case Case CellText EQ 'Multi' PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup end GoSub DisplayMetPopup Case BackColor EQ 'Yellow' PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup end GoSub DisplayStageDisPopup End Case end end event Event OLE_DISP_STAGE_EDT.OnHeaderClick(Cell, Point, Button, Shift, Ctrl) If Button EQ 'Right' then Col = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) Scribe = Get_Property(CtrlEntID, "OLE.HeaderText[":Col:";":Row:"]") Scribe = Scribe[1, 'F '] RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') Scribes = Get_Property(@Window, '@SCRIBES') RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') RDSClosed = Xlate('REACT_RUN', RDSNo, 'DISP_COMPLETE', 'X') Locate Scribe in Scribes using @VM setting WfrIndex then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) DataValidationDisabled = ReactRunRec DataIsMissing = ReactRunRec DataOutOfSpec = ReactRunRec If RDSClosed EQ True$ then Enabled = False$ end else Enabled = True$ end Menu = '' Begin Case Case DataValidationDisabled EQ True$ Menu<-1> = 'ENABLE' :@VM: 'Enable Data Validation' :@VM: Enabled Case ( ( (DataValidationDisabled NE True$) and (DataIsMissing EQ True$) ) or (DataOutOfSpec EQ True$) ) Menu<-1> = 'DISABLE' :@VM: 'Disable Data Validation' :@VM: Enabled Case Otherwise$ Menu<-1> = 'DISABLE' :@VM: 'Disable Data Validation' :@VM: False$ End Case // Note you must pass all variables when calling Send_Message otherwise the call will fail User = '' Locate Scribe in Scribes using @VM setting WfrIndex then User = WfrIndex end Send_Message(CtrlEntID, "OLE.ShowContextMenu", Point, Menu, User) end end end event Event OLE_DISP_STAGE_EDT.OnContextMenuClick(Item, UserData) Abort = False$ If Not( Memberof(@User4, 'GAN_WIP_SUPERVISOR') ) then MsgText = 'A member of the "GAN_WIP_SUPERVISOR" group must override.' Response = Msg(@Window, '', 'OVERRIDE', '', MsgText) If Response EQ Yes$ then // Verify credentials Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4:@FM:'GAN_WIP_SUPERVISOR') Valid = Response<1> If Valid NE True$ then Abort = True$ end else Abort = True$ end end If Abort EQ False$ then RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) WfrIDs = ReactRunRec Action = Item WfrIndex = UserData WfrID = WfrIDs<0, WfrIndex> TabCount = Get_Property(@Window:'.OLE_TAB', 'OLE.TabCount') CellColorArray = Get_Property(@Window, '@COLOR_ARRAY') Begin Case Case Action EQ 'DISABLE' ReactRunRec = True$ ReactRunRec = @User4 ReactRunRec = Datetime() Case Action EQ 'ENABLE' ReactRunRec = False$ ReactRunRec = '' ReactRunRec = '' End Case For TabIndex = 1 to TabCount ThisTabCellColorArray = CellColorArray Convert @VM to @FM in ThisTabCellColorArray Convert @SVM to @VM in ThisTabCellColorArray ThisTabCellColorArray = SRP_Array('Rotate', ThisTabCellColorArray, @FM, @VM) ThisWaferCellColorArray = ThisTabCellColorArray Stage = Get_Property(@Window:'.OLE_TAB', "OLE.TabCaption[":TabIndex:"]") Swap ' ' with '_' in Stage Swap '*' with '.' in WfrID RunStageWfrKey = RDSNo:'*':Stage:'*':WfrID ParamOutOfSpec = Xlate('RUN_STAGE_WFR', RunStageWfrKey, RUN_STAGE_WFR_PARAM_OUT_OF_SPEC$, 'X') DataOutOfSpec = False$ DataMissing = False$ For each Value in ParamOutOfSpec using @VM If Value EQ 1 then DataOutOfSpec = True$ If Value EQ -1 then DataMissing = True$ Next Value Begin Case Case Action EQ 'DISABLE' Begin Case Case DataOutOfSpec EQ True$ Swap 'Red' with 'SlateBlue L=75' in ThisWaferCellColorArray Case DataMissing EQ True$ Swap 'Yellow' with 'SlateBlue L=75' in ThisWaferCellColorArray End Case Case Action EQ 'ENABLE' Begin Case Case DataOutOfSpec EQ True$ Swap 'SlateBlue L=75' with 'Red' in ThisWaferCellColorArray Case DataMissing EQ True$ Swap 'SlateBlue L=75' with 'Yellow' in ThisWaferCellColorArray End Case End Case ThisTabCellColorArray = ThisWaferCellColorArray ThisTabCellColorArray = SRP_Array('Rotate', ThisTabCellColorArray, @FM, @VM) Convert @VM to @SVM in ThisTabCellColorArray Convert @FM to @VM in ThisTabCellColorArray CellColorArray = ThisTabCellColorArray Next TabIndex Set_Property(@Window, '@COLOR_ARRAY', CellColorArray) Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) Disposition_Services('AutoDispositionRun', RDSNo) GoSub ColorCells GoSub ColorTabs GoSub FillDispEditTable GoSub EnableCloseRDSButton end end event Event OLE_DISP_EDT.OnClick(Cell, Point, Button, Shift, Ctrl) Col = Field(Cell, ';', 1, 1) Row = Field(Cell, ';', 2, 1) Begin Case Case Col EQ COL$DISP_WFR_ID If Button _EQC 'Right' then RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') WfrID = Get_Property(CtrlEntID, "OLE.CellText[":COL$DISP_WFR_ID:";":Row:"]") Menu = '' MenuEnabled = False$ If RowExists('WO_WFR', WfrID) then MenuEnabled = True$ Menu<-1> = "CharStages" :@VM:"View Char Stages" :@VM:MenuEnabled Menu<-1> = "WaferTrace" :@VM:"View Wafer Trace" :@VM:MenuEnabled Send_Message(CtrlEntID, "OLE.ShowContextMenu", Point, Menu, WfrID) end End Case If Col EQ COL$DISP_WFR_ID then If Button _EQC 'Right' then RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') WfrID = Get_Property(CtrlEntID, "OLE.CellText[":COL$DISP_WFR_ID:";":Row:"]") Menu = '' MenuEnabled = False$ If RowExists('WO_WFR', WfrID) then MenuEnabled = True$ Menu<-1> = "CharStages" :@VM:"View Char Stages" :@VM:MenuEnabled Menu<-1> = "WaferTrace" :@VM:"View Wafer Trace" :@VM:MenuEnabled Send_Message(CtrlEntID, "OLE.ShowContextMenu", Point, Menu, WfrID) end end end event Event OLE_DISP_EDT.OnContextMenuClick(Item, UserData) RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') Action = Item WfrID = UserData Begin Case Case Action _EQC 'CharStages' WfrSigProfile = obj_React_Run('GetWfrSigKeys', RDSNo:@RM:WfrID) TypeOver = '' TypeOver = WfrSigProfile Dummy = Popup(@Window, TypeOver, 'CHAR_WFR_STAGES') Case Action _EQC 'WaferTrace' TraceData = obj_WO_Wfr('TraceData', WfrID:@RM:'') TypeOver = '' TypeOver = TraceData Dummy = Popup(@Window, TypeOver, 'WAFER_TRACE') End Case end event EnableNCRButton: Checkmarks = Get_Property(@Window:".OLE_DISP_EDT", "OLE.CellCheck[":COL$DISP_RDS_NCR:"; All]") Checksum = Sum(Checkmarks) If ( Checksum GT 0 ) then NCRButton = True$ end else NCRButton = False$ end Set_Property(@Window:'.PUB_CREATE_NCR', 'ENABLED', NCRButton) return FillNCREditTable: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') NCRCtrl = @Window:'.OLE_NCR_EDT' InWfrIDs = Get_Property(@Window, '@WFRIDS') NCRCtrlArray = '' NCRNos = '' RDSNCRs = Xlate('WO_WFR', InWfrIDs, 'RDS_NCR_NO', 'X') WMONCRs = Xlate('WO_WFR', InWfrIDs, 'WMO_NCR_NO', 'X') NCRNos = SRP_Array('Join', RDSNCRs, WMONCRs, 'OR', @VM) NCRNos = SRP_Array('Clean', NCRNos, 'Trim', @VM) If NCRNos NE '' then For each NCRNo in NCRNos using @VM setting nPos Database_Services('ActivateRecord', 'NCR', NCRNo) If Error_Services('NoError') then NCRCtrlArray = NCRNo NCRCtrlArray = {STATUS} NCRCtrlArray = {REJ_CNT} NCRCtrlArray = {LOSS_BY} NCRCtrlArray = {LOSS_STAGE} NCRCtrlArray = {LOSS_DESC} NCRCtrlArray = {LOSS_COMMENTS} NCRCtrlArray = OConv({AUTH_SHIP_SIG}, '[XLATE_CONV,LSL_USERS*FIRST_LAST]') NCRCtrlArray = OConv({AUTH_SHIP_SIG_DTM}, 'DT') end else NCRCtrlArray = NCRNo NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' NCRCtrlArray = 'Error' end Next NCRNo end else // No NCRs associated with this inbound cassette, so clear the NCR table. NCRDimArray = Get_Property(@Window, '@NCRDIMARRAY') NumRows = NCRDimArray<2> For nPos = 1 to NumRows NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' NCRCtrlArray = '' Next nPos end Set_Property(NCRCtrl, "OLE.ARRAY", NCRCtrlArray) return DismissPopup: PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then Send_Message(PopupCtrl, 'OLE.Close') end return DisplayPopup: Set_Property('SYSTEM', 'CURSOR', 'H') BackColor = Get_Property(@Window, 'BACKCOLOR') ForeColor = Get_Property(@Window, 'FORECOLOR') CursorXPos = Field(Point, ',', 1, 1) CursorYPos = Field(Point, ',', 2, 1) FormSize = SRP_Get_Window_Rect(@Window) FormXPos = FormSize<1> FormYPos = FormSize<2> CtrlSize = Get_Property(CtrlEntID, 'SIZE') CtrlXPos = CtrlSize<1> CtrlYPos = CtrlSize<2> PopupWidth = 160 PopupHeight = 60 XPadding = 10 YPadding = 10 XOffset = 10 YOffset = 55 PopupXPos = FormXPos + CtrlXPos + CursorXPos + XOffset PopupYPos = FormYPos + CtrlYPos + CursorYPos + YOffset StatusBy = '' StatusDTM = '' RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) StageDesc = Get_Property(CtrlEntID, 'OLE.CellText[1; ':Row:']') StageID = Gan_Services('GetStageID', StageDesc) Begin Case Case CtrlEntID _EQC @Window:'.OLE_REACTOR_EDT' // Cassette Level RunStageKey = RDSNo:'*':StageID RunStageRec = Database_Services('ReadDataRow', 'RUN_STAGE', RunStageKey) StageStatus = RunStageRec Begin Case Case StageStatus _EQC 'COMP' or StageStatus _EQC 'SKIP' StatusBy = RunStageRec StatusDTM = RunStageRec Case StageStatus _EQC 'START' InvActions = RunStageRec Locate 'START' in InvActions using @VM setting vPos then StatusBy = RunStageRec StatusDTM = RunStageRec end End Case Case CtrlEntID _EQC @Window:'.OLE_METROLOGY_EDT' // Wafer level ScribeHeader = Get_Property(CtrlEntID, 'OLE.HeaderText[':Column+1:'; 1]') Scribe = ScribeHeader[1, 'F '] Scribes = Xlate('REACT_RUN', RDSNo, 'WFR_SCRIBES', 'X') WfrIDs = ReactRunRec WfrID = '' Locate Scribe in Scribes using @VM setting vPos then WfrID = WfrIDs<0, vPos> end Convert '*' to '.' in WfrID RunStageWfrKey = RDSNo:'*':StageID:'*':WfrID If RowExists('RUN_STAGE_WFR', RunStageWfrKey) then RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey) end else // This may be an old run that has a CAN stage instead of a CAN_PRE stage If StageID EQ 'CAN_PRE' then RunStageWfrKey = RDSNo:'*CAN*':WfrID If RowExists('RUN_STAGE_WFR', RunStageWfrKey) then RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey) end end end StageStatus = RunStageWfrRec Begin Case Case StageStatus _EQC 'COMP' or StageStatus _EQC 'SKIP' or StageStatus _EQC 'CHAR' or StageStatus _EQC 'DISP' StatusBy = RunStageWfrRec StatusDTM = RunStageWfrRec Case StageStatus _EQC 'START' InvActions = RunStageWfrRec Locate 'START' in InvActions using @VM setting vPos then StatusBy = RunStageWfrRec StatusDTM = RunStageWfrRec end End Case End Case If (StatusBy NE '') and (StatusDTM NE '') then HoverData = '' HoverData := OConv(StatusBy, '[XLATE_CONV,LSL_USERS*FIRST_LAST]') : @FM HoverData := OConv(StatusDTM, 'DT') NumLines = DCount(HoverData, @FM) ItemList = '' If HoverData NE '' then For Each Item in HoverData using @FM setting ItemCount ItemList = XPadding ; // X Position of item ItemList = (20 * (ItemCount - 1) ) ; // Y Position of item ItemList = PopupWidth - (2 * XPadding) ; // Width ItemList = PopupHeight - (2 * YPadding) ; // Height ItemList = Item ItemList = Forecolor ItemList = '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' ItemList = 'Left' : @SVM : 'Center' Next Item end Set_Property(PopupCtrl, 'OLE.Theme', 'Custom') Set_Property(PopupCtrl, 'OLE.Opacity', 255) Set_Property(PopupCtrl, 'OLE.Animation', 'N') Set_Property(PopupCtrl, 'OLE.Background', 'Vertical(Gradient(' : Backcolor : ', ' : Backcolor : '), Border(' : Backcolor : ' L=20))' : @FM : 'None' : @FM : 'None') Set_Property(PopupCtrl, 'OLE.ItemList', ItemList) Set_Property(PopupCtrl, 'OLE.ShowDelay', 1000) Set_Property(PopupCtrl, 'OLE.Size', 0 : @FM : 0 : @FM : PopupWidth : @FM : PopupHeight) Send_Message(PopupCtrl, 'OLE.ShowAt', PopupXPos, PopupYPos) end Set_Property('SYSTEM', 'CURSOR', 'A') return DisplayMetPopup: Set_Property('SYSTEM', 'CURSOR', 'H') BackColor = Get_Property(@Window, 'BACKCOLOR') ForeColor = Get_Property(@Window, 'FORECOLOR') CursorXPos = Field(Point, ',', 1, 1) CursorYPos = Field(Point, ',', 2, 1) FormSize = SRP_Get_Window_Rect(@Window) FormXPos = FormSize<1> FormYPos = FormSize<2> CtrlSize = Get_Property(CtrlEntID, 'SIZE') CtrlXPos = CtrlSize<1> CtrlYPos = CtrlSize<2> PopupWidth = 130 XPadding = 10 YPadding = 10 XOffset = 10 YOffset = 55 PopupXPos = FormXPos + CtrlXPos + CursorXPos + XOffset PopupYPos = FormYPos + CtrlYPos + CursorYPos + YOffset StatusBy = '' StatusDTM = '' RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) TabIndex = Get_Property(@Window:'.OLE_TAB', 'OLE.SelectedTab') Stage = Get_Property(@Window:'.OLE_TAB', 'OLE.TabCaption[':TabIndex:']') WfrIndex = Col - 3 InWfrIDs = Get_Property(@Window, '@WFRIDS') WfrID = InWfrIDs<0, WfrIndex> Convert '*' to '.' in WfrID RunStageWfrKey = RDSNo:'*':Stage:'*':WfrID RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey) ParamValues = RunStageWfrRec OutOfSpec = RunStageWfrRec RowParamValues = ParamValues<0, Row> RowOutOfSpec = OutOfSpec<0, Row> ColorArray = '' Convert @SVM to @FM in RowParamValues HoverData = 'Index | Value' For each Value in RowParamValues setting Index HoverData := @FM:Index:' | ':Value If RowOutOfSpec<0, 0, Index> EQ True$ then ColorArray = 'Red' end else ColorArray = 'None' end Next Value NumLines = DCount(HoverData, @FM) PopupHeight = (25 * (NumLines) ) ItemList = '' If HoverData NE '' then For Each Item in HoverData using @FM setting ItemCount ItemList = XPadding ; // X Position of item ItemList = ( 25 * (ItemCount - 1) ) ; // Y Position of item ItemList = PopupWidth - (2 * XPadding) ; // Width ItemList = 25 ; // Height ItemList = Item ItemList = ColorArray ItemList = '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' ItemList = 'Left' : @SVM : 'Center' Next Item end Set_Property(PopupCtrl, 'OLE.Theme', 'Custom') Set_Property(PopupCtrl, 'OLE.Opacity', 255) Set_Property(PopupCtrl, 'OLE.Animation', 'N') Set_Property(PopupCtrl, 'OLE.Background', 'Vertical(Gradient(' : Backcolor : ', ' : Backcolor : '), Border(' : Backcolor : ' L=20))' : @FM : 'None' : @FM : 'None') Set_Property(PopupCtrl, 'OLE.ItemList', ItemList) Set_Property(PopupCtrl, 'OLE.ShowDelay', 1000) Set_Property(PopupCtrl, 'OLE.Size', 0 : @FM : 0 : @FM : PopupWidth : @FM : PopupHeight) Send_Message(PopupCtrl, 'OLE.ShowAt', PopupXPos, PopupYPos) Set_Property('SYSTEM', 'CURSOR', 'A') return DisplayStageDisPopup: Set_Property('SYSTEM', 'CURSOR', 'H') BackColor = Get_Property(@Window, 'BACKCOLOR') ForeColor = Get_Property(@Window, 'FORECOLOR') CursorXPos = Field(Point, ',', 1, 1) CursorYPos = Field(Point, ',', 2, 1) FormSize = SRP_Get_Window_Rect(@Window) FormXPos = FormSize<1> FormYPos = FormSize<2> CtrlSize = Get_Property(CtrlEntID, 'SIZE') CtrlXPos = CtrlSize<1> CtrlYPos = CtrlSize<2> PopupWidth = 160 PopupHeight = 60 XPadding = 10 YPadding = 10 XOffset = 10 YOffset = 55 PopupXPos = FormXPos + CtrlXPos + CursorXPos + XOffset PopupYPos = FormYPos + CtrlYPos + CursorYPos + YOffset StatusBy = '' StatusDTM = '' RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) * WfrStages = Locate StageID in WfrStages using @VM setting StageIndex then DisabledBy = ReactRunRec DisabledDTM = ReactRunRec If (DisabledBy NE '') and (DisabledDTM NE '') then HoverData = '' HoverData := OConv(DisabledBy, '[XLATE_CONV,LSL_USERS*FIRST_LAST]') : @FM HoverData := OConv(DisabledDTM, 'DT') NumLines = DCount(HoverData, @FM) ItemList = '' If HoverData NE '' then For Each Item in HoverData using @FM setting ItemCount ItemList = XPadding ; // X Position of item ItemList = (20 * (ItemCount - 1) ) ; // Y Position of item ItemList = PopupWidth - (2 * XPadding) ; // Width ItemList = PopupHeight - (2 * YPadding) ; // Height ItemList = Item ItemList = Forecolor ItemList = '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' ItemList = 'Left' : @SVM : 'Center' Next Item end Set_Property(PopupCtrl, 'OLE.Theme', 'Custom') Set_Property(PopupCtrl, 'OLE.Opacity', 255) Set_Property(PopupCtrl, 'OLE.Animation', 'N') Set_Property(PopupCtrl, 'OLE.Background', 'Vertical(Gradient(' : Backcolor : ', ' : Backcolor : '), Border(' : Backcolor : ' L=20))' : @FM : 'None' : @FM : 'None') Set_Property(PopupCtrl, 'OLE.ItemList', ItemList) Set_Property(PopupCtrl, 'OLE.ShowDelay', 1000) Set_Property(PopupCtrl, 'OLE.Size', 0 : @FM : 0 : @FM : PopupWidth : @FM : PopupHeight) Send_Message(PopupCtrl, 'OLE.ShowAt', PopupXPos, PopupYPos) end end Set_Property('SYSTEM', 'CURSOR', 'A') return VerifyRecipe: GaNRunID = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') If GaNRunID NE '' then GaNRecipe = Get_Property(@Window:'.GAN_RECIPE', 'TEXT') Convert @Lower_Case to @Upper_Case in GaNRunID SchedRecipe = Xlate('GAN_SCHEDULE', GaNRunID, 'RECIPE', 'X') If GaNRecipe NE '' then If SchedRecipe _EQC GaNRecipe then // If the recipes match, then color the recipe ID bright green, otherwise // color it bright red and block the Run Configuration "Complete" event. Set_Property(@Window:'.GAN_RECIPE', 'BACKCOLOR', BGREEN$) Set_Property(@Window, '@RECIPEMISMATCH', False$) end else Set_Property(@Window:'.GAN_RECIPE', 'BACKCOLOR', BRED$) Set_Property(@Window, '@RECIPEMISMATCH', True$) end end end return EnableRunIDComboBox: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') EtchKey = RDSNo:'*ETCH' EtchStatus = Xlate('RUN_STAGE', EtchKey, 'STATUS', 'X') If EtchStatus _EQC 'COMP' then Set_Property(@Window:'.CMB_GAN_RUN_ID', 'ENABLED', True$) end else Set_Property(@Window:'.CMB_GAN_RUN_ID', 'ENABLED', False$) end return FillCommentsTable: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') CassComments = Xlate('REACT_RUN', RDSNo, 'CASS_COMMENTS', 'X') Set_Property(@Window:'.EDB_CASS_COMMENTS', 'TEXT', CassComments) Set_Property(@Window, '@COMMENTS', CassComments) return EnableCloseRDSButton: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) DispComp = ReactRunRec DispCtrl = @Window:'.PUB_CLOSE_RDS' If DispComp NE True$ then Set_Property(DispCtrl, 'ENABLED', True$) end else Set_Property(DispCtrl, 'ENABLED', False$) end return UpdateRDSStatus: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) DispComp = ReactRunRec If DispComp EQ True$ then Set_Property(@Window:'.LBL_RDS_STATUS', 'TEXT', 'CLOSED') Set_Property(@Window:'.LBL_RDS_STATUS', 'FORECOLOR', BRED$) end else Set_Property(@Window:'.LBL_RDS_STATUS', 'TEXT', 'OPEN') Set_Property(@Window:'.LBL_RDS_STATUS', 'FORECOLOR', BGREEN$) end return EnableLotAbortButton: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') GrowthKey = RDSNo:'*GROWTH' GrowthStatus = Xlate('RUN_STAGE', GrowthKey, 'STATUS', 'X') // Need to check each wafer's current stage. If all wafers are at disposition, then // there is no need to enable the "Lot Abort" button. LotAbortAllowed = False$ WfrIDs = Xlate('REACT_RUN', RDSNo, 'IN_WFR_ID', 'X') For each WfrID in WfrIDs using @VM setting vPos CurrStage = Gan_Services('GetCurrStage', WfrID) If (CurrStage _NEC 'DISP') and (CurrStage _NEC 'G_PACK') and (CurrStage _NEC 'RETAIN') then LotAbortAllowed = True$ end Next WfrID If (GrowthStatus _EQC 'COMP') and (LotAbortAllowed EQ True$) then Set_Property(@Window:'.PUB_LOT_ABORT', 'ENABLED', True$) end else Set_Property(@Window:'.PUB_LOT_ABORT', 'ENABLED', False$) end return EnableImportMetDataButton: RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') UserAuthorized = Memberof(@User4, 'GAN_WIP_SUPERVISOR') RDSClosed = Xlate('REACT_RUN', RDSNo, 'DISP_COMPLETE', 'X') Enabled = ( (RDSClosed NE True$) and (UserAuthorized EQ True$) ) Set_Property(@Window:'.PUB_IMPORT_MET_DATA', 'ENABLED', Enabled) return ResetColorArrays: PSNo = Get_Property('PROD_SPEC.PROD_SPEC_ID', 'TEXT') PartNo = Get_Property(@Window, '@CURR_PART_NO') GaNParamStages = Get_Property(@Window, '@GAN_PARAM_STAGES') CellColorArray = '' For each Stage in GaNParamStages using @VM setting TabIndex GaNParamConfigKey = PSNo:'*':PartNo:'*':Stage GaNParamConfigRec = Database_Services('ReadDataRow', 'GAN_PARAM_CONFIG', GaNParamConfigKey) ParamNames = GaNParamConfigRec For each ParamName in ParamNames using @VM setting RowPos CellColorArray = 'None' CellColorArray = 'None' CellColorArray = 'None' CellColorArray = 'None' CellColorArray = 'None' Next ParamName Next Stage Set_Property(@Window, '@COLOR_ARRAY', CellColorArray) return SetupTabCtrl: GaNParamStages = Xlate('APP_INFO', 'GAN_PARAM_STAGES_DEMO', '', 'X') TabCtrl = @Window:'.OLE_TAB' NumTabs = DCount(GaNParamStages, @VM) Set_Property(TabCtrl, "OLE.TabCount", NumTabs) Convert @VM to ',' in GaNParamStages Convert '_' to ' ' in GaNParamStages Set_Property(TabCtrl, "OLE.CaptionList", GaNParamStages) FontArray = 'Segoe UI':@SVM:9:@SVM:700 Set_Property(TabCtrl, "OLE.Font", FontArray) Set_Property(TabCtrl, "OLE.SelectFont", FontArray) // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously Send_Message(TabCtrl, 'QUALIFY_EVENT', 'OLE.SelChanged', Qualifier) return SetupDispStageCtrl: DispStageCtrl = @Window:'.OLE_DISP_STAGE_EDT' ScribeHeaderTitles = Get_Property(@Window, '@SCRIBE_HEADER_TITLES') HeaderRowTitles = 'LSL':@VM:'Target':@VM:'USL':@VM:ScribeHeaderTitles DispRows = 6 DispCols = 11 DispStageDimArray = DispCols:@FM:DispRows Set_Property(DispStageCtrl, "OLE.Dimension", DispStageDimArray) * DispStageList = '' * For Row = 1 to DispRows * For Col = 1 to DispCols * DispStageList = ' ' * Next Col * Next Row * Set_Property(DispStageCtrl, "OLE.LIST", DispStageList) Set_Property(DispStageCtrl, "OLE.TitleList", HeaderRowTitles) HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 Set_Property(DispStageCtrl, "OLE.HeaderFont[All; All]", HeaderFontArray) HeaderColArray = 181:@FM:True$:@FM:False$:@FM:False$ Set_Property(DispStageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(DispStageCtrl, "OLE.HeaderText[1; 1]", "Metrology Limits") // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(DispStageCtrl, "OLE.DataColumn[1]") StageColSize<1> = 55 StageColSize<3> = False$ Set_Property(DispStageCtrl, "OLE.DataColumn[1-3]", StageColSize) StageColSize<1> = 96 Set_Property(DispStageCtrl, "OLE.DataColumn[4-11]", StageColSize) Set_Property(DispStageCtrl, "OLE.CellProtection[All; All]", 'None') // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(DispStageCtrl, 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier) Send_Message(DispStageCtrl, 'QUALIFY_EVENT', 'OLE.OnHeaderClick', Qualifier) Send_Message(DispStageCtrl, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualifier) return ReadCurrParams: * RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') * ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) * ValidationDisFlags = ReactRunRec * MetStageCtrl = @Window:'.OLE_METROLOGY_EDT' * MetStageList = Get_Property(MetStageCtrl, "OLE.ColumnData[1]") * Reactor = 'R':Get_Property(@Window, '@REACTOR') * RunNo = Get_Property(@Window:'.CMB_GAN_RUN_ID', 'TEXT') * Scribes = Get_Property(@Window, '@SCRIBES') * InWfrIDs = Get_Property(@Window, '@WFRIDS') * * PSNo = Get_Property(@Window, '@PS_NO') * If PSNo NE '' then * GaNParamStages = Xlate('APP_INFO', 'GAN_PARAM_STAGES', '', 'X') * GaNParamKeys = Xlate('REACT_RUN', RDSNo, 'GAN_PARAM_KEYS', 'X') * ParameterList = '' * ParamNameList = '' * MetNameList = '' * CellColorArray = '' * ParamOutOfSpec = '' * * GaNParamKeysPrime = SRP_Array('Rotate', GaNParamKeys, @VM, '*') * ConfigGaNParamStages = GaNParamKeysPrime<0, 2> * Set_Property(@Window, '@GAN_PARAM_STAGES', GaNParamStages) * Convert '*' to @VM in ConfigGaNParamStages * * For each GaNParamKey in GaNParamKeys using @VM * * MetType = Field(GaNParamKey, '*', 2) * Locate MetType in GaNParamStages using @VM setting TabPos then * * StageID = MetType * StageDesc = GaN_Services('GetStageDesc', MetType) * ToolType = MetType * * GaNParamRec = Database_Services('ReadDataRow', 'GAN_PARAMS', GaNParamKey) * PartNo = Field(GaNParamKey, '*', 1) * ParamNames = GaNParamRec * MetNames = GaNParamRec * * Locate StageDesc in MetStageList using @VM setting StageRowPos then * Tool = Get_Property(@Window : '.OLE_METROLOGY_EDT', 'OLE.CellText[2; ':StageRowPos:']') * end * * MetParameter = '' * ParamValues = '' * MetData = '' * * For each WfrID in InWfrIDs using @VM setting WaferIndex * * Convert '*' to '.' in WfrID * Begin Case * Case StageID EQ 'UV_PRE' * // Check if UV stage exists * UVStageWfrKey = RDSNo:'*UV*':WfrID * If RowExists('RUN_STAGE_WFR', UVStageWfrKey) then * // Display this on the UV_PRE line * RunStageWfrKey = UVStageWfrKey * end else * RunStageWfrKey = RDSNo:'*':StageID:'*':WfrID * end * Case StageID EQ 'CAN_PRE' * // Check if CAN stage exists * CanStageWfrKey = RDSNo:'*CAN*':WfrID * If RowExists('RUN_STAGE_WFR', CanStageWfrKey) then * // Display this on the CAN_PRE line * RunStageWfrKey = CanStageWfrKey * end else * RunStageWfrKey = RDSNo:'*':StageID:'*':WfrID * end * Case Otherwise$ * RunStageWfrKey = RDSNo:'*':StageID:'*':WfrID * End Case * If RowExists('RUN_STAGE_WFR', RunStageWfrKey) then * RunStageWfrRec = Database_Services('ReadDataRow', 'RUN_STAGE_WFR', RunStageWfrKey) * TheseParamValues = RunStageWfrRec * TheseOutOfSpecValues = RunStageWfrRec * If Index(TheseParamValues, @SVM, 1) GT 0 then * For each FlagSet in TheseOutOfSpecValues using @VM setting ParamIndex * ValueSet = TheseParamValues<0, ParamIndex> * NumVals = DCount(ValueSet, @SVM) * If NumVals GT 1 then * ParamValues = 'Multi' * OutOfSpec = ( Sum(TheseOutOfSpecValues<1, ParamIndex>) > 0 ) * end else * ParamValues = ValueSet * OutOfSpec = TheseOutOfSpecValues<1, ParamIndex> * end * ParamOutOfSpec = OutOfSpec * Next FlagSet * end else * ParamValues = TheseParamValues * ParamOutOfSpec = TheseOutOfSpecValues * end * end else * ParamValues = '' * ParamOutOfSpec = '' * end * Next WfrID * * ParamValues = SRP_Array('Rotate', ParamValues, @FM, @VM) * ParamOutOfSpec = SRP_Array('Rotate', ParamOutOfSpec, @FM, @VM) * * Convert @VM to @SVM in ParamValues * Convert @VM to @SVM in ParamOutOfSpec * Convert @FM to @VM in ParamOutOfSpec * * ParamOutOfSpec = SRP_Array('Rotate', ParamOutOfSpec, @VM, @SVM) * For each WfrID in InWfrIDs using @VM setting WaferIndex * ValidDisabled = ValidationDisFlags<0, WaferIndex> * WfrParamOutOfSpec = ParamOutOfSpec<0, WaferIndex> * If ValidDisabled EQ True$ then * Swap '-1' with 'SlateBlue L=75' in WfrParamOutOfSpec * Swap 1 with 'SlateBlue L=75' in WfrParamOutOfSpec * end else * Swap '-1' with 'Yellow' in WfrParamOutOfSpec * end * ParamOutOfSpec<0, WaferIndex> = WfrParamOutOfSpec * Next WfrID * ParamOutOfSpec = SRP_Array('Rotate', ParamOutOfSpec, @VM, @SVM) * * Swap 1 with 'Red' in ParamOutOfSpec * Swap 0 with 'None' in ParamOutOfSpec * * CellColorArray = ParamOutOfSpec * For each ParamName in ParamNames using @VM setting RowPos * * MetName = MetNames<0, RowPos> * MetNameList = ParamName * ParamNameList = MetName * ParameterList = GaNParamRec * ParameterList = GaNParamRec * ParameterList = GaNParamRec * If ParamValues NE '' then ParameterList = ParamValues * Next ParamName * * end * Next GaNParamKey * * Set_Property(@Window, '@NAME_LIST', ParamNameList) * Set_Property(@Window, '@VALUE_LIST', ParameterList) * Set_Property(@Window, '@ORIG_VALUE_LIST', ParameterList) * Set_Property(@Window, '@ORIG_MET_LIST', MetNameList) * Set_Property(@Window, '@COLOR_ARRAY', CellColorArray) * * end return FillDispStageCtrl: DispStageCtrl = @Window:'.OLE_DISP_STAGE_EDT' TabCtrl = @Window:'.OLE_TAB' TabIndex = Get_Property(TabCtrl, 'OLE.SelectedTab') HeaderTitles = '' ; //Get_Property(@Window, '@NAME_LIST') ParameterList = '' ; //Get_Property(@Window, '@VALUE_LIST') NumCols = 11 NumRows = 6 * DispStageDimArray = NumCols:@FM:NumRows * Set_Property(DispStageCtrl, "OLE.Dimension", DispStageDimArray) * DispStageList = '' * For Row = 1 to NumRows * For Col = 1 to NumCols * DispStageList = ' ' * Next Col * Next Row * Set_Property(DispStageCtrl, "OLE.LIST", DispStageList) * DispStageDimArray = NumCols:@FM:NumRows * Set_Property(DispStageCtrl, "OLE.Dimension", DispStageDimArray) * Convert @VM to @FM in ParameterList * Convert @SVM to @VM in ParameterList * Set_Property(@Window:'.OLE_DISP_STAGE_EDT', 'OLE.LIST', ParameterList) * Convert @VM to @FM in HeaderTitles * Convert @SVM to @VM in HeaderTitles HeaderTitles = 'Limit 1' HeaderTitles<2> = 'Limit 2' HeaderTitles<3> = 'Limit 3' HeaderTitles<4> = 'Limit 4' HeaderTitles<5> = 'Limit 5' HeaderTitles<6> = 'Limit 6' For each HeaderTitle in HeaderTitles using @FM setting RowIndex Set_Property(DispStageCtrl, "OLE.HeaderText[1; ":RowIndex + 1:"]", HeaderTitle) Next HeaderTitle Set_Property(DispStageCtrl, "OLE.HeaderAlignment[1; 2-":NumRows + 1:"]", 'C':@FM:'L':@FM:'L') Set_Property(DispStageCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'R':@FM:'L') Set_Property(DispStageCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') // Color headers Set_Property(DispStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") // Color limit columns Set_Property(DispStageCtrl, "OLE.CellColors[1-3; All]", @FM:"{240, 240, 240}") // Bold limit text BoldFontArray = 'Segoe UI':@SVM:8:@SVM:700 Set_Property(DispStageCtrl, "OLE.CellFont[1-3; All]", BoldFontArray) GoSub ColorCells return ColorCells: TabIndex = Get_Property(@Window:'.OLE_TAB', 'OLE.SelectedTab') CellColorArray = Get_Property(@Window, '@COLOR_ARRAY') DispStageCtrl = @Window:'.OLE_DISP_STAGE_EDT' DimArray = Get_Property(DispStageCtrl, "OLE.Dimension") NumCols = DimArray<1> NumRows = DimArray<2> For Row = 1 to NumRows For Col = 1 to NumCols CellColor = CellColorArray<0, Row, Col> If CellColor EQ '' then CellColor = 'None' Set_Property(DispStageCtrl, 'OLE.CellColors[':Col+3:';':Row:']', @FM:CellColor) Next Col Next Row return ColorTabs: TabCtrl = @Window:'.OLE_TAB' RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNParamStages = Get_Property(@Window, '@GAN_PARAM_STAGES') CellColorArray = Get_Property(@Window, '@COLOR_ARRAY') WfrStages = ReactRunRec For each Stage in GaNParamStages using @VM setting TabIndex ThisCellColorArray = CellColorArray GoSub ColorTab Next Stage return EnableTabs: SelTabIndex = Get_Property(@Window:".OLE_TAB", "OLE.SelectedTab") GaNParamStages = Get_Property(@Window, '@GAN_PARAM_STAGES') NameArray = Get_Property(@Window, '@NAME_LIST') For each Stage in GaNParamStages using @VM setting TabIndex ThisNameArray = NameArray GoSub EnableTab Next Stage SelTabVisible = Get_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':SelTabIndex:']') If SelTabVisible EQ False$ then For TabIndex = 1 to 12 TabVisible = Get_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':TabIndex:']') Until TabVisible EQ True$ Next TabIndex If TabVisible EQ True$ then Set_Property(@Window:".OLE_TAB", "OLE.SelectedTab", TabIndex) end return EnableTab: If ThisNameArray EQ '' then Set_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':TabIndex:']', False$) end else Set_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':TabIndex:']', True$) end return ColorTab: GaNMetStages = Database_Services('ReadDataRow', 'APP_INFO', 'GAN_MET_STAGES') Locate Stage in GaNMetStages using @FM setting sPos then PostSplit = (sPos GT 6) end else PostSplit = False$ end WfrChar = (Sum(ReactRunRec) GT 0) NumRows = DCount(ThisCellColorArray, @VM) NumCols = DCount(ThisCellColorArray, @SVM) MetFailed = False$ MetMissing = False$ ValidDisabled = False$ For Row = 1 to NumRows For Col = 1 to NumCols CellColor = ThisCellColorArray<0, Row, Col> If CellColor EQ 'Red' then MetFailed = True$ end If CellColor EQ 'Yellow' then MetMissing = True$ end If CellColor EQ 'SlateBlue L=75' then ValidDisabled = True$ end Until MetFailed EQ True$ Next Col Until MetFailed EQ True$ Next Row Begin Case Case MetFailed EQ True$ Colors = "" Colors<1, 2> = "Vertical(Gradient(Red L=80, Red L=90), Border(Red))" Colors<2, 2> = "Vertical(Gradient(Red L=90, Red L=95), Border(Red))" Colors<3, 2> = "Vertical(Gradient(Red L=85, Red L=95), Border(Red))" Colors<4, 1> = "Gray" Colors<4, 2> = "Vertical(Gradient(Gray L=80, Gray L=90), Border(Gray))" Colors<5> = "Vertical(Gradient(Red L=95, Red L=80), Border(Red))" Set_Property(TabCtrl, "OLE.TabColors[":TabIndex:"]", Colors) Case MetMissing EQ True$ Colors = "" Colors<1, 2> = "Vertical(Gradient(Yellow L=80, Yellow L=90), Border(Yellow))" Colors<2, 2> = "Vertical(Gradient(Yellow L=90, Yellow L=95), Border(Yellow))" Colors<3, 2> = "Vertical(Gradient(Yellow L=85, Yellow L=95), Border(Yellow))" Colors<4, 1> = "Gray" Colors<4, 2> = "Vertical(Gradient(Gray L=80, Gray L=90), Border(Gray))" Colors<5> = "Vertical(Gradient(Yellow L=95, Yellow L=80), Border(Yellow))" Set_Property(TabCtrl, "OLE.TabColors[":TabIndex:"]", Colors) Case ValidDisabled EQ True$ Colors = "" Colors<1, 2> = "Vertical(Gradient(Blue L=80, Blue L=90), Border(Blue))" Colors<2, 2> = "Vertical(Gradient(Blue L=90, Blue L=95), Border(Blue))" Colors<3, 2> = "Vertical(Gradient(Blue L=85, Blue L=95), Border(Blue))" Colors<4, 1> = "Gray" Colors<4, 2> = "Vertical(Gradient(Gray L=80, Gray L=90), Border(Gray))" Colors<5> = "Vertical(Gradient(Blue L=95, Blue L=80), Border(Blue))" Set_Property(TabCtrl, "OLE.TabColors[":TabIndex:"]", Colors) Case ( ( (PostSplit EQ True$) and (WfrChar EQ False$) ) or (NumRows EQ 0) ) Null Case Otherwise$ Colors = "" Colors<1, 2> = "Vertical(Gradient(Green L=80, Green L=90), Border(Green))" Colors<2, 2> = "Vertical(Gradient(Green L=90, Green L=95), Border(Green))" Colors<3, 2> = "Vertical(Gradient(Green L=85, Green L=95), Border(Green))" Colors<4, 1> = "Gray" Colors<4, 2> = "Vertical(Gradient(Gray L=80, Gray L=90), Border(Gray))" Colors<5> = "Vertical(Gradient(Green L=95, Green L=80), Border(Green))" Set_Property(TabCtrl, "OLE.TabColors[":TabIndex:"]", Colors) End Case return SetupDispEDT: DispCtrl = @Window:'.OLE_DISP_EDT' // Disable resizing of the header row and header column // Resize header column to fit contents HeaderRowArray = Get_Property(DispCtrl, "OLE.HeaderRow[1]") HeaderColArray = Get_Property(DispCtrl, "OLE.HeaderColumn[1]") HeaderRowArray<3> = False$ HeaderColArray<1> = 80 HeaderColArray<3> = False$ Set_Property(DispCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(DispCtrl, "OLE.HeaderRow[1]", HeaderRowArray) // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(DispCtrl, "OLE.DataColumn[1]") StageColSize<3> = False$ Set_Property(DispCtrl, "OLE.DataColumn[All]", StageColSize) WfrColSize = Get_Property(DispCtrl, "OLE.DataColumn[1]") // Set column widths WfrColSize<1> = 30 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_SLOT:"]", WfrColSize) WfrColSize<1> = 79 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_WFR_ID:"-":COL$DISP_SCRIBE:"]", WfrColSize) WfrColSize<1> = 50 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_GRADE:"]", WfrColSize) WfrColSize<1> = 244 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_REASON:"]", WfrColSize) WfrColSize<1> = 69 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_RDS_NCR:"-":COL$DISP_WMO_NCR:"]", WfrColSize) WfrColSize<1> = 81 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_SHIP_ID:"]", WfrColSize) WfrColSize<1> = 70 Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_RETAIN_BOX:"-":COL$DISP_RETAIN_SLOT:"]", WfrColSize) WfrColSize<4> = True$ ; // Set this column autosize property to true Set_Property(DispCtrl, "OLE.DataColumn[":COL$DISP_ROOT_CAUSE:"]", WfrColSize) // Disable resizing of rows as there is no need for this on this form RowSizeProps = Get_Property(DispCtrl, "OLE.DataRow[1]") RowSizeProps<3> = False$ Set_Property(DispCtrl, "OLE.DataRow[All]", RowSizeProps) // Disable scrollbars Set_Property(DispCtrl, "OLE.ScrollBarsVisible", 'N':@FM:'N') // Color headers Set_Property(DispCtrl, "OLE.HeaderColors[All; 1]", @FM:"{200, 200, 200}") // Set edit mode of cells if and when we enable them EditArray = 'E' EditArray<2> = 'O' Set_Property(DispCtrl, "OLE.CellEditMode[All; All]", EditArray) // Disable editing of all cells Set_Property(DispCtrl, "OLE.CellProtection[All; All]", 'None') // Do not allow scrolling past the bottom right cell. // This prevents scrolling when tabbing out of the bottom right cell. Set_Property(DispCtrl, "OLE.FreezePos", COL$DISP_RETAIN_SLOT:@FM:8) return Abort: Utility('DESTROY', @Window) return PopulateControls: RDSNo = 123456 WONo = 123456 PSNo = 1234 Set_Property(@Window:'.RDS_NO', 'TEXT', RDSNo) Set_Property(@Window:'.WO_NO', 'TEXT', WONo) Set_Property(@Window:'.PS_NO', 'TEXT', PSNo) Set_Property(@Window, '@RDSNO', RDSNo) Def = "" Def = "Loading..." Def = "G" Def = 100 ; // 100% Def = 400 Def = -2 ;* message h-pos in pixels, or -2 (center screen, the default), -1 (center parent) Def = -2 ;* message v-pos in pixels MsgUp = Msg(@Window, Def) Set_Property(@Window, 'REDRAW', False$) Set_Property(@Window:'.OLE_REACTOR_EDT' , "OLE.Redraw", False$) Set_Property(@Window:'.OLE_METROLOGY_EDT' , "OLE.Redraw", False$) Set_Property(@Window:'.OLE_DISP_EDT' , "OLE.Redraw", False$) Set_Property(@Window:'.OLE_DISP_STAGE_EDT' , "OLE.Redraw", False$) Set_Property(@Window:'.OLE_NCR_EDT' , "OLE.Redraw", False$) RunPriorities = '':@FM:'P1':@FM:'P2':@FM:'P3' Set_Property(@Window:'.COMBO_PRIORITY', 'LIST', RunPriorities) If RDSNo Not(Num(RDSNo)) then * update the gauge Msg(@Window, MsgUp, 10, MSGINSTUPDATE$) // Check if run info scribes have been updated InWfrIDs = '' Scribes = '' For WfrIndex = 1 to 8 InWfrIDs<0, WfrIndex> = '123456*1*':WfrIndex Scribes<0, WfrIndex> = 'Scribe0':WfrIndex Next WfrIndex RunPriority = 1 Set_Property(@Window:'.COMBO_PRIORITY', 'TEXT', RunPriority) GaNRunID = '9900001abcde' * update the gauge Msg(@Window, MsgUp, 20, MSGINSTUPDATE$) SPCWaferTrackPart = 'WTPart01' Set_Property(@Window:'.EDL_WAFER_TRACK_PART', 'TEXT', SPCWaferTrackPart) Reactor = 99 Set_Property(@Window, '@REACTOR', Reactor) * update the gauge Msg(@Window, MsgUp, 30, MSGINSTUPDATE$) Convert @Upper.Case to @Lower.Case in GaNRunID Set_Property(@Window : '.CMB_GAN_RUN_ID', 'LIST', GaNRunID) Set_Property(@Window : '.CMB_GAN_RUN_ID', 'SELPOS', 1) * update the gauge Msg(@Window, MsgUp, 50, MSGINSTUPDATE$) GaNEtchIDs = '9900000etch' Convert @VM to @FM in GaNEtchIDs NumEtchIDs = DCount(GaNEtchIDs, @FM) Set_Property(@Window : '.CMB_GAN_ETCH_ID', 'LIST', GaNEtchIDs) // Select the last external etch ID to display by default Set_Property(@Window : '.CMB_GAN_ETCH_ID', 'SELPOS', NumEtchIDs) GaNEtchRecipes = 'EtchRecipe1234' LastEtchRecipe = GaNEtchRecipes<0, NumEtchIDs> Set_Property(@Window : '.ETCH_RECIPE', 'TEXT', LastEtchRecipe) GoSub Setup_OLE_Controls // Need to check if any wafers have made it to disposition. If so, then check the Disposition Report // for any updates. * update the gauge Msg(@Window, MsgUp, 60, MSGINSTUPDATE$) * WfrIDs = ReactRunRec * If WfrIDs NE '' then * For each WfrID in WfrIDs using @VM setting vPos * MetDone = GaN_Services('GetMetrologyStatus', WfrID) * If MetDone EQ True$ then * Set_Property(@Window:'.PUB_UPDATE_DISP', 'ENABLED', True$) * end * Until MetDone EQ True$ * Next WfrID * end GoSub VerifyRecipe * update the gauge Msg(@Window, MsgUp, 70, MSGINSTUPDATE$) GoSub FillDispEditTable * update the gauge Msg(@Window, MsgUp, 80, MSGINSTUPDATE$) GoSub FillNCREditTable * update the gauge Msg(@Window, MsgUp, 90, MSGINSTUPDATE$) GoSub FillCommentsTable end GoSub EnableRunIDComboBox GoSub EnableCloseRDSButton GoSub UpdateRDSStatus GoSub EnableLotAbortButton GoSub EnableImportMetDataButton GoSub FillDispStageCtrl * update the gauge Msg(@Window, MsgUp, 100, MSGINSTUPDATE$) Msg(@Window, MsgUp) ;* take down the gauge Set_Property(@Window, 'REDRAW', True$) Set_Property(@Window:'.OLE_REACTOR_EDT' , "OLE.Redraw", True$) Set_Property(@Window:'.OLE_METROLOGY_EDT' , "OLE.Redraw", True$) Set_Property(@Window:'.OLE_DISP_EDT' , "OLE.Redraw", True$) Set_Property(@Window:'.OLE_DISP_STAGE_EDT' , "OLE.Redraw", True$) Set_Property(@Window:'.OLE_NCR_EDT' , "OLE.Redraw", True$) return