COMPILE FUNCTION Comm_RDS_Test(Instruction, Parm1, Parm2) #pragma precomp SRP_PreCompiler /* Commuter module for RDS_Test Window 02/17/2006 - John C. Henry, J.C. Henry & Co., Inc. 01/12/2023 - djs - Updated the refresh subroutine to disable TW_USE related controls for EpiPro RDSs as EpiPro records test wafers at the EpiPro Load Run Configuration dialog. */ DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, Center_Window,Print_Vend_CofA, SPC_Services DECLARE SUBROUTINE ErrMsg, Send_Message, Set_Property, Send_Event, Btree.Extract, obj_AppWindow, Msg,Post_Event DECLARE SUBROUTINE obj_WO_Mat, obj_TW_Use, Forward_Event, Error_Services, Database_Services, Logging_Services DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, Utility, Center_Window, Popup, Collect.Ixvals, MemberOf DECLARE FUNCTION Send_Message, obj_RDS_Test, Send_Message, RDS_Comm, Start_Window, Msg, Create_Dialog, obj_WO_Mat DECLARE FUNCTION obj_TW_Use, Environment_Services, Get_EventStatus, Logging_Services, Database_Services DECLARE FUNCTION SPC_Services, Error_Services, RDS_Services $INSERT RDS_LAYER_EQUATES $INSERT RDS_EQU $INSERT RDS_TEST_EQUATES $INSERT REACT_RUN_EQUATES $INSERT RECIPE_PARMS_EQU $INSERT REACT_STATUS_EQUATES $INSERT POPUP_EQUATES $INSERT LOGICAL $INSERT DICT_EQUATES $INSERT APPCOLORS $INSERT LSL_USERS_EQU $INSERT MSG_EQUATES $INSERT TW_USE_EQUATES $INSERT SPC_QUEUE_EQUATES EQU CRLF$ TO \0D0A\ EQU SHEETRHO_SPEC_UNITS$ TO \EA2FDC\ EQU RES_SPEC_UNITS$ TO \EA2D636D\ EQU TAB$ TO CHAR(9) EQU EDITABLE$ TO 4 EQU PROTECTED$ TO 8 EQU HIDDEN$ TO 32 EQU COL$TW_QTY TO 1 EQU COL$TW_CODE TO 2 EQU COL$TW_USAGE_DESC TO 3 EQU COL$TW_TOOL TO 4 EQU COL$TW_TYPE TO 5 EQU COL$TW_SIG TO 6 EQU COL$TW_SIG_DTM TO 7 EQU COL$TW_HRS_SINCE_PROD TO 8 EQU COL$TW_HRS_ESC TO 9 EQU COL$TW_WAFER_ID TO 10 EQU COL$TW_USE_ID TO 11 EQU COL$USE_NO TO 1 EQU COL$QTY TO 2 EQU COL$CODE TO 3 EQU COL$DESC TO 4 EQU COL$TOOL TO 5 EQU COL$TYPE TO 6 EQU COL$SIGNATURE TO 7 EQU COL$SIG_DTM TO 8 EQU COL$WAFER_ID TO 9 ErrTitle = 'Error in Comm_RDS_Test' ErrorMsg = '' Result = '' BEGIN CASE CASE Instruction = 'Create' ; GOSUB Create CASE Instruction = 'Read' ; GOSUB Read CASE Instruction = 'Clear' ; GOSUB Clear CASE Instruction = 'Refresh' ; GOSUB Refresh CASE Instruction = 'Write' ; GOSUB Write CASE Instruction = 'Delete' ; GOSUB Delete CASE Instruction = 'Close' ; GOSUB Close CASE Instruction = 'SYSMSG' ; GOSUB SYSMSG CASE Instruction = 'ReadingsLF' ; GOSUB ReadingsLF CASE Instruction = 'ReadingsPC' ; GOSUB ReadingsPC CASE Instruction = 'ReadingsDel' ; GOSUB ReadingsDel CASE Instruction = 'ReadingsIns' ; GOSUB ReadingsIns CASE Instruction = 'TWOptions' ; GOSUB TWOptions CASE Instruction = 'TWUseDC' ; GOSUB TWUseDC CASE Instruction = 'TWPC' ; GOSUB TWPC CASE Instruction = 'TWLF' ; GOSUB TWLF CASE Instruction = 'TWDel' ; GOSUB TWDel CASE Instruction = 'OverRide' ; GOSUB OverRide CASE Instruction = 'CopyTSLine' ; GOSUB CopyTSLine CASE Instruction = 'AddSRP' ; GOSUB AddSRP CASE Instruction = 'ViewSRP' ; GOSUB ViewSRP CASE Instruction = 'InsertSRP' ; GOSUB InsertSRP CASE Instruction = 'RemoveSRP' ; GOSUB RemoveSRP CASE Instruction = 'ThickDC' ; GOSUB ThickDC CASE Instruction = 'SendSPC' ; GOSUB SendSPC CASE Instruction = 'NewTWUse' ; GOSUB NewTWUse CASE 1 ErrorMsg = 'Unknown Instruction passed to routine.' ErrMsg(ErrorMsg) END CASE RETURN Result * * * * * * * Create: * * * * * * * Center_Window(@WINDOW) IF Parm1 NE '' THEN obj_AppWindow('LoadFormKeys',@WINDOW:@RM:Parm1) END UserGroups = XLATE( 'LSL_USERS', @USER4 , LSL_USERS_GROUPS$, 'X' ) AddNewSRPButton = 0 LOCATE 'ENGINEERING' IN UserGroups USING @VM SETTING Dummy THEN AddNewSRPButton = 1 END ELSE LOCATE 'MASTER' IN UserGroups USING @VM SETTING Dummy THEN AddNewSRPButton = 1 END END IF MemberOf(@USER4, 'OI_SUPERUSER') THEN AddNewSRPButton = 1 Set_Property(@WINDOW:'.TEST_POINT_MAP','VISIBLE',1) Set_Property(@WINDOW:'.TEST_POINT_MAP_LABEL','VISIBLE',1) Set_Property(@WINDOW:'.SEND_SPC','VISIBLE',1) Set_Property(@WINDOW:'.SPC_DTM','VISIBLE',1) END ELSE Set_Property(@WINDOW:'.TEST_POINT_MAP','VISIBLE',0) Set_Property(@WINDOW:'.TEST_POINT_MAP_LABEL','VISIBLE',0) Set_Property(@WINDOW:'.SEND_SPC','VISIBLE',1) ;* Chad is ready to go live 3/11/2010 JCH Set_Property(@WINDOW:'.SPC_DTM','VISIBLE',1) END // Deprecated control per the information on the form. Preventing button from becoming visible - dmb - 07/03/2018 - [IREPIOI-50] * Set_Property(@WINDOW:'.ADD_SRP_BUTTON','VISIBLE',AddNewSRPButton) MeasureUnits = XLATE('LISTBOX_CONFIG','UNITS','','X') CONVERT @VM TO @FM IN MeasureUnits Set_Property(@WINDOW:'.SPEC_THICK_UNITS','LIST',MeasureUnits) Set_Property(@WINDOW:'.SPEC_RES_UNITS','LIST',MeasureUnits) Set_Property(@WINDOW:'.SPEC_CON_UNITS','LIST',MeasureUnits) Set_Property(@WINDOW:'.SPEC_CRES_UNITS','LIST',MeasureUnits) * Build @ET_SYMBOLICS data structure for window ETSymbolics = '' EditTables = Utility ('OBJECTLIST', @WINDOW, 'EDITTABLE') FOR I = 1 TO COUNT(EditTables,@FM) + (EditTables NE '') EditTable = EditTables CtrlCols = Get_Property(EditTable,'COLUMN') CtrlTables = Get_Property(EditTable, 'TABLE') LastTable = '' FOR N = 1 TO COUNT(CtrlCols,@SVM) + (CtrlCols NE '') CtrlCol = CtrlCols<1,1,N> TableName = CtrlTables<1,1,N> IF TableName NE '' THEN IF TableName NE LastTable THEN DictStruct = XLATE('DICT.':TableName,'%FIELDS%','','X') LastTable = TableName END LOCATE CtrlCol IN DictStruct USING @VM SETTING Pos THEN IF DictStruct = 'S' THEN LOCATE EditTable IN ETSymbolics<1> USING @VM SETTING ETPos ELSE ETSymbolics = INSERT(ETSymbolics,1,ETPos,0,EditTable) END ETSymbolics<2,ETPos,-1> = N ;* Add Column Number to the list END END END NEXT N NEXT I Set_Property(@WINDOW,'@ET_SYMBOLICS',ETSymbolics) GOSUB Refresh RETURN * * * * * * * Clear: * * * * * * * GOSUB Refresh RETURN * * * * * * * Read: * * * * * * * CurrRecord = Get_Property(@WINDOW,'RECORD') Set_Property(@WINDOW,'@ORG_RECORD',CurrRecord) * Send_Event(@Window : '.THICK_READINGS', 'POSCHANGED') * Send_Event(@Window : '.SHEETRHO_READINGS', 'POSCHANGED') * Send_Event(@Window : '.RES_READINGS', 'POSCHANGED') * Send_Event(@Window : '.HGCV1_READINGS', 'POSCHANGED') * IOOptions = Get_Property(@Window, 'IOOPTIONS') * IOOptions<6> = 1 * Set_Property(@Window, 'IOOPTIONS', IOOptions) * Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE','1') * Send_Event(@Window, 'WRITE') * IOOptions<6> = 0 * Set_Property(@Window, 'IOOPTIONS', IOOptions) * * * * * * * Refresh: * * * * * * * /* CtrlEntID = @WINDOW:'.WFR_USAGE' TWArray = Get_Property(CtrlEntID,'DEFPROP') TestVals = TWArray CONVERT @VM TO '' IN TestVals IF TestVals NE '' THEN Set_Property(@WINDOW:'.WFR_USAGE','VISIBLE',0) Set_Property(@WINDOW:'.TW_USE','VISIBLE',1) END ELSE Set_Property(@WINDOW:'.WFR_USAGE','VISIBLE',1) Set_Property(@WINDOW:'.TW_USE','VISIBLE',0) END */ IF MemberOf(@USER4,'OI_ADMIN') THEN Set_Property(@WINDOW:'.DELETE_BUTTON_FIX','VISIBLE',1) END ELSE Set_Property(@WINDOW:'.DELETE_BUTTON_FIX','VISIBLE',0) END InjectPcnt = Get_Property(@WINDOW:'.INJECT_PCNT','DEFPROP') CONVERT '%' TO '' IN InjectPcnt IF ABS(InjectPcnt) > 4.0 THEN Set_Property(@WINDOW:'.INJECT_PCNT','BACKCOLOR',KEY_YELLOW$) END ELSE Set_Property(@WINDOW:'.INJECT_PCNT','BACKCOLOR',INP_BLUE$) END DepTmPcnt = Get_Property(@WINDOW:'.DEP_TM_PCNT','DEFPROP') CONVERT '%' TO '' IN DepTmPcnt IF ABS(DepTmPcnt) > 4.0 THEN Set_Property(@WINDOW:'.DEP_TM_PCNT','BACKCOLOR',KEY_YELLOW$) END ELSE Set_Property(@WINDOW:'.DEP_TM_PCNT','BACKCOLOR',INP_BLUE$) END 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 LSId = Get_Property(@WINDOW:'.LS_ID','TEXT') BEGIN CASE CASE LSId = 'L1' Set_Property(@WINDOW:'.LS_ID','BACKCOLOR',RCV_BLUE$) CASE LSId = 'L2' Set_Property(@WINDOW:'.LS_ID','BACKCOLOR',PRE_BLUE$) CASE LSId = '2' Set_Property(@WINDOW:'.LS_ID','BACKCOLOR',INP_BLUE$) CASE 1 Set_Property(@WINDOW:'.LS_ID','BACKCOLOR',GREEN$) END CASE DataPointList = Get_Property(@WINDOW:'.TEST_POINTS','DEFPROP') ReactorType = Get_Property(@WINDOW:'.REACTOR_TYPE_IN','TEXT') ;* Hidden control without any conversion on it PSNo = Get_Property(@WINDOW:'.PS_NO','DEFPROP') ThickFilmMet = Get_Property(@WINDOW:'.THICKFILM_MET','CHECK') Ctrls = @WINDOW:'.THICK_READINGS':@RM:@WINDOW:'.SHEETRHO_READINGS':@RM:@WINDOW:'.HGCV1_READINGS' Props = 'BACKCOLOR':@RM:'BACKCOLOR':@RM:'BACKCOLOR' * * * * * EpiPROCtrls = @WINDOW:'.INJECT_FLOW_LABEL':@RM ; EpiPROProps = 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.INJECT_FLOW':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.SUGG_INJECT_FLOW_LABEL':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.SUGG_INJECT_FLOW':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.INJECT_PCNT_LABEL':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.INJECT_PCNT':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.SUGG_DEP_TM_LABEL':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.SUGG_DEP_TM':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.DEP_TM_PCNT_LABEL':@RM ; EpiPROProps := 'VISIBLE':@RM EpiPROCtrls := @WINDOW:'.DEP_TM_PCNT' ; EpiPROProps := 'VISIBLE' IF ReactorType = 'P' OR ReactorType = 'EPP' THEN EpiPROVals = STR('0':@RM,10) END ELSE EpiPROVals = STR('1':@RM,10) END EpiPROVals[-1,1]= '' ;* Trim trailing @RM Set_Property(EpiPROCtrls,EpiPROProps,EpiPROVals) * * * * * HalfCtrls = @WINDOW:'.SMALL_DELTA_DP_GROUP':@RM ; HalfProps = 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_SUGG_DEP_TM':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_SUGG_DEP_TM_LABEL':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_DEP_TM_PCNT':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_DEP_TM_PCNT_LABEL':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.SMALL_DELTA_INJ_GROUP':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_SUGG_INJECT':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_SUGG_INJECT_LABEL':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_INJECT_PCNT':@RM ; HalfProps := 'VISIBLE':@RM HalfCtrls := @WINDOW:'.HALF_INJECT_PCNT_LABEL' ; HalfProps := 'VISIBLE' IF Get_Property(@WINDOW:'.SMALL_REACTOR_DELTA','CHECK') = 1 THEN HalfVals = STR('1':@RM,10) END ELSE HalfVals = STR('0':@RM,10) END HalfVals[-1,1]= '' ;* Trim trailing @RM Set_Property(HalfCtrls,HalfProps,HalfVals) * * * * * SheetRhoStyles = Send_Message( @WINDOW:'.SHEETRHO_READINGS', "COLSTYLE", 0, '' ) ThickStyles = Send_Message( @WINDOW:'.THICK_READINGS', "COLSTYLE", 0, '' ) HgCv1Styles = Send_Message( @WINDOW:'.HGCV1_READINGS', "COLSTYLE", 0, '' ) IF ReactorType = 'EPP' OR ReactorType = 'P' OR ThickFilmMet = 1 THEN * EpiPRO Reactor Vals = GREEN$:@RM:GREEN$:@RM:GREEN$ ThickStyles<1> = BitOr(ThickStyles<1>,PROTECTED$ ) SheetRhoStyles<1> = BitOr(SheetRhoStyles<1>,PROTECTED$ ) HgCv1Styles <1> = BitOr(HgCv1Styles<1>, PROTECTED$ ) HgCvFlag = 0 END ELSE * Regular Reactor Vals = WHITE$:@RM ;* Thickness background ThickStyles<1> = BitAnd(ThickStyles<1> , BitNot(PROTECTED$) ) ;* Thickness enabled IF Get_Property(@WINDOW:'.SPEC_RES_MTOOL','TEXT') = 'HgCv' Then ;* OR Get_Property(@WINDOW:'.SPEC_CON_MTOOL','TEXT') = 'HgCv' HgCvFlag = 1 Vals := GREEN$:@RM:WHITE$ SheetRhoStyles<1> = BitOr(SheetRhoStyles<1> , PROTECTED$ ) ;* Disable SheetRho table HgCv1Styles <1> = BitAnd(HgCv1Styles<1>, BitNot(PROTECTED$) ) ;* Enable HgCv1 table END ELSE HgCvFlag = 0 Vals := WHITE$:@RM:GREEN$ SheetRhoStyles<1> = BitAnd(SheetRhoStyles<1> , BitNot(PROTECTED$) ) ;* Enable SheetRho table HgCv1Styles <1> = BitOr(HgCv1Styles<1>, PROTECTED$ ) ;* Disable HgCv1 table END END Savewarn = Get_Property(@Window, 'SAVEWARN') If Savewarn EQ False$ then ThisMetNo = Get_Property(@Window: '.MET_NO', 'TEXT') ThisMetRec = Database_Services('ReadDataRow', 'RDS_TEST', ThisMetNo) ResReadings = obj_RDS_Test('Resistivity',ThisMetNo:@RM:ThisMetRec:@RM:1) for i = 1 to DCount(ResReadings, @VM) ResReading = ResReadings<1,i> ResReadings<1,i> = OConv(ResReading,'MD4Z') Next i Set_Property(@Window : '.RES_READINGS', 'ARRAY', ResReadings) end Set_Property(Ctrls,Props,Vals) Send_Message( @WINDOW:'.SHEETRHO_READINGS', "COLSTYLE", 1, SheetRhoStyles ) Send_Message( @WINDOW:'.THICK_READINGS', "COLSTYLE", 1, ThickStyles ) Send_Message( @WINDOW:'.HGCV1_READINGS', "COLSTYLE", 1, HgCv1Styles ) LOCATE 'Center' IN DataPointList USING @VM SETTING CenterPoint ELSE CenterPoint = 9 END Send_Message(@WINDOW:'.TEST_POINTS','COLOR_BY_POS',1,CenterPoint,ORANGE$) Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,CenterPoint,ORANGE$) Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,CenterPoint,ORANGE$) Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,CenterPoint,ORANGE$) Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,CenterPoint,ORANGE$) WaferSize = Get_Property(@WINDOW:'.WAFER_SIZE','DEFPROP') IF WaferSize NE '' THEN BEGIN CASE CASE WaferSize[1,' '] = '75' FirstValidLine = 6 LastValidLine = 12 CASE WaferSize[1,' '] = '100' FirstValidLine = 5 LastValidLine = 13 CASE WaferSize[1,' '] = '125' FirstValidLine = 4 LastValidLine = 14 CASE WaferSize[1,' '] = '150' FirstValidLine = 3 LastValidLine = 15 CASE 1 FirstValidLine = 1 LastValidLine = 17 END CASE Set_Property(@Window:'.TEST_POINTS', 'MINROWLIMIT', 17) Set_Property(@Window:'.THICK_READINGS', 'MINROWLIMIT', 17) Set_Property(@Window:'.SHEETRHO_READINGS', 'MINROWLIMIT', 17) Set_Property(@Window:'.RES_READINGS', 'MINROWLIMIT', 17) IF FirstValidLine > 1 THEN FOR I = 1 TO (FirstValidLine - 1) Send_Message(@WINDOW:'.TEST_POINTS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,GREY$) NEXT I FOR I = (LastValidLine + 1) TO 17 Send_Message(@WINDOW:'.TEST_POINTS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,GREY$) Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,GREY$) NEXT I END END SpecType = Get_Property(@WINDOW:'.SPEC_TYPE','TEXT') Set_Property(@WINDOW:'.SPEC_TYPE_LABEL','TEXT',SpecType) IF Get_Property(@WINDOW:'.SPEC_RES_MOVERGROW','INVALUE') = 1 THEN Set_Property(@WINDOW:'.THICK_OVERGROW_AVG','BACKCOLOR',YELLOW$) END ELSE Set_Property(@WINDOW:'.THICK_OVERGROW_AVG','BACKCOLOR',WHITE$) END SpecResUnits = Get_Property(@WINDOW:'.SPEC_RES_UNITS', 'DEFPROP') BEGIN CASE CASE SpecResUnits = SHEETRHO_SPEC_UNITS$ Vals = '0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1' CASE SpecResUnits = RES_SPEC_UNITS$ Vals = '-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'-1':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0' CASE 1 Vals = '0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0' END CASE Ctrls = @WINDOW:'.SHEETRHO_AVG':@RM ; Props = 'ENABLED':@RM Ctrls := @WINDOW:'.SHEETRHO_STDV':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.SHEETRHO_RANGE':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.SHEETRHO_RANGE_PCNT':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.SHEETRHO_UNIF':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.SHEETRHO_MIN':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.SHEETRHO_MAX':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_AVG':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_STDV':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_RANGE':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_RANGE_PCNT':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_UNIF':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_MIN':@RM ; Props := 'ENABLED':@RM Ctrls := @WINDOW:'.RES_MAX' ; Props := 'ENABLED' Set_Property(Ctrls,Props,Vals) ReadCtrls = @WINDOW:'.THICK_READINGS':@RM:@WINDOW:'.SHEETRHO_READINGS':@RM:@WINDOW:'.RES_READINGS':@RM:@WINDOW:'.HGCV1_READINGS' ReadProps = 'INVALUE':@RM:'INVALUE':@RM:'INVALUE':@RM:'INVALUE' ReadVals = Get_Property(ReadCtrls,ReadProps) ThickReads = ReadVals[1,@RM] SheetRhoReads = ReadVals[COL2()+1,@RM] ResReads = ReadVals[COL2()+1,@RM] HgCv1Reads = ReadVals[COL2()+1,@RM] LimitCtrls = @WINDOW:'.SPEC_THICK_MIN':@RM ; LimitProps = 'INVALUE':@RM LimitCtrls := @WINDOW:'.SPEC_THICK_MAX':@RM ; LimitProps := 'INVALUE':@RM LimitCtrls := @WINDOW:'.SPEC_RES_MIN':@RM ; LimitProps := 'INVALUE':@RM LimitCtrls := @WINDOW:'.SPEC_RES_MAX' ; LimitProps := 'INVALUE' Limits = Get_Property(LimitCtrls,LimitProps) SpecThickMin = Limits[1,@RM] SpecThickMax = Limits[COL2()+1,@RM] SpecResMin = Limits[COL2()+1,@RM] SpecResMax = Limits[COL2()+1,@RM] ReadLineCnt = COUNT(ThickReads,@VM) + (ThickReads NE '') ThickSpecFlag = 0 SheetRhoSpecFlag = 0 ResistivitySpecFlag = 0 HgCv1SpecFlag = 0 FOR I = 1 TO ReadLineCnt ThickVal = ThickReads<1,I> IF ThickVal NE '' THEN ThickVal = IConv(ThickVal, "MD1") IF ThickVal > SpecThickMax OR ThickVal < SpecThickMin THEN Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,RED$) ThickSpecFlag = 1 END ELSE IF I = CenterPoint THEN Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,ORANGE$) END ELSE Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,WHITE$) END END END IF SpecResUnits = SHEETRHO_SPEC_UNITS$ THEN ResVal = SheetRhoReads<1,I> IF ResVal NE '' THEN ResVal = ResVal IF ResVal > SpecResMax OR ResVal < SpecResMin THEN Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,RED$) SheetRhoSpecFlag = 1 END ELSE IF I = CenterPoint THEN Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,ORANGE$) END ELSE Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,WHITE$) END END END END IF SpecResUnits = RES_SPEC_UNITS$ THEN ResVal = ResReads<1,I> IF ResVal NE '' THEN * Spec is in MD3, Calculated value is in MD4 -> *10 is a multiplier to make the adjustment * Added 7/1/2008 JCH IF ResVal > SpecResMax*10 OR ResVal < SpecResMin*10 THEN Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,RED$) ;* Changes the reading ResistivitySpecFlag = 1 END ELSE IF I = CenterPoint THEN Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,ORANGE$) END ELSE Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,GREEN$) END END END HgCv1Val = HgCv1Reads<1,I> IF HgCv1Val NE '' THEN IF HgCv1Val > SpecResMax OR HgCv1Val < SpecResMin THEN Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,RED$) ;* Changes the reading ResistivitySpecFlag = 1 END ELSE IF I = CenterPoint THEN Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,ORANGE$) END ELSE IF HgCvFlag = 1 THEN Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,WHITE$) END ELSE Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,GREEN$) END END END END END IF SpecResUnits = '' THEN IF I = CenterPoint THEN Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,ORANGE$) Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,ORANGE$) Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,ORANGE$) Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,ORANGE$) END ELSE Send_Message(@WINDOW:'.THICK_READINGS','COLOR_BY_POS',1,I,WHITE$) Send_Message(@WINDOW:'.SHEETRHO_READINGS','COLOR_BY_POS',1,I,WHITE$) Send_Message(@WINDOW:'.RES_READINGS','COLOR_BY_POS',1,I,GREEN$) Send_Message(@WINDOW:'.HGCV1_READINGS','COLOR_BY_POS',1,I,GREEN$) END END NEXT I ThickMinValue = Get_Property(@WINDOW:'.THICK_MIN','INVALUE') ThickMaxValue = Get_Property(@WINDOW:'.THICK_MAX','INVALUE') ThickMinValue = IConv(ThickMinValue, "MD1") ThickMaxValue = IConv(ThickMaxValue, "MD1") IF ThickMinValue < SpecThickMin AND ThickMinValue NE '' THEN Set_Property(@WINDOW:'.THICK_MIN','BACKCOLOR',RED$) ThickSpecFlag = 1 END ELSE Set_Property(@WINDOW:'.THICK_MIN','BACKCOLOR',GREEN$) END IF ThickMaxValue > SpecThickMax AND ThickMaxValue NE '' THEN Set_Property(@WINDOW:'.THICK_MAX','BACKCOLOR',RED$) ThickSpecFlag = 1 END ELSE Set_Property(@WINDOW:'.THICK_MAX','BACKCOLOR',GREEN$) END BEGIN CASE CASE SpecResUnits = SHEETRHO_SPEC_UNITS$ ResMinValue = Get_Property(@WINDOW:'.SHEETRHO_MIN','INVALUE') ResMaxValue = Get_Property(@WINDOW:'.SHEETRHO_MAX','INVALUE') IF ResMinValue < SpecResMin AND ResMinValue NE ''THEN Set_Property(@WINDOW:'.SHEETRHO_MIN','BACKCOLOR',RED$) SheetRhoSpecFlag = 1 END ELSE Set_Property(@WINDOW:'.SHEETRHO_MIN','BACKCOLOR',GREEN$) END IF ResMaxValue > SpecResMax AND ResMaxValue NE '' THEN Set_Property(@WINDOW:'.SHEETRHO_MAX','BACKCOLOR',RED$) SheetRhoSpecFlag = 1 END ELSE Set_Property(@WINDOW:'.SHEETRHO_MAX','BACKCOLOR',GREEN$) END CASE SpecResUnits = RES_SPEC_UNITS$ ResMinValue = Get_Property(@WINDOW:'.RES_MIN','INVALUE') ResMaxValue = Get_Property(@WINDOW:'.RES_MAX','INVALUE') IF ResMinValue < SpecResMin*10 AND ResMinValue NE '' THEN Set_Property(@WINDOW:'.RES_MIN','BACKCOLOR',RED$) ResistivitySpecFlag = 1 END ELSE Set_Property(@WINDOW:'.RES_MIN','BACKCOLOR',GREEN$) END IF ResMaxValue > SpecResMax*10 AND ResMaxValue NE '' THEN Set_Property(@WINDOW:'.RES_MAX','BACKCOLOR',RED$) ResistivitySpecFlag = 1 END ELSE Set_Property(@WINDOW:'.RES_MAX','BACKCOLOR',GREEN$) END HgCv1MinValue = Get_Property(@WINDOW:'.HGCV1_RES_MIN','INVALUE') HgCv1MaxValue = Get_Property(@WINDOW:'.HGCV1_RES_MAX','INVALUE') IF HgCv1MinValue < SpecResMin AND HgCv1MinValue NE '' THEN Set_Property(@WINDOW:'.HGCV1_RES_MIN','BACKCOLOR',RED$) HgCv1SpecFlag = 1 END ELSE Set_Property(@WINDOW:'.HGCV1_RES_MIN','BACKCOLOR',GREEN$) END IF HgCv1MaxValue > SpecResMax AND HgCv1MaxValue NE '' THEN Set_Property(@WINDOW:'.HGCV1_RES_MAX','BACKCOLOR',RED$) HgCv1SpecFlag = 1 END ELSE Set_Property(@WINDOW:'.HGCV1_RES_MAX','BACKCOLOR',GREEN$) END CASE 1 Set_Property(@WINDOW:'.SHEETRHO_MIN','BACKCOLOR',GREEN$) Set_Property(@WINDOW:'.SHEETRHO_MAX','BACKCOLOR',GREEN$) Set_Property(@WINDOW:'.RES_MIN','BACKCOLOR',GREEN$) Set_Property(@WINDOW:'.RES_MAX','BACKCOLOR',GREEN$) Set_Property(@WINDOW:'.HGCV1_RES_MIN','BACKCOLOR',GREEN$) Set_Property(@WINDOW:'.HGCV1_RES_MAX','BACKCOLOR',GREEN$) END CASE IF ThickSpecFlag OR SheetRhoSpecFlag OR ResistivitySpecFlag OR HgCv1SpecFlag THEN Set_Property(@WINDOW:'.OUT_OF_SPEC','CHECK',1) END ELSE Set_Property(@WINDOW:'.OUT_OF_SPEC','CHECK',0) END * Reset OverRide enabled controls ORCtrls = @WINDOW:'.SPEC_THICK_MIN':@RM:@WINDOW:'.SPEC_THICK_TARGET':@RM:@WINDOW:'.SPEC_THICK_MAX':@RM:@WINDOW:'.SPEC_THICK_UNITS':@RM ORCtrls := @WINDOW:'.SPEC_RES_MIN':@RM:@WINDOW:'.SPEC_RES_TARGET':@RM:@WINDOW:'.SPEC_RES_MAX':@RM:@WINDOW:'.SPEC_RES_UNITS':@RM ORCtrls := @WINDOW:'.SPEC_CON_MIN':@RM:@WINDOW:'.SPEC_CON_TARGET':@RM:@WINDOW:'.SPEC_CON_MAX':@RM:@WINDOW:'.SPEC_CON_UNITS':@RM ORCtrls := @WINDOW:'.SPEC_CRES_MIN':@RM:@WINDOW:'.SPEC_CRES_TARGET':@RM:@WINDOW:'.SPEC_CRES_MAX':@RM:@WINDOW:'.SPEC_CRES_UNITS' Props = STR('ENABLED':@RM,16) ; Props[-1,1] = '' Vals = STR('0':@RM,16) ; Vals[-1,1] = '' Set_Property(ORCtrls,Props,Vals) Props = STR('BACKCOLOR':@RM,16) ; Props[-1,1] = '' Vals = STR(GREEN$ :@RM,16) ; Vals[-1,1] = '' Set_Property(ORCtrls,Props,Vals) * Disable Test Wafer related controls for EpiPro Runs to eliminate confusion * around whether or not TW_USE records need to be created in order to account * for test wafers for SAP purposes. (EpiPro test wafers are accounted for * at the load run configuration step within the RDS Load EpiPro operation.) RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') ReactType = Xlate('RDS', RDSNo, 'REACTOR_TYPE', 'X') TWEnabled = (ReactType NE 'EPP') Set_Property(@Window:'.NEW_TW_USE', 'ENABLED', TWEnabled) Set_Property(@Window:'.COPY_TW_LINE', 'ENABLED', TWEnabled) Set_Property(@Window:'.TW_USE', 'ENABLED', TWEnabled) * 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> IF ETCtrl NE @WINDOW:'.RES_READINGS' THEN ETList = Get_Property(ETCtrl,'LIST') FOR Line = 1 TO COUNT(ETList,@FM) + (ETList NE '') IF ETList 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 END NEXT I RETURN * * * * * * * Write: * * * * * * * RDSTestKey = Get_Property(@WINDOW,'ID') CurrRecord = Get_Property(@WINDOW,'RECORD') OrgRecord = Get_Property(@WINDOW,'@ORG_RECORD') IF CurrRecord = '' OR CurrRecord = '' THEN Result = 0 ErrMsg('This record may not be saved.') RETURN END IF CurrRecord NE OrgRecord THEN CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') NewLine = @USER4:@VM:CurrDTM Send_Message(@WINDOW:'.MODIFY_USER','INSERT',1,NewLine) *Dummy = Msg(@WINDOW,'','SPC_REMINDER') * Section added 2/21/2011 JCH - Synchronizes 'TW_USE' table with RDS_TEST * Made live on 4/2/2011 JCH END // Ask the system event handler to attempt to write the row and then come back. Forward_Event() // Check to see if the MFS set an FS error. There are conditions that will prevent RDS_TEST data from being modified. EventCode = '' Error = Get_EventStatus(EventCode) If Error then // If EventCode contains error code FS104 then display our own message box. ErrorNumber = EventCode[1, @VM] ErrorMessage = EventCode[Col2() + 1, @VM] If ErrorNumber EQ 'FS104' then MsgStruct = '' MsgStruct = -1 MsgStruct = -1 // Users belonging to the SPEC_CHANGE security group will be allowed to override the block. However, these // users must confirm that this is what they want. If MemberOf(@User4, 'SPEC_CHANGE') then Override = Msg(@Window, MsgStruct, 'YESNO', '', 'RDS Test' : @FM : ErrorMessage : @TM : @TM : 'Please confirm that you want to override.') If Override EQ True$ then Record = Get_Property(@Window, 'ATRECORD') Record = True$ Database_Services('WriteDataRow', 'RDS_TEST', @ID, Record, True$, False$, False$) FocusCtrl = Get_Property(@Window, 'FOCUS') Set_Property(FocusCtrl, 'GOTFOCUS_VALUE', Get_Property(FocusCtrl, 'DEFPROP')) Set_Property(@Window, 'SAVEWARN', False$) IF Get_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE') THEN Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE','0') END ELSE Post_Event(@WINDOW,'CLOSE') END end end else Msg(@Window, MsgStruct, 'OK', '', 'RDS Test' : @FM : ErrorMessage) end end end else IF Get_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE') THEN Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE','0') END ELSE Post_Event(@WINDOW,'CLOSE') END end // Set the result variable to 0 so the event chain does not continue. Both pre- and post-event handlers are done here. Result = 0 RETURN * * * * * * * Delete: * * * * * * * IF MemberOf(@USER4,'OI_ADMIN') THEN Result = Msg(@WINDOW,'','PRE_DELETE') END ELSE ErrMsg('Records may not be modified or deleted.') Result = 0 END RETURN * * * * * * * Close: * * * * * * * obj_Appwindow('DetailReturn') RETURN SYSMSG: MsgCode = Parm1[1, @RM] CancelFlag = Parm1[Col2() + 1, @RM] StatCode = Parm1[Col2() + 1, @RM] ErrorNumber = StatCode[1, @VM] If ErrorNumber EQ 'FS104' then // This means our custom logic in RDS_TEST_ACTIONS has blocked this row from being written. The WRITE event // handler will display a custom message instead of the system. Result = 0 end else // Allow the system to handle this message (if any). Result = 1 end return * * * * * * * ReadingsLF: * * * * * * * CtrlName = Parm1 IF CtrlName = '' THEN CurrCtrl = Get_Property(@WINDOW,'FOCUS') END ELSE CurrCtrl = @WINDOW:'.':CtrlName END FirstColumnData = Get_Property(CurrCtrl,'DEFPROP') DataPointDist = Get_Property(@WINDOW:'.TEST_POINTS','DEFPROP') LOCATE 'Center' IN DataPointDist USING @VM SETTING CenterPos ELSE CenterPos = 9 ;* This will break if the number of data points is increased above 17! Readings = '' TotalLineCnt = COUNT(FirstColumnData,@VM) + (FirstColumnData NE '') FOR I = 1 TO TotalLineCnt IF FirstColumnData<1,I> NE '' THEN Readings<1,-1> = FirstColumnData<1,I> NEXT I ReadingCnt = COUNT(Readings,@VM) + (Readings NE '') IF ReadingCnt > 0 THEN *IF Mod(ReadingCnt,2) = 0 THEN * ErrMsg('Incorrect number of readings entered. 1,3,5,7,9,11,13,15 or 17 values must be entered.') ;* Dead on 11/29/2016 Added 10 wafer metrology DKK * Set_Property('FOCUS',CtrlName,1) * RETURN *END ELSE Set_Property(CurrCtrl,'DEFPROP',STR(@VM,16)) StartPos = CenterPos - (ReadingCnt - 1)*(.5) Set_Property(@WINDOW,'@FIRST_READING_LINE',StartPos) FOR I = 1 TO TotalLineCnt IF I >= StartPos AND Readings NE '' THEN Set_Property(CurrCtrl,'DEFPROP',Readings<1,1>,1:@FM:I) Readings = DELETE(Readings,0,1,0) END ELSE Set_Property(CurrCtrl,'DEFPROP','',1:@FM:I) END NEXT I *END END //Post_Event(@WINDOW:'.RES_READINGS','CALCULATE',1) UpdatedRec = Get_Property(@Window, 'ATRECORD') ThisMetNo = Get_Property(@Window: '.MET_NO', 'TEXT') ResReadings = obj_RDS_Test('Resistivity',ThisMetNo:@RM:UpdatedRec:@RM:1) for i = 1 to DCount(ResReadings, @VM) ResReading = ResReadings<1,i> ResReadings<1,i> = OConv(ResReading,'MD4Z') Next i Set_Property(@Window : '.RES_READINGS', 'ARRAY', ResReadings) Send_Event(@WINDOW:'.GROWTH_RATE','CALCULATE') * * * * * * * ReadingsPC: * * * * * * * OrigRec = Get_Property(@Window, '@ORG_RECORD') RDSNo = Get_Property(@Window:'.RDS_NO', 'TEXT') CtrlName = Parm1 IF CtrlName = '' THEN CurrCtrl = Get_Property(@WINDOW,'FOCUS') END ELSE If Index(CtrlName, '.', 1) then CurrCtrl = CtrlName end else CurrCtrl = @WINDOW:'.':CtrlName end END //Problem line here. Removed 10/25/2024 //Send_Event(@WINDOW:'.RES_READINGS','CALCULATE') UpdatedRec = Get_Property(@Window, 'ATRECORD') ThisMetNo = Get_Property(@Window: '.MET_NO', 'TEXT') ResReadings = obj_RDS_Test('Resistivity',ThisMetNo:@RM:UpdatedRec:@RM:1) for i = 1 to DCount(ResReadings, @VM) ResReading = ResReadings<1,i> ResReadings<1,i> = OConv(ResReading,'MD4Z') Next i Set_Property(@Window : '.RES_READINGS', 'ARRAY', ResReadings) Readings = Get_Property(CurrCtrl,'ARRAY') Conversion = Get_Property(CurrCtrl,'CONV')<1,1,1> IF CurrCtrl = 'RDS_TEST.SHEETRHO_READINGS' THEN Conversion = 'MD3' Set_Status(0) Stats = obj_RDS_Test('CalcStats',Readings:@RM:Conversion) IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END UnQualCtrlName = FIELD(CurrCtrl,'.',2) IF UnQualCtrlName = 'HGCV1_READINGS' THEN CtrlPref = 'HGCV1_RES' END ELSE CtrlPref = UnQualCtrlName[1,'_'] END Ctrls = @WINDOW:'.':CtrlPref:'_AVG':@RM ; Props = 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_STDV':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_UNIF':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_MIN':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_MAX':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_RANGE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_RANGE_PCNT' ; Props := 'DEFPROP' Set_Property(Ctrls,Props,Stats) ResCtrl = @WINDOW:'.RES_READINGS' IF CurrCtrl NE ResCtrl THEN * Update the resistance statistics Readings = Get_Property(ResCtrl,'ARRAY') Conversion = Get_Property(ResCtrl,'CONV')<1,1,1> testReadings = Readings CONVERT @VM TO '' IN testReadings Set_Status(0) Stats = obj_RDS_Test('CalcStats',Readings:@RM:Conversion) IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END UnQualCtrlName = FIELD(ResCtrl,'.',2) CtrlPref = UnQualCtrlName[1,'_'] Ctrls = @WINDOW:'.':CtrlPref:'_AVG':@RM ; Props = 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_STDV':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_UNIF':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_MIN':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_MAX':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_RANGE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.':CtrlPref:'_RANGE_PCNT' ; Props := 'DEFPROP' Set_Property(Ctrls,Props,Stats) END Send_Event(@WINDOW:'.GROWTH_RATE','CALCULATE') GOSUB Refresh CalcRec = Get_Property(@Window, 'ATRECORD') Savewarn = (OrigRec NE CalcRec) Set_Property(@Window, 'SAVEWARN', Savewarn) RETURN * * * * * * * ReadingsIns: * * * * * * * return RowIndex = Parm1 CurrCtrl = Get_Property(@WINDOW,'FOCUS') *Dummy = Send_Message(CurrCtrl, "DELETE", RowIndex) ;* Row Limit of 17 doesn't allow additional lines to be added //ErrMsg('Rows may not be inserted or deleted.') RETURN * * * * * * * ReadingsDel: * * * * * * * DeletedRowIndex = Parm1 DeletedRowText = Parm2 CurrCtrl = Get_Property(@WINDOW,'FOCUS') Dummy = Send_Message(CurrCtrl, "INSERT",DeletedRowIndex, DeletedRowText) ErrMsg('Rows may not be inserted or deleted.') RETURN * * * * * * * SyncTestWafers: * * * * * * * * * * * * * Conversion routine to match up TW_USE with associated MV's in RDS_TEST * * * * * * * * * * * * * * This will go away once conversion is completed. * * * * * * * * ListCnt = COUNT(TWList,@FM) + (TWList NE '') TWUseCodes = obj_TW_Use('Convert',MetNo:@RM:TWList) ;* Creates new TW_USE records and returns updated list of TWUseCodes IF TWUseCodes NE TWArray THEN ;* New TW_USED record created - update RDS_TEST record TWArray = TWUseCodes ;* Set Use ID column values Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE',1) Set_Property(CtrlEntID,'DEFPROP',TWArray) Send_Event (@WINDOW,'WRITE') ;* Write updated Met Rec to disk Set_Property(@WINDOW:'.MET_NO','DEFPROP',MetNo) Send_Event(@WINDOW:'.MET_NO','LOSTFOCUS') ;* Read Updated Met Rec From disk END RETURN * * * * * * * NewTWUse: * * * * * * * RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') FQASigned = RDS_Services('GetFinalQAStatus', RDSNo) RecordLocked = False$ RDSNo = Get_Property(@WINDOW:'.RDS_NO', 'DEFPROP') WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') * If WOMatKey NE '' then RecordLocked = Database_Services('IsKeyIDLocked', 'WO_MAT', WOMatKey, False$) Begin Case Case FQASigned EQ True$ // FQA Signed -> Block TW_USE creation/deletion/modification ErrorMsg = 'FQA has already been signed. Metrology test record cannot be updated!' ErrMsg(ErrorMsg) Return 0 Case RecordLocked EQ True$ LockOwner = Xlate('WO_MAT', WOMatKey, 'LOCKED_BY', 'X') If LockOwner NE '' then DisplayName = Oconv(LockOwner,'[XLATE_CONV,LSL_USERS*FIRST_LAST]') end else DisplayName = 'an unknown user' end MsgParms = '' MsgParms<1> = 'Record Locked' MsgParms<2> = 'The WO_MAT record for this RDS is locked by ':DisplayName:'. Only one user session at a time can edit an RDS.' Msg(@Window, '', 'OK', '', MsgParms) Return 0 Case Otherwise$ CtrlEntID = @WINDOW:'.TW_USE' MetNo = Get_Property(@WINDOW,'ID') IF MetNo = '' THEN RETURN TW_UseNos = Get_Property(CtrlEntID,'ARRAY')<1> ;* Just need the first column LastTW_UseNo = 0 DetItemCnt = COUNT(TW_UseNos,@VM) + (TW_UseNos NE '') FOR I = 1 TO DetItemCnt TW_UseNo = TW_UseNos<1,I> IF TW_UseNo = '' THEN TW_UseNo = 0 IF TW_UseNo > LastTW_UseNo THEN LastTW_UseNo = TW_UseNo NEXT I Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE',1) Send_Event(@WINDOW,'WRITE') TW_UseKey = MetNo:'*':LastTW_UseNo + 1 DetWindow = 'TW_USE' DetKeys = TW_UseKey DefaultRec = '' RetKey = MetNo RetWin = @WINDOW RetPage = 1 RetCtrl = CtrlEntID RetPos = 1:@FM:LastTW_UseNo + 1 obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos) End Case * If FQASigned EQ False$ then * * CtrlEntID = @WINDOW:'.TW_USE' * MetNo = Get_Property(@WINDOW,'ID') * IF MetNo = '' THEN RETURN * TW_UseNos = Get_Property(CtrlEntID,'ARRAY')<1> ;* Just need the first column * LastTW_UseNo = 0 * DetItemCnt = COUNT(TW_UseNos,@VM) + (TW_UseNos NE '') * * FOR I = 1 TO DetItemCnt * TW_UseNo = TW_UseNos<1,I> * IF TW_UseNo = '' THEN TW_UseNo = 0 * IF TW_UseNo > LastTW_UseNo THEN LastTW_UseNo = TW_UseNo * NEXT I * * Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE',1) * Send_Event(@WINDOW,'WRITE') * * TW_UseKey = MetNo:'*':LastTW_UseNo + 1 * DetWindow = 'TW_USE' * DetKeys = TW_UseKey * DefaultRec = '' * RetKey = MetNo * RetWin = @WINDOW * RetPage = 1 * RetCtrl = CtrlEntID * RetPos = 1:@FM:LastTW_UseNo + 1 * obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos) * * end else * // FQA Signed -> Block TW_USE creation/deletion/modification * ErrorMsg = 'FQA has already been signed. Metrology test record cannot be updated!' * ErrMsg(ErrorMsg) * Return 0 * * end RETURN * * * * * * * TWUseDC: * * * * * * * RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') FQASigned = RDS_Services('GetFinalQAStatus', RDSNo) RecordLocked = False$ RDSNo = Get_Property(@WINDOW:'.RDS_NO', 'DEFPROP') WOMatKey = Xlate('RDS', RDSNo, 'WO_MAT_KEY', 'X') * If WOMatKey NE '' then RecordLocked = Database_Services('IsKeyIDLocked', 'WO_MAT', WOMatKey, False$) Begin Case Case FQASigned EQ True$ // FQA Signed -> Block TW_USE creation/deletion/modification ErrorMsg = 'FQA has already been signed. Metrology test record cannot be updated!' ErrMsg(ErrorMsg) Return 0 Case RecordLocked EQ True$ LockOwner = Xlate('WO_MAT', WOMatKey, 'LOCKED_BY', 'X') If LockOwner NE '' then DisplayName = Oconv(LockOwner,'[XLATE_CONV,LSL_USERS*FIRST_LAST]') end else DisplayName = 'an unknown user' end MsgParms = '' MsgParms<1> = 'Record Locked' MsgParms<2> = 'The WO_MAT record for this RDS is locked by ':DisplayName:'. Only one user session at a time can edit an RDS.' Msg(@Window, '', 'OK', '', MsgParms) Return 0 Case Otherwise$ MetNo = Get_Property(@WINDOW,'ID') CtrlEntID = @WINDOW:'.TW_USE' CurrPos = Get_Property(CtrlEntID,'CARETPOS') CurrCol = CurrPos<1> CurrRow = CurrPos<2> IF CurrCol = COL$USE_NO THEN UseNo = Get_Property(CtrlEntID,'CELLPOS',COL$USE_NO:@FM:CurrRow) IF MetNo NE '' AND UseNo NE '' THEN IF Get_Property(@WINDOW,'QBFLIST') = '' THEN Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE','1') Send_Event(@WINDOW,'WRITE') END DetWindow = 'TW_USE' DetKeys = MetNo:'*':UseNo DefaultRec = '' RetKey = MetNo RetPage = 1 RetCtrl = CtrlEntID RetPos = CurrPos oAParms = DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos obj_AppWindow('ViewNewDetail',oAParms) IF Get_Status(errCode) THEN ErrMsg(errCode) END END END ;* End of ItemNo column End Case * If FQASigned EQ False$ then * * MetNo = Get_Property(@WINDOW,'ID') * CtrlEntID = @WINDOW:'.TW_USE' * CurrPos = Get_Property(CtrlEntID,'CARETPOS') * CurrCol = CurrPos<1> * CurrRow = CurrPos<2> * IF CurrCol = COL$USE_NO THEN * UseNo = Get_Property(CtrlEntID,'CELLPOS',COL$USE_NO:@FM:CurrRow) * IF MetNo NE '' AND UseNo NE '' THEN * IF Get_Property(@WINDOW,'QBFLIST') = '' THEN * Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE','1') * Send_Event(@WINDOW,'WRITE') * END * DetWindow = 'TW_USE' * DetKeys = MetNo:'*':UseNo * DefaultRec = '' * RetKey = MetNo * RetPage = 1 * RetCtrl = CtrlEntID * RetPos = CurrPos * oAParms = DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos * obj_AppWindow('ViewNewDetail',oAParms) * IF Get_Status(errCode) THEN * ErrMsg(errCode) * END * END * END ;* End of ItemNo column * * end else * * // FQA Signed -> Block TW_USE creation/deletion/modification * ErrorMsg = 'FQA has already been signed. Metrology test record cannot be updated!' * ErrMsg(ErrorMsg) * Return 0 * * end RETURN * * * * * * * TWOptions: * * * * * * * CtrlEntID = @WINDOW:'.WFR_USAGE' CurrPos = Get_Property(CtrlEntID,'SELPOS') CurrCol = CurrPos<1> CurrRow = CurrPos<2> MetNo = Get_Property(@WINDOW:'.MET_NO','DEFPROP') TWList = Get_Property(CtrlEntID,'LIST') TWArray = Get_Property(CtrlEntID,'DEFPROP') CurrUseID = TWArray IF CurrUseID NE '' THEN obj_AppWindow('ViewRelated','TW_USE':@RM:CurrUseID) END BEGIN CASE CASE CurrCol = COL$TW_TYPE Result = Popup(@WINDOW,'','TW_TYPES') IF Result NE '' THEN Parms = Result:@RM:CtrlEntId:@RM:CurrPos obj_Appwindow('LUValReturn',Result:@RM:CtrlEntId:@RM:CurrPos ) END CASE CurrCol = COL$TW_CODE Result = Popup(@WINDOW,'','SHOW_TW_CODES') IF Result NE '' THEN Parms = Result:@RM:CtrlEntId:@RM:CurrPos obj_Appwindow('LUValReturn',Result:@RM:CtrlEntId:@RM:CurrPos ) END CASE CurrCol = COL$TW_TOOL Result = Popup( @WINDOW, '', 'CHOOSE_TOOL' ) IF Result NE '' THEN Parms = Result:@RM:CtrlEntId:@RM:CurrPos obj_Appwindow('LUValReturn',Result:@RM:CtrlEntId:@RM:CurrPos ) END END CASE RETURN * * * * * * * TWPC: * * * * * * * RETURN ;****************************** CtrlEntID = Get_Property(@WINDOW,'FOCUS') PrevSelPos = Get_Property(CtrlEntId,"PREVSELPOS") PrevCol = PrevSelPos<1> PrevRow = PrevSelPos<2> CurrPos = Get_Property(CtrlEntId,'SELPOS') CurrCol = CurrPos<1> CurrRow = CurrPos<2> ListData = Get_Property(CtrlEntId,'LIST') MetNo = Get_Property(@WINDOW:'.MET_NO','TEXT') ColCnt = 11 * LostFocus checks IF ListData NE '' THEN BEGIN CASE CASE PrevCol = COL$TW_CODE TWCode = ListData IF RowExists('TW_CODES', TWCode) THEN IF TWCode = '99' THEN Parms = 'NA':@RM:CtrlEntId:@RM:COL$TW_TOOL:@FM:PrevRow ;* Added 'NA' defaults for signature line 11/14/2007 JCH obj_Appwindow('LUValReturn',Parms) Parms = 'NA':@RM:CtrlEntId:@RM:COL$TW_TYPE:@FM:PrevRow obj_Appwindow('LUValReturn',Parms) END END ELSE Mesg = 'Invalid Test Wafer Code Entered.':@TM:@TM Mesg := 'Code ':QUOTE(TWCode):' not found in':@TM:'TestWafer Code Table!' ErrMsg(Mesg) Set_Property(CtrlEntId,"SELPOS",PrevSelPos) Set_Property(CtrlEntID,'INVALUE','',PrevSelPos) ;* Clear entered field END CASE PrevCol = COL$TW_TOOL TWTool = ListData IF TWTool NE 'NA' THEN AllTools = XLATE('LISTBOX_CONFIG','ALLTOOLS',1,'X') LOCATE TWTool IN AllTools USING @VM SETTING Dummy ELSE Mesg = 'Invalid TestWafer Tool Entered.':@TM:@TM Mesg := 'Tool ':QUOTE(TWTool):' not found in LISTBOX_CONFIG table.':@TM:'ALLTOOLS record.' ErrMsg(Mesg) Set_Property(CtrlEntId,"SELPOS",PrevSelPos) Set_Property(CtrlEntID,'INVALUE','',PrevSelPos) ;* Clear entered field END END CASE PrevCol = COL$TW_TYPE TWType = ListData IF TWType NE 'NA' THEN TWTypes = XLATE('SYSREPOSPOPUPS','LSL2**TW_TYPES',8,'X') TypeCnt = COUNT(TWTypes,@VM) + (TWTypes NE '') Found = 0 FOR N = 1 TO TypeCnt IF TWTypes<1,N,1> = TWType THEN Found = 1 UNTIL Found NEXT N IF NOT(Found) THEN Mesg = 'Invalid Test Wafer Type Entered.':@TM:@TM Mesg := 'Tool ':QUOTE(TWType):' not found in TW_TYPES popup.':@TM:'ALLTOOLS record.' ErrMsg(Mesg) Set_Property(CtrlEntId,"SELPOS",PrevSelPos) Set_Property(CtrlEntID,'INVALUE','',PrevSelPos) ;* Clear entered field END END END CASE END * Gotfocus checks IF ListData = '' AND CurrCol NE COL$TW_USAGE_DESC THEN ColPointer = CurrCol LinePointer = CurrRow * Find the first non-empty cell LOOP Test = ListData UNTIL Test NE '' OR (LinePointer = 0 AND ColPointer = 1) ColPointer -= 1 IF ColPointer = 0 THEN ColPointer = ColCnt - 2 LinePointer -= 1 END REPEAT * Move one past the non empty cell BEGIN CASE CASE LinePointer = 0 * Empty Table LinePointer = 1 ColPointer = 1 CASE ColPointer = ColCnt - 2 LinePointer += 1 ColPointer = 1 CASE 1 ColPointer += 1 END CASE Set_Property(CtrlEntId,"SELPOS",ColPointer:@FM:LinePointer) ToolCtrls = @WINDOW:'.SPEC_THICK_MTOOL':@RM ; ToolProps = 'DEFPROP':@RM ToolCtrls := @WINDOW:'.SPEC_RES_MTOOL':@RM ; ToolProps := 'DEFPROP':@RM ToolCtrls := @WINDOW:'.SPEC_CON_MTOOL':@RM ; ToolProps := 'DEFPROP':@RM ToolCtrls := @WINDOW:'.SPEC_CRES_MTOOL' ; ToolProps := 'DEFPROP' AvailTools = Get_Property(ToolCtrls,ToolProps) CONVERT @RM TO @VM IN AvailTools SWAP @VM:@VM WITH @VM IN AvailTools TypeCtrls = @WINDOW:'.SPEC_THICK_MTYPE':@RM ; TypeProps = 'DEFPROP':@RM TypeCtrls := @WINDOW:'.SPEC_RES_MTYPE':@RM ; TypeProps := 'DEFPROP':@RM TypeCtrls := @WINDOW:'.SPEC_CON_MTYPE':@RM ; TypeProps := 'DEFPROP':@RM TypeCtrls := @WINDOW:'.SPEC_CRES_MYPE' ; TypeProps := 'DEFPROP' MTypeCtrls = @WINDOW:'.SPEC_THICK_MPROVEIN':@RM ; MTypeProps = 'DEFPROP':@RM MTypeCtrls := @WINDOW:'.SPEC_RES_MPROVEIN':@RM ; MTypeProps := 'DEFPROP':@RM MTypeCtrls := @WINDOW:'.SPEC_CON_MPROVEIN':@RM ; MTypeProps := 'DEFPROP':@RM MTypeCtrls := @WINDOW:'.SPEC_CRES_MPROVEIN' ; MTypeProps := 'DEFPROP' AvailTypes = Get_Property(TypeCtrls,TypeProps) CONVERT @RM TO @VM IN AvailTypes AvailMTypes = Get_Property(MTypeCtrls,MTypeProps) CONVERT @RM TO @VM IN AvailMTypes BEGIN CASE CASE ColPointer = COL$TW_CODE * Leave this null for now CASE ColPointer = COL$TW_TOOL IF ListData = '' THEN * Popup Tools TypeOver = '' TypeOver = AvailTools Tool = Popup(@WINDOW,TypeOver,'RDS_SPEC_TOOLS') IF Tool NE '' THEN Parms = Tool:@RM:CtrlEntId:@RM:ColPointer:@FM:LinePointer obj_Appwindow('LUValReturn',Parms) END END CASE ColPointer = COL$TW_TYPE IF ListData = '' THEN * Popup WaferTypes on this tools line TypeCode = Popup(@WINDOW,'','TW_TYPES') IF TypeCode NE '' THEN Parms = TypeCode:@RM:CtrlEntId:@RM:ColPointer:@FM:LinePointer obj_Appwindow('LUValReturn',Parms) END END CASE ColPointer = COL$TW_SIG IF ListData = '' THEN Valid = Dialog_Box( 'QUOTE_SIG_PWD_ENTRY', @WINDOW, @USER4:@VM:XLATE( 'LSL_USERS', @USER4, LSL_USERS_PASSWORD$, 'X' ) ) IF Valid THEN Parms = @USER4:@RM:CtrlEntId:@RM:ColPointer:@FM:LinePointer ;* Username obj_Appwindow('LUValReturn',Parms ) CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTS') Parms = CurrDTM:@RM:CtrlEntId:@RM:ColPointer+1:@FM:LinePointer ;* Date-Time Stamp obj_Appwindow('LUValReturn',Parms ) CurrDTM = ICONV(CurrDTM,'DT') ReactNo = Get_Property(@WINDOW:'.REACTOR','DEFPROP') OutOfProdDTM = XLATE('REACT_STATUS',ReactNo,REACT_STATUS_OUT_OF_PROD_DTM$,'X') HrsSinceProd = OCONV((CurrDTM - OutOfProdDTM)*24,'MD2') Parms = HrsSinceProd:@RM:CtrlEntId:@RM:ColPointer+2:@FM:LinePointer ;* Hours Since Production obj_Appwindow('LUValReturn',Parms ) EscHrs = XLATE('REACTOR',ReactNo,'ACT_ESC_HRS','X') IF EscHrs = '' THEN EscHrs = 0 EscElapsedTime = OCONV(EscHrs,'MD2') Parms = EscElapsedTime:@RM:CtrlEntId:@RM:ColPointer+3:@FM:LinePointer ;* Hours in Escalation obj_Appwindow('LUValReturn',Parms ) END END CASE 1 NULL END CASE RETURN END IF CurrCol = COL$TW_USAGE_DESC THEN Set_Property(CtrlEntId,'SELPOS',CurrCol + 1:@FM:CurrRow) END IF CurrCol = COL$TW_QTY OR CurrCol = COL$TW_CODE OR CurrCol = COL$TW_TOOL OR CurrCol = COL$TW_TYPE THEN IF ListData NE '' AND ListData NE '' THEN Set_Property(CtrlEntId,'SELPOS',CurrCol + 1:@FM:CurrRow) ;* 11/19/2007 JCH no change in parms once signed END END GOSUB Refresh RETURN * * * * * * * TWLF: * * * * * * * RETURN CtrlEntID = @WINDOW:'.WFR_USAGE' ;*************************************************** MetNo = Get_Property(@WINDOW:'.MET_NO','DEFPROP') ListData = Get_Property(CtrlEntId,'LIST') TWArray = Get_Property(CtrlEntID,'ARRAY') ReactType = Get_Property(@WINDOW:'.REACTOR_TYPE_IN','TEXT') WriteFlag = 0 ListCnt = COUNT(ListData,@FM) + (ListData NE '') FOR I = 1 TO ListCnt Tool = ListData *IF ListData = 'PROD' THEN * IF Tool NE 'SRP' AND Tool NE 'HgCv' THEN * Mesg = 'The ':Tool:' tool is Non_Destructive to a Product wafer':CRLF$:CRLF$ * Mesg := 'Only tests that are destructive to a product wafer are recorded':CRLF$ ;* Dead 3/31/2009 JCH & DKK * Mesg := 'in the Test Wafer Usage area.' * ErrMsg(Mesg) * Set_Property(CtrlEntID, 'FOCUS', 1) * RETURN * END *END IF ListData NE '' THEN IF ListData = '' THEN Mesg = 'Incomplete Test Wafer Line - All Fields must be completed.' ErrMsg(Mesg) Set_Property(CtrlEntID, 'FOCUS', 1) Set_Property(CtrlEntId,"SELPOS",I:@FM:COL$TW_CODE) RETURN END ELSE IF ListData = '' THEN Mesg = 'Incomplete Test Wafer Line - All Fields must be completed.' ErrMsg(Mesg) Set_Property(CtrlEntID, 'FOCUS', 1) Set_Property(CtrlEntId,"SELPOS",I:@FM:COL$TW_TOOL) RETURN END ELSE IF ListData = '' THEN Mesg = 'Incomplete Test Wafer Line - All Fields must be completed.' ErrMsg(Mesg) Set_Property(CtrlEntID, 'FOCUS', 1) Set_Property(CtrlEntId,"SELPOS",I:@FM:COL$TW_TOOL) RETURN END END END END * This section added 8/11/2008 JCH for Test wafer slot maintenance in the WO_MAT table IF ReactType NE 'P' THEN RDSNo = Get_Property(@WINDOW:'.RDS_NO','DEFPROP') RRRec = XLATE('REACT_RUN',RDSno,'','X') WONo = RRRec CassNo = RRRec IF ListData = 'PROD' AND ListData = '' THEN SlotWaferIDs = obj_WO_Mat('SlotWaferIDs',WONo:'*':CassNo) ;* Get list of available wafers in cassette WaferIDCnt = COUNT(SlotWaferIDs,@VM) + (SlotWaferIDs NE '') FOR N = 1 TO WaferIDCnt SlotWaferIDs<1,N> = N:@SVM:SlotWaferIDs<1,N> NEXT N TypeOver = '' TypeOver = SlotWaferIDs ProdTestSlots = Popup(@WINDOW,TypeOver,'SELECT_PROD_TEST') ;* Select from list of available wafers IF ProdTestSlots NE '' THEN Set_Status(0) WaferIDList = obj_WO_Mat('RemProdTW',WONo:@RM:CassNo:@RM:MetNo:@RM:ProdTestSlots) ;* Add metrology number to each selected slot IF Get_Status(errCode) THEN ErrMsg(errCode) END ELSE IF ListData = 'PROD' AND ListData = '' THEN Parms = WaferIDList:@RM:CtrlEntId:@RM:COL$TW_WAFER_ID:@FM:I obj_Appwindow('LUValReturn',Parms) ;* Add @SVM'd wafer ids to test wafer line END END END NULL WriteFlag = 1 END IF ListData NE 'PROD' AND ListData NE '' THEN obj_WO_Mat('RepProdTW',WONo:@RM:CassNo:@RM:MetNo:@RM:ListData) ;* Put the test wafers back in the box Parms = '':@RM:CtrlEntId:@RM:COL$TW_WAFER_ID:@FM:I obj_Appwindow('LUValReturn',Parms) ;* WriteFlag = 1 END END ;* End of check for Non EpiPRO reactor type NEXT I IF WriteFlag = 1 THEN Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE',1) Send_Event(@WINDOW,'WRITE') obj_AppWindow('LoadFormKeys',@WINDOW:@RM:MetNo) END RETURN * * * * * * * TWDel: * * * * * * * RETURN RowNum = Parm1 RowData = Parm2 CtrlEntID = @WINDOW:'.WFR_USAGE' UserRec = XLATE( 'LSL_USERS', @USER4, '', 'X' ) Groups = UserRec WriteFlag = 0 *Add LEAD to group LOCATE 'SUPERVISOR' IN Groups USING @VM SETTING DUMMY THEN MetNo = Get_Property(@WINDOW:'.MET_NO','DEFPROP') RDSNo = Get_Property(@WINDOW:'.RDS_NO','DEFPROP') RRRec = XLATE('REACT_RUN',RDSno,'','X') WONo = RRRec CassNo = RRRec TWUseID = RowData<1,COL$TW_USE_ID> IF TWUseID NE '' THEN obj_TW_Use('Delete',WONo:@RM:CassNo:@RM:MetNo:@RM:TWUseID) IF Get_Status(errCode) THEN * * * * * * * END END ELSE IF RowData<1,COL$TW_WAFER_ID> NE '' THEN obj_WO_Mat('RepProdTW',WONo:@RM:CassNo:@RM:MetNo:@RM:RowData<1,COL$TW_WAFER_ID>) ;* Put the test wafers back in the box END END WriteFlag = 1 END ELSE Send_Message(CtrlEntID, "INSERT", RowNum, RowData) ErrMsg('Only supervisors may delete test wafer line items.') END IF WriteFlag = 1 THEN Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE',1) Send_Event(@WINDOW,'WRITE') obj_AppWindow('LoadFormKeys',@WINDOW:@RM:MetNo) END RETURN * * * * * * * OverRide: * * * * * * * IF XLATE( 'LSL_USERS', @USER4, LSL_USERS_RDS_MASTER$, 'X' ) THEN IF NOT( Dialog_Box( 'PWD_ENTRY', @WINDOW, '' ) ) THEN RETURN END ELSE MSGINFO = '' MSGINFO = 'You do not have security rights to override Run Data Sheet information.' MSGINFO = 'H' VOID = MSG( '', MSGINFO ) RETURN END ORCtrls = @WINDOW:'.SPEC_THICK_MIN':@RM:@WINDOW:'.SPEC_THICK_TARGET':@RM:@WINDOW:'.SPEC_THICK_MAX':@RM:@WINDOW:'.SPEC_THICK_UNITS':@RM ORCtrls := @WINDOW:'.SPEC_RES_MIN':@RM:@WINDOW:'.SPEC_RES_TARGET':@RM:@WINDOW:'.SPEC_RES_MAX':@RM:@WINDOW:'.SPEC_RES_UNITS':@RM ORCtrls := @WINDOW:'.SPEC_CON_MIN':@RM:@WINDOW:'.SPEC_CON_TARGET':@RM:@WINDOW:'.SPEC_CON_MAX':@RM:@WINDOW:'.SPEC_CON_UNITS':@RM ORCtrls := @WINDOW:'.SPEC_CRES_MIN':@RM:@WINDOW:'.SPEC_CRES_TARGET':@RM:@WINDOW:'.SPEC_CRES_MAX':@RM:@WINDOW:'.SPEC_CRES_UNITS' Props = STR('ENABLED':@RM,16) ; Props[-1,1] = '' Vals = STR('1':@RM,16) ; Vals[-1,1] = '' Set_Property(ORCtrls,Props,Vals) Props = STR('BACKCOLOR':@RM,16) ; Props[-1,1] = '' Vals = STR(WHITE$ :@RM,16) ; Vals[-1,1] = '' Set_Property(ORCtrls,Props,Vals) RETURN * * * * * * * CopyTSLine: * * * * * * * RDSNo = Get_Property(@Window : '.RDS_NO', 'TEXT') FQASigned = RDS_Services('GetFinalQAStatus', RDSNo) If FQASigned EQ False$ then CtrlEntID = @WINDOW:'.WFR_USAGE' CurrPos = Get_Property(CtrlEntId,"SELPOS") CurrRow = CurrPos<2> IF CurrPos = '' THEN RETURN ;* No row selected CtrlEntID = @WINDOW:'.TW_USE' CurrPos = Get_Property(CtrlEntId,"SELPOS") CurrRow = CurrPos<2> IF CurrRow = '' THEN MText = 'Please select an existing row to copy.' Msg(@WINDOW,'', 'ERROR','','Copy Test Wafer Use':@FM: MText) RETURN END IF INDEX(CurrRow,@VM,1) THEN MText = 'Please select a single row to copy.' Msg(@WINDOW,'', 'ERROR','','Copy Test Wafer Use':@FM: MText) RETURN END CurrWaferIDs = Get_Property(CtrlEntID,'CELLPOS',COL$WAFER_ID:@FM:CurrRow) IF CurrWaferIDs NE '' THEN MText = 'Selected Wafer Usage uses Product Test Wafers and may not be copied.' Msg(@WINDOW,'', 'ERROR','','Copy Test Wafer Use':@FM: MText) RETURN END UseNos = Get_Property(CtrlEntId,'DEFPROP') CurrUseNo = UseNos IF CurrUseNo = '' THEN MText = 'No Test Wafer Use line selected to copy.' Msg(@WINDOW,'', 'ERROR','','Copy Test Wafer Use':@FM: MText) RETURN END LOOP UNTIL UseNos[-1,1] NE @VM OR UseNos = '' UseNos[-1,1] = '' REPEAT UseCnt = COUNT(UseNos,@VM) + (UseNos NE '') LastSeq = 0 FOR I = 1 to UseCnt UseNo =UseNos<1,I> IF UseNo > LastSeq THEN LastSeq = UseNo END NEXT I NextSeq = LastSeq + 1 MetNo = Get_Property(@WINDOW:'.MET_NO','DEFPROP') Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE','1') Send_Event('RDS_TEST','WRITE') Set_Status(0) obj_TW_Use('Copy',MetNo:@RM:NextSeq:@RM:CurrUseNo) IF Get_Status(errCode) THEN ErrMsg(errCode) obj_AppWindow('LoadFormKeys',@WINDOW:@RM:MetNo) RETURN END obj_AppWindow('LoadFormKeys',@WINDOW:@RM:MetNo) obj_AppWindow('ViewRelated','TW_USE':@RM:MetNo:'*':NextSeq) end else // FQA Signed -> Block TW_USE creation/deletion/modification ErrorMsg = 'FQA has already been signed. Metrology test record cannot be updated!' ErrMsg(ErrorMsg) Return 0 end RETURN * * * * * * * AddSRP: * * * * * * * RDSNo = Get_Property(@WINDOW:'.RDS_NO','DEFPROP') SRPPaths = Get_Property(@WINDOW:'.SRP_BITMAPS','ARRAY')<1> thisSRPPaths = SRPPaths FirstMTLine = 1 LOOP thisSRPPath = thisSRPPaths[1,@VM] UNTIL thisSRPPath = '' FirstMTLine += 1 thisSRPPaths[1,COL2()] = '' REPEAT * Display the Windows Choosefile Dialog with the default filename loaded. * SRPDirectory = 'N:\Engineering\CommonRW\SRPScans\' SRPDirectory = Environment_Services('GetUserDataRootPath') : '\Engineering\CommonRW\SRPScans\' CFOpt = '' CFOpt<1> = '' CFOpt<2> = 'Bitmaps (*.bmp)/*.bmp/' CFOpt<3> = 1 CFOpt<4> = RDSNo:'.bmp' CFOpt<6> = SRPDirectory FullPath = Utility('CHOOSEFILE',@WINDOW,CFOpt) IF FullPath = '' THEN RETURN LOCATE FullPath IN SRPPaths USING @VM SETTING Pos THEN ErrMsg('Bitmap is already attached.') END ELSE Send_Message(@WINDOW:'.SRP_BITMAPS','INSERT',1,FullPath) END RETURN * * * * * * * ViewSRP: * * * * * * * CtrlEntID = @WINDOW:'.SRP_BITMAPS' CurrPos = Get_Property(CtrlEntID,'SELPOS') CurrRow = CurrPos<2> AllPaths = Get_Property(CtrlEntID,'DEFPROP')<1> FullPath = AllPaths<1,CurrRow> IF FullPath NE '' THEN Void = Start_Window('RDS_SRP',@WINDOW,FullPath,'','') END RETURN * * * * * * * RemoveSRP: * * * * * * * CtrlEntID = @WINDOW:'.SRP_BITMAPS' DeletedRowIndex = Parm1 DeletedRowText = Parm2 Result = Msg(@WINDOW,'','REMOVE_SRP_POINTER') IF Result = 0 THEN Send_Message(CtrlEntID, "INSERT",DeletedRowIndex, DeletedRowText) ;* Put it back in the list END RETURN * * * * * * * InsertSRP: * * * * * * * RowIndex = Parm1 CurrCtrl = Get_Property(@WINDOW,'FOCUS') Dummy = Send_Message(CurrCtrl, "DELETE", RowIndex) ErrMsg('Rows may not be inserted.') RETURN * * * * * * * ThickDC: * * * * * * * ReactorType = Get_Property(@WINDOW:'.REACTOR_TYPE_IN','TEXT') PSNo = Get_Property(@WINDOW:'.PS_NO','DEFPROP') ThickFilmMet = Get_Property(@WINDOW:'.THICKFILM_MET','CHECK') IF ReactorType = 'EPP' OR ReactorType = 'P' OR ThickFilmMet = 1 THEN RDSNo = Get_Property(@WINDOW:'.RDS_NO','TEXT') LSID = Get_Property(@WINDOW:'.LS_ID','TEXT') LSKeys = XLATE('RDS',RDSNo,RDS_RDS_LAYER_KEYS$,'X') LastLSID = LSKeys[-1,'B*'] IF LSID NE LastLSID THEN ErrMsg('EpiPRO results may only be entered on the LAST layer set.') RETURN END Ctrls = @WINDOW:'.MET_NO':@RM ; Props = 'TEXT':@RM Ctrls := @WINDOW:'.ZONE' ; Props := 'TEXT' Vals = Get_Property(Ctrls,Props) MetNo = Vals[1,@RM] Zone = Vals[COL2()+1,@RM] IF MetNo = '' THEN RETURN IF Zone = '' AND NOT(ThickFilmMet) THEN ;* Added check for ThickFilmMet 1/15/2009 JCH, J.C. Henry & Co., Inc. ErrMsg('Zone must be filled in before entering metrology data.') Set_Property(@WINDOW:'.ZONE','FOCUS',1) RETURN END Set_Property(@WINDOW,'@DONT_CLOSE_ON_WRITE',1) ;* Sets a flag to keep the RDS_TEST window from closing on the WRITE event Send_Event(@WINDOW,'WRITE') dummy = Create_Dialog('DIALOG_EPI_PRO_MET',@WINDOW,0,MetNo) END RETURN * * * * * * * SendSPC: * * * * * * * // Temporarily disable the "Send SPC" button to avoid duplicate requests from being generated. Set_Property(@Window : '.SEND_SPC', 'ENABLED', False$) Send_Event(@WINDOW:'.GROWTH_RATE','CALCULATE') Ctrls = @WINDOW:'.PS_NO':@RM ; Props = 'DEFPROP':@RM Ctrls := @WINDOW:'.RDS_NO':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.LS_ID':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.REACTOR':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.ZONE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.THICK_AVG':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.THICK_STDV':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.SHEETRHO_AVG':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.SHEETRHO_STDV':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.RES_AVG':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.RES_STDV':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.HGCV1_RES_AVG':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.HGCV1_RES_STDV':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.GROWTH_RATE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.THICK_RANGE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.THICK_RANGE_PCNT':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.SHEETRHO_RANGE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.SHEETRHO_RANGE_PCNT':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.RES_RANGE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.RES_RANGE_PCNT':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.HGCV1_RES_RANGE':@RM ; Props := 'DEFPROP':@RM Ctrls := @WINDOW:'.HGCV1_RES_RANGE_PCNT':@RM ; Props := 'DEFPROP':@RM Vals = Get_Property(Ctrls,Props) PSNo = Vals[1,@RM] RDSNo = Vals[COL2()+1,@RM] LSId = Vals[COL2()+1,@RM] Reactor = Vals[COL2()+1,@RM] Zone = Vals[COL2()+1,@RM] ThickAvg = Vals[COL2()+1,@RM] ThickStdv = Vals[COL2()+1,@RM] SheetRhoAvg = Vals[COL2()+1,@RM] SheetRhoStdv = Vals[COL2()+1,@RM] ResAvg = Vals[COL2()+1,@RM] ResStdv = Vals[COL2()+1,@RM] HgcvAvg = Vals[COL2()+1,@RM] HgCvStdv = Vals[COL2()+1,@RM] GrowthRate = Vals[COL2()+1,@RM] ThickRange = Vals[COL2()+1,@RM] ThickRangePcnt = Vals[COL2()+1,@RM] SheetRhoRange = Vals[COL2()+1,@RM] SheetRhoRangePcnt = Vals[COL2()+1,@RM] ResRange = Vals[COL2()+1,@RM] ResRangePcnt = Vals[COL2()+1,@RM] Hgcv1ResRange = Vals[COL2()+1,@RM] Hgcv1ResRangePcnt = Vals[COL2()+1,@RM] //////////////////////////////////////////////////////////////////////////////////////////////////////////////// IOOptions = Get_Property(@Window, 'IOOPTIONS') IOOptions<6> = True$ Set_Property(@Window, 'IOOPTIONS', IOOptions) Set_Property(@WINDOW, '@DONT_CLOSE_ON_WRITE', True$) Savewarn = Get_Property(@Window, 'SAVEWARN') If Savewarn EQ True$ then // User has entered in new data so save before posting SPC request. Set_Status(0) Send_Event(@Window, 'WRITE') If Get_Status(StatusCode) then ErrMsg('Error saving metrology record. Could not send metrology data to SPC.') Set_Property(@Window : '.SEND_SPC', 'ENABLED', True$) return end end LayerRec = XLATE('RDS_LAYER',RDSNo:'*':LSId,'','X') DictInfo = XLATE('DICT.RDS_LAYER','%FIELDS%','','X') GoodData = True$ IF LayerRec = '' THEN GoodData = False$ IF LayerRec = '' THEN GoodData = False$ IF NOT(GoodData) THEN ErrMsg('Incomplete Reactor Parameters (RDS Layer) record.') Set_Property(@Window : '.SEND_SPC', 'ENABLED', True$) RETURN END IF Reactor EQ '' THEN ErrMsg('':@VM:'Process Error':@SVM:'Reactor No. is required on RDS prior to recording test results.') Set_Property(@Window : '.SEND_SPC', 'ENABLED', True$) RETURN End KeyID = Get_Property(@Window : '.MET_NO', 'TEXT') If KeyID NE '' then SPC_Services('PostToQueue', 'RDS_TEST', KeyID) If Error_Services('NoError') else ErrMsg('Error posting Metrology data to SPC queue. Error message: ':Error_Services('GetMessage')) Set_Property(@Window : '.SEND_SPC', 'ENABLED', True$) return end end else ErrMsg('Process Error':@SVM:'Met. No. is required prior to recording test results.') Set_Property(@Window : '.SEND_SPC', 'ENABLED', True$) return end CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTHS') Set_Property(@Window : '.SPC_DTM', 'DEFPROP', CurrDTM) // Save new sent to SPC datetime. Send_Event(@Window, 'WRITE') // Revert IOOptions to previous setting. IOOptions = Get_Property(@Window, 'IOOPTIONS') IOOptions<6> = False$ Set_Property(@Window, 'IOOPTIONS', IOOptions) // Request posted -> reenable the "Send SPC" button. Set_Property(@Window : '.SEND_SPC', 'ENABLED', True$) return //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CONVERT '%' TO '' IN ThickRangePcnt CONVERT '%' TO '' IN SheetRhoRangePcnt CONVERT '%' TO '' IN ResRangePcnt CONVERT '%' TO '' IN Hgcv1ResRangePcnt IF NUM(LSId) THEN DepositTime = '' DopantFlow = '' EpiH2Flow = '' FOffset = '' ROffset= '' SOffset = '' TcsFlow = '' END ELSE LayerRec = XLATE('RDS_LAYER',RDSNo:'*':LSId,'','X') DictInfo = XLATE('DICT.RDS_LAYER','%FIELDS%','','X') GoodData = 1 IF LayerRec = '' THEN GoodData = 0 IF LayerRec = '' THEN GoodData = 0 IF NOT(GoodData) THEN ErrMsg('Incomplete Reactor Parameters (RDS Layer) record.') RETURN END IF Get_Property(@WINDOW:'.REACTOR','DEFPROP') = '' THEN ErrMsg('':@VM:'Process Error':@SVM:'Reactor No. is required on RDS prior to recording test results.') RETURN End LOCATE RDS_LAYER_EPI_TIME$ IN DictInfo SETTING Pos THEN DepositTime = OCONV(LayerRec,DictInfo) END ELSE DepositTime = LayerRec END LOCATE RDS_LAYER_DOPANT_FLOW$ IN DictInfo SETTING Pos THEN DopantFlow = OCONV(LayerRec,DictInfo) END ELSE DopantFlow = LayerRec END LOCATE RDS_LAYER_EPI_H2_FLOW$ IN DictInfo SETTING Pos THEN EpiH2Flow = OCONV(LayerRec,DictInfo) END ELSE EpiH2Flow = LayerRec END LOCATE RDS_LAYER_F_OFFSET$ IN DictInfo SETTING Pos THEN FOffset = OCONV(LayerRec,DictInfo) END ELSE FOffset = LayerRec END LOCATE RDS_LAYER_R_OFFSET$ IN DictInfo SETTING Pos THEN ROffset = OCONV(LayerRec,DictInfo) END ELSE ROffset = LayerRec END LOCATE RDS_LAYER_S_OFFSET$ IN DictInfo SETTING Pos THEN SOffset = OCONV(LayerRec,DictInfo) END ELSE SOffset = LayerRec END LOCATE RDS_LAYER_TCS_FLOW$ IN DictInfo SETTING Pos THEN TcsFlow = OCONV(LayerRec,DictInfo) END ELSE TcsFlow = LayerRec END END ;* End of check for Numeric Layer Set ID UserName = OCONV(@USER4,'[XLATE_CONV,LSL_USERS*FIRST_LAST]') DataLine = QUOTE(PSNo):TAB$ DataLine := QUOTE(RDSNo):TAB$ DataLine := QUOTE(LSId):TAB$ DataLine := QUOTE(Reactor):TAB$ DataLine := QUOTE(Zone):TAB$ DataLine := QUOTE(ThickAvg):TAB$ DataLine := QUOTE(ThickStdv):TAB$ DataLine := QUOTE(SheetRhoAvg):TAB$ DataLine := QUOTE(SheetRhoStdv):TAB$ DataLine := QUOTE(ResAvg):TAB$ DataLine := QUOTE(ResStdv):TAB$ DataLine := QUOTE(HgcvAvg):TAB$ DataLine := QUOTE(HgcvStdv):TAB$ DataLine := QUOTE(GrowthRate):TAB$ DataLine := QUOTE(DepositTime):TAB$ DataLine := QUOTE(DopantFlow):TAB$ DataLine := QUOTE(EpiH2Flow):TAB$ DataLine := QUOTE(FOffset):TAB$ DataLine := QUOTE(ROffset):TAB$ DataLine := QUOTE(SOffset):TAB$ DataLine := QUOTE(TcsFlow):TAB$ DataLine := QUOTE(UserName):TAB$ DataLine := QUOTE(ThickRange):TAB$ DataLine := QUOTE(ThickRangePcnt):TAB$ DataLine := QUOTE(SheetRhoRange):TAB$ DataLine := QUOTE(SheetRhoRangePcnt):TAB$ DataLine := QUOTE(ResRange):TAB$ DataLine := QUOTE(ResRangePcnt):TAB$ DataLine := QUOTE(Hgcv1ResRange):TAB$ DataLine := QUOTE(Hgcv1ResRangePcnt):TAB$ * DOSFile = 'N:\IT\CommonRW\OI_SPC_Data_Transfer\SPC_Data.TXT' * DOSFile = Environment_Services('GetUserDataProductionPath') : '\CommonRW\OI_SPC_Data_Transfer\SPC_Data.TXT' DOSFile = Environment_Services('GetSPCDataPath') : '\SPC_Data.txt' * * * * * * * DosRead: * * * * * * * Set_Status(0) OSRead DOSRecord FROM DOSFile ELSE ErrCode = Status() IF ErrCode = 4 THEN DOSRecord = '' ;* File doesn't exist END ELSE ErrMsg('Unable to read DOS file "SPC_Data.TXT" for update. ':ErrCode:' Please try again.') RETURN END END DOSRecord := DataLine:CRLF$ OSWrite DOSRecord ON DOSFile CurrDTM = OCONV(Date(),'D4/'):' ':OCONV(Time(),'MTHS') Set_Property(@WINDOW:'.SPC_DTM','DEFPROP',CurrDTM) RETURN