1964 lines
85 KiB
Plaintext
1964 lines
85 KiB
Plaintext
COMPILE FUNCTION Clean_Insp(EntID,Event,Parm1,Parm2,Parm3,Parm4,Parm5)
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
/*
|
|
Commuter module for CLEAN_INSP (Clean & Inspection) window
|
|
|
|
08/05/2009 - John C. Henry, J.C. Henry & Co., Inc.
|
|
03/07/2017 - djs - Changed the SCAN_RESULTS.GOT_FOCUS event to a CHAR event instead to allow users to select
|
|
the scan results row of their choice (to view those individual wafer results) without being
|
|
prompted for a manual entry data override.
|
|
10/29/2019 - djs - Fixed "SigRow EQ 1" to 'SelectedRow EQ 1' logic check within SignClean, SignInsp,
|
|
and SignScan subroutines
|
|
04/23/2021 - djs - Updated SIGN_ROTR_ACCEPTANCE.CLICK event to not block acceptance signatures when a 100%
|
|
failure scan is required.
|
|
05/13/2024 - djs - Replaced Ole Tab control (OLE_TAB_ROTR) with a groupbox control (ROTR_GROUP) to mitigate
|
|
form behavior bugs in OI 10 post migration.
|
|
06/13/2024 djm Add new stage-specific supplement system.
|
|
*/
|
|
|
|
DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, Center_Window, Post_Event, Comm_RDS
|
|
DECLARE SUBROUTINE ErrMsg, Send_Message, Set_Property, Send_Event, Btree.Extract, obj_AppWindow, Signature_Services
|
|
DECLARE SUBROUTINE obj_Notes, Security_Err_Msg, End_Window, Forward_Event, Start_Window, Create_Note
|
|
DECLARE SUBROUTINE obj_WO_Mat_Log, obj_WO_Mat, obj_Clean_Insp, Unlock, Lock, Database_Services, Yield
|
|
DECLARE SUBROUTINE Override_Log_Services, Dialog_Box, obj_WO_Wfr, Error_Services, Hold_Services
|
|
|
|
DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, Utility, Popup, Collect.Ixvals, Environment_Services
|
|
DECLARE FUNCTION Send_Message, Msg, Security_Check, obj_React_Run_CI, Select_Into, MemberOf, Database_Services
|
|
DECLARE FUNCTION Start_Window, Create_Dialog, Database_Services, Set_Property, Error_Services, SRP_DateTime
|
|
DECLARE FUNCTION obj_NCR, SRP_Array, Supplement_Services
|
|
|
|
$INSERT LOGICAL
|
|
$INSERT MSG_EQUATES
|
|
$INSERT APPCOLORS
|
|
$INSERT LSL_USERS_EQU
|
|
$INSERT SECURITY_RIGHTS_EQU
|
|
$INSERT REACT_EVENT_EQUATES
|
|
$INSERT POPUP_EQUATES
|
|
$INSERT RTI_STYLE_EQUATES
|
|
$INSERT CLEAN_INSP_EQUATES
|
|
$INSERT TOOL_CLASS_EQUATES
|
|
$INSERT TOOL_EQUATES
|
|
$INSERT WO_MAT_EQUATES
|
|
$INSERT WO_LOG_EQUATES
|
|
$INSERT SPC_QUEUE_EQUATES
|
|
$INSERT WM_OUT_EQUATES
|
|
$INSERT REACTOR_EQUATES
|
|
$INSERT NOTIFICATION_EQUATES
|
|
|
|
EQU PROTECTED$ TO 8
|
|
EQU CRLF$ TO \0D0A\
|
|
EQU TAB$ TO \09\
|
|
Equ ESC$ TO Char(27)
|
|
|
|
EQU COL$CLEAN_TOOL TO 1
|
|
EQU COL$CLEAN_BOAT_ID TO 2
|
|
EQU COL$CLEAN_SRD_NO TO 3
|
|
EQU COL$CLEAN_SIG TO 4
|
|
EQU COL$CLEAN_SIG_DTM TO 5
|
|
|
|
EQU COL$DUMMY_1_PIXEL_WIDE TO 1 ;* Used for both INSP_SPEC and INSP controls
|
|
|
|
EQU COL$INSP_SPEC_LPD TO 2
|
|
EQU COL$INSP_SPEC_SCRATCHES TO 3
|
|
EQU COL$INSP_SPEC_SCRATCH_LEN TO 4
|
|
EQU COL$INSP_SPEC_PITS TO 5
|
|
EQU COL$INSP_SPEC_MOUNDS TO 6
|
|
EQU COL$INSP_SPEC_STACK_FAULTS TO 7
|
|
EQU COL$INSP_SPEC_SPIKES TO 8
|
|
EQU COL$INSP_SPEC_SPOTS TO 9
|
|
EQU COL$INSP_SPEC_FOV TO 10
|
|
EQU COL$INSP_SPEC_BL_DEFECTS TO 11
|
|
|
|
EQU COL$INSP_TOOL TO 2 ;* Added INSP_TOOL column 10/29/2012 JCH
|
|
EQU COL$INSP_LPD TO 3
|
|
EQU COL$INSP_SCRATCHES TO 4
|
|
EQU COL$INSP_SCRATCH_LEN TO 5
|
|
EQU COL$INSP_PITS TO 6
|
|
EQU COL$INSP_MOUNDS TO 7
|
|
EQU COL$INSP_STACK_FAULTS TO 8
|
|
EQU COL$INSP_SPIKES TO 9
|
|
EQU COL$INSP_SPOTS TO 10
|
|
EQU COL$INSP_FOV TO 11
|
|
EQU COL$INSP_BL_DEFECTS TO 12
|
|
EQU COL$INSP_SIG TO 13
|
|
EQU COL$INSP_SIG_DTM TO 14
|
|
|
|
EQU COL$INSP_SPEC_BSIDE_SCRATCHES TO 1
|
|
EQU COL$INSP_SPEC_BSIDE_SCRATCH_LEN TO 2
|
|
EQU COL$INSP_SPEC_BSIDE_NODULES TO 3
|
|
EQU COL$INSP_SPEC_BSIDE_SPIKES TO 4
|
|
|
|
EQU COL$INSP_BSIDE_SCRATCHES TO 1
|
|
EQU COL$INSP_BSIDE_SCRATCH_LEN TO 2
|
|
EQU COL$INSP_BSIDE_NODULES TO 3
|
|
EQU COL$INSP_BSIDE_SPIKES TO 4
|
|
|
|
EQU COL$SCAN_SPEC_SURF_RECIPE$ TO 1
|
|
EQU COL$SCAN_SPEC_SURF_DEFECTS$ TO 2
|
|
EQU COL$SCAN_SPEC_SURF_HAZE$ TO 3
|
|
EQU COL$SCAN_SPEC_SCRATCHES$ TO 4
|
|
|
|
EQU COL$SCAN_RECIPE TO 1
|
|
EQU COL$SCAN_TOOL TO 2
|
|
EQU COL$SCAN_SUM_OF_DEF_MIN TO 3
|
|
EQU COL$SCAN_SUM_OF_DEF_MAX TO 4
|
|
EQU COL$SCAN_SUM_OF_DEF_AVG TO 5
|
|
|
|
EQU COL$SCAN_HAZE_AVG_AVG TO 6
|
|
EQU COL$SCAN_DCNMM2 TO 7
|
|
EQU COL$SCAN_REASON TO 8
|
|
EQU COL$SCAN_SIG TO 9
|
|
EQU COL$SCAN_SIG_DTM TO 10
|
|
EQU COL$SCAN_TEST_RUN_DTM TO 11
|
|
|
|
EQU COL$SLOT TO 1
|
|
EQU COL$WAFER_ID TO 2
|
|
EQU COL$SLOT_NCR TO 3
|
|
EQU COL$MET_NO$ TO 4
|
|
EQU COL$MOVED_TO_SLOT TO 5
|
|
EQU COL$MU_WAFER_ID TO 6
|
|
EQU COL$MOVED_FROM_SLOT TO 7
|
|
EQU COL$REPLACED_BY TO 8
|
|
EQU COL$MU_ADD_DATE TO 9
|
|
EQU COL$MU_REM_DATE TO 10
|
|
|
|
EQU COL$EPP_SLOT TO 1
|
|
EQU COL$EPP_RDS_NO TO 2
|
|
EQU COL$EPP_REACT_NO TO 3
|
|
EQU COL$EPP_RDS_STATUS TO 4
|
|
EQU COL$EPP_POCKET TO 5
|
|
EQU COL$EPP_ZONE TO 6
|
|
EQU COL$EPP_IN_CASS TO 7
|
|
EQU COL$EPP_IN_SLOT TO 8
|
|
EQU COL$EPP_SLOT_NCR TO 9
|
|
EQU COL$EPP_MU_WO_NO TO 10
|
|
EQU COL$EPP_MU_WO_STEP TO 11
|
|
EQU COL$EPP_MU_CASS_NO TO 12
|
|
EQU COL$EPP_MU_SLOT_NO TO 13
|
|
EQU COL$EPP_UMW_CASS_ID TO 14
|
|
EQU COL$EPP_UMW_SLOT_NO TO 15
|
|
EQU COL$EPP_MU_BY TO 16
|
|
EQU COL$EPP_MU_ADD_DATE TO 17
|
|
EQU COL$EPP_MU_REM_DATE TO 18
|
|
|
|
EQU HIDDEN$ TO 32
|
|
EQU SKIPPED$ TO 4100
|
|
|
|
ErrTitle = 'Error in CleanInsp'
|
|
ErrorMsg = ''
|
|
|
|
Result = ''
|
|
|
|
BEGIN CASE
|
|
CASE EntID = @WINDOW
|
|
BEGIN CASE
|
|
CASE Event = 'CLEAR' ; GOSUB Clear
|
|
CASE Event = 'CREATE' ; GOSUB Create
|
|
CASE Event = 'CLOSE' ; GOSUB Close
|
|
CASE Event = 'WRITE' ; GOSUB Write
|
|
CASE Event = 'READ' ; GOSUB Read
|
|
CASE Event = 'VSCROLL' ; GOSUB VScroll
|
|
CASE Event[1,3] = 'QBF' ; GOSUB Refresh
|
|
END CASE
|
|
|
|
CASE EntID = @WINDOW:'.SIGN_CLEAN' AND Event = 'CLICK' ; GOSUB SignClean
|
|
CASE EntID = @WINDOW:'.SIGN_INSP' AND Event = 'CLICK' ; GOSUB SignInsp
|
|
CASE EntID = @WINDOW:'.SIGN_SCAN' AND Event = 'CLICK' ; GOSUB SignScan
|
|
CASE EntID = @WINDOW:'.SIGN_ROTR_ACCEPTANCE' AND Event = 'CLICK' ; GOSUB SIGN_ROTR_ACCEPTANCE.CLICK
|
|
CASE EntID = @WINDOW:'.BTN_WAFER_DETAILS' AND Event = 'CLICK' ; GOSUB BTN_WAFER_DETAILS.CLICK
|
|
CASE EntID = @WINDOW:'.SCAN_RESULTS' AND Event = 'CHAR' ; GOSUB SCAN_RESULTS.CHAR
|
|
CASE EntID = @WINDOW:'.SCAN_RESULTS' AND Event = 'POSCHANGED' ; GOSUB SCAN_RESULTS.POSCHANGED
|
|
CASE EntID = @WINDOW:'.SPEC_BRIGHTLIGHT' AND Event = 'CLICK' ; GOSUB Refresh
|
|
CASE EntID = @WINDOW:'.SPEC_MICROSCOPE' AND Event = 'CLICK' ; GOSUB Refresh
|
|
CASE EntID = @WINDOW:'.CHK_EDGE' AND Event = 'CLICK' ; GOSUB Refresh
|
|
CASE EntID = @WINDOW:'.REFRESH_SPEC' AND Event = 'CLICK' ; GOSUB RefreshSpec
|
|
CASE EntID = @WINDOW:'.CI_TAB' AND Event = 'CLICK' ; GOSUB Page
|
|
CASE EntID = @WINDOW:'.INSP_RESULTS' AND Event = 'POSCHANGED' ; GOSUB InspPC
|
|
CASE EntID = @WINDOW:'.INSP_RESULTS_BSIDE' AND Event = 'POSCHANGED' ; GOSUB BSideInspPC
|
|
|
|
|
|
CASE EntID = @WINDOW:'.SEND_SPC' AND Event = 'CLICK' ; GOSUB SendSPC
|
|
|
|
CASE 1
|
|
|
|
ErrorMsg = 'Unknown Parameters ':EntID:' - ':Event:' passed to commuter'
|
|
ErrMsg(ErrorMsg)
|
|
|
|
END CASE
|
|
|
|
IF ErrorMsg NE '' THEN
|
|
ErrMsg(ErrTitle:@SVM:ErrorMsg)
|
|
END
|
|
|
|
RETURN Result
|
|
|
|
|
|
|
|
* * * * * * *
|
|
Create:
|
|
* * * * * * *
|
|
|
|
obj_Appwindow('Create',@WINDOW)
|
|
|
|
IF MemberOf(@USER4, 'OI_SUPERUSER') THEN
|
|
Set_Property(@WINDOW:'.SEND_SPC','VISIBLE',1)
|
|
Set_Property(@WINDOW:'.SPC_DTM','VISIBLE',1)
|
|
END ELSE
|
|
Set_Property(@WINDOW:'.SEND_SPC','VISIBLE',0)
|
|
Set_Property(@WINDOW:'.SPC_DTM','VISIBLE',0)
|
|
END
|
|
|
|
CIKey = Get_Property(@Window : '.CI_NO', 'TEXT')
|
|
|
|
* Setup Cleans Section
|
|
|
|
CleanStyles = Send_Message(@WINDOW:'.CLEAN_RESULTS','COLSTYLE',0,'')
|
|
|
|
CleanStyles<COL$CLEAN_TOOL> = BitOr(CleanStyles<COL$CLEAN_TOOL>,DTCS_DROPDOWN$)
|
|
CleanStyles<COL$CLEAN_BOAT_ID> = BitOr(CleanStyles<COL$CLEAN_BOAT_ID>,DTCS_DROPDOWN$)
|
|
CleanStyles<COL$CLEAN_SRD_NO> = BitOr(CleanStyles<COL$CLEAN_SRD_NO>,DTCS_DROPDOWN$)
|
|
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLSTYLE',0,CleanStyles) ;* Set Styles
|
|
|
|
* Setup Inspection Section
|
|
|
|
InspStyles = Send_Message(@WINDOW:'.INSP_RESULTS','COLSTYLE',0,'')
|
|
|
|
InspStyles<COL$INSP_TOOL> = BitOr(InspStyles<COL$INSP_TOOL>,DTCS_DROPDOWN$)
|
|
|
|
Send_Message(@WINDOW:'.INSP_RESULTS','COLSTYLE',0,InspStyles)
|
|
|
|
InspTools = 'SCOPE':@VM:'FF EDGE INSP':@VM:'SCOPE/FF EDGE INSP'
|
|
|
|
Send_Message(@WINDOW:'.INSP_RESULTS','COLFORMAT',COL$INSP_TOOL,InspTools)
|
|
|
|
* Setup Scan Section
|
|
|
|
ScanStyles = Send_Message(@WINDOW:'.SCAN_RESULTS','COLSTYLE',0,'')
|
|
|
|
ScanStyles<COL$SCAN_RECIPE> = BitOr(ScanStyles<COL$SCAN_RECIPE>,DTCS_DROPDOWN$)
|
|
ScanStyles<COL$SCAN_TOOL> = BitOr(ScanStyles<COL$SCAN_TOOL>,DTCS_DROPDOWN$)
|
|
|
|
Send_Message(@WINDOW:'.SCAN_RESULTS','COLSTYLE',0,ScanStyles)
|
|
|
|
ScanTools = XLATE('TOOL_CLASS','TENCOR',TOOL_CLASS_TOOL$,'X') ;* Tencor class tools
|
|
|
|
Send_Message(@WINDOW:'.SCAN_RESULTS','COLFORMAT',COL$SCAN_TOOL,ScanTools)
|
|
|
|
IF MemberOf(@USER4, 'OI_SUPERUSER') THEN
|
|
Set_Property(@WINDOW:'.REFRESH_SPEC','VISIBLE',1)
|
|
END ELSE
|
|
Set_Property(@WINDOW:'.REFRESH_SPEC','VISIBLE',0)
|
|
END
|
|
|
|
CIKey = Get_Property(@Window : '.CI_NO', 'TEXT')
|
|
ReactorNo = Xlate('CLEAN_INSP', CIKey, 'REACT_NO', 'X')
|
|
|
|
Stage = Get_Property(@Window : '.STAGE', 'TEXT')
|
|
If Stage EQ 'LWI' then
|
|
CanEdit = Memberof(@USER4, 'ENGINEERING') or Memberof(@USER4, 'LEAD') or Memberof(@USER4, 'SUPERVISOR') |
|
|
or Memberof(@USER4, 'FINAL_QA') or Memberof(@USER4, 'ROTR_OVERRIDE')
|
|
// Check if manual entry lock is temporarily disabled for all users due to ROTR queue overflow.
|
|
ManualEntryLock = Xlate('APP_INFO', 'ROTR_DATA_ENTRY_LOCK', 1, 'X')
|
|
If (ManualEntryLock EQ False$) then CanEdit = True$
|
|
Set_Property(@Window, '@CAN_EDIT', CanEdit)
|
|
If Not(CanEdit) then
|
|
// Disable manual entry of data.
|
|
ScanStyles = Send_Message(@Window : '.SCAN_RESULTS', 'COLSTYLE', 0, '')
|
|
For column = 1 to 7
|
|
ScanStyles<column> = BitOr( ScanStyles<column>, PROTECTED$ )
|
|
Next column
|
|
// Disable dropdown menus for recipe and tool columns.
|
|
ScanStyles<COL$SCAN_RECIPE> = BitAnd(ScanStyles<COL$SCAN_RECIPE>, BitNot(DTCS_DROPDOWN$) )
|
|
ScanStyles<COL$SCAN_TOOL> = BitAnd(ScanStyles<COL$SCAN_TOOL>, BitNot(DTCS_DROPDOWN$) )
|
|
ScanStyles = Send_Message(@Window : '.SCAN_RESULTS', 'COLSTYLE', 0, ScanStyles)
|
|
end
|
|
end
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Page:
|
|
* * * * * * *
|
|
|
|
Page = Get_Property(@WINDOW:'.CI_TAB', 'VALUE')
|
|
|
|
Set_Property(@WINDOW,'VPOSITION', Page)
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
VScroll:
|
|
* * * * * * *
|
|
|
|
Page = Parm1
|
|
|
|
Set_Property(@WINDOW:'.CI_TAB','VALUE', Page)
|
|
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Clear:
|
|
* * * * * * *
|
|
|
|
Send_Event(@WINDOW,'PAGE',1)
|
|
|
|
|
|
* * * * * * *
|
|
Refresh:
|
|
* * * * * * *
|
|
|
|
CIKey = Get_Property(@WINDOW:'.CI_NO', 'TEXT')
|
|
// Hide or show the Cass No label and edit line based on the whether the reactor is EpiPro or not. - 04/10/2018 - dmb
|
|
WONo = Get_Property(@Window : '.WO_NO', 'TEXT')
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
ReactType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
If ReactType NE 'EPP' then
|
|
Visible = True$
|
|
end else
|
|
Visible = False$
|
|
end
|
|
Set_Property(@Window : '.CASS_NO_LABEL', 'VISIBLE', Visible)
|
|
Set_Property(@Window : '.CASS_NO', 'VISIBLE', Visible)
|
|
|
|
Stage = Get_Property(@WINDOW:'.STAGE','TEXT')
|
|
|
|
* * * * *
|
|
|
|
Ctrls = @WINDOW:'.STAGE':@RM ; Props = 'TEXT':@RM
|
|
Ctrls := @WINDOW:'.SPEC_FWI_LWI':@RM ; Props := 'TEXT':@RM
|
|
Ctrls := @WINDOW:'.SPEC_CLEAN_TOOL_REP':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SPEC_BRIGHTLIGHT':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_MICROSCOPE':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.CHK_EDGE':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_CLEAN_TOOL' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
Stage = Vals[1,@RM]
|
|
SpecFwiLwi = Vals[COL2()+1,@RM]
|
|
SpecCleanToolRep = Vals[COL2()+1,@RM]
|
|
SpecBrightlight = Vals[COL2()+1,@RM]
|
|
SpecMicroscope = Vals[COL2()+1,@RM]
|
|
SpecEdge = Vals[COL2()+1,@RM]
|
|
SpecCleanTool = Vals[COL2()+1,@RM]
|
|
|
|
SpecCleanTools = Get_Property(@WINDOW:'.SPEC_CLEAN_TOOL$','ARRAY')
|
|
|
|
IF SpecCleanTools = '' THEN
|
|
AkrionCleanTools = XLATE('TOOL_CLASS','AKRION',TOOL_CLASS_TOOL$,'X')
|
|
WetBenchTools = XLATE('TOOL_CLASS','WET BENCH',TOOL_CLASS_TOOL$,'X')
|
|
|
|
BEGIN CASE
|
|
CASE AkrionCleanTools NE '' AND WetBenchTools NE '' ; SpecCleanTools = AkrionCleanTools:@VM:WetBenchTools
|
|
CASE AkrionCleanTools NE '' AND WetBenchTools = '' ; SpecCleanTools = AkrionCleanTools
|
|
CASE AkrionCleanTools = '' AND WetBenchTools NE '' ; SpecCleanTools = WetBenchTools
|
|
CASE 1 ; NULL
|
|
END CASE
|
|
END
|
|
|
|
LOOP
|
|
UNTIL SpecCleanTools[-1,1] NE @VM OR SpecCleanTools = ''
|
|
SpecCleanTools[-1,1] = ''
|
|
REPEAT
|
|
|
|
ScanRecipes = Get_Property(@WINDOW:'.SPEC_SURFSCAN','ARRAY')<COL$SCAN_SPEC_SURF_RECIPE$> ;* 1/22/2013 JCH ***********
|
|
Send_Message(@WINDOW:'.SCAN_RESULTS','COLFORMAT',COL$SCAN_RECIPE,ScanRecipes)
|
|
|
|
BEGIN CASE
|
|
CASE Stage = 'PRE'
|
|
LabelText = 'Pre Epi Cleaning && Inspection'
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLFORMAT',COL$CLEAN_TOOL,SpecCleanTools)
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLFORMAT',COL$CLEAN_BOAT_ID,XLATE('LISTBOX_CONFIG','PRECLEANCASSID',1,'X'))
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLFORMAT',COL$CLEAN_SRD_NO,XLATE('LISTBOX_CONFIG','PRECLEANSRD',1,'X'))
|
|
|
|
CASE Stage = 'POST'
|
|
LabelText = 'Post Epi Cleaning && Inspection'
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLFORMAT',COL$CLEAN_TOOL,SpecCleanTools)
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLFORMAT',COL$CLEAN_BOAT_ID,XLATE('LISTBOX_CONFIG','POSTCLEANCASSID',1,'X'))
|
|
Send_Message(@WINDOW:'.CLEAN_RESULTS','COLFORMAT',COL$CLEAN_SRD_NO,XLATE('LISTBOX_CONFIG','POSTCLEANSRD',1,'X'))
|
|
|
|
|
|
CASE Stage = 'FWI' ; LabelText = 'First Wafer Inspection'
|
|
CASE Stage = 'LWI' ; LabelText = 'Last Wafer Inspection'
|
|
CASE Stage = 'WFR' AND SpecFwiLwi = 'FWI' ; LabelText = 'First Wafer Inspection'
|
|
CASE Stage = 'WFR' AND SpecFwiLwi = 'LWI' ; LabelText = 'Last Wafer Inspection'
|
|
CASE Stage[1,3] = 'WFR' ; LabelText = 'Wafer ':Stage[4,99]:' Extra Inspection'
|
|
CASE 1 ; LabelText = 'Cleaning && Inspection'
|
|
END CASE
|
|
Set_Property(@WINDOW:'.WINDOW_LABEL_FIX','TEXT',LabelText)
|
|
|
|
Ctrls = @WINDOW:'.SPEC_CLEAN_SUBOXIDE':@RM ; Props = 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_CLEAN_TOOL':@RM ; Props := 'TEXT':@RM
|
|
Ctrls := @WINDOW:'.SPEC_CLEAN_AKRION_RECIPE':@RM ; Props := 'TEXT':@RM
|
|
Ctrls := @WINDOW:'.SPEC_BRIGHTLIGHT':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_MICROSCOPE':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.CHK_EDGE':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_SURFSCAN' ; Props := 'ARRAY'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
SCSubOxide = Vals[1,@RM]
|
|
SCTool = Vals[COL2()+1,@RM]
|
|
SCAkrionRecipe = Vals[COL2()+1,@RM]
|
|
SBrightLight = Vals[COL2()+1,@RM]
|
|
SMicroscope = Vals[COL2()+1,@RM]
|
|
SEdge = Vals[COL2()+1,@RM]
|
|
SSurfScanArray = Vals[COL2()+1,@RM]
|
|
|
|
ScanRecipes = SSurfScanArray<COL$SCAN_SPEC_SURF_RECIPE$>
|
|
|
|
CONVERT @VM TO '' IN ScanRecipes
|
|
|
|
SSurfScanRecipe = ScanRecipes
|
|
|
|
Ctrls = @WINDOW:'.SPEC_CLEAN_REQ':@RM ; Props = 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_INSP_REQ':@RM ; Props := 'CHECK':@RM
|
|
Ctrls := @WINDOW:'.SPEC_SURFSCAN_REQ' ; Props := 'CHECK'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
CleanSigReq = Vals[1,@RM]
|
|
InspSigReq = Vals[COL2()+1,@RM]
|
|
SurfScanSigReq = Vals[COL2()+1,@RM]
|
|
|
|
IF SCTool NE '' OR CleanSigReq = 1 then
|
|
CleanSigReq = 1
|
|
end else
|
|
CleanSigReq = 0
|
|
end
|
|
|
|
InspReq = Xlate('CLEAN_INSP', CIKey, 'SPEC_INSP_REQ', 'X')
|
|
If InspReq EQ '' then InspReq = Xlate('CLEAN_INSP', CIKey, 'INSP_REQ', 'X')
|
|
// Old records may have more than one RDS/CLEAN_INSP key.
|
|
InspInterval = Xlate('CLEAN_INSP', CIKey, 'INSP_INTERVAL', 'X')<0, 1>
|
|
If InspInterval NE '' then
|
|
// Use the stored interval
|
|
RDSNo = Xlate('CLEAN_INSP', CIKey, 'RDS_NO', 'X')<0, 1>
|
|
PSNo = Xlate('CLEAN_INSP', CIKey, 'PS_NO', 'X')<0, 1>
|
|
WONo = Xlate('CLEAN_INSP', CIKey, 'WO_NO', 'X')<0, 1>
|
|
WOQty = Xlate('WO_LOG', WONo, 'QTY', 'X')<0, 1>
|
|
RunNo = Xlate('RDS', RDSNo, 'RUN_ORDER_NUM', 'X')<0, 1>
|
|
StageKey = PSNo:'*LWI'
|
|
LastRun = ( (RunNo * 25) EQ WOQty )
|
|
InspReq = ( (Mod((RunNo - 1), InspInterval) EQ 0) or LastRun )
|
|
end else
|
|
// Use the current PRS_STAGE interval
|
|
InspReq = Xlate('CLEAN_INSP', CIKey, 'INSP_REQ', 'X')
|
|
end
|
|
|
|
If InspReq EQ False$ then
|
|
Set_Property(@WINDOW:'.INSP_RESULT_GROUP', 'TEXT', 'Visual Inspection Not Required')
|
|
end
|
|
|
|
IF SBrightLight = 1 OR SMicroscope = 1 OR SEdge OR InspSigReq = 1 THEN
|
|
InspSigReq = 1
|
|
end ELSE
|
|
InspSigReq = 0
|
|
end
|
|
|
|
IF SSurfScanRecipe NE '' OR SurfScanSigReq = 1 THEN
|
|
SurfScanSigReq = 1
|
|
end ELSE
|
|
SurfScanSigReq = 0
|
|
end
|
|
|
|
DefBack = Get_Property(@WINDOW,'BACKCOLOR')
|
|
|
|
ReqBackColor = CI_GROUP_BLUE$
|
|
|
|
* ROTR 2/1/2012
|
|
|
|
RotrAction = Get_Property(@WINDOW:'.ROTR_ACTION','TEXT')
|
|
|
|
BEGIN CASE
|
|
CASE RotrAction = 'Passed'
|
|
RBackColor = GREEN$ ;*LS1_GREEN$
|
|
BypassEnabled = False$
|
|
CASE RotrAction = 'Failed'
|
|
RBackColor = RED$
|
|
BypassEnabled = MemberOf(@USER4, 'ENGINEERING') OR MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') OR MemberOf(@USER4, 'OI_ADMIN') OR MemberOf(@USER4, 'ROTR_OVERRIDE')
|
|
CASE RotrAction = 'Waived'
|
|
RBackColor = YELLOW$ ;*CMB_YELLOW$
|
|
BypassEnabled = False$
|
|
CASE RotrAction = 'Accepted'
|
|
RBackColor = ORANGE$
|
|
BypassEnabled = False$
|
|
CASE 1
|
|
IF SurfScanSigReq THEN
|
|
RBackColor = ReqBackColor
|
|
END ELSE
|
|
RBackColor = DefBack
|
|
END
|
|
BypassEnabled = False$
|
|
END CASE
|
|
|
|
Ctrls = @WINDOW:'.ROTR_STATUS_LABEL':@FM ; Props = 'BACKCOLOR':@FM ; Vals = RBackColor:@FM
|
|
Ctrls := @WINDOW:'.ROTR_REASON_LABEL':@FM ; Props := 'BACKCOLOR':@FM ; Vals := RBackColor:@FM
|
|
Ctrls := @WINDOW:'.SIGN_ROTR_SIGNATURE_LABEL':@FM ; Props := 'BACKCOLOR':@FM ; Vals := RBackColor:@FM
|
|
Ctrls := @WINDOW:'.SIGN_ROTR_REASON_LABEL':@FM ; Props := 'BACKCOLOR':@FM ; Vals := RBackColor:@FM
|
|
Ctrls := @WINDOW:'.ROTR_GROUP':@FM ; Props := 'BACKCOLOR':@FM ; Vals := RBackColor:@FM
|
|
Ctrls := @WINDOW:'.ROTR_ACTION':@FM ; Props := 'ENABLED':@FM ; Vals := 0:@FM
|
|
Ctrls := @WINDOW:'.EDL_ROTR_REASON':@FM ; Props := 'ENABLED':@FM ; Vals := 0:@FM
|
|
Ctrls := @WINDOW:'.SIGN_ROTR_ACCEPTANCE':@FM ; Props := 'ENABLED':@FM ; Vals := BypassEnabled:@FM
|
|
Ctrls := @WINDOW ; Props := 'REDRAW' ; Vals := 1
|
|
|
|
Convert @FM to @RM in Ctrls
|
|
Convert @FM to @RM in Props
|
|
Convert @FM to @RM in Vals
|
|
Set_Property(Ctrls,Props,Vals)
|
|
Set_Property(@Window:'.OLE_PIC_ROTR', 'OLE.BackgroundColor', RBackColor)
|
|
|
|
IF Get_Property(@WINDOW:'.SPC_DTM','DEFPROP') = '' THEN
|
|
Set_Property(@WINDOW:'.SEND_SPC','TEXT','Send to SPC')
|
|
END ELSE
|
|
Set_Property(@WINDOW:'.SEND_SPC','TEXT','Resend to SPC')
|
|
END
|
|
|
|
|
|
* Check for out of spec on the Inspection
|
|
|
|
InspSpecs = Get_Property(@WINDOW:'.SPEC_INSP','LIST')
|
|
InspResults = Get_Property(@WINDOW:'.INSP_RESULTS','LIST')
|
|
BSInspSpecs = Get_Property(@WINDOW:'.SPEC_INSP_BSIDE','LIST')
|
|
BSInspResults = Get_Property(@WINDOW:'.INSP_RESULTS_BSIDE','LIST')
|
|
|
|
InspComplete = 1
|
|
InspOutOfSpec = 0
|
|
ResultLineNo = 1
|
|
OutOfSpecLine = 0
|
|
|
|
LOOP
|
|
InspResult = InspResults[1,@FM]
|
|
InspResults = DELETE(InspResults,1,0,0)
|
|
|
|
BSInspResult = BSInspResults[1,@FM]
|
|
BSInspReults = DELETE(BSInspResults,1,0,0)
|
|
|
|
UNTIL InspOutOfSpec OR InspResult = '' OR InspResult[1,9] = @VM:@VM:@VM:@VM:@VM:@VM:@VM:@VM:@VM
|
|
|
|
* Check Frontside columns
|
|
|
|
FOR Col = COL$INSP_SPEC_LPD TO COL$INSP_SPEC_BL_DEFECTS
|
|
ColSpec = InspSpecs<1,Col>
|
|
colResult = InspResult<1,Col + 1> ;* Results has the tool column in front of the actual data
|
|
|
|
IF ColSpec NE '' AND colResult = '' THEN InspComplete = 0
|
|
|
|
IF colResult > 0 AND ColSpec NE '' THEN
|
|
BEGIN CASE
|
|
CASE Col = COL$INSP_SPEC_SCRATCH_LEN
|
|
IF ColResult GT ColSpec THEN InspOutOfSpec = 1
|
|
|
|
CASE Col = COL$INSP_SPEC_FOV
|
|
IF ColResult GT ColSpec THEN InspOutOfSpec = 1
|
|
|
|
CASE 1
|
|
IF ColResult GE ColSpec THEN InspOutOfSpec = 1
|
|
END CASE
|
|
END
|
|
NEXT Col
|
|
|
|
* Check Backside columns
|
|
|
|
FOR Col = COL$INSP_SPEC_BSIDE_SCRATCHES TO COL$INSP_SPEC_BSIDE_SPIKES
|
|
ColSpec = BSInspSpecs<1,Col>
|
|
colResult = BSInspResult<1,Col>
|
|
|
|
IF ColSpec NE '' AND colResult = '' THEN InspComplete = 0
|
|
|
|
IF colResult > 0 AND ColSpec NE '' THEN
|
|
BEGIN CASE
|
|
CASE Col = COL$INSP_SPEC_BSIDE_SCRATCH_LEN
|
|
IF ColResult GT ColSpec THEN InspOutOfSpec = 1
|
|
|
|
CASE 1
|
|
IF ColResult GE ColSpec THEN InspOutOfSpec = 1
|
|
|
|
END CASE
|
|
END
|
|
NEXT Col
|
|
|
|
|
|
IF NOT(InspOutOfSpec) THEN
|
|
ResultLineNo += 1
|
|
END
|
|
|
|
REPEAT
|
|
|
|
IF InspOutOfSpec THEN
|
|
Set_Property(@WINDOW:'.INSP_RESULTS','BACKCOLOR',RED$)
|
|
Set_Property(@WINDOW:'.INSP_RESULTS_BSIDE','BACKCOLOR',RED$)
|
|
Set_Property(@WINDOW:'.SIGN_INSP','ENABLED',0)
|
|
END ELSE
|
|
Set_Property(@WINDOW:'.INSP_RESULTS','BACKCOLOR',WHITE$)
|
|
Set_Property(@WINDOW:'.INSP_RESULTS_BSIDE','BACKCOLOR',WHITE$)
|
|
Set_Property(@WINDOW:'.SIGN_INSP','ENABLED',1)
|
|
END
|
|
|
|
|
|
IF NOT(InspComplete) THEN
|
|
Set_Property(@WINDOW:'.SIGN_INSP','ENABLED',0)
|
|
END
|
|
|
|
|
|
* Check for out of spec on the Surface Scan results *******************************
|
|
|
|
SSurfRecipes = SSurfScanArray<COL$SCAN_SPEC_SURF_RECIPE$>
|
|
SSurfDefects = SSurfScanArray<COL$SCAN_SPEC_SURF_DEFECTS$>
|
|
SSurfHazes = SSurfScanArray<COL$SCAN_SPEC_SURF_HAZE$>
|
|
|
|
|
|
LOOP
|
|
SSurfRecipe = SSurfRecipes[-1,'B':@VM]
|
|
UNTIL SSurfRecipe NE '' OR SSurfRecipes = ''
|
|
SSurfRecipes[COL1(),1] = ''
|
|
REPEAT
|
|
|
|
SurfResults = Get_Property(@WINDOW:'.SCAN_RESULTS','LIST')
|
|
|
|
* Remove empty lines from control
|
|
|
|
LOOP
|
|
SurfResLine = SurfResults[-1,'B':@FM]
|
|
CONVERT @VM TO '' IN SurfResLine
|
|
UNTIL SurfResLine NE '' OR SurfResults = ''
|
|
SurfResults[COL1(),99] = ''
|
|
REPEAT
|
|
|
|
CurrRec = Get_Property(@Window, 'RECORD')
|
|
ScanResults = CurrRec<CLEAN_INSP_SCAN_RESULT$>
|
|
CtrlName = @WINDOW:'.SCAN_RESULTS'
|
|
For each ScanResult in ScanResults using @VM setting Line
|
|
Begin Case
|
|
Case ScanResult EQ 'P'
|
|
Color = GREEN$:@FM:BLACK$:@FM:BGREEN$:@FM:BLACK$
|
|
Case ScanResult EQ 'F'
|
|
Color = RED$:@FM:BLACK$:@FM:BRED$:@FM:BLACK$
|
|
Case Otherwise$
|
|
Null
|
|
End Case
|
|
// Color the row
|
|
stat = Send_Message(CtrlName, 'COLOR_BY_POS', 0, Line, Color)
|
|
Next ScanResult
|
|
|
|
Set_Property(@Window:'.SPEC_MICROSCOPE', 'ENABLED', False$)
|
|
Set_Property(@Window:'.CHK_EDGE', 'ENABLED', False$)
|
|
|
|
* QBF buttons
|
|
|
|
Ctrls = @WINDOW:'.QBF_FIRST_FIX':@RM ; Props = 'ENABLED':@RM
|
|
Ctrls := @WINDOW:'.QBF_PREV_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := @WINDOW:'.QBF_ABS_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := @WINDOW:'.QBF_NEXT_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := @WINDOW:'.QBF_LAST_FIX':@RM ; Props := 'ENABLED':@RM
|
|
Ctrls := @WINDOW:'.QBF_STOP_FIX' ; Props := 'ENABLED'
|
|
|
|
IF Get_Property(@WINDOW,'QBFLIST') = '' THEN
|
|
Vals = 0:@RM:0:@RM:0:@RM:0:@RM:0:@RM:0
|
|
END ELSE
|
|
Vals = 1:@RM:1:@RM:1:@RM:1:@RM:1:@RM:1
|
|
END
|
|
|
|
Set_Property(Ctrls,Props,Vals)
|
|
|
|
* Turn edit table symbolic column backgrounds to green **************************************************
|
|
|
|
ETSymbolics = Get_Property(@WINDOW,'@ET_SYMBOLICS') ;* Loaded during 'Create' in obj_Appwindow
|
|
|
|
ETCtrls = ETSymbolics<1>
|
|
ETCols = ETSymbolics<2>
|
|
|
|
FOR I = 1 TO COUNT(ETCtrls,@VM) + (ETCtrls NE '')
|
|
ETCtrl = ETCtrls<1,I>
|
|
ETList = Get_Property(ETCtrl,'LIST')
|
|
FOR Line = 1 TO COUNT(ETList,@FM) + (ETList NE '')
|
|
IF ETList<Line,1> NE '' THEN
|
|
FOR N = 1 TO COUNT(ETCols<1,I>,@SVM) + (ETCols<1,I> NE '')
|
|
stat = Send_Message(ETCtrl,'COLOR_BY_POS',ETCols<1,I,N>,Line,GREEN$)
|
|
NEXT N
|
|
END
|
|
NEXT I
|
|
NEXT I
|
|
|
|
ScanResultsArray = Get_Property(@Window : '.SCAN_RESULTS', 'ARRAY')
|
|
TestDTMs = ScanResultsArray<COL$SCAN_TEST_RUN_DTM>
|
|
Done = False$
|
|
For each DTM in TestDTMs using @VM setting vPos
|
|
If DTM NE '' then Done = True$
|
|
Until Done EQ True$
|
|
Next DTM
|
|
Convert @VM to '' in TestDTMs
|
|
TestDTMs = Trim(TestDTMs)
|
|
If TestDTMs EQ '' then
|
|
Set_Property(@Window : '.BTN_WAFER_DETAILS', 'ENABLED', False$)
|
|
end else
|
|
Set_Property(@Window : '.SCAN_RESULTS', 'SELPOS', 1:@FM:vPos)
|
|
end
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Read:
|
|
* * * * * * *
|
|
|
|
GOSUB Refresh
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Write:
|
|
* * * * * * *
|
|
|
|
DontClose = Get_Property(@WINDOW,'@DONT_CLOSE')
|
|
|
|
IF NOT(DontClose) THEN
|
|
Forward_Event()
|
|
Post_Event(@WINDOW,'CLOSE')
|
|
END ELSE
|
|
Set_Property(@WINDOW,'@DONT_CLOSE',0)
|
|
Result = 1
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
Close:
|
|
* * * * * * *
|
|
|
|
obj_Appwindow('DetailReturn',@WINDOW)
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
* * * * * * *
|
|
Delete:
|
|
* * * * * * *
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SignClean:
|
|
* * * * * * *
|
|
|
|
CtrlID = @WINDOW:'.CLEAN_RESULTS'
|
|
|
|
CtrlList = Get_Property(CtrlID,'LIST')
|
|
|
|
SlotSelection = Get_Property(CtrlID,'SELPOS')
|
|
SelectedRow = SlotSelection<2>
|
|
|
|
SigRow = CtrlList<SelectedRow>
|
|
|
|
|
|
IF SigRow<1,COL$CLEAN_TOOL> = '' THEN
|
|
ErrMsg('Process Error':@SVM:'Clean Tool column is required.')
|
|
Set_Property(CtrlID,'SELPOS',COL$CLEAN_TOOL:@FM:SelectedRow)
|
|
RETURN
|
|
END
|
|
|
|
|
|
CONVERT @VM TO '' IN SigRow
|
|
|
|
****
|
|
|
|
Ctrls = @WINDOW:'.WO_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.WO_STEP':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.CASS_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.STAGE':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.RDS_NO' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
WOStep = Vals[COL2()+1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
Stage = Vals[COL2()+1,@RM]
|
|
RDSNo = Vals[COL2()+1,@RM]
|
|
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
ReactType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
|
|
IF Stage = 'POST' THEN
|
|
IF RDSNo = '' THEN
|
|
* Epi Pro wafers
|
|
SigAction = WOStep:'MO_PSTC'
|
|
SigStage = 'MO_PSTC'
|
|
END ELSE
|
|
SigAction = WOStep:'PSTC'
|
|
SigStage = 'PSTC'
|
|
END
|
|
|
|
END ELSE
|
|
SigAction = WOStep:Stage:'C'
|
|
SigStage = Stage:'C'
|
|
END
|
|
|
|
IF SigRow NE '' AND CtrlList<SelectedRow,COL$CLEAN_SIG> = '' THEN
|
|
|
|
If SelectedRow EQ 1 then
|
|
WOMatKey = WONo:'*':CassNo
|
|
Signature_Services('CheckSigOrder', WOMatKey, SigStage, RDSNo)
|
|
If Error_Services('HasError') then
|
|
ErrMsg(Error_Services('GetMessage'))
|
|
return
|
|
end
|
|
end
|
|
|
|
// Add check for supplement signatures
|
|
ValidStages = Supplement_Services('GetStagesForLot', 'RDS', RDSNo)
|
|
If Count(ValidStages, SigStage) NE 0 then
|
|
UnacknowledgedSupp = Supplement_Services('UnacknowledgedSupplementCheck', 'RDS', RDSNo, SigStage)
|
|
If UnacknowledgedSupp NE FALSE$ then
|
|
Response = Dialog_Box('NDW_RDS_SUPP_SIG', @Window, RDSNo :@FM: SigStage :@FM: FALSE$)
|
|
If Response EQ False$ then return
|
|
end
|
|
End
|
|
|
|
IF MemberOf(@USER4, 'OI_SUPERUSER') THEN
|
|
Valid = 1
|
|
END ELSE
|
|
Valid = Dialog_Box( 'QUOTE_SIG_PWD_ENTRY', @WINDOW, @USER4:@VM:XLATE( 'LSL_USERS', @USER4, LSL_USERS_PASSWORD$, 'X' ) )
|
|
END
|
|
|
|
IF Valid = 1 THEN
|
|
|
|
CurrDate = OCONV(Date(),'D4/')
|
|
CurrTime = OCONV(Time(),'MTHS')
|
|
CurrDTM = CurrDate:' ':CurrTime
|
|
Signer = @USER4
|
|
|
|
ToolID = CtrlList<SelectedRow,COL$INSP_TOOL>
|
|
ToolRec = XLATE('TOOL',ToolID,'','X')
|
|
|
|
ToolWHCd = ToolRec<TOOL_TOOL_WH$>
|
|
ToolLoc = ToolRec<TOOL_TOOL_LOC$>
|
|
Tag = ''
|
|
|
|
owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:SigStage:@RM:Signer:@RM:CurrDTM:@RM:ToolID:@RM:ToolWHCd:@RM:ToolLoc:@RM:Tag ;* Sets PSTC signature
|
|
|
|
IF Get_Status(errCode) THEN
|
|
CALL ErrMsg(ErrCode)
|
|
RETURN
|
|
END
|
|
|
|
ToolID = CtrlList<SelectedRow,COL$CLEAN_TOOL>
|
|
ToolRec = XLATE('TOOL',ToolID,'','X')
|
|
|
|
ToolWHCd = ToolRec<TOOL_TOOL_WH$>
|
|
ToolLoc = ToolRec<TOOL_TOOL_LOC$>
|
|
|
|
LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM
|
|
LogDTM = CurrDTM ; WOMLParms := LogDTM:@RM
|
|
Action = SigAction ; WOMLParms := Action:@RM
|
|
WhCd = ToolWHCd ; WOMLParms := WhCd:@RM
|
|
LocCd = ToolLoc ; WOMLParms := LocCd:@RM
|
|
WONos = WONo ; WOMLParms := WONos:@RM
|
|
CassNos = CassNo ; WOMLParms := CassNos:@RM
|
|
UserID = Signer ; WOMLParms := UserID:@RM
|
|
Tags = Tag ; WOMLParms := Tags:@RM
|
|
ToolID = ToolID ; WOMLParms := ToolID
|
|
|
|
obj_WO_Mat_Log('Create',WOMLParms) ;* Stage PSTC log entry
|
|
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
RETURN
|
|
END
|
|
|
|
Set_Property(CtrlID,'CELLPOS',Signer,COL$CLEAN_SIG:@FM:SelectedRow)
|
|
Set_Property(CtrlID,'CELLPOS',CurrDTM,COL$CLEAN_SIG_DTM:@FM:SelectedRow)
|
|
|
|
|
|
CINo = Get_Property(@WINDOW:'.CI_NO','DEFPROP')
|
|
|
|
Set_Property(@WINDOW,'@DONT_CLOSE',1)
|
|
|
|
Send_Event(@WINDOW,'WRITE')
|
|
|
|
obj_AppWindow('LUValReturn',CINo:@RM:@WINDOW:'.CI_NO')
|
|
|
|
END
|
|
|
|
END ELSE
|
|
IF SigRow = '' THEN
|
|
ErrMsg('Process Error':@SVM:'Must have some information in selected row to sign.')
|
|
RETURN
|
|
END
|
|
|
|
IF CtrlList<SelectedRow,COL$CLEAN_SIG> NE '' THEN
|
|
ErrMsg('Process Error':@SVM:'Row is already signed.')
|
|
RETURN
|
|
END
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SignInsp:
|
|
* * * * * * *
|
|
|
|
CtrlID = @WINDOW:'.INSP_RESULTS'
|
|
|
|
CtrlList = Get_Property(CtrlID,'LIST')
|
|
|
|
SlotSelection = Get_Property(CtrlID,'SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
|
|
SlotSelection = Get_Property(CtrlID,'SELPOS')
|
|
SelectedRow = SlotSelection<2>
|
|
|
|
SigRow = CtrlList<SelectedRow>
|
|
BackSigRow = Get_Property(@Window:'.INSP_RESULTS_BSIDE', 'LIST')<SelectedRow>
|
|
|
|
FrontSpecRow = Get_Property(@Window:'.SPEC_INSP', 'LIST')
|
|
BackSpecRow = Get_Property(@Window:'.SPEC_INSP_BSIDE', 'LIST')
|
|
|
|
InspTools = 'SCOPE':@VM:'FF EDGE INSP':@VM:'SCOPE/FF EDGE INSP'
|
|
SelTool = SigRow<1,COL$INSP_TOOL>
|
|
|
|
IF SelTool = '' THEN
|
|
ErrMsg('Process Error':@SVM:'Insp Tool column is required.')
|
|
Set_Property(CtrlID,'SELPOS',COL$INSP_TOOL:@FM:SelectedRow)
|
|
RETURN
|
|
END
|
|
|
|
// Ensure tool selected matches that of the prescribed inspection type
|
|
EdgeInspReq = Get_Property(@Window:'.CHK_EDGE', 'CHECK')
|
|
ScopeInspReq = Get_Property(@Window:'.SPEC_MICROSCOPE', 'CHECK')
|
|
Begin Case
|
|
Case EdgeInspReq and ScopeInspReq
|
|
If SelTool NE 'SCOPE/FF EDGE INSP' then
|
|
ErrMsg('Process Error':@SVM:'Edge inspection and scope inspection are required. Selected tool must be "SCOPE/FF EDGE INSP"')
|
|
Set_Property(CtrlID,'SELPOS',COL$INSP_TOOL:@FM:SelectedRow)
|
|
return
|
|
end
|
|
Case ScopeInspReq
|
|
If SelTool NE 'SCOPE' then
|
|
ErrMsg('Process Error':@SVM:'Microscope inspection is required. Selected tool must be "SCOPE"')
|
|
Set_Property(CtrlID,'SELPOS',COL$INSP_TOOL:@FM:SelectedRow)
|
|
return
|
|
end
|
|
Case EdgeInspReq
|
|
If SelTool NE 'FF EDGE INSP' then
|
|
ErrMsg('Process Error':@SVM:'Edge inspection is required. Selected tool must be "FF EDGE INSP"')
|
|
Set_Property(CtrlID,'SELPOS',COL$INSP_TOOL:@FM:SelectedRow)
|
|
return
|
|
end
|
|
End Case
|
|
|
|
// Verify frontside inspection data
|
|
For Col = COL$INSP_SPEC_LPD to COL$INSP_SPEC_BL_DEFECTS
|
|
|
|
ColSpec = FrontSpecRow<1, Col>
|
|
ColVal = SigRow<1, Col + 1> ;* Results has the tool column in front of the actual data
|
|
If ( (ColSpec NE '') and (ColVal EQ '') ) then
|
|
ErrMsg('Process Error':@SVM:'Data is missing in column number ':Col-1:'.')
|
|
Set_Property(CtrlID,'SELPOS',Col:@FM:SelectedRow)
|
|
RETURN
|
|
end
|
|
|
|
Next Col
|
|
|
|
// Verify backside inspection data
|
|
For Col = COL$INSP_SPEC_BSIDE_SCRATCHES to COL$INSP_SPEC_BSIDE_SPIKES
|
|
|
|
ColSpec = BackSpecRow<1, Col>
|
|
ColVal = BackSigRow<1, Col>
|
|
If ( (ColSpec NE '') and (ColVal EQ '') ) then
|
|
ErrMsg('Process Error':@SVM:'Data is missing in column number ':Col-1:'.')
|
|
Set_Property(CtrlID,'SELPOS',Col:@FM:SelectedRow)
|
|
RETURN
|
|
end
|
|
|
|
Next Col
|
|
|
|
CONVERT @VM TO '' IN SigRow
|
|
|
|
Ctrls = @WINDOW:'.WO_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.WO_STEP':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.CASS_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.STAGE':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.RDS_NO' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
WOStep = Vals[COL2()+1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
Stage = Vals[COL2()+1,@RM]
|
|
RDSNo = Vals[COL2()+1,@RM]
|
|
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
ReactType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
|
|
IF Stage = 'POST' THEN
|
|
IF RDSNo = '' THEN
|
|
* Epi Pro wafers
|
|
SigAction = WOStep:'MO_PSTI'
|
|
SigStage = 'MO_PSTI'
|
|
END ELSE
|
|
SigAction = WOStep:'PSTI'
|
|
SigStage = 'PSTI'
|
|
END
|
|
|
|
END ELSE
|
|
SigAction = WOStep:Stage:'I'
|
|
SigStage = Stage:'I'
|
|
END
|
|
|
|
IF SigRow NE '' AND CtrlList<SelectedRow,COL$INSP_SIG> = '' THEN
|
|
|
|
If SelectedRow EQ 1 then
|
|
WOMatKey = WONo:'*':CassNo
|
|
Signature_Services('CheckSigOrder', WOMatKey, SigStage, False$, RDSNo)
|
|
If Error_Services('HasError') then
|
|
ErrMsg(Error_Services('GetMessage'))
|
|
return
|
|
end
|
|
|
|
END ;* End of check for 1st Signature row
|
|
|
|
// Add check for supplement signatures
|
|
ValidStages = Supplement_Services('GetStagesForLot', 'RDS', RDSNo)
|
|
If Count(ValidStages, SigStage) NE 0 then
|
|
UnacknowledgedSupp = Supplement_Services('UnacknowledgedSupplementCheck', 'RDS', RDSNo, SigStage)
|
|
If UnacknowledgedSupp NE FALSE$ then
|
|
Response = Dialog_Box('NDW_RDS_SUPP_SIG', @Window, RDSNo :@FM: SigStage :@FM: FALSE$)
|
|
If Response EQ False$ then return
|
|
end
|
|
End
|
|
|
|
// Check if edge inspection is prescribed. If so, prompt user whether or not edge defects are present.
|
|
If EdgeInspReq then
|
|
// If edge defects are present, present user with a wafer selection dialog and create an NCR for those wafers.
|
|
Response = Msg(@Window, '', 'YESNO', '', 'Edge Defects':@FM:'Are any edge defects present?')
|
|
If Response EQ True$ then
|
|
// Display a popup of wafers in the RDS or WM_OUT cassette
|
|
WONo = Get_Property(@Window : '.WO_NO', 'TEXT')
|
|
WOStepNo = Get_Property(@Window:'.WO_STEP', 'TEXT')
|
|
ReactType = Xlate('WO_LOG', WONo, 'REACT_TYPE', 'X')
|
|
CassNo = Get_Property(@Window:'.CASS_NO', 'TEXT')
|
|
WOMatKey = WONo:'*':CassNo
|
|
|
|
If ReactType NE 'EPP' then
|
|
// Non-EpiPro
|
|
// Loop until user successfully creates an NCR
|
|
Loop
|
|
ErrFlag = False$
|
|
// Prompt user to select affected wafers
|
|
Response = Dialog_Box('DBW_WO_MAT_WAFER_SELECT', @Window, WOMatKey)
|
|
If Response EQ 'Cancel' then
|
|
ErrMsg('Signature operation aborted.')
|
|
return
|
|
end
|
|
SelRowData = SRP_Array('Rotate', Response, @FM, @VM)
|
|
|
|
SlotNos = SelRowData<COL$SLOT>
|
|
WfrIDs = SelRowData<COL$WAFER_ID>
|
|
PrevNCRs = SelRowData<COL$SLOT_NCR>
|
|
MetNos = SelRowData<COL$MET_NO$>
|
|
MUWfrIDs = SelRowData<COL$MU_WAFER_ID>
|
|
|
|
IneligibleSlots = ''
|
|
For each SlotNo in SlotNos using @VM setting vPos
|
|
MetNo = MetNos<0, vPos>
|
|
WfrID = WfrIDs<0, vPos>
|
|
PrevNCR = PrevNCRs<0, vPos>
|
|
MUWfrID = MUWfrIDs<0, vPos>
|
|
If ( (MetNo NE '') or (WfrID EQ '') or (PrevNCR NE '' and MUWfrID EQ '') ) then
|
|
ErrFlag = True$
|
|
IneligibleSlots<0, -1> = SlotNo
|
|
end
|
|
Next SlotNo
|
|
|
|
If ErrFlag EQ False$ then
|
|
|
|
// Place the lot on hold if it isn't already.
|
|
HoldEntity = 'WO_MAT'
|
|
HoldEntityID = WOMatKey
|
|
Set_Status(0)
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
* If Not(OnHold) then obj_WO_Mat('ToggleHold',WOMatKey:@RM:HoldEntity:@RM:HoldEntityID:@RM:'')
|
|
If Not(OnHold) then Hold_Services('ToggleHold', WOMatKey, HoldEntity, HoldEntityID, '', '', '', '')
|
|
ErrCode = ''
|
|
If Not(Get_Status(ErrCode)) then
|
|
// Ensure the user didn't cancel the hold operation.
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
If OnHold then
|
|
|
|
// Set ROTR block on reactor
|
|
Reactor = Xlate('RDS', RDSNo, 'REACTOR', 'X')
|
|
ReactorRec = Database_Services('ReadDataRow', 'REACTOR', Reactor)
|
|
ReactorRec<REACTOR_ROTR_STATUS$> = 'F'
|
|
ReactorRec<REACTOR_ROTR_STATUS_REASON$> = 'Edge defects reported for RDS ':RDSNo:'.'
|
|
Database_Services('WriteDataRow', 'REACTOR', RDSNo, ReactorRec)
|
|
|
|
Def = ""
|
|
Def<MTEXT$> = "Creating NCR...Please wait"
|
|
Def<MTYPE$> = "U"
|
|
MsgUp = Msg(@window, Def) ;* display the processing message
|
|
|
|
WOMatKey = WONo:'*':CassNo
|
|
ncrParms = WONo:@RM
|
|
ncrParms := WOStepNo:@RM
|
|
ncrParms := CassNo:@RM
|
|
ncrParms := RDSNo:@RM
|
|
ncrParms := Reactor:@RM
|
|
ncrParms := '':@RM ;* Stage
|
|
ncrParms := '':@RM ;* InCassNos
|
|
ncrParms := SlotNos:@RM ;* InSlotNos
|
|
ncrParms := '':@RM ;* EPP only - PockeNots
|
|
ncrParms := '':@RM ;* EPP only - Zones
|
|
ncrParms := '':@RM ;* EPP only - OutCassNos
|
|
ncrParms := '':@RM ;* EPP only - OutSlotNos
|
|
ncrParms := '':@RM ;* EPP only - Multiple RDSNos
|
|
ncrParms := WfrIDs:@RM ;* Rejected Wafer ID's
|
|
ncrParms := PrevNCRs:@RM ;* Previous NCR Nos
|
|
ncrParms := '':@RM ;* EPP only - MU WONos
|
|
ncrParms := '':@RM ;* EPP only - MU WO Step Nos
|
|
ncrParms := '':@RM ;* EPP only - MU Cass Nos
|
|
ncrParms := '':@RM ;* EPP only - MU Slot Nos
|
|
ncrParms := 'C':@RM ;* Loss By
|
|
ncrParms := 'Wafers removed due to edge defects':@RM ;* Containment Actions
|
|
ncrParms := 'Edge defects discovered during post-epi inspection':@RM ;* Loss Comments
|
|
ncrParms := '':@RM ;* AC Comments
|
|
ncrParms := '':@RM ;* Department Responsible
|
|
ncrParms := '':@RM ;* AC Code
|
|
ncrParms := 'D63':@RM ;* Loss Code
|
|
ncrParms := 'O':@RM ;* NCR Status - Open
|
|
ncrParms := '':@RM ;* Shift
|
|
ncrParms := '':@RM ;* Shipment Signature
|
|
ncrParms := '':@RM ;* Reject Signature
|
|
ncrParms := '':@RM ;* Sent to SPC Datetime
|
|
ncrParms := '':@RM ;* Shipment Signature Datetime
|
|
ncrParms := 'Production' ;* Department Handled
|
|
|
|
Set_Status(0)
|
|
NCRNo = obj_NCR('Create',ncrParms) ;* Create new NCR for this wafer/group of wafers
|
|
Msg(@window, MsgUp) ;* take down the processing message
|
|
|
|
SAPBatchNo = Xlate('WO_MAT', WOMatKey, 'SAP_BATCH_NO', 'X')
|
|
|
|
IF Not(Get_Status(errCode)) THEN
|
|
IF SAPBatchNo NE '' THEN
|
|
IF SAPBatchNo[-1,1] NE 'R' THEN
|
|
MUFlag = Xlate('NCR', NCRNo, 'MAKEUP_BOX', 'X')
|
|
MUFlag = OCONV(MUFlag ,'BYes,')
|
|
PartNoID = Xlate('NCR', NCRNo, 'WO_MAT_PART_NO', 'X')
|
|
RejCnt = Xlate('NCR', NCRNo, 'REJ_CNT', 'X')
|
|
Recipients = XLATE('NOTIFICATION', 'NCR_AFTER_GR', NOTIFICATION_USER_ID$, 'X')
|
|
SentFrom = @USER4
|
|
Subject = 'SAP Post - GR Scrap Qty - NCR Reported' ;* Modified subject line - dkk 7/17/14
|
|
Message = "NCR: ":NCRNo:CRLF$:"Batch_No: ":SAPBatchNo:CRLF$:"MU Box: ":MUFlag:CRLF$:"Epi PN: ":PartNoID:CRLF$:"Qty: ":RejCnt ;* Added Epi PN on the end - dkk 7/17/14
|
|
AttachWindow = 'NCR'
|
|
AttachKey = NCRNo
|
|
SendToGroup = ''
|
|
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
|
|
obj_Notes('Create',Parms)
|
|
END
|
|
END
|
|
|
|
RejDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')
|
|
|
|
sCnt = COUNT(SlotNos,@VM) + (SlotNos NE '')
|
|
FOR N = 1 TO sCnt
|
|
* * * * Added 3/23/2016 JCH - wafer history * * * *
|
|
|
|
RejWfrID = WfrIDs<1,N>
|
|
CurrSlotID = WONo:'*':CassNo:'*':SlotNos<1,N>
|
|
|
|
Convert '.' To '*' In RejWfrID
|
|
|
|
Parms = RejWfrID:@RM ;* WfrID
|
|
Parms := RejDTM:@RM ;* EventDtm
|
|
Parms := @USER4:@RM ;* EventBy
|
|
Parms := 'NCR':@RM ;* Event
|
|
Parms := '':@RM ;* NewSlotID
|
|
Parms := '':@RM ;* RunLoc
|
|
Parms := NCRNo:@RM ;* NCRNo
|
|
Parms := '':@RM ;* TWUse
|
|
Parms := CurrSlotID:@RM ;* CurrSlotID
|
|
Parms := '':@RM ;* NewToolID
|
|
Parms := '':@RM ;* CurrToolID
|
|
Parms := '':@RM ;* NewInvLoc
|
|
Parms := '':@RM ;* CurrInvLoc
|
|
Parms := 'O' ;* Wfr Side
|
|
|
|
obj_WO_Wfr('AddEvent',Parms)
|
|
* * * * * * * * *
|
|
LineNo = SlotNos<1,N>
|
|
NEXT N
|
|
|
|
// Display the new NCR so the user can fill in the details and sign it off.
|
|
Dialog_Box('NCR', @Window, NCRNo)
|
|
|
|
end else
|
|
// Bail to force user to contact FI to correct issue.
|
|
ErrMsg('Error creating NCR. Error message: ':ErrCode:'. Please contact FI for assistance.')
|
|
return
|
|
end
|
|
end else
|
|
// User cancelled the hold operation.
|
|
ErrMsg('The lot must be placed on hold. Signature operation cancelled.')
|
|
return
|
|
end
|
|
end else
|
|
// Bail to force user to contact FI to correct issue.
|
|
ErrMsg('Error placing lot on hold. Error message: ':ErrCode:'. Please contact FI for assistance.')
|
|
return
|
|
end
|
|
end else
|
|
// Inform user ineligible wafer(s) were selected and loop to try again.
|
|
Swap @VM with ',' in IneligibleSlots
|
|
ErrMsg('Selected slot(s) ' : IneligibleSlots : ' are not eligible for NCR.')
|
|
end
|
|
|
|
Until Not(ErrFlag)
|
|
Repeat
|
|
|
|
end else
|
|
// EpiPro
|
|
WMOKey = WONo:'*':WOStepNo:'*':CassNo
|
|
|
|
// Loop until user selects at least one eligible wafer to NCR.
|
|
Loop
|
|
ErrFlag = False$
|
|
|
|
// Prompt user to select affected wafers.
|
|
SelRows = ''
|
|
Response = Dialog_Box('DBW_WM_OUT_WAFER_SELECT', @Window, WMOKey)
|
|
If Response EQ 'Cancel' then
|
|
ErrMsg('Signature operation aborted.')
|
|
return
|
|
end
|
|
SelRowData = SRP_Array('Rotate', Response, @FM, @VM)
|
|
|
|
NCROutSlotNos = SelRowData<COL$EPP_SLOT>
|
|
NCROutCassNos = Str(CassNo:@VM, DCount(NCROutSlotNos, @VM))
|
|
NCROutCassNos[-1 ,1] = ''
|
|
NCRRDSNos = SelRowData<COL$EPP_RDS_NO>
|
|
NCRPocketNos = SelRowData<COL$EPP_POCKET>
|
|
NCRZones = SelRowData<COL$EPP_ZONE>
|
|
NCRInCassNos = SelRowData<COL$EPP_IN_CASS>
|
|
NCRInSlotNos = SelRowData<COL$EPP_IN_SLOT>
|
|
NCRSlotNCRs = SelRowData<COL$EPP_SLOT_NCR>
|
|
NCRMUWONos = SelRowData<COL$EPP_MU_WO_NO>
|
|
NCRMUWOSteps = SelRowData<COL$EPP_MU_WO_STEP>
|
|
NCRMUCassIDs = SelRowData<COL$EPP_MU_CASS_NO>
|
|
NCRMUSlotNos = SelRowData<COL$EPP_MU_SLOT_NO>
|
|
UsedMUCassIDs = SelRowData<COL$EPP_UMW_CASS_ID>
|
|
|
|
ErrFlag = False$
|
|
For each SelSlot in NCROutSlotNos using @VM setting vPos
|
|
IF UsedMUCassIDs<0, vPos> = '' THEN
|
|
IF NCRRDSNos<0, vPos> NE '' THEN
|
|
IF NCRSlotNCRs<0, vPos> = '' OR NCRMUWONos<0, vPos> NE '' THEN
|
|
Null
|
|
END ELSE
|
|
ErrMsg('Slot ':SelSlot:' is empty.')
|
|
ErrFlag = True$
|
|
END ;* End of check for no Slot NCR (original wafer being rejected) or MU wafer data (makeup wafer being rejected)
|
|
END ELSE
|
|
ErrMsg('Slot ':SelSlot:' is not used.')
|
|
ErrFlag = True$
|
|
END ;* End of check for RDS (wafer) present and not used for makeup
|
|
END ELSE
|
|
ErrMsg('Slot ':SelSlot:' has been used for makeup.')
|
|
ErrFlag = True$
|
|
END ;* End of check for slot Used for Makeup Wafer
|
|
Until ErrFlag
|
|
Next SelSlot
|
|
|
|
// Create an NCR with edge defects loss code
|
|
If Not(ErrFlag) then
|
|
|
|
// Place the lot on hold if it isn't already on hold.
|
|
HoldEntity = 'WM_OUT'
|
|
HoldEntityID = WMOKey
|
|
Set_Status(0)
|
|
OnHold = Xlate('WO_MAT', WOMatKey, 'HOLD', 'X')
|
|
* If Not(OnHold) then obj_WO_Mat('ToggleHold',WOMatKey:@RM:HoldEntity:@RM:HoldEntityID:@RM:'')
|
|
If Not(OnHold) then Hold_Services('ToggleHold', WOMatKey, HoldEntity, HoldEntityID, '', '', '', '')
|
|
ErrCode = ''
|
|
If Not(Get_Status(ErrCode)) then
|
|
|
|
// Ensure the user didn't cancel the hold operation.
|
|
OnHold = Xlate('WM_OUT', WMOKey, 'HOLD', 'X')
|
|
If OnHold then
|
|
|
|
// Set ROTR block on reactor
|
|
ROTRReactNos = SRP_Array('Clean', NCRRDSNos, 'TrimAndMakeUnique', @VM)
|
|
If ROTRReactNos NE '' then
|
|
For each ROTRReactNo in ROTRReactNos using @VM
|
|
Reactor = Xlate('RDS', ROTRReactNo, 'REACTOR', 'X')
|
|
ReactorRec = Database_Services('ReadDataRow', 'REACTOR', Reactor)
|
|
ReactorRec<REACTOR_ROTR_STATUS$> = 'F'
|
|
ReactorRec<REACTOR_ROTR_STATUS_REASON$> = 'Edge defects reported for outbound cassette ':WMOKey:'.'
|
|
Database_Services('WriteDataRow', 'REACTOR', Reactor, ReactorRec)
|
|
Next ROTRReactNo
|
|
end
|
|
|
|
Def = ""
|
|
Def<MTEXT$> = "Creating NCR...Please wait"
|
|
Def<MTYPE$> = "U"
|
|
MsgUp = Msg(@window, Def) ;* display the processing message
|
|
|
|
ncrParms = WONo:@RM
|
|
ncrParms := WOStep:@RM
|
|
ncrParms := CassNo:@RM
|
|
ncrParms := '':@RM ;* Single RDS field - N/A for EpiPro
|
|
ncrParms := '':@RM ;* Reactor No - N/A for EpiPro
|
|
ncrParms := 'POST':@RM
|
|
ncrParms := NCRInCassNos:@RM
|
|
ncrParms := NCRInSlotNos:@RM
|
|
ncrParms := NCRPocketNos:@RM
|
|
ncrParms := NCRZones:@RM
|
|
ncrParms := NCROutCassNos:@RM
|
|
ncrParms := NCROutSlotNos:@RM
|
|
ncrParms := NCRRDSNos:@RM
|
|
ncrParms := '':@RM ;* Placeholder for RejWaferIDS - N/A for EpiPro
|
|
ncrParms := NCRSlotNCRs:@RM
|
|
ncrParms := NCRMUWONos:@RM
|
|
ncrParms := NCRMUWOSteps:@RM
|
|
ncrParms := NCRMUCassIDs:@RM
|
|
ncrParms := NCRMUSlotNos:@RM
|
|
ncrParms := 'C':@RM ;* Loss By
|
|
ncrParms := 'Wafers removed due to edge defects':@RM ;* Containment Actions
|
|
ncrParms := 'Edge defects discovered during post-epi inspection':@RM ;* Loss Comments
|
|
ncrParms := '':@RM ;* AC Comments
|
|
ncrParms := '':@RM ;* Department Responsible
|
|
ncrParms := '':@RM ;* AC Code
|
|
ncrParms := 'D63':@RM ;* Loss Code
|
|
ncrParms := 'O':@RM ;* NCR Status - Open
|
|
ncrParms := '':@RM ;* Shift
|
|
ncrParms := '':@RM ;* Shipment Signature
|
|
ncrParms := '':@RM ;* Reject Signature
|
|
ncrParms := '':@RM ;* Sent to SPC Datetime
|
|
ncrParms := '':@RM ;* Shipment Signature Datetime
|
|
ncrParms := 'Production' ;* Department Handled
|
|
|
|
Set_Status(0)
|
|
NCRNo = obj_NCR('Create',ncrParms) ;* Create new NCR for this wafer/group of wafers
|
|
Msg(@window, MsgUp) ;* take down the processing message
|
|
|
|
ErrCode = ''
|
|
If Not(Get_Status(ErrCode)) then
|
|
|
|
WMORec = Database_Services('ReadDataRow', 'WM_OUT', WMOKey)
|
|
|
|
RejDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')
|
|
|
|
RejWfrIDs = ''
|
|
|
|
FOR N = 1 TO COUNT(NCROutSlotNos,@VM) + (NCROutSlotNos NE '')
|
|
|
|
* * * * Added 4/23/2016 JCH - wafer history * * * *
|
|
|
|
CurrSlotID = WONo:'*':NCROutCassNos<1,N>:'*':NCROutSlotNos<1,N>
|
|
|
|
IF NCRMUWONos<1,N> = '' THEN
|
|
RejWfrID = WONo:'*':NCRInCassNos<1,N>:'*':NCRInSlotNos<1,N>
|
|
END ELSE
|
|
RejWfrID = NCRMUWONos<1,N>:'*':NCRMUCassIDs<1,N>:'*':NCRMUSlotNos<1,N>
|
|
END
|
|
|
|
RejWfrIDs<1,-1> = RejWfrID
|
|
|
|
Parms = RejWfrID:@RM ;* WfrID
|
|
Parms := RejDTM:@RM ;* EventDtm
|
|
Parms := @USER4:@RM ;* EventBy
|
|
Parms := 'NCR':@RM ;* Event
|
|
Parms := '':@RM ;* NewSlotID
|
|
Parms := '':@RM ;* RunLoc
|
|
Parms := NCRNo:@RM ;* NCRNo
|
|
Parms := '':@RM ;* TWUse
|
|
Parms := CurrSlotID:@RM ;* CurrSlotID
|
|
Parms := '':@RM ;* NewToolID
|
|
Parms := '':@RM ;* CurrToolID
|
|
Parms := '':@RM ;* NewInvLoc
|
|
Parms := '':@RM ;* CurrInvLoc
|
|
Parms := 'O' ;* Wfr Side
|
|
|
|
obj_WO_Wfr('AddEvent',Parms)
|
|
|
|
// Add NCR details to WM_OUT record
|
|
SlotNo = NCROutSlotNos<1,N>
|
|
WMORec<WM_OUT_RDS$, SlotNo> = ''
|
|
WMORec<WM_OUT_POCKET$, SlotNo> = ''
|
|
WMORec<WM_OUT_ZONE$, SlotNo> = ''
|
|
WMORec<WM_OUT_IN_CASS_NO$, SlotNo> = ''
|
|
WMORec<WM_OUT_IN_SLOT_NO$, SlotNo> = ''
|
|
WMORec<WM_OUT_SLOT_NCR$, SlotNo> = NCRNo
|
|
WMORec<WM_OUT_MU_WO_NO$, SlotNo> = ''
|
|
WMORec<WM_OUT_MU_WO_STEP$, SlotNo> = ''
|
|
WMORec<WM_OUT_MU_CASS_NO$, SlotNo> = ''
|
|
WMORec<WM_OUT_MU_SLOT_NO$, SlotNo> = ''
|
|
|
|
NEXT N
|
|
|
|
Database_Services('WriteDataRow', 'WM_OUT', WMOKey, WMORec)
|
|
|
|
Dialog_Box('NCR', @Window, NCRNo)
|
|
|
|
end else
|
|
// Bail to force user to contact FI to correct issue.
|
|
ErrMsg('Error creating NCR. Error message: ':ErrCode:'. Please contact FI for assistance.')
|
|
return
|
|
end
|
|
end else
|
|
// User cancelled the hold operation.
|
|
ErrMsg('The lot must be placed on hold. Signature operation cancelled.')
|
|
return
|
|
end
|
|
end else
|
|
// Bail to force user to contact FI to correct issue.
|
|
ErrMsg('Error placing lot on hold. Error message: ':ErrCode:'. Please contact FI for assistance.')
|
|
return
|
|
end
|
|
end
|
|
Until Not(ErrFlag)
|
|
Repeat
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
IF MemberOf(@USER4, 'OI_SUPERUSER') THEN
|
|
Valid = 1
|
|
END ELSE
|
|
Valid = Dialog_Box( 'QUOTE_SIG_PWD_ENTRY', @WINDOW, @USER4:@VM:XLATE( 'LSL_USERS', @USER4, LSL_USERS_PASSWORD$, 'X' ) )
|
|
END
|
|
|
|
IF Valid = 1 THEN
|
|
|
|
Def = ""
|
|
Def<MTEXT$> = "Updating material log and saving clean && inspection record..."
|
|
Def<MTYPE$> = "U"
|
|
MsgUp = Msg(@window, Def) ;* display the processing message
|
|
|
|
CurrDate = OCONV(Date(),'D4/')
|
|
CurrTime = OCONV(Time(),'MTHS')
|
|
CurrDTM = CurrDate:' ':CurrTime
|
|
Signer = @USER4
|
|
|
|
ToolID = CtrlList<SelectedRow,COL$INSP_TOOL>
|
|
If ToolID EQ 'SCOPE' or ToolID EQ 'SCOPE/FF EDGE INSP' then
|
|
ToolWHCd = 'CR'
|
|
ToolLoc = 'QA'
|
|
end else
|
|
ToolRec = XLATE('TOOL',ToolID,'','X')
|
|
ToolWHCd = ToolRec<TOOL_TOOL_WH$>
|
|
ToolLoc = ToolRec<TOOL_TOOL_LOC$>
|
|
end
|
|
|
|
Tag = ''
|
|
|
|
IF CassNo NE '' THEN
|
|
|
|
owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:SigStage:@RM:Signer:@RM:CurrDTM:@RM:ToolID:@RM:ToolWHCd:@RM:ToolLoc:@RM:Tag ;* Sets PSTI signature
|
|
|
|
IF Get_Status(errCode) THEN
|
|
CALL ErrMsg(ErrCode)
|
|
RETURN 0
|
|
END
|
|
|
|
LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM
|
|
LogDTM = CurrDTM ; WOMLParms := LogDTM:@RM
|
|
Action = SigAction ; WOMLParms := Action:@RM
|
|
WhCd = ToolWHCd ; WOMLParms := WhCd:@RM
|
|
LocCd = ToolLoc ; WOMLParms := LocCd:@RM
|
|
WONos = WONo ; WOMLParms := WONos:@RM
|
|
CassNos = CassNo ; WOMLParms := CassNos:@RM
|
|
UserID = @USER4 ; WOMLParms := UserID:@RM
|
|
Tags = '' ; WOMLParms := Tags:@RM
|
|
ToolID = ToolID ; WOMLParms := ToolID
|
|
|
|
obj_WO_Mat_Log('Create',WOMLParms) ;* Add WOStep:'PSTI' to WO_MAT Event Log
|
|
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
END
|
|
END ;* End of check for null Cass No (EpiPro Reactor runs)
|
|
|
|
Set_Property(CtrlID,'CELLPOS',Signer,COL$INSP_SIG:@FM:SelectedRow)
|
|
Set_Property(CtrlID,'CELLPOS',CurrDTM,COL$INSP_SIG_DTM:@FM:SelectedRow)
|
|
|
|
CINo = Get_Property(@WINDOW:'.CI_NO','DEFPROP')
|
|
|
|
Set_Property(@WINDOW,'@DONT_CLOSE',1)
|
|
|
|
Send_Event(@WINDOW,'WRITE')
|
|
|
|
Msg(@window, MsgUp) ;* take down the processing message
|
|
|
|
obj_AppWindow('LUValReturn',CINo:@RM:@WINDOW:'.CI_NO')
|
|
|
|
END
|
|
|
|
END ELSE
|
|
IF SigRow = '' THEN
|
|
ErrMsg('Process Error':@SVM:'Must have some information in selected row to sign.')
|
|
RETURN
|
|
END
|
|
|
|
IF CtrlList<SelectedRow,COL$INSP_SIG> NE '' THEN
|
|
ErrMsg('Process Error':@SVM:'Row is already signed.')
|
|
RETURN
|
|
END
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SignScan:
|
|
* * * * * * *
|
|
|
|
CtrlID = @WINDOW:'.SCAN_RESULTS'
|
|
|
|
CtrlList = Get_Property(CtrlID,'LIST')
|
|
|
|
|
|
SlotSelection = Get_Property(CtrlID,'SELPOS')
|
|
SelectedRows = SlotSelection<2>
|
|
|
|
SlotSelection = Get_Property(CtrlID,'SELPOS')
|
|
SelectedRow = SlotSelection<2>
|
|
|
|
SigRow = CtrlList<SelectedRow>
|
|
|
|
IF SigRow<1,COL$SCAN_TOOL> = '' THEN
|
|
ErrMsg('Process Error':@SVM:'Scan Tool column is required.')
|
|
Set_Property(CtrlID,'SELPOS',COL$SCAN_TOOL:@FM:SelectedRow)
|
|
RETURN
|
|
END
|
|
|
|
|
|
CONVERT @VM TO '' IN SigRow
|
|
|
|
***
|
|
|
|
Ctrls = @WINDOW:'.WO_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.WO_STEP':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.CASS_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.STAGE':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.RDS_NO' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
WONo = Vals[1,@RM]
|
|
WOStep = Vals[COL2()+1,@RM]
|
|
CassNo = Vals[COL2()+1,@RM]
|
|
Stage = Vals[COL2()+1,@RM]
|
|
RDSNo = Vals[COL2()+1,@RM]
|
|
|
|
WOLogRow = Database_Services('ReadDataRow', 'WO_LOG', WONo)
|
|
ReactType = WOLogRow<WO_LOG_REACT_TYPE$>
|
|
|
|
IF Stage = 'POST' THEN
|
|
IF RDSNo = '' THEN
|
|
* Epi Pro wafers
|
|
SigAction = WOStep:'MO_PSTS'
|
|
SigStage = 'MO_PSTS'
|
|
END ELSE
|
|
SigAction = WOStep:'PSTS'
|
|
SigStage = 'PSTS'
|
|
END
|
|
|
|
END ELSE
|
|
SigAction = WOStep:Stage:'S'
|
|
SigStage = Stage:'S'
|
|
END
|
|
|
|
IF SigRow NE '' AND CtrlList<SelectedRow,COL$SCAN_SIG> = '' AND CtrlList<SelectedRow,COL$SCAN_SIG_DTM> = '' THEN
|
|
|
|
If SelectedRow EQ 1 then
|
|
WOMatKey = WONo:'*':CassNo
|
|
Signature_Services('CheckSigOrder', WOMatKey, SigStage, False$, RDSNo)
|
|
If Error_Services('HasError') then
|
|
ErrMsg(Error_Services('GetMessage'))
|
|
return
|
|
end
|
|
end
|
|
|
|
// Add check for supplement signatures
|
|
ValidStages = Supplement_Services('GetStagesForLot', 'RDS', RDSNo)
|
|
If Count(ValidStages, SigStage) NE 0 then
|
|
UnacknowledgedSupp = Supplement_Services('UnacknowledgedSupplementCheck', 'RDS', RDSNo, SigStage)
|
|
If UnacknowledgedSupp NE FALSE$ then
|
|
Response = Dialog_Box('NDW_RDS_SUPP_SIG', @Window, RDSNo :@FM: SigStage :@FM: FALSE$)
|
|
If Response EQ False$ then return
|
|
end
|
|
End
|
|
|
|
// This checks to see if manually entered data is authorized to be signed.
|
|
IF (SigRow NE '') AND (CtrlList<SelectedRow,COL$SCAN_TEST_RUN_DTM> = '') AND (Stage NE 'POST') THEN
|
|
Authorized = MemberOf(@USER4, 'ENGINEERING') OR MemberOf(@USER4, 'LEAD') OR MemberOf(@USER4, 'SUPERVISOR') OR MemberOf(@USER4, 'ROTR_OVERRIDE')
|
|
If Not(Authorized) then
|
|
ErrorText = 'Only Leads, Supervisors or Engineers can sign ROTR Tencor data manually entered.'
|
|
ErrMsg('Process Error':@SVM:ErrorText)
|
|
Return
|
|
end
|
|
end
|
|
|
|
IF MemberOf(@USER4, 'OI_SUPERUSER') THEN
|
|
Valid = 1
|
|
END ELSE
|
|
Valid = Dialog_Box( 'QUOTE_SIG_PWD_ENTRY', @WINDOW, @USER4:@VM:XLATE( 'LSL_USERS', @USER4, LSL_USERS_PASSWORD$, 'X' ) )
|
|
END
|
|
|
|
IF Valid = 1 THEN
|
|
|
|
CurrDate = OCONV(Date(),'D4/')
|
|
CurrTime = OCONV(Time(),'MTHS')
|
|
CurrDTM = CurrDate:' ':CurrTime
|
|
Signer = @USER4
|
|
|
|
ToolID = CtrlList<SelectedRow,COL$SCAN_TOOL>
|
|
ToolRec = XLATE('TOOL',ToolID,'','X')
|
|
ToolWHCd = ToolRec<TOOL_TOOL_WH$>
|
|
ToolLoc = ToolRec<TOOL_TOOL_LOC$>
|
|
Tag = ''
|
|
|
|
|
|
// Only call if this is non-EpiPro. - 04/09/2018 - dmb
|
|
If ReactType NE 'EPP' then
|
|
owmParms = WONo:@RM:CassNo:@RM:WOStep:@RM:SigStage:@RM:Signer:@RM:CurrDTM:@RM:ToolID:@RM:ToolWHCd:@RM:ToolLoc:@RM:Tag ;* Sets PSTI signature
|
|
|
|
IF Get_Status(errCode) THEN
|
|
CALL ErrMsg(ErrCode)
|
|
RETURN 0
|
|
END
|
|
|
|
LogFile = 'WO_MAT' ; WOMLParms = LogFile:@RM
|
|
LogDTM = CurrDTM ; WOMLParms := LogDTM:@RM
|
|
Action = SigAction ; WOMLParms := Action:@RM
|
|
WhCd = ToolWHCd ; WOMLParms := WhCd:@RM
|
|
LocCd = ToolLoc ; WOMLParms := LocCd:@RM
|
|
WONos = WONo ; WOMLParms := WONos:@RM
|
|
CassNos = CassNo ; WOMLParms := CassNos:@RM
|
|
UserID = @USER4 ; WOMLParms := UserID:@RM
|
|
Tags = '' ; WOMLParms := Tags:@RM
|
|
ToolID = ToolID ; WOMLParms := ToolID
|
|
|
|
obj_WO_Mat_Log('Create',WOMLParms) ;* Sets PSTI in WO_MAT Event Log
|
|
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
|
|
END
|
|
end
|
|
|
|
Set_Property(CtrlID,'CELLPOS',Signer,COL$SCAN_SIG:@FM:SelectedRow)
|
|
Set_Property(CtrlID,'CELLPOS',CurrDTM,COL$SCAN_SIG_DTM:@FM:SelectedRow)
|
|
|
|
|
|
CINo = Get_Property(@WINDOW:'.CI_NO','DEFPROP')
|
|
|
|
Set_Property(@WINDOW,'@DONT_CLOSE',1)
|
|
|
|
Send_Event(@WINDOW,'WRITE')
|
|
|
|
obj_AppWindow('LUValReturn',CINo:@RM:@WINDOW:'.CI_NO')
|
|
END
|
|
|
|
END ELSE
|
|
IF SigRow = '' THEN
|
|
ErrMsg('Process Error':@SVM:'Must have some information in selected row to sign.')
|
|
RETURN
|
|
END
|
|
|
|
IF CtrlList<SelectedRow,COL$SCAN_SIG> NE '' OR CtrlList<SelectedRow,COL$SCAN_SIG_DTM> NE '' THEN
|
|
ErrMsg('Process Error':@SVM:'Row is already signed.')
|
|
RETURN
|
|
END
|
|
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
SIGN_ROTR_ACCEPTANCE.CLICK:
|
|
|
|
Valid = Dialog_Box( 'QUOTE_SIG_PWD_ENTRY', @WINDOW, @USER4:@VM:XLATE( 'LSL_USERS', @USER4, LSL_USERS_PASSWORD$, 'X' ) )
|
|
If Valid EQ True$ then
|
|
OrigReason = Get_Property(@Window : '.SIGN_ROTR_REASON', 'DEFPROP')
|
|
Reason = Msg(@Window, '', 'MESSAGE_INPUT', '', 'ROTR Acceptance' : @FM : 'ROTR Acceptance Reason' : @FM : OrigReason)
|
|
If Reason NE '' then
|
|
Set_Property(@Window : '.SIGN_ROTR_SIGNATURE', 'INVALUE', @USER4)
|
|
Set_Property(@Window : '.SIGN_ROTR_DATE_TIME', 'DEFPROP', Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTHS'))
|
|
Set_Property(@Window : '.SIGN_ROTR_REASON', 'DEFPROP', Reason)
|
|
Send_Event(@Window : '.SIGN_ROTR_SIGNATURE_NAME', 'CALCULATE')
|
|
end
|
|
end
|
|
|
|
return
|
|
|
|
|
|
SCAN_RESULTS.CHAR:
|
|
|
|
Stage = Get_Property(@Window : '.STAGE', 'TEXT')
|
|
If Stage EQ 'LWI' then
|
|
CtrlEntID = 'SCAN_RESULTS'
|
|
CIKey = Get_Property(@Window : '.CI_NO', 'TEXT')
|
|
ReactorNo = Xlate('CLEAN_INSP', CIKey, 'REACT_NO', 'X')
|
|
CanEdit = Get_Property(@Window, '@CAN_EDIT')
|
|
If Not(CanEdit) then
|
|
PrevFocusID = Get_Property (@Window, "PREVFOCUS")
|
|
Message = 'Only a member of lead, supervisor, final_qa,':@SVM:'engineering, or rotr_override can manually enter data.'
|
|
Response = Msg(@Window, '', 'OVERRIDE', '', Message)
|
|
|
|
Begin Case
|
|
Case Response EQ 1
|
|
Response = True$ ; // User Clicked Override
|
|
Case Response EQ 2
|
|
Response = False$ ; // User Clicked Cancel
|
|
Case Response EQ char(27)
|
|
Response = False$ ; // User Pressed Escape Key
|
|
End Case
|
|
|
|
If Response EQ True$ then
|
|
OverrideGroups = 'LEAD' : @VM : 'SUPERVISOR' : @VM : 'ENGINEERING' :@VM: 'FINAL_QA' :@VM: 'ROTR_OVERRIDE'
|
|
Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : OverrideGroups)
|
|
Valid = Response<1>
|
|
Username = Response<2>
|
|
If NOT(Valid) then
|
|
Set_Property(@Window, 'FOCUS', PrevFocusID)
|
|
Set_Property(CtrlEntID, 'SELPOS', -1:@FM:-1)
|
|
end else
|
|
Set_Property(@Window, '@CAN_EDIT', True$)
|
|
CanEdit = True$
|
|
end
|
|
end else
|
|
Set_Property(@Window, 'FOCUS', PrevFocusID)
|
|
Set_Property(CtrlEntID, 'SELPOS', -1:@FM:-1)
|
|
end
|
|
end
|
|
|
|
If (CanEdit EQ True$) then
|
|
// Enable manual entry of data.
|
|
ScanStyles = Send_Message(@Window : '.SCAN_RESULTS', 'COLSTYLE', 0, '')
|
|
For column = 1 to 7
|
|
ScanStyles<column> = BitAnd( ScanStyles<column>, BitNot(PROTECTED$) )
|
|
Next column
|
|
// Enable dropdown menus for recipe and tool columns.
|
|
ScanStyles<COL$SCAN_RECIPE> = BitOr(ScanStyles<COL$SCAN_RECIPE>, DTCS_DROPDOWN$ )
|
|
ScanStyles<COL$SCAN_TOOL> = BitOr(ScanStyles<COL$SCAN_TOOL>, DTCS_DROPDOWN$ )
|
|
ScanStyles = Send_Message(@Window : '.SCAN_RESULTS', 'COLSTYLE', 0, ScanStyles)
|
|
end
|
|
end
|
|
****************Logging Manual Data Entry********************
|
|
TableContents = Get_Property(@Window:'.SCAN_RESULTS', 'ARRAY')
|
|
ToolID = TableContents<COL$SCAN_TOOL, 1>
|
|
IF ToolID NE '' then
|
|
Date = SRP_DateTime('Now')
|
|
EpochStart = 00732
|
|
EpochTime = SRP_DateTime('SecondSpan',EpochStart, Date)
|
|
RDSNo = Get_Property(@Window:'.RDS_NO', 'DEFPROP')
|
|
PSNo = Get_Property(@Window:'.PS_NO', 'DEFPROP')
|
|
User = @User4
|
|
Description = 'Manual SurfScan Data Entry detected for RDS #: ':RDSNo
|
|
Reactor = XLATE('RDS', RDSNo, 2, 'X')
|
|
|
|
FileName = Environment_Services('GetApplicationRootPath'): '\LogFiles\ManualDataEntry\PollPath\' : EpochTime :'.json'
|
|
|
|
OSWrite '' to FileName
|
|
JSON = '{"Equipment":"':ToolID:'", "Reactor":"':Reactor:'", "PSN":"':PSNo:'", "RDS":"':RDSNo:'", "User": "':User:'", "Description":"':Description:'"}'
|
|
|
|
OSWrite JSON to FileName
|
|
end
|
|
|
|
return
|
|
|
|
|
|
SCAN_RESULTS.POSCHANGED:
|
|
|
|
ScanCtrl = @Window : '.SCAN_RESULTS'
|
|
ScanCtrlList = Get_Property(ScanCtrl, 'LIST')
|
|
SelPos = Get_Property(ScanCtrl, 'SELPOS')
|
|
RowPos = SelPos<2>
|
|
TestDTM = ScanCtrlList<RowPos,COL$SCAN_TEST_RUN_DTM>
|
|
If TestDTM EQ '' then
|
|
Set_Property(@Window:'.BTN_WAFER_DETAILS', 'ENABLED', False$)
|
|
end else
|
|
Set_Property(@Window:'.BTN_WAFER_DETAILS', 'ENABLED', True$)
|
|
end
|
|
|
|
return
|
|
|
|
|
|
BTN_WAFER_DETAILS.CLICK:
|
|
|
|
PrevCursor = Set_Property('SYSTEM', 'CURSOR', 'H')
|
|
Yield()
|
|
CleanInspKey = Get_Property(@Window : '.CI_NO', 'TEXT')
|
|
SelPos = Get_Property(@Window : '.SCAN_RESULTS', 'SELPOS')
|
|
RowPos = SelPos<2>
|
|
If RowPos EQ '' then RowPos = 1
|
|
CreateParam = CleanInspKey : @FM : RowPos
|
|
WindowName = Create_Dialog('NDW_ROTR_WAFER_DETAILS', @Window, True$, CreateParam)
|
|
PrevCursor = Set_Property('SYSTEM', 'CURSOR', PrevCursor)
|
|
|
|
return
|
|
|
|
|
|
* * * * * * *
|
|
RefreshSpec:
|
|
* * * * * * *
|
|
|
|
CINo = Get_Property(@WINDOW:'.CI_NO','TEXT')
|
|
|
|
PSStageKey = Get_Property(@WINDOW:'.PS_STAGE_KEY','TEXT')
|
|
|
|
IF CINo NE '' AND PSStageKey NE '' THEN
|
|
Send_Event(@WINDOW,'WRITE')
|
|
obj_Clean_Insp('SpecDelta',CINo:@RM:PSStageKey)
|
|
IF Get_Status(errCode) THEN
|
|
ErrMsg(errCode)
|
|
END
|
|
|
|
obj_Appwindow('LUValReturn',CINo:@RM:@WINDOW:'.CI_NO')
|
|
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
InspPC:
|
|
* * * * * * *
|
|
|
|
CurrInspPos = Get_Property(@WINDOW:'.INSP_RESULTS','SELPOS')
|
|
CurrBSInspPos = Get_Property(@WINDOW:'.INSP_RESULTS_BSIDE','SELPOS')
|
|
|
|
CurrInspCol = CurrInspPos<1>
|
|
CurrInspRow = CurrInspPos<2>
|
|
|
|
CurrBSInspCol = CurrBSInspPos<1>
|
|
CurrBSInspRow = CurrBSInspPos<2>
|
|
|
|
Set_Property(@WINDOW:'.INSP_RESULTS_BSIDE','SELPOS',CurrBSInspCol:@FM:CurrInspRow)
|
|
|
|
GOSUB Refresh
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
BSideInspPC:
|
|
* * * * * * *
|
|
|
|
CurrInspPos = Get_Property(@WINDOW:'.INSP_RESULTS','SELPOS')
|
|
CurrBSInspPos = Get_Property(@WINDOW:'.INSP_RESULTS_BSIDE','SELPOS')
|
|
|
|
CurrInspCol = CurrInspPos<1>
|
|
CurrInspRow = CurrInspPos<2>
|
|
|
|
CurrBSInspCol = CurrBSInspPos<1>
|
|
CurrBSInspRow = CurrBSInspPos<2>
|
|
|
|
Set_Property(@WINDOW:'.INSP_RESULTS','SELPOS',CurrInspCol:@FM:CurrBSInspRow)
|
|
|
|
GOSUB Refresh
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SendSPC:
|
|
* * * * * * *
|
|
|
|
Ctrls = @WINDOW:'.RDS_NO':@RM ; Props = 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.STAGE':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SS_SCAN_TOOL':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SUM_OF_DEF_MIN':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SUM_OF_DEF_MAX':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SUM_OF_DEF_AVG':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.HAZE_AVG_AVG':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SPOTS':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.FOV':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SCRATCHES':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SCRATCH_LEN':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.REACT_NO':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.WAFER_SIZE':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SS_SCRATCH_MAX':@RM ; Props := 'DEFPROP':@RM
|
|
Ctrls := @WINDOW:'.SS_SCRATCH_AVG' ; Props := 'DEFPROP'
|
|
|
|
Vals = Get_Property(Ctrls,Props)
|
|
|
|
RDSNo = Vals[1,@RM]
|
|
Stage = Vals[COL2()+1,@RM]
|
|
ScanTool = Vals[COL2()+1,@RM]
|
|
SumOfDefMin = Vals[COL2()+1,@RM]
|
|
SumOfDefMax = Vals[COL2()+1,@RM]
|
|
SumOfDefAvg = Vals[COL2()+1,@RM]
|
|
HazeAvgAvg = Vals[COL2()+1,@RM]
|
|
Spots = Vals[COL2()+1,@RM]
|
|
FOV = Vals[COL2()+1,@RM]
|
|
Scratches = Vals[COL2()+1,@RM]
|
|
ScratchLen = Vals[COL2()+1,@RM]
|
|
ReactNo = Vals[COL2()+1,@RM]
|
|
WaferSize = Vals[COL2()+1,@RM]
|
|
SSScratchMax = Vals[COL2()+1,@RM]
|
|
SSScratchAvg = Vals[COL2()+1,@RM]
|
|
|
|
|
|
WaferSize = WaferSize[1,' '] ;* Data looks like "125 mm 6 in"
|
|
|
|
UserName = OCONV(@USER4,'[XLATE_CONV,LSL_USERS*FIRST_LAST]')
|
|
|
|
DataLine = QUOTE(ReactNo):TAB$
|
|
DataLine := QUOTE(RDSNo):TAB$
|
|
DataLine := QUOTE(Stage):TAB$
|
|
DataLine := QUOTE(ScanTool):TAB$
|
|
DataLine := QUOTE(SumOfDefMin):TAB$
|
|
DataLine := QUOTE(SumOfDefMax):TAB$
|
|
DataLine := QUOTE(SumOfDefAvg):TAB$
|
|
DataLine := QUOTE(HazeAvgAvg):TAB$
|
|
DataLine := QUOTE(Spots):TAB$
|
|
DataLine := QUOTE(FOV):TAB$
|
|
DataLine := QUOTE(Scratches):TAB$
|
|
DataLine := QUOTE(ScratchLen):TAB$
|
|
DataLine := QUOTE(UserName):TAB$
|
|
DataLine := QUOTE(SSScratchAvg):TAB$
|
|
DataLine := QUOTE(SSScratchMax):TAB$
|
|
DataLine := QUOTE(WaferSize)
|
|
|
|
DOSFile = Environment_Services('GetSPCDataPath') : '\SPC_Surf.txt'
|
|
|
|
* * * * * * *
|
|
DosRead:
|
|
* * * * * * *
|
|
|
|
// SPC Server has been migrated to the EC domain. SPC Queue must be utilized to transfer SPC files.
|
|
Filename = 'SPC_Surf.txt'
|
|
SPCQueueKey = Date():'*':Time():'*':@USER4
|
|
SPCQueueRec = ''
|
|
SPCQueueRec<SPC_QUEUE.SPC_FILENAME$> = Filename
|
|
SPCQueueRec<SPC_QUEUE.SPC_DOC$> = DataLine:CRLF$
|
|
Database_Services('WriteDataRow', 'SPC_QUEUE', SPCQueueKey, SPCQueueRec, True$, False$, False$)
|
|
|
|
CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS')
|
|
|
|
Set_Property(@WINDOW:'.SPC_DTM','DEFPROP',CurrDTM)
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SetGroupBackground:
|
|
* * * * * * *
|
|
|