COMPILE FUNCTION Comm_Prod_Spec(Instruction, Parm1,Parm2)
#pragma precomp SRP_PreCompiler

/*
	Commuter module for PROD_SPEC (Product Specification) window
	
	09/20/2004 - John C. Henry, J.C. Henry & Co., Inc.
	03/11/2019 - djs - Updated "StatusClick" subroutine to call "NDW_MAKEUP_WAFER_NCR" when a PSN is inactivated.
	                   Also updated two lines using an undefined equate statement PRS_PROP_UNITS$ to use the defined
	                   equate statement PRS_PROP_UNITS_ORG$.
	07/27/2020 - JRO - Updated COL$ Equate for the LS table due to adding new cols.
	02/23/2020 - JRO - Added in methods for Parameter checks
	10/10/2024 - DJM - Changed QUOTE_SIGS to Security groups to be tied into AD groups.
*/

DECLARE SUBROUTINE Set_Property, End_Dialog, Send_Event, Set_Status, Center_Window, Post_Event, obj_Tables
DECLARE SUBROUTINE ErrMsg, Send_Message, Set_Property, Send_Event, Btree.Extract, obj_AppWindow, Make.List
DECLARE SUBROUTINE Database_Services, Error_Services, Dialog_Box, Start_Window, Unlock, Utility
DECLARE SUBROUTINE Psn_Services, Logging_Services
DECLARE FUNCTION Get_Property, Get_Status, Dialog_Box, Utility, Center_Window, Popup, Collect.Ixvals, Error_Services
DECLARE FUNCTION Send_Message, obj_PR_Spec, Msg, Security_Check, obj_Tables, obj_Popup, MemberOf, Database_Services
DECLARE FUNCTION RowExists, Repository, Logging_Services, Environment_Services

$INSERT POPUP_EQUATES
$INSERT LOGICAL
$INSERT MSG_EQUATES
$INSERT APPCOLORS
$INSERT RTI_STYLE_EQUATES
$INSERT QUOTE_SIGS_EQU
$INSERT QUOTE_SPEC_EQU
$INSERT LSL_USERS_EQU
$INSERT PROD_SPEC_EQUATES
$INSERT PRS_LAYER_EQUATES
$INSERT PRS_PROP_EQUATES
$INSERT PRS_STAGE_EQUATES
$INSERT DICT_EQUATES
$INSERT CUST_EPI_PART_EQUATES
$INSERT EPI_PART_EQUATES
$INSERT PROD_VER_EQUATES
$INSERT COMPANY_EQUATES
$INSERT RLIST_EQUATES
$INSERT PROD_SPEC_REV_HIST_EQUATES
$Insert MESSAGE_BOX_EQUATES


EQU EDITABLE$			TO 4
EQU PROTECTED$			TO 8			;* Protected  - Edittable COLSTYLE constants
EQU MULTILINE_STYLE$	TO 512 			;* MultiLine Select
EQU LOCKED$				TO 8192
EQU DROPDOWN_STYLE$		TO 131072

EQU CRLF$	TO \0D0A\

EQU COL$LAYER			TO 1
EQU COL$LS_ID			TO 2
EQU COL$TYPE			TO 3
EQU COL$RECIPE			TO 4
EQU COL$DOPANT			TO 5
EQU COL$THICK_MIN		TO 6
EQU COL$THICK_TARG      To 7
EQU COL$THICK_MAX		TO 8
EQU COL$THICK_UNITS		TO 9
EQU COL$THICKA_MIN		TO 10
EQU COL$THICKA_TARG		TO 11
EQU COL$THICKA_MAX		TO 12
EQU COL$THICKA_UNITS	TO 13
EQU COL$RES_MIN			TO 14
EQU COL$RES_TARG		TO 15
EQU COL$RES_MAX			TO 16
EQU COL$RES_UNITS		TO 17
EQU COL$SRES_MIN		TO 18
EQU COL$SRES_TARG       To 19
EQU COL$SRES_MAX		TO 20
EQU COL$SRES_UNITS		TO 21

EQU COL$CEP_KEY	TO 1;* Used in .CEP_KEYS control
EQU COL$CEP_CUST_NAME		TO 2
EQU COL$CEP_CUST_PART_NO	TO 3
EQU COL$CEP_CUST_PART_DESC	TO 4
EQU COL$CEP_CUST_PN_INBOUND	TO 5

EQU HIDDEN$		TO 32
EQU SKIPPED$	TO 4100


*************************************************

EQU COL$CUST_PART_NO	TO 1
EQU COL$CUST_PART_REV	TO 2
EQU COL$CUST_PART_DESC	TO 3
EQU COL$INBOUND_CUST_PN	TO 4

EQU COL$SPEC_NO			TO 1
EQU COL$SPEC_DESC		TO 2
EQU COL$SPEC_REV		TO 3
EQU COL$SPEC_REV_DT		TO 4
EQU COL$SPEC_HARDCOPY	TO 5

EQU COL$EP_SUB_PART_NO	TO 1
EQU COL$EP_SUB_PART_REV	TO 2
EQU COL$EP_SUB_MFR		TO 3

EQU COL$PROD_VER_NO		TO 1
EQU COL$DESC			TO 2
EQU COL$STATUS			TO 3
EQU COL$SUB_PART_NO		TO 4
EQU COL$REACT_TYPE		TO 5
EQU COL$STEP_PSN		TO 6
EQU COL$CUST_NO			TO 7
EQU COL$EPI_PART_NO		TO 8


EQU COL$QA_MET_STAGE			TO 1			;* Used in GetQAMet data structure return variable and the edit table 'QA_STAGE'
EQU COL$QA_MET_TEST				TO 2
EQU COL$QA_MET_TEST_DESC		TO 3
EQU COL$QA_MET_RECIPE			TO 4
EQU COL$QA_MET_RECIPE_PATTERN	TO 5
EQU COL$QA_MET_MIN				TO 6
EQU COL$QA_MET_MAX				TO 7
EQU COL$QA_MET_SLOT				TO 8
EQU COL$QA_MET_INTERVAL			TO 9
EQU COL$QA_MET_START			TO 10
EQU COL$QA_MET_SEQUENCE			TO 11

EQU COL$MODE_CODE		TO 1
EQU COL$MODE_SIG		TO 2
EQU COL$MODE_SIG_DTM	TO 3

EQU COL$STAGE					TO 1
EQU COL$STAGE_CLEAN_TOOL		TO 2
EQU COL$STAGE_BRIGHTLIGHT		TO 3
EQU COL$STAGE_MICROSCOPE		TO 4
EQU COL$STAGE_SURFSCAN_RECIPE	TO 5

Equ COL$SIG_STAGE				To 1
Equ COL$SIG_STAGE_DESC 			To 2
Equ MSG_WIDTH$ to 600

EQU OHMS_SQUARE$ TO CHAR(234):'/':CHAR(220)	;* Ohms/Square

ErrCode  = ''
ErrorMsg = ''
ErrTitle = 'Error in Comm_Prod_Spec'

Result = ''
LogPath      = Environment_Services('GetApplicationRootPath') : '\LogFiles\PROD_SPEC'
LogDate      = Oconv(Date(), 'D4/')
LogTime      = Oconv(Time(), 'MTS')
LoggingDTM   = LogDate : ' ' : LogTime   ; // Logging DTM

LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ProdSpecLog.csv'
Headers     = 'Logging DTM' : @FM : 'User' : @FM : 'PSN Key' : @FM : 'Action'
objPSNLog    = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)


BEGIN CASE
	CASE Instruction = 'Create'						; GOSUB Create
	CASE Instruction = 'Refresh'					; GOSUB Refresh
	CASE Instruction = 'Page'						; GOSUB Page
	CASE Instruction = 'Clear'						; GOSUB Clear
	CASE Instruction = 'Read'						; GOSUB Read
	CASE Instruction = 'SurfScanClick'				; GOSUB SurfScanClick
	CASE Instruction = 'LoadSurfScanDefaults'		; GOSUB LoadSurfScanDefaults
	CASE Instruction = 'LUTestPointMap'				; GOSUB LUTestPointMap
	CASE Instruction = 'StatusClick'				; GOSUB StatusClick
	CASE Instruction = 'LUEpiPart'					; GOSUB LUEpiPart
	CASE Instruction = 'ViewCustEpiPart'			; GOSUB ViewCustEpiPart
	CASE Instruction = 'ViewEpiPart'				; GOSUB ViewEpiPart
	CASE Instruction = 'ViewCust'					; GOSUB ViewCust
	CASE Instruction = 'ProdVer_DC'					; GOSUB ProdVerDC
	CASE Instruction = 'ProdVerPC'					; GOSUB ProdVerPC
	CASE Instruction = 'LayerSpecDC'				; GOSUB LayerSpecDC
	CASE Instruction = 'StageSpecDC'				; GOSUB StageSpecDC
	CASE Instruction = 'WipStageClick'				; GOSUB WipStageClick
	CASE Instruction = 'SignNextMode'				; GOSUB SignNextMode
	CASE Instruction = 'UnsignCurrMode'				; GOSUB UnsignCurrMode
	CASE Instruction = 'NewStage'					; GOSUB NewStage
	CASE Instruction = 'ViewCurr'					; GOSUB ViewCurr
	CASE Instruction = 'CepPC'						; GOSUB CepPC
	CASE Instruction = 'FixCEPClick'				; GOSUB FixCEPClick
	Case Instruction = 'LUWipStage'					; Gosub LUWipStage
	CASE Instruction = 'LUToolSeq'					; GOSUB LUToolSeq
	CASE Instruction = 'UpdateRevHist'				; GOSUB UpdateRevHist
		
	CASE 1
		ErrorMsg = 'Unknown Instruction passed to routine.'
		ErrMsg(ErrorMsg)
END CASE

RETURN Result


* * * * * *
Create:
* * * * * *
	
	obj_AppWindow('Create')
	
	IF (MemberOf(@USER4,'OI_ADMIN') OR MemberOf(@USER4, 'OI_SUPERUSER')) THEN
		Set_Property(@WINDOW:'.FIX_CEP','VISIBLE',1)
	END ELSE
		Set_Property(@WINDOW:'.FIX_CEP','VISIBLE',0)
	End
	
	if (MemberOf(@USER4,'EXPORT_CONTROL_ADMINS')) then
		Set_Property(@WINDOW:'.EXPORT_CONTROL','VISIBLE',1)
	end else
		Set_Property(@WINDOW:'.EXPORT_CONTROL','VISIBLE',0)
	end
	
RETURN



* * * * * *
Refresh:
* * * * * *
    
    PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT')
    If RowExists('PROD_SPEC', PSNo) then

        CtrlID = @WINDOW:'.MODE_CODE'
        ModeArray = Get_Property(CtrlID,'DEFPROP')
        
        IF ModeArray<1,1> = '' THEN
            * Set the Mode Codes 
            atRec = Get_Property(@WINDOW,'ATRECORD')
            ReactorType = Get_Property(@Window:'.RTYPE', 'DEFPROP')
            If ReactorType EQ 'GAN' then
                atRec<PROD_SPEC_MODE_CODE$> = 'Q':@VM:'P'
            end else
                atRec<PROD_SPEC_MODE_CODE$> = 'U':@VM:'Q':@VM:'E':@VM:'P'
            end
            
            Set_Property(@WINDOW,'ATRECORD',atRec)
            ModeArray = Get_Property(CtrlID,'ARRAY')
        END
        
        BEGIN CASE
            CASE ModeArray<COL$MODE_SIG,4> NE ''	; ModeCode = 'P'	; NextMode = ''								; UnsignMode = ModeArray<COL$MODE_CODE,4>
            CASE ModeArray<COL$MODE_SIG,3> NE ''	; ModeCode = 'E'	; NextMode = ModeArray<COL$MODE_CODE,4>		; UnsignMode = ModeArray<COL$MODE_CODE,3>
            CASE ModeArray<COL$MODE_SIG,2> NE ''	; ModeCode = 'Q'	; NextMode = ModeArray<COL$MODE_CODE,3>		; UnsignMode = ModeArray<COL$MODE_CODE,2>
            CASE ModeArray<COL$MODE_SIG,1> NE ''	; ModeCode = 'U'	; NextMode = ModeArray<COL$MODE_CODE,2>		; UnsignMode = ModeArray<COL$MODE_CODE,1>
            CASE 1									; ModeCode = ''		; NextMode = ModeArray<COL$MODE_CODE,1>		; UnsignMode = ''
                
        END CASE
        
*        IF NextMode = '' THEN
*            Set_Property(@WINDOW:'.SIGN_MODE','ENABLED',0)
*            Set_Property(@WINDOW:'.SIGN_MODE','TEXT','Signed')
*        END ELSE
*            Set_Property(@WINDOW:'.SIGN_MODE','ENABLED',1)
*            Set_Property(@WINDOW:'.SIGN_MODE','TEXT','Sign ':NextMode)
*        END
*        
*        IF UnsignMode = '' THEN 
*            Set_Property(@WINDOW:'.UNSIGN_MODE','ENABLED',0)
*            Set_Property(@WINDOW:'.UNSIGN_MODE','TEXT','None Signed')
*        END ELSE
*            Set_Property(@WINDOW:'.UNSIGN_MODE','ENABLED',1)
*            Set_Property(@WINDOW:'.UNSIGN_MODE','TEXT','Unsign ':UnsignMode)
*        END
        
        
        CurrStatus = Get_Property(@WINDOW:'.STATUS','DEFPROP')
        EntryID = Get_Property(@WINDOW:'.ENTRY_ID','DEFPROP')
        
        IF CurrStatus = 'I' AND EntryID NE '' THEN
            Set_Property(@WINDOW:'.STATUS','BACKCOLOR',RED$)
            Set_Property(@WINDOW:'.STATUS.ACTIVE','BACKCOLOR',RED$)
            Set_Property(@WINDOW:'.STATUS.INACTIVE','BACKCOLOR',RED$)
            Set_Property(@WINDOW:'.STATUS.HOLD','BACKCOLOR',RED$)
        END ELSE
            DefColor = Get_Property(@WINDOW,'BACKCOLOR')
            Set_Property(@WINDOW:'.STATUS','BACKCOLOR',DefColor)
            Set_Property(@WINDOW:'.STATUS.ACTIVE','BACKCOLOR',DefColor)
            Set_Property(@WINDOW:'.STATUS.INACTIVE','BACKCOLOR',DefColor)
            Set_Property(@WINDOW:'.STATUS.HOLD','BACKCOLOR',DefColor)
        END
        
        BuriedLayer = Get_Property(@WINDOW:'.BURIED_LAYER','INVALUE')
        
        IF BuriedLayer = '' THEN
            Set_Property(@WINDOW:'.PRE_EPI_V','ENABLED',0)
            Set_Property(@WINDOW:'.POST_EPI_V','ENABLED',0)
            Set_Property(@WINDOW:'.PRE_EPI_BL','ENABLED',0)
            Set_Property(@WINDOW:'.POST_EPI_BL','ENABLED',0)
        END ELSE
            IF BuriedLayer = 1 THEN
                Set_Property(@WINDOW:'.PRE_EPI_BL','ENABLED',1)
                Set_Property(@WINDOW:'.POST_EPI_BL','ENABLED',1)
            END ELSE
                Set_Property(@WINDOW:'.PRE_EPI_V','ENABLED',1)
                Set_Property(@WINDOW:'.POST_EPI_V','ENABLED',1)
            END
        END
        
        Props = 'ENABLED':@RM:'ENABLED':@RM:'ENABLED'
        Ctrls  = @WINDOW:'.PRE_SURFSCAN_RECIPE':@RM:@WINDOW:'.PRE_SURF_DEFECTS':@RM:@WINDOW:'.PRE_SURF_HAZE'
        
        IF Get_Property(@WINDOW:'.PRE_SURFSCAN','CHECK') THEN
            Vals = '1':@RM:'1':@RM:'1'
        END ELSE
            Vals = '0':@RM:'0':@RM:'0'
        END
        Set_Property(Ctrls,Props,Vals)
        
        
        Ctrls  = @WINDOW:'.POST_SURFSCAN_RECIPE':@RM:@WINDOW:'.POST_SURF_DEFECTS':@RM:@WINDOW:'.POST_SURF_HAZE'
        
        IF Get_Property(@WINDOW:'.POST_SURFSCAN','CHECK') THEN
            Vals = '1':@RM:'1':@RM:'1'
        END ELSE
            Vals = '0':@RM:'0':@RM:'0'
        END
        Set_Property(Ctrls,Props,Vals)
        
        
        Ctrls  = @WINDOW:'.CLEAN_SURFSCAN_RECIPE':@RM:@WINDOW:'.CLEAN_SURF_DEFECTS':@RM:@WINDOW:'.CLEAN_SURF_HAZE'
        
        IF Get_Property(@WINDOW:'.CLEAN_SURFSCAN','CHECK') THEN
            Vals = '1':@RM:'1':@RM:'1'
        END ELSE
            Vals = '0':@RM:'0':@RM:'0'
        END
        Set_Property(Ctrls,Props,Vals)
        
        
        ReactorType = Get_Property(@WINDOW:'.RTYPE','VALUE')
        
        *    If ReactorType EQ 'GAN' then
        *        
        *        Ctrls  = @WINDOW:'.VERIFY_INSP_REQ':@FM         ; Props  = 'SIZE':@FM
        *        Ctrls := @WINDOW:'.PI_PARTICLE_QUAL':@FM        ; Props := 'SIZE':@FM
        *        Ctrls := @WINDOW:'.THICKFILM_MET':@FM           ; Props := 'SIZE':@FM
        *        Ctrls := @WINDOW:'.DEP_TIME_RATIO':@FM          ; Props := 'SIZE':@FM
        *        Ctrls := @WINDOW:'.SMALL_REACTOR_DELTA':@FM     ; Props := 'SIZE':@FM  
        *        Ctrls := @WINDOW:'.EXPORT_CONTROL'              ; Props := 'SIZE'
        *        
        *        For each Ctrl in Ctrls using @FM setting fPos
        *            Size = Get_Property(Ctrl, 'SIZE')
        *            xPos = Size<1>
        *            If xPos LT 440 then
        *                xPos += 400
        *                Size<1> = xPos
        *                Set_Property(Ctrl, 'SIZE', Size)
        *            end
        *        Next Ctrl
        *    end else
        *        Ctrls  = @WINDOW:'.VERIFY_INSP_REQ':@FM         ; Props  = 'SIZE':@FM
        *        Ctrls := @WINDOW:'.PI_PARTICLE_QUAL':@FM        ; Props := 'SIZE':@FM
        *        Ctrls := @WINDOW:'.THICKFILM_MET':@FM           ; Props := 'SIZE':@FM
        *        Ctrls := @WINDOW:'.DEP_TIME_RATIO':@FM          ; Props := 'SIZE':@FM
        *        Ctrls := @WINDOW:'.SMALL_REACTOR_DELTA':@FM     ; Props := 'SIZE':@FM  
        *        Ctrls := @WINDOW:'.EXPORT_CONTROL'              ; Props := 'SIZE'
        *        
        *        For each Ctrl in Ctrls using @FM setting fPos
        *            Size = Get_Property(Ctrl, 'SIZE')
        *            xPos = Size<1>
        *            If xPos GT 440 then
        *                xPos -= 400
        *                Size<1> = xPos
        *                Set_Property(Ctrl, 'SIZE', Size)
        *            end
        *        Next Ctrl
        *    end
        *    
        *    Ctrls  = @WINDOW:'.CASS_SHIP_QTY_LABEL':@RM		; Props  = 'ENABLED':@RM
        *    Ctrls := @WINDOW:'.CASS_SHIP_QTY':@RM			; Props := 'ENABLED':@RM
        *    Ctrls := @WINDOW:'.WMO_LOAD_CNT_LABEL':@RM		; Props := 'ENABLED':@RM
        *    Ctrls := @WINDOW:'.WMO_LOAD_CNT':@RM		    ; Props := 'ENABLED':@RM
        *    Ctrls := @WINDOW:'.LAYER_SPEC':@RM              ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.DATA_MAPPING':@RM            ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.LAYERTYPE':@RM               ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.GENRECIPES':@RM              ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.LBL_LAYER_TYPE':@RM          ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.LBL_GEN_RECIPE':@RM          ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PROVEIN_GROU':@RM            ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PROCESS_TIME_GROUP':@RM      ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.CEP_MAKEUP_WAFERS':@RM       ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.VERIFY_INSP_REQ':@RM         ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PI_PARTICLE_QUAL':@RM        ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.THICKFILM_MET':@RM           ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.DEP_TIME_RATIO':@RM          ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.SMALL_REACTOR_DELTA':@RM     ; Props := 'VISIBLE':@RM  
        *    Ctrls := @WINDOW:'.EXPORT_CONTROL':@RM          ; Props := 'VISIBLE':@RM    
        *    Ctrls := @WINDOW:'.LBL_MIN_PER_WFR':@RM         ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.MINUTES_PER_WAFER':@RM       ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PROVEIN_MIN_LABEL':@RM       ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PROVEIN_MIN':@RM             ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.EPI_PART_LABEL':@RM          ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.CUST_EPI_PART':@RM           ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PROD_VER_LABEL':@RM          ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PRS_STAGE_LABEL':@RM         ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.PRS_LAYER_LABEL':@RM         ; Props := 'VISIBLE':@RM
        *    Ctrls := @WINDOW:'.SPEC_BUTTON_FIX'             ; Props := 'VISIBLE'
        *    
        *    
        *    BEGIN CASE
        *        CASE ReactorType = 'HTR'
        *            Vals  = '1':@RM:'1':@RM:'0':@RM:'0':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM
        *            Vals := '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM
        *            Vals := '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1'
        *        CASE ReactorType = 'EPP'
        *            Vals  = '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM
        *            Vals := '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM
        *            Vals := '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1'
        *        CASE ReactorType = 'GAN'
        *            Vals  = '1':@RM:'1':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM
        *            Vals := '0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'1':@RM:'0':@RM
        *            Vals := '0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0':@RM:'0'
        *            ECCtrlSize = Get_Property(@Window:'.EXPORT_CONTROL', 'SIZE')
        *            
        *        CASE Otherwise$
        *            Vals  = '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM
        *            Vals := '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM
        *            Vals := '1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1':@RM:'1'
        *    END CASE
        *    
        
        Ctrls  = @WINDOW:'.CASS_SHIP_QTY_LABEL':@RM		; Props  = 'ENABLED':@RM
        Ctrls := @WINDOW:'.CASS_SHIP_QTY':@RM			; Props := 'ENABLED':@RM
        Ctrls := @WINDOW:'.WMO_LOAD_CNT_LABEL':@RM		; Props := 'ENABLED':@RM
        Ctrls := @WINDOW:'.WMO_LOAD_CNT'		        ; Props := 'ENABLED'
        
        BEGIN CASE
            CASE ReactorType = 'HTR'	; Vals = '1':@RM:'1':@RM:'0':@RM:'0'
            CASE ReactorType = 'EPP'	; Vals = '1':@RM:'1':@RM:'1':@RM:'1'
            CASE 1					    ; Vals = '1':@RM:'1':@RM:'0':@RM:'0'
        END CASE
        
        
        Set_Property(Ctrls,Props,Vals)
        
        ****************************************************************************************************
        
        // Fill Revision History Edit Table
        PSNo        = Get_Property(@Window : '.PROD_SPEC_ID', 'DEFPROP')
        RevHistRec  = Database_Services('ReadDataRow', 'PROD_SPEC_REV_HIST', PSNo)
        List = ''
        
        RevisionCol = 1
        UsernameCol = 2
        DateCol     = 3
        TimeCol     = 4
        
        For each Field in RevHistRec using @FM setting fPos
            For Each Value in Field using @VM setting vPos
                Begin Case
                    Case fPos EQ 1
                        List<vPos, UsernameCol> = Value
                    Case fPos EQ 2
                        List<vPos, DateCol> = OConv(Value, 'D2/HS')
                    Case fPos EQ 3
                        List<vPos, TimeCol> = OConv(Value, 'MTH')
                    Case fPos EQ 4
                        List<vPos, RevisionCol> = Value
                End Case
            Next Value
        Next Field
        Set_Property(@Window : '.EDT_REV_HIST', 'LIST', List)
        
        
        ****************************************************************************************************
        
        
        
        LSArray = Get_Property(@WINDOW:'.LAYER_SPEC','ARRAY')
        
        * Remove blank lines from display

        LOOP
        UNTIL LSArray[-1,1] NE @VM OR LSArray = ''
            LSArray[-1,1] = ''
        REPEAT
        
        LSKeys = Get_Property(@WINDOW:'.PRS_LAYER_KEY','ARRAY')
        
        LOOP
        UNTIL LSKeys[-1,1] NE @VM OR LSKeys = ''
            LSKeys[-1,1] = ''
        REPEAT
        
        //8-3-2020 JRO Added to bypass removing cols if we cannot detect any columns(Need this because initially when Read event is calling Refresh there are no columns to start with)
        //IF @USER4 EQ 'JONATHAN_O' then debug
        IF LSKeys<1,1> NE '' THEN
            LSCnt = COUNT(LSKeys,@VM) + (LSKeys NE '')
            
            AllProps = ''
            apCnt = 0
            
            FOR I = 1 TO LSCnt
                LSKey = LSKeys<1,I>
                LSProps = XLATE('PRS_LAYER',LSKey,PRS_LAYER_PRS_PROP_KEY$,'X')
                PropCnt = COUNT(LSProps,@VM) + (LSProps NE '')
                FOR N = 1 TO PropCnt
                    LSProp = FIELD(LSProps<1,N>,'*',3) ;* 3 part key prop code is on the end
                    LOCATE LSProp IN AllProps USING @VM SETTING Dummy ELSE
                        apCnt += 1
                        AllProps = INSERT(AllProps,1,apCnt,0,LSProp)
                    END
                NEXT N	
            NEXT I
            
            ShowCols = ''
            
            FOR I = 1 TO apCnt
                Prop = AllProps<1,I>
                BEGIN CASE
                    CASE Prop = 'THICK'		; ShowCols := COL$THICK_MIN:@VM:COL$THICK_TARG:@VM:COL$THICK_MAX:@VM:COL$THICK_UNITS:@VM
                    CASE Prop = 'THICKA'	; ShowCols := COL$THICKA_MIN:@VM:COL$THICKA_TARG:@VM:COL$THICKA_MAX:@VM:COL$THICKA_UNITS:@VM
                    CASE Prop = 'RES'		; ShowCols := COL$RES_MIN:@VM:COL$RES_TARG:@VM:COL$RES_MAX:@VM:COL$RES_UNITS:@VM
                    CASE Prop = 'SRES'		; ShowCols := COL$SRES_MIN:@VM:COL$SRES_TARG:@VM:COL$SRES_MAX:@VM:COL$SRES_UNITS:@VM
                END CASE
            NEXT I
            
            /*
                CASE Prop = 'CRES'		; ShowCols := COL$CRES_MIN:@VM:COL$CRES_MAX:@VM:COL$CRES_UNITS:@VM
                CASE Prop = 'CONC'		; ShowCols := COL$CONC_MIN:@VM:COL$CONC_MAX:@VM:COL$CONC_UNITS:@VM
                CASE Prop = 'STRESS'	; ShowCols := COL$STRESS_MIN:@VM:COL$STRESS_MAX:@VM:COL$STRESS_UNITS:@VM
                CASE Prop = 'BOW'		; ShowCols := COL$BOW_MIN:@VM:COL$BOW_MAX:@VM:COL$BOW_UNITS:@VM
                CASE Prop = 'TRANS'		; ShowCols := COL$TRANS_MIN:@VM:COL$TRANS_MAX:@VM:COL$TRANS_UNITS:@VM
                
                */
            
            IF ShowCols[-1,1] = @VM THEN ShowCols[-1,1] = ''
            
            HideCols = ''
            hcCnt = 0
            FOR I = 6 TO 21
                LOCATE I IN ShowCols USING @VM SETTING DUMMY ELSE
                    hcCnt += 1
                    HideCols<1,hcCnt> = I
                END
            NEXT I
            
            LSStyles = Send_Message(@WINDOW:'.LAYER_SPEC','COLSTYLE',0,'')
            
            scCnt = COUNT(ShowCols,@VM) + (ShowCols NE '')
            
            FOR I = 1 TO scCnt
                ShowCol = ShowCols<1,I>
                LSStyles<ShowCol> = BitAnd(LSStyles<ShowCol>,BitNot(HIDDEN$))
            NEXT I
            
            FOR I = 1 TO hcCnt
                HideCol = HideCols<1,I>
                LSStyles<HideCol> = BitOr(LSStyles<HideCol>,HIDDEN$)
            NEXT I
            
            Send_Message(@WINDOW:'.LAYER_SPEC','COLSTYLE',0,LSStyles)
            
            CtrlEntID = @WINDOW:'.PROD_VER'
            ProdVerNos = Get_Property(CtrlEntID,'ARRAY')<COL$PROD_VER_NO>
            
            LOOP
                TestChar = ProdVerNos[-1,1]
            UNTIL TestChar NE @VM OR TestChar = ''			;* Strip off trailing @VM's 
                ProdVerNos[-1,1] = ''
            REPEAT
            
            LastRow = COUNT(ProdVerNos,@VM) + (ProdVerNos NE '')
            
            IF LastRow = 0 THEN LastRow = 1
            
            CurrPos = Get_Property(CtrlEntID,'SELPOS')
            CurrCol = CurrPos<1>
            
            Set_Property(CtrlEntID,'SELPOS',CurrCol:@FM:LastRow)
            
        END
        GOSUB ProdVerPC:
        
        ****************************************************
        
        
        * 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 'PROD_SPEC.LAYER_SPEC' AND ETCtrl NE 'PROD_SPEC.PROD_VER' THEN
                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 Line
            END
        NEXT I
        
        
        SpecCtrl = @WINDOW:'.LAYER_SPEC'
        LSList = Get_Property(SpecCtrl,'LIST')
        LSCnt = COUNT(LSList,@FM) + (LSList NE '')
        
        FOR Line = 1 TO LSCnt
            BEGIN CASE
                CASE LSList<Line,COL$LS_ID> = 'L1'	; LineColor = LS1_GREEN$
                CASE LSList<Line,COL$LS_ID> = 'L2'	; LineColor = LS2_GREEN$
                CASE LSList<Line,COL$LS_ID> = 'L3'	; LineColor = LS3_GREEN$
                CASE NUM(LSList<Line,COL$LS_ID>)	; LineColor = CMB_YELLOW$
                CASE 1 ;LineColor = WHITE$
            END CASE
            stat = Send_Message(SpecCtrl,'COLOR_BY_POS',0,Line,LineColor)
        NEXT Line
        
        GOSUB CepPC
        
        
        PVCtrl = @WINDOW:'.PROD_VER'
        PVList = Get_Property(PVCtrl,'LIST')
        
        PVCnt = COUNT(PVList,@FM) + (PVList NE '')
        
        FOR Line = 1 TO PVCnt
            
            LineStatus = PVList<Line,COL$STATUS>
            
            BEGIN CASE
                CASE LineStatus = 'A'	;	LineColor = GREEN$
                CASE LineStatus = 'I'	;	LineColor = RED$
                CASE 1					;	LineColor = GREEN$
                    
            END CASE
            stat = Send_Message(PVCtrl,'COLOR_BY_POS',0,Line,LineColor)
            
        NEXT Line
        
        Set_Property(@Window:'.DUP_PSN', 'ENABLED', True$)
        
    end else
        Set_Property(@Window:'.DUP_PSN', 'ENABLED', False$)
    end
	
RETURN


* * * * * * *
Page:
* * * * * * *
	
	Page = Parm1
	
	IF Page = '' THEN
		Page = Get_Property(@WINDOW:'.TAB_MAIN','VALUE')
	END ELSE
		Set_Property(@WINDOW:'.TAB_MAIN','VALUE',Page)
	END
	
	Set_Property(@WINDOW,'VPOSITION', Page)
	
	GOSUB Refresh
	
RETURN


* * * * * * *
Read:
* * * * * * *

    Set_Property(@WINDOW:'.TAB_MAIN','VALUE',1)
    Send_Event(@WINDOW,'PAGE',1)
    GOSUB Refresh

RETURN


* * * * * * *
Clear:
* * * * * * *
	
	Set_Property(@WINDOW:'.TAB_MAIN','VALUE',1)
	
	Send_Event(@WINDOW,'PAGE',1)
	
	GOTO Refresh
	
RETURN


* * * * * *
SurfScanClick:
* * * * * *
	
	CurrCtrl = Parm1
	
	PrePostClean = CurrCtrl[-1,'B.']
	PrePostClean = PrePostClean[1,'_']
	
	IF Get_Property( @WINDOW:'.':PrePostClean:'_SURFSCAN', 'CHECK' ) THEN
		Set_Property( @WINDOW:'.':PrePostClean:"_SURFSCAN_RECIPE", "ENABLED", 1 )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURF_DEFECTS", "ENABLED", 1 )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURF_HAZE", "ENABLED", 1 )                  
	END ELSE
		Set_Property( @WINDOW:'.':PrePostClean:"_SURFSCAN_RECIPE", "TEXT", '' )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURF_DEFECTS", "TEXT", '' )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURF_HAZE", "TEXT", '' )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURFSCAN_RECIPE", "ENABLED", 0 )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURF_DEFECTS", "ENABLED", 0 )
		Set_Property( @WINDOW:'.':PrePostClean:"_SURF_HAZE", "ENABLED", 0 )      
	END
	
RETURN


* * * * * * *
LoadSurfScanDefaults:
* * * * * * * 
	
	PreCtrls  = @WINDOW:'.PRE_PITS':@RM				; PreProps  = 'INVALUE':@RM		; PreVirginVals  = '1':@RM		; PreBLVals  = '10':@RM
	PreCtrls := @WINDOW:'.PRE_MOUNDS':@RM			; PreProps := 'INVALUE':@RM		; PreVirginVals := '1':@RM		; PreBLVals := '10':@RM
	PreCtrls := @WINDOW:'.PRE_BL_DEFECTS':@RM		; PreProps := 'INVALUE':@RM		; PreVirginVals := '1':@RM		; PreBLVals := '10':@RM
	PreCtrls := @WINDOW:'.PRE_SPOTS':@RM			; PreProps := 'INVALUE':@RM		; PreVirginVals := '1':@RM		; PreBLVals := '5':@RM
	PreCtrls := @WINDOW:'.PRE_FOV':@RM				; PreProps := 'INVALUE':@RM		; PreVirginVals := '1':@RM		; PreBLVals := '2':@RM
	PreCtrls := @WINDOW:'.PRE_SCRATCHES':@RM		; PreProps := 'INVALUE':@RM		; PreVirginVals := '1':@RM		; PreBLVals := '1':@RM
	PreCtrls := @WINDOW:'.PRE_SCRATCH_LEN':@RM		; PreProps := 'INVALUE':@RM		; PreVirginVals := '1':@RM		; PreBLVals := '1':@RM
	PreCtrls := @WINDOW:'.PRE_LPD':@RM				; PreProps := 'INVALUE':@RM		; PreVirginVals := '10':@RM		; PreBLVals := '10':@RM
	PreCtrls := @WINDOW:'.PRE_MICROSCOPE':@RM		; PreProps := 'INVALUE':@RM		; PreVirginVals := '0':@RM		; PreBLVals := '1':@RM
	PreCtrls := @WINDOW:'.PRE_BRIGHTLIGHT'			; PreProps := 'INVALUE'			; PreVirginVals := '1'			; PreBLVals := '1'
	
	PostCtrls  = @WINDOW:'.POST_PITS':@RM			; PostProps  = 'INVALUE':@RM	; PostVirginVals  = '1':@RM		; PostBLVals  = '20':@RM
	PostCtrls  = @WINDOW:'.POST_MOUNDS':@RM			; PostProps := 'INVALUE':@RM	; PostVirginVals := '1':@RM		; PostBLVals := '20':@RM
	PostCtrls := @WINDOW:'.POST_BL_DEFECTS':@RM		; PostProps := 'INVALUE':@RM	; PostVirginVals := '1':@RM		; PostBLVals := '20':@RM
	PostCtrls := @WINDOW:'.POST_STACK_FAULTS':@RM	; PostProps := 'INVALUE':@RM	; PostVirginVals := '20':@RM	; PostBLVals := '20':@RM
	PostCtrls := @WINDOW:'.POST_SPOTS':@RM			; PostProps := 'INVALUE':@RM	; PostVirginVals := '1':@RM		; PostBLVals := '1':@RM
	PostCtrls := @WINDOW:'.POST_FOV':@RM			; PostProps := 'INVALUE':@RM	; PostVirginVals := '1':@RM		; PostBLVals := '1':@RM
	PostCtrls := @WINDOW:'.POST_SPIKES':@RM			; PostProps := 'INVALUE':@RM	; PostVirginVals := '5':@RM		; PostBLVals := '5':@RM
	PostCtrls := @WINDOW:'.POST_SCRATCHES':@RM		; PostProps := 'INVALUE':@RM	; PostVirginVals := '2':@RM		; PostBLVals := '1':@RM
	PostCtrls := @WINDOW:'.POST_SCRATCH_LEN':@RM	; PostProps := 'INVALUE':@RM	; PostVirginVals := '1':@RM		; PostBLVals := '1':@RM
	PostCtrls := @WINDOW:'.POST_LPD':@RM			; PostProps := 'INVALUE':@RM	; PostVirginVals := '20':@RM	; PostBLVals := '20':@RM
	PostCtrls := @WINDOW:'.POST_MICROSCOPE':@RM		; PostProps := 'INVALUE':@RM	; PostVirginVals := '1':@RM		; PostBLVals := '1':@RM
	PostCtrls := @WINDOW:'.POST_BRIGHTLIGHT'		; PostProps := 'INVALUE'		; PostVirginVals := '1'			; PostBLVals := '1'	
	
	CurrButton = Parm1[-1,'B.']
	
	BEGIN CASE
		CASE CurrButton = 'PRE_EPI_V'
			Ctrls	= PreCtrls
			Props	= PreProps
			Vals	= PreVirginVals
			MsgText = ' Pre Epi Virgin'
			
		CASE CurrButton = 'PRE_EPI_BL'
			Ctrls	= PreCtrls
			Props	= PreProps
			Vals	= PreBLVals
			MsgText = ' Pre Epi Buried Layer'
			
		CASE CurrButton = 'POST_EPI_V'
			Ctrls	= PostCtrls
			Props	= PostProps
			Vals	= PostVirginVals
			MsgText	= 'Post Epi Virgin'
			
		CASE CurrButton = 'POST_EPI_BL'
			Ctrls	= PostCtrls
			Props	= PostProps
			Vals	= PostBLVals
			MsgText	= 'Post Epi Buried Layer'
			
	END CASE
	
	CurrVals = Get_Property(Ctrls,Props)
	
	CONVERT @RM TO '' IN CurrVals
	
	Response = 1
	IF LEN(TRIM(CurrVals)) AND CurrVals NE 0 THEN
		
		MsgInfo = ''
		MsgText = 'There is already data in the':MsgText:'section...':CrLf$:'Do you wish to overwrite with the standards?'
		MsgInfo<MTEXT$> = MsgText
		MsgInfo<MICON$> = '?'
		MsgInfo<MTYPE$> = 'BNY'
		Response = Msg( @WINDOW, MsgInfo )
	END
	
	IF Response THEN
		Set_Property(Ctrls,Props,Vals)
		IF CurrButton = 'POST_EPI_BL' THEN
			Set_Property( @WINDOW:'.CLEAN_BRIGHTLIGHT', 'INVALUE', 1 )
		END
	END
	
RETURN


* * * * * * *
LUTestPointMap:
* * * * * * *
	
	MapKey = Popup(@WINDOW,'','TEST_POINT_MAP')
	
	IF MapKey NE '' THEN
		Set_Property(@WINDOW:'.TEST_POINT_MAP','DEFPROP',MapKey)
		Send_Event(@WINDOW:'.TP_MAP_DESC','CALCULATE')
	END
	
RETURN


* * * * * * *
StatusClick:
* * * * * * *
	
	ReactorType	= Get_Property(@WINDOW:'.RTYPE','DEFPROP')
	PSNo		= Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	OldStatus   = XLATE('PROD_SPEC', PSNo, PROD_SPEC_STATUS$ ,'X')
	NewStatus	= Get_Property(@WINDOW:'.STATUS','DEFPROP')
	
	CtrlID = @WINDOW:'.MODE_CODE'
	
	ModeArray = Get_Property(CtrlID,'DEFPROP')
	
	ActivationAllowed = FALSE$
	
	BEGIN CASE
		CASE ModeArray<COL$MODE_SIG,4> NE ''
		    ActivationAllowed = TRUE$
		CASE ModeArray<COL$MODE_SIG,3> NE ''
		    ActivationAllowed = TRUE$
		CASE ModeArray<COL$MODE_SIG,2> NE ''
		    ActivationAllowed = TRUE$
		CASE ModeArray<COL$MODE_SIG,1> NE ''
		    ActivationAllowed = FALSE$
		    Error_Services('Add', 'Both the Pre Qual and the Qual signatures must be signed in order for the PSN to be activated.')
		CASE 1
		    ActivationAllowed = FALSE$
		    Error_Services('Add', 'Both the Pre Qual and the Qual signatures must be signed in order for the PSN to be activated.')
	END CASE
	
	IF PSNo = '' THEN RETURN
	If NewStatus NE OldStatus then
		IF NewStatus = 'I' THEN
		
			MsgInfo         = ''
			MsgInfo<mtype$> = 'BNY'
			MsgInfo<micon$> = '?'
			MsgInfo<mtext$> = 'Inactivating this PSN will clear the signatures...Do you wish to continue???'
			
			Resp = msg( '', MsgInfo )
			
			IF Resp THEN
				
				ModeArray = Get_Property(@WINDOW:'.MODE_CODE','DEFPROP')
				ModeArray<COL$MODE_SIG> = STR(@VM,3)			;* Clears Mode Signatures		8/22/2012 JCH
				ModeArray<COL$MODE_SIG_DTM> = STR(@VM,3)		;* Clears Mode Sig Timestamps	8/22/2012 JCH
				Set_Property(@WINDOW:'.MODE_CODE','DEFPROP',ModeArray)
				
				* From here down goes away
				
				SpecEpi = Get_Property(@WINDOW:'.SPEC_EPI','TEXT')
				SpecEpi<1,QSEpiRecipe$>		= '' 		;* Clear the recipe number
				SpecEpi<1,QSEpiRecipeName$>	= ''		;* and name
				Set_Property(@WINDOW:'.SPEC_EPI','TEXT',SpecEpi)
				SpecAddtl = Get_Property(@WINDOW:'.SPEC_ADDL','TEXT')		;* Clear signatures'
				
				Set_Property(@WINDOW:'.SPEC_ADDL','TEXT',SpecAddtl)
				SpecSub = Get_Property(@WINDOW:'.SPEC_SUBSTRATE','TEXT')
				SpecSub<1,QSSubSpecType$> = ''								;* Clear Spec Type
				Set_Property(@WINDOW:'.SPEC_SUBSTRATE','TEXT',SpecSub)
				
				* Call Auto-NCR form to provide the user an easy way to automatically NCR all makeup wafers
				* associated with the now inactivated PSN.
				
				Dialog_Box( 'NDW_MAKEUP_WAFER_NCR', @WINDOW, PSNo)
				If Error_Services('HasError') then
					ErrorMessage = 'An errror occurred during the Automatic NCR process for PSN '
					Error = Error_Services('GetMessage')
					ErrMsg(ErrorMessage : PSNo : @SVM : 'Please notify OpenInsight administrator. Error message:':Error)
				end
					CurrDate = OCONV(Date(),'D4/')
                    CurrTime = OCONV(Time(),'MTHS')
                    CurrDTM = CurrDate:' ':CurrTime
                    
                    
                    LogData    = ''
                    LogData<1> = CurrDTM
                    LogData<2> = @USER4
                    LogData<3> = PSNo
                    LogData<4> = 'Inactivate PSN ' : PSNo
                    Logging_Services('AppendLog', objPSNLog, LogData, @RM, @FM, False$)
			END ELSE
				If OldStatus EQ 'A' then
					Set_Property(@WINDOW:'.STATUS','VALUE','A')
				end else
					Set_Property(@WINDOW:'.STATUS','VALUE',OldStatus)
				end
				
				RETURN
				
			END
			
			*   Code deprecated on 03/11/19 - DJS
			* 	IF ReactorType = 'EPP' THEN
			*		
			*		OPEN 'DICT.WM_OUT' TO DictVar ELSE
			*			ErrMsg('Unable to open DICT.WM_OUT in COMM_WM_OUT.')
			*		END
			* 
			*		SearchString  = 'MU_PS_NO':@VM:PSNo:@FM
			* 
			*		Set_Status(0)
			* 
			*		MUWMOutIDs = ""
			*		Option = ""
			*		Flag = ""
			*		Btree.Extract(SearchString, 'WM_OUT', DictVar, MUWMOutIDs, option, flag)
			* 
			*		IF Get_Status(errCode) THEN ErrMsg(errCode)
			*		
			*		AvailMU_WOMatKeys = MUWMOutIDs
			* 
			* 	END ELSE
			* 
			*		TableName = 'WO_MAT'
			*		
			*		OPEN 'DICT.':TableName TO DictVar ELSE
			*			ErrMsg('Unable to open DICT.':TableName:' in obj_MUWafers.')
			*			
			*			RETURN
			*		END
			*		
			*		SearchString  = 'MU_PS_NO':@VM:PSNo:@FM
			*		SearchString := 'CURR_STATUS':@VM:'RTU':@FM
			*			
			*		Set_Status(0)
			* 
			*		OpenRecordIDs = ""
			*		Option = ""
			*		Flag = ""
			*		Btree.Extract(SearchString, TableName, DictVar, OpenRecordIDs, option, flag)
			* 
			*		IF Get_Status(errCode) THEN ErrMsg(errCode)
			* 
			*		AvailMU_WOMatKeys = OpenRecordIDs
			*				
			* 	END
			* 
			* 	TypeOver = ''
			* 	TypeOver<PDISPLAY$> = AvailMU_WOMatKeys
			* 	TypeOver<PSELECT$> = 0
			* 	TypeOver<PPrintable$> = 1
			* 
			* 	Dummy = Popup(@WINDOW,TypeOver,'WO_MAT_MAKEUP')
		END
		
		//Activation Parameters Check JRO - 2-24-2021
		IF NewStatus = 'A' then
		    If ActivationAllowed EQ TRUE$ then
                Error_Services('Clear')
                MsgStruct = "" 
                MsgStruct<MTEXTWIDTH$> = MSG_WIDTH$
                GoSub ReactorVerification
                If Error_Services('NoError') then
                    GoSub SpecVerification
                end
                If Error_Services('NoError') then
                    GoSub ProdVerVerification
                end
                If Error_Services('NoError') then
                    GoSub StageVerification
                    CurrDate = OCONV(Date(),'D4/')
                    CurrTime = OCONV(Time(),'MTHS')
                    CurrDTM = CurrDate:' ':CurrTime
                    
                    
                    LogData    = ''
                    LogData<1> = CurrDTM
                    LogData<2> = @USER4
                    LogData<3> = PSNo
                    LogData<4> = 'Activate PSN ' : PSNo
                    Logging_Services('AppendLog', objPSNLog, LogData, @RM, @FM, False$)
                end
			end else
			    Set_Property(@WINDOW:'.STATUS','DEFPROP', OldStatus)
			    Error = Error_Services('GetMessage')
				ErrMsg(Error)
			end
		end
	end else
		Set_Property(@WINDOW:'.STATUS','DEFPROP', OldStatus)
	end
	
    
RETURN


* * * * * * *
LUEpiPart:
* * * * * * *
	
	TypeOver = ''
	TypeOver<PSELECT$> = 1
	
	EpiPartNo = Popup(@WINDOW,TypeOver,'EPI_PART_NOS')
	
	IF EpiPartNo NE '' THEN
		obj_AppWindow('LUValReturn',@WINDOW:@RM:@WINDOW:'.EPI_PART_NO')
	END
	
RETURN


* * * * * * *
ViewEpiPart:
* * * * * * *
	
	EpiPartNo = Get_Property(@WINDOW:'.CEP_EPI_PART_NO','DEFPROP')
	
	IF EpiPartNo = '' THEN RETURN
	
	obj_AppWindow('ViewRelated','EPI_PART':@RM:EpiPartNo)
	
	Set_Property('EPI_PART.TAB_CONTROL','VALUE',3)
	
	Send_Event('EPI_PART.TAB_CONTROL','CLICK')
	
RETURN


* * * * * * *
ViewCust:
* * * * * * *
	
	CustNo = Get_Property(@WINDOW:'.CEP_CUST_NO','DEFPROP')
	
	IF CustNo = '' THEN RETURN
	
	obj_AppWindow('ViewRelated','CUSTOMER_EPI':@RM:CustNo)
	
RETURN


* * * * * * *
ViewCustEpiPart:
* * * * * * *
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	CtrlEntID = @WINDOW:'.CEP_KEYS'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	CEPKey	= Get_Property(CtrlEntID,'CELLPOS',COL$CEP_KEY:@FM:CurrRow)
	
	IF CEPKey NE '' THEN
		
		Send_Event(@WINDOW,'WRITE')
		
		DetWindow	= 'CUST_EPI_PART'
		DetKeys		= CEPKey
		DefaultRec	= ''
		RetKey		= PSNo
		RetPage		= 2
		RetCtrl		= @WINDOW:'.CEP_KEYS'
		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
	
RETURN


* * * * * * *
ProdVerDC:
* * * * * * *
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	
	CtrlEntID = @WINDOW:'.PROD_VER'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	
	IF CurrCol = COL$PROD_VER_NO THEN
		ProdVerNo = Get_Property(CtrlEntID,'CELLPOS',COL$PROD_VER_NO:@FM:CurrRow)
		
		IF PSNo NE '' THEN
			
			Send_Event(@WINDOW,'WRITE')
			
			DetWindow	= 'PROD_VER'
			DetKeys		= ProdVerNo
			DefaultRec	= ''
			RetKey		= PSNo
			RetPage		= 2
			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
	
	
	IF CurrCol = COL$EPI_PART_NO THEN
		EpiPN = Get_Property(CtrlEntID,'CELLPOS',COL$EPI_PART_NO:@FM:CurrRow)
		
		IF PSNo NE '' THEN
			
			Send_Event(@WINDOW,'WRITE')
			
			DetWindow	= 'EPI_PART'
			DetKeys		= EpiPN
			DefaultRec	= ''
			RetKey		= PSNo
			RetPage		= 2
			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
	
	
	IF CurrCol = COL$CUST_NO THEN
		EpiPN	= Get_Property(CtrlEntID,'CELLPOS',COL$EPI_PART_NO:@FM:CurrRow)
		CustNo	= Get_Property(CtrlEntID,'CELLPOS',COL$CUST_NO:@FM:CurrRow)
		
		IF EpiPN NE '' AND CustNo NE '' AND PSNo NE '' THEN
			
			Send_Event(@WINDOW,'WRITE')
			
			DetWindow	= 'CUST_EPI_PART'
			DetKeys		= CustNo:'*':EpiPN
			DefaultRec	= ''
			RetKey		= PSNo
			RetPage		= 2
			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 of check for all parameters needed
	END
	
	
RETURN


* * * * * * *
ProdVerPC:
* * * * * * *
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	
	CtrlEntID = @WINDOW:'.PROD_VER'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	ProdVerNo	= Get_Property(CtrlEntID,'CELLPOS',COL$PROD_VER_NO:@FM:CurrRow)
	EpiPN		= Get_Property(CtrlEntID,'CELLPOS',COL$EPI_PART_NO:@FM:CurrRow)
	CustNo		= Get_Property(CtrlEntID,'CELLPOS',COL$CUST_NO:@FM:CurrRow)
	
	CEPKey = CustNo:'*':EpiPN
	
	CEPKeys = Get_Property(@WINDOW:'.CEP_KEYS','ARRAY')<COL$CEP_KEY>
	
	LOCATE CEPKey IN CEPKeys USING @VM SETTING Pos THEN
		Set_Property(@WINDOW:'.CEP_KEYS','SELPOS',COL$CEP_KEY:@FM:Pos)
	END
	
RETURN


* * * * * * *
QAStagePC:
* * * * * * *
	
RETURN

* Can be removed after test of the PRS_STAGE window dropdowns JCH * * * * * * ** * * 

PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')

IF PSNo = '' THEN RETURN

* Get Last Layer No

LayerNos = Get_Property(@WINDOW:'.LAYER_SPEC','DEFPROP')<COL$LAYER>

LOOP
	LayerNo = LayerNos[-1,'B':@VM]
UNTIL LayerNo NE ''
	LayerNos[COL1(),5] = ''
REPEAT


CtrlEntID = @WINDOW:'.QA_STAGE'
CurrPos = Get_Property(CtrlEntID,'SELPOS')
CurrCol = CurrPos<1>
CurrRow = CurrPos<2>

CurrLine = Get_Property(CtrlEntID,'LIST')<CurrRow>

DefProp = ''
BEGIN CASE
	
	CASE CurrCol = COL$QA_MET_MIN AND CurrLine<1,COL$QA_MET_MIN> = ''
		MetTest = CurrLine<1,COL$QA_MET_TEST>
		
		BEGIN CASE
			CASE MetTest = 'THICK_ONLY' OR MetTest = 'ADE'
				
				DefProp = XLATE('PRS_PROP',PSNo:'*':LayerNo:'*THICK',PRS_PROP_RAW_MIN$,'X')
				
			CASE MetTest = 'LW_RHO' 
				
				Units = OHMS_SQUARE$	;* Resistivity units for 'ohms square' (see Metrology_Units popup)
				EpiProps = XLATE('PRS_PROP',PSNo:'*':LayerNo:'*RES','','X')
				IF EpiProps<PRS_PROP_UNITS_ORG$> = OHMS_SQUARE$ THEN
					DefProp = EpiProps<PRS_PROP_RAW_MIN$>
				END
				
			CASE MetTest = 'SRP'
				
				DefProp = XLATE('PRS_PROP',PSNo:'*':LayerNo:'*CONC',PRS_PROP_RAW_MIN$,'X')
				
		END CASE
		
	CASE CurrCol = = COL$QA_MET_MAX AND CurrLine<1,COL$QA_MET_MAX> = ''
		
		MetTest = CurrLine<1,COL$QA_MET_TEST>
		
		BEGIN CASE
			CASE MetTest = 'THICK_ONLY' OR MetTest = 'ADE'
				DefProp = XLATE('PRS_PROP',PSNo:'*':LayerNo:'*THICK',PRS_PROP_RAW_MAX$,'X')
				
			CASE MetTest = 'LW_RHO' 
				Units = OHMS_SQUARE$	;* Resistivity units for 'ohms square' (see Metrology_Units popup)
				EpiProps = XLATE('PRS_PROP',PSNo:'*':LayerNo:'*RES','','X')
				IF EpiProps<PRS_PROP_UNITS_ORG$> = OHMS_SQUARE$ THEN
					DefProp = EpiProps<PRS_PROP_RAW_MAX$>
				END
				
			CASE MetTest = 'SRP'
				
				DefProp = XLATE('PRS_PROP',PSNo:'*':LayerNo:'*CONC',PRS_PROP_RAW_MAX$,'X')
				
			CASE 1
				
		END CASE
		
END CASE


IF DefProp NE '' THEN
	Set_Property(CtrlEntId,"CELLPOS",DefProp,CurrCol:@FM:CurrRow)
END

RETURN


* * * * * * *
MetTestLF:
* * * * * * *
	
RETURN

** This needs moved to the PRS_STAGE window JCH 3/16/2015

PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')

IF PSNo = '' THEN RETURN

CtrlEntID	= @WINDOW:'.QA_STAGE'
MetList		= Get_Property(CtrlEntID,'LIST')

OrgRec = XLATE('PROD_SPEC',PSNo,'','X')

LOOP
	TestLine = MetList[-1,'B':@FM]
UNTIL TestLine<1,COL$QA_MET_TEST> NE '' OR MetList = ''
	MetList[COL1(),199] = ''
REPEAT

CurrArray = ''
LineCnt = COUNT(MetList,@FM) + (MetList NE '')

FOR Line = 1 TO LineCnt
	CurrArray<1,Line> 	= MetList<Line,COL$QA_MET_TEST>
	CurrArray<3,Line>	= MetList<Line,COL$MET_MIN>
	CurrArray<4,Line>	= MetList<Line,COL$MET_MAX>
	CurrArray<5,Line>	= MetList<Line,COL$MET_SLOT>
	CurrArray<6,Line>	= MetList<Line,COL$MET_INTERVAL>
	CurrArray<7,Line>	= MetList<Line,COL$MET_START>
NEXT Line

Delta = 0

IF OrgRec<PROD_SPEC_MET_TEST$>		NE CurrArray<1>	THEN Delta = 1
IF OrgRec<PROD_SPEC_MET_INTERVAL$>	NE CurrArray<6> THEN Delta = 1
IF OrgRec<PROD_SPEC_MET_START$>		NE CurrArray<7>	THEN Delta = 1
IF OrgRec<PROD_SPEC_MET_SLOT$>		NE CurrArray<5>	THEN Delta = 1
IF OrgRec<PROD_SPEC_MET_RUN_STEP$>	NE CurrArray<2>	THEN Delta = 1
IF OrgRec<PROD_SPEC_MET_MIN$>		NE CurrArray<3>	THEN Delta = 1
IF OrgRec<PROD_SPEC_MET_MAX$>		NE CurrArray<4>	THEN Delta = 1

/*
IF Delta THEN

	DEBUG
	
	MsgHead	= 'QA Metrology changed'
	MsgText	= 'Do you wish to update in process WO Material with the new QA Met specification?'

	OK = Msg(@WINDOW,'','YESNO','',MsgHead:@FM:MsgText)

	IF OK = 1 THEN
		OPEN 'DICT.WO_MAT' TO DictVar ELSE
			ErrMsg('Unable to open "DICT.WO_MAT" for Btree.Extract')
			RETURN
		END
		
		Search	 = 'SAP_BATCH_NO':@VM:'=':@FM				;* SAP_BATCH_NO = null
		Search	:= 'WO_STEP_PS_NO':@VM:'[':PSNo:']':@FM		;* WO_STEP_PS_NO contains PSNo
		Options  = ''
		Flag 	 = ''
		
		Btree.Extract(Search,'WO_MAT',DictVar,WOMatKeys,Options,Flag)
		
		IF Get_Status(errCode) THEN
			ErrMsg(errCode)
			RETURN
		END
	
		DEBUG
	END

END	;* End of check for delta
*/

RETURN


* * * * * * *
LayerSpecDC:
* * * * * * * 
	
	
	IF MemberOf(@USER4, 'OI_SUPERUSER') ELSE RETURN
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	CtrlEntID = @WINDOW:'.LAYER_SPEC'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	
	IF CurrCol = COL$LAYER THEN
		LayerNo = Get_Property(CtrlEntID,'CELLPOS',COL$LAYER:@FM:CurrRow)
		
		IF PSNo NE '' THEN
			
			
			Send_Event(@WINDOW,'WRITE')
			
			DetWindow	= 'PRS_LAYER'
			DetKeys		= PSNo:'*':LayerNo
			DefaultRec	= ''
			RetKey		= PSNo
			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 LayerNo Column
	
	
RETURN


* * * * * * *
StageSpecDC:
* * * * * * * 
	
	If MemberOf(@USER4,'ENGINEERING') OR MemberOf(@USER4,'CONFIG_LIMITED') Else
		ErrMsg('You must be authorized to change the specification.')
		Return
	END
	
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	CtrlEntID = @WINDOW:'.STAGE_SPEC'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>

	IF CurrCol = COL$STAGE THEN
		Stage = Get_Property(CtrlEntID,'CELLPOS',COL$STAGE:@FM:CurrRow)
		
		IF PSNo NE '' THEN
			
			Send_Event(@WINDOW,'WRITE')
			
			DetWindow	= 'PRS_STAGE'
			DetKeys		= PSNo:'*':Stage
			DefaultRec	= ''
			RetKey		= PSNo
			RetPage		= 5
			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 Stage Column
	
	
RETURN


* * * * * * *
SignNextMode:
* * * * * * *
	
	CtrlID = @WINDOW:'.MODE_CODE'
	
	ModeArray = Get_Property(CtrlID,'DEFPROP')
	
	Qualified = FALSE$
	
	BEGIN CASE
		CASE ModeArray<COL$MODE_SIG,4> NE ''	; NextSigPos = ''
		CASE ModeArray<COL$MODE_SIG,3> NE ''	; NextSigPos = 4	; NextMode = ModeArray<COL$MODE_CODE,4>
		CASE ModeArray<COL$MODE_SIG,2> NE ''	; NextSigPos = 3	; NextMode = ModeArray<COL$MODE_CODE,3>
		CASE ModeArray<COL$MODE_SIG,1> NE ''	; NextSigPos = 2	; NextMode = ModeArray<COL$MODE_CODE,2>
		CASE 1									; NextSigPos = 1	; NextMode = ModeArray<COL$MODE_CODE,1>
	END CASE
	
	BEGIN CASE
		CASE NextSigPos = 4
		    SigStage = 'PSN_PROD'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE NextSigPos = 3
		    SigStage = 'PSN_PRE_PROD'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE NextSigPos = 2
		    SigStage = 'PSN_QUAL'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE NextSigPos = 1
		    SigStage = 'PSN_PRE_QUAL'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE 1	; Qualified = FALSE$
	END CASE
    
	
	If Qualified EQ TRUE$ THEN
		Valid = Dialog_Box('NDW_VERIFY_USER', @Window, @User4)
        Valid = Valid<1>
	END ELSE
		ErrorMsg = 'Current user is not an authorized ':NextMode:' signer.'
		ErrMsg(ErrorMsg)
		RETURN
	END
	
	IF Valid = 1 THEN
		CurrDate = OCONV(Date(),'D4/')
		CurrTime = OCONV(Time(),'MTHS')
		CurrDTM = CurrDate:' ':CurrTime
		
		Set_Property(CtrlID,'CELLPOS',@USER4,COL$MODE_SIG:@FM:NextSigPos)
		Set_Property(CtrlID,'CELLPOS',CurrDTM,COL$MODE_SIG_DTM:@FM:NextSigPos)
	
        PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
        
        Send_Event(@WINDOW,'WRITE')
        
        obj_Appwindow('LUValReturn',PSNo:@RM:@WINDOW:'.PROD_SPEC_ID')
        
        LogData    = ''
        LogData<1> = CurrDTM
        LogData<2> = @USER4
        LogData<3> = PSNo
        LogData<4> = 'Sign ' : SigStage
        Logging_Services('AppendLog', objPSNLog, LogData, @RM, @FM, False$)
	End
	
RETURN


* * * * * * *
UnsignCurrMode:
* * * * * * *
	
	CtrlID = @WINDOW:'.MODE_CODE'
	
	ModeArray = Get_Property(CtrlID,'DEFPROP')
	
	Qualified = FALSE$
	
	BEGIN CASE
		CASE ModeArray<COL$MODE_SIG,4> NE ''	; UnsigPos = 4		; UnsignMode = ModeArray<COL$MODE_CODE,4>
		CASE ModeArray<COL$MODE_SIG,3> NE ''	; UnsigPos = 3		; UnsignMode = ModeArray<COL$MODE_CODE,3>
		CASE ModeArray<COL$MODE_SIG,2> NE ''	; UnsigPos = 2		; UnsignMode = ModeArray<COL$MODE_CODE,2>
		CASE ModeArray<COL$MODE_SIG,1> NE ''	; UnsigPos = 1		; UnsignMode = ModeArray<COL$MODE_CODE,1>
		CASE 1									; UnsigPos = ''
	END CASE
	
	BEGIN CASE
		CASE UnSigPos = 4
		    SigStage = 'PSN_PROD'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE UnSigPos = 3
		    SigStage = 'PSN_PRE_PROD'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE UnSigPos = 2
		    SigStage = 'PSN_QUAL'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE UnSigPos = 1
		    SigStage = 'PSN_PRE_QUAL'
		    Qualified =  (MemberOf(@USER4,SigStage)) 
		CASE 1	; Qualified = FALSE$
	END CASE
	
	If Qualified EQ TRUE$ THEN
		Valid = Dialog_Box('NDW_VERIFY_USER', @Window, @User4)
        Valid = Valid<1>
	END ELSE
		ErrorMsg = 'Current user is not an authorized ':UnsignMode:' signer.'
		ErrMsg(ErrorMsg)
		RETURN
	END
	
	
	IF Valid = 1 THEN
	    PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
		CurrDate = OCONV(Date(),'D4/')
		CurrTime = OCONV(Time(),'MTHS')
		CurrDTM = CurrDate:' ':CurrTime
		
		Set_Property(CtrlID,'CELLPOS','',COL$MODE_SIG:@FM:UnsigPos)
		Set_Property(CtrlID,'CELLPOS','',COL$MODE_SIG_DTM:@FM:UnsigPos)
		
		LogData    = ''
        LogData<1> = CurrDTM
        LogData<2> = @USER4
        LogData<3> = PSNo
        LogData<4> = 'UnSign ' : SigStage
        Logging_Services('AppendLog', objPSNLog, LogData, @RM, @FM, False$)
	END
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	Send_Event(@WINDOW,'WRITE')
	
	obj_Appwindow('LUValReturn',PSNo:@RM:@WINDOW:'.PROD_SPEC_ID')
	
	
RETURN


* * * * * *
NewStage:
* * * * * * 
	
	StageArray	= Get_Property(@WINDOW:'.STAGE_SPEC','ARRAY')
	PSNo		= Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	CurrStages = StageArray<COL$STAGE>
	
	LOOP
	UNTIL CurrStages[-1,1] NE @VM
		CurrStages[-1,1] = ''
	REPEAT
	
	CurrStageCnt = COUNT(CurrStages,@VM) + (CurrStages NE '')
	
	PopupID = @APPID<1>:'**STAGE'
	PopupLiteral = XLATE('SYSREPOSPOPUPS',PopupID,PDISPLAY$,'X')
	
	CONVERT @VM:@SVM TO @FM:@VM IN PopupLiteral
	
	LOOP
		CurrStage = CurrStages[1,@VM]
		
	UNTIL CurrStage = ''
		Done = 0
		PopCnt = COUNT(PopupLiteral,@FM) + (PopupLiteral NE '')
		FOR I = 1 TO PopCnt
			IF PopupLiteral<I,1> = CurrStage THEN
				PopupLiteral = DELETE(PopupLiteral,I,0,0)	;* Remove current stages from popup display literal
				Done = 1
			END
		UNTIL Done
		NEXT I
		CurrStages[1,COL2()] = ''
	REPEAT
	
	CONVERT @FM:@VM TO @VM:@SVM IN PopupLiteral
	
	TypeOver = ''
	TypeOver<PDISPLAY$> = PopupLiteral
	
	NewStage = Popup(@WINDOW,TypeOver,'STAGE')
	
	Send_Event(@WINDOW,'WRITE')
	
	StageKey = PSNo:'*':NewStage
	
	DetWindow	= 'PRS_STAGE'
	DetKeys		= StageKey
	DefaultRec	= ''
	RetKey		= PSNo
	RetWin		= @WINDOW
	RetPage		= 5
	RetCtrl		= @WINDOW:'.STAGE_SPEC'
	RetPos		= COL$STAGE:@FM:CurrStageCnt + 1
	
	obj_Appwindow('ViewNewDetail',DetWindow:@RM:DetKeys:@RM:DefaultRec:@RM:RetKey:@RM:RetPage:@RM:RetCtrl:@RM:RetPos)
	
	
RETURN


* * * * * * *
ViewCurr:
* * * * * * *
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	CtrlEntID = @WINDOW:'.PROD_VER'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	ProdVerNo	= Get_Property(CtrlEntID,'CELLPOS',COL$PROD_VER_NO:@FM:CurrRow)
	EpiPN		= Get_Property(CtrlEntID,'CELLPOS',COL$EPI_PART_NO:@FM:CurrRow)
	CustNo		= Get_Property(CtrlEntID,'CELLPOS',COL$CUST_NO:@FM:CurrRow)
	
	CurrCtrl = Get_Property(@WINDOW,'FOCUS')
	
	
	BEGIN CASE
		CASE CurrCtrl = @WINDOW:'.PROD_VER_BUTTON' AND ProdVerNo NE ''
			DetWindow	= 'PROD_VER'
			DetKeys		= ProdVerNo
			
		CASE CurrCtrl = @WINDOW:'.CUST_EPI_PART_BUTTON' AND CustNo NE '' AND EpiPN NE ''
			DetWindow	= 'CUST_EPI_PART'
			DetKeys		= CustNo:'*':EpiPN
			
		CASE CurrCtrl = @WINDOW:'.EPI_PART_BUTTON'
			DetWindow	= 'EPI_PART'
			DetKeys		= EpiPN
			
		CASE 1
			DetWindow	= ''
			DetKeys		= ''
			
	END CASE
	
	IF DetWindow NE '' THEN
		
		Send_Event(@WINDOW,'WRITE')
		
		DefaultRec	= ''
		RetKey		= PSNo
		RetPage		= 2
		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
	
RETURN


* * * * * * *
CepPC:
* * * * * * *
	
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	CtrlEntID = @WINDOW:'.CEP_KEYS'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	CEPKey	= Get_Property(CtrlEntID,'CELLPOS',COL$CEP_KEY:@FM:CurrRow)
	CustNo	= CEPKey[1,'*']
	EpiPN	= CEPKey[COL2()+1,'*']
	
	CustEpiPartRec = XLATE('CUST_EPI_PART',CEPKey,'','X')
	
	PSArray = ''
	
	PSArray<COL$SPEC_NO>		= CustEpiPartRec<CUST_EPI_PART_SPEC_NO$>
	PSArray<COL$SPEC_DESC>		= CustEpiPartRec<CUST_EPI_PART_SPEC_DESC$>
	PSArray<COL$SPEC_REV>		= CustEpiPartRec<CUST_EPI_PART_SPEC_REV$>
	PSArray<COL$SPEC_REV_DT>	= OCONV(CustEpiPartRec<CUST_EPI_PART_SPEC_REV_DT$>,'D4/')
	PSArray<COL$SPEC_HARDCOPY>	= OCONV(CustEpiPartRec<CUST_EPI_PART_SPEC_HARDCOPY$>,'B')
	
	
	
	Ctrls  = @WINDOW:'.CEP_CUST_NO':@RM				; Props  = 'TEXT':@RM		; Vals  = CustNo:@RM
	Ctrls := @WINDOW:'.CEP_EPI_PART_NO':@RM			; Props := 'TEXT':@RM		; Vals := EpiPN:@RM
	Ctrls := @WINDOW:'.CEP_SALES_NOTES':@RM			; Props := 'DEFPROP':@RM	; Vals := CustEpiPartRec<CUST_EPI_PART_SALES_NOTES$>:@RM
	Ctrls := @WINDOW:'.CEP_SPEC':@RM				; Props := 'DEFPROP':@RM	; Vals := PSArray:@RM
	Ctrls := @WINDOW:'.CEP_MAKEUP_WAFERS'			; Props := 'DEFPROP':@RM	; Vals := CustEpiPartRec<CUST_EPI_PART_MAKEUP_WAFERS$>
	
	
	Set_Property(Ctrls,Props,Vals)
	
	EpiPartRec = XLATE('EPI_PART',EpiPN,'','X')
	
	
	Ctrls  = @WINDOW:'.SUB_SUPP_BY':@RM			; Props  = 'VALUE':@RM		; Vals  = EpiPartRec<EPI_PART_SUB_SUPP_BY$>:@RM
	
	Ctrls := @WINDOW:'.SUB_MAT_MANAGE':@RM		; Props := 'CHECK':@RM		; Vals := EpiPartRec<EPI_PART_SAP_MATERIAL$>:@RM
	Ctrls := @WINDOW:'.SUB_PRODUCT':@RM			; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_PRODUCT$>:@RM
	Ctrls := @WINDOW:'.SUB_ORIENTATION':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_ORIENTATION$>:@RM
	Ctrls := @WINDOW:'.SUB_RESISTIVITY':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_RES$>:@RM
	Ctrls := @WINDOW:'.SUB_RES_UNITS':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_RES_UNITS$>:@RM
	Ctrls := @WINDOW:'.SUB_POLISH':@RM			; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_POLISH$>:@RM
	Ctrls := @WINDOW:'.SUB_SIZE':@RM			; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_WAFER_SIZE$>:@RM
	Ctrls := @WINDOW:'.SUB_DOPE_TYPE':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_DOPE_TYPE$>:@RM
	Ctrls := @WINDOW:'.SUB_OXIDE':@RM			; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_OXIDE$>:@RM
	Ctrls := @WINDOW:'.SUB_MATERIAL':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_MATERIAL$>:@RM
	Ctrls := @WINDOW:'.SUB_DOPANT':@RM			; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_DOPANT$>:@RM
	Ctrls := @WINDOW:'.SUB_THICKNESS':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_THICK$>:@RM
	Ctrls := @WINDOW:'.SUB_ANGSTROMS':@RM		; Props := 'DEFPROP':@RM	; Vals := EpiPartRec<EPI_PART_SUB_OXIDE_ANGSTROMS$>:@RM
	Ctrls := @WINDOW:'.SUB_BACKSEAL'			; Props := 'DEFPROP'		; Vals := EpiPartRec<EPI_PART_SUB_BACKSEAL$>
	
	Set_Property(Ctrls,Props,Vals)
	
RETURN


* * * * * * *
FixCEPClick:
* * * * * * * 
	
	* Fixit routine to copy CUST_PART_NO data to Selected CUST_EPI_PART record during conversion data cleanup
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	IF PSNo = '' THEN RETURN
	
	CtrlEntID = @WINDOW:'.CEP_KEYS'
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	CEPKey	= Get_Property(CtrlEntID,'CELLPOS',COL$CEP_KEY:@FM:CurrRow)
	CustNo	= CEPKey[1,'*']
	EpiPN	= CEPKey[COL2()+1,'*']
	
	otParms = 'CUST_EPI_PART':@RM:CEPKey
	CustEpiPartRec = obj_Tables('ReadRec',otParms)
	
	IF Get_Status(errCode) THEN
		ErrMsg(errCode)
		RETURN
	END
	
	PSCustPartData = Get_Property(@WINDOW:'.CUST_PART_NO','ARRAY')
	
	PSCustPartNos = PSCustPartData<1>
	
	LOOP
		TestChar = PSCustPartNos[-1,1]
	UNTIL TestChar NE @VM OR PSCustPartNos = ''
		PSCustPartNos[-1,1] = ''
	REPEAT
	
	
	PSCustPartDescs = PSCustPartData<2>
	
	LOOP
		TestChar = PSCustPartDescs[-1,1]
	UNTIL TestChar NE @VM OR PSCustPartDescs = ''
		PSCustPartDescs[-1,1] = ''
	REPEAT
	
	
	PSCustPartInbounds = PSCustPartData<3>
	
	LOOP
		TestChar = PSCustPartInbounds[-1,1]
	UNTIL TestChar NE @VM OR PSCustPartInbounds = ''
		PSCustPartInbounds[-1,1] = ''
	REPEAT
	
	CustEpiPartRec = XLATE('CUST_EPI_PART',CEPKey,'','X')
	
	CustEpiPartRec<CUST_EPI_PART_CUST_PART_NO$>			= PSCustPartNos
	CustEpiPartRec<CUST_EPI_PART_CUST_PART_DESC$>		= PSCustPartDescs
	CustEpiPartRec<CUST_EPI_PART_CUST_PART_NO_INBOUND$>	= PSCustPartInbounds
	
	otParms = FieldStore(otParms, @RM, 4, 1, CustEpiPartRec)
	obj_Tables('WriteRec',otParms)
	
	Send_Event(@WINDOW,'READ')
	
	
Return


* * * * * * * *
LUWipStage:
* * * * * * * *
	
	CtrlEntID = @WINDOW:'.':Parm1
	
	
	Stages = Popup(@WINDOW,'','GAN_WIP_STAGES')
	
	If Stages = '' Or Stages = CHAR(27) Then Return
	
	CurrArray = Get_Property(CtrlEntID,'ARRAY')
	
	CurrCodes = CurrArray<1>	;* 1st column has the codes in it
	
	CurrArray<1> = Stages
	
	Set_Property(CtrlEntID,'DEFPROP',CurrArray)
	
	Send_Event(CtrlEntID,'CALCULATE',2)
	Gosub Refresh
	
RETURN


* * * * * * *
WiPStageClick:
* * * * * * * 
	
	If MemberOf(@USER4,'ENGINEERING') OR MemberOf(@USER4,'CONFIG_LIMITED') Else
		ErrMsg('You must be authorized to change the specification.')
		Return
	END
	
	
	PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP')
	
	CtrlEntID = Get_Property(@WINDOW,'FOCUS')
	CurrPos = Get_Property(CtrlEntID,'SELPOS')
	CurrCol = CurrPos<1>
	CurrRow = CurrPos<2>
	
	IF CurrCol = COL$STAGE THEN
		SigStage = Get_Property(CtrlEntID,'CELLPOS',COL$STAGE:@FM:CurrRow)
		
		IF PSNo NE '' THEN
			
			
			Send_Event(@WINDOW,'WRITE')
			
			DetWindow	= 'PRS_STAGE'
			DetKeys		= PSNo:'*':SigStage
			DefaultRec	= ''
			RetKey		= PSNo
			RetPage		= 5
			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 Stage Column
	
	
RETURN


* * * * * * *
LUToolSeq:
* * * * * * *
	
	CtrlEntID = @WINDOW:'.':Parm1
	
	
	ToolIDs = Popup(@WINDOW,'','TOOL_CLASS_SEQ')
	
	If ToolIDs = '' Or ToolIDs = CHAR(27) Then Return
	
	
	CurrArray = Get_Property(CtrlEntID,'ARRAY')
	
	CurrCodes = CurrArray<1>	;* 1st column has the codes in it
	
	CurrArray<1> = ToolIDs
	
	Set_Property(CtrlEntID,'DEFPROP',CurrArray)
	
	Send_Event(CtrlEntID,'CALCULATE',2)
	
	
	GOSUB Refresh
	
	
RETURN


* * * * * * *
UpdateRevHist:
* * * * * * *
	
	// Gather one line revision detail
	Result              = False$
	Response            = Dialog_Box('NDW_ADD_PSN_REVISION', @WINDOW)
	Valid               = Response<1>
	RevisionDetail      = Response<2>
	If Valid then
		// Update PROD_SPEC_REV_HIST record
		If @Window EQ 'PRS_STAGE' then
			CtrlName = @Window : '.PS_NO'
		end
		If @Window EQ 'PROD_SPEC' then
			CtrlName = @Window : '.PROD_SPEC_ID'
		end
		PSNo = Get_Property(CtrlName,'DEFPROP')
		If RowExists('PROD_SPEC_REV_HIST', PSNo) then
			PSRevHistRec = Database_Services('ReadDataRow', 'PROD_SPEC_REV_HIST', PSNo)
		end else
			PSRevHistRec = ''
			Database_Services('WriteDataRow', 'PROD_SPEC_REV_HIST', PSNo, PSRevHistRec, True$)
			If Error_Services('NoError') then
				// Rev Hist record created successfully
			end else
				Errmsg('Error creating PROD_SPEC_REV_HIST record: ' : PSNo : @SVM : 'Please notify OpenInsight administrator')
			end
		end
		If Error_Services('NoError') then
			Usernames   = PSRevHistRec<PROD_SPEC_REV_HIST_MOD_USERNAME$>
			Dates       = PSRevHistRec<PROD_SPEC_REV_HIST_MOD_DATE$>
			Times       = PSRevHistRec<PROD_SPEC_REV_HIST_MOD_TIME$>
			Revisions   = PSRevHistRec<PROD_SPEC_REV_HIST_REVISION_DETAIL$>
			ModUser     = OConv( @user4, '[XLATE_CONV,LSL_USERS*FIRST_LAST]' )
			ModDate     = Date()
			ModTime     = Time()
			ModRevision = RevisionDetail
			PSRevHistRec<PROD_SPEC_REV_HIST_MOD_USERNAME$>      = Insert(Usernames, 0, 1, 0, ModUser)
			PSRevHistRec<PROD_SPEC_REV_HIST_MOD_DATE$>          = Insert(Dates, 0, 1, 0, ModDate)
			PSRevHistRec<PROD_SPEC_REV_HIST_MOD_TIME$>          = Insert(Times, 0, 1, 0, ModTime)
			PSRevHistRec<PROD_SPEC_REV_HIST_REVISION_DETAIL$>   = Insert(Revisions, 0, 1, 0, ModRevision)
			
			Database_Services('WriteDataRow', 'PROD_SPEC_REV_HIST', PSNo, PSRevHistRec, True$)
			If Error_Services('NoError') then
				Result = True$
			end else
				Errmsg('Error writing PROD_SPEC_REV_HIST record: ' : PSNo : @SVM : 'Please notify OpenInsight administrator')
			end
		end else
			Errmsg('Error reading PROD_SPEC_REV_HIST record: ' : PSNo : @SVM : 'Please notify OpenInsight administrator')
		end
	end else
		Errmsg('You must enter revision details in order to save changes to product specifications')
	end
	
Return Result

Abort:
    
    Utility('DESTROY', @Window)
    
return

SpecVerification:
    
    EQU RES_MIN$ TO 4
    EQU RES_MAX$ TO 5
    EQU RES_UNIT$ TO 6
    EQU THICK_MIN$ TO 7
    EQU THICK_MAX$ TO 8
    EQU THICK_UNIT$ TO 9
    EQU DOPANT$ TO 10
    EQU THICK_MEASURES$ TO 13
    EQU RES_MEASURE$ TO 14
    EQU CRES_MEASURE$ TO 15
    
    //MEASUREMENT DETAILS EQUATES
    
    EQU MEAS_TOOL$ TO 1
    EQU MEAS_TYPE$ TO 2
    EQU MEAS_RECIPE$ TO 3
    EQU MEAS_FREQ$ TO 4
    EQU MEAS_PROVE_IN$ TO 5
    EQU MEAS_FIRST_WAFER$ TO 6
    EQU MEAS_LAST_WAFER$ TO 7
    EQU MEAS_CONTROL_SPC$ TO 8
    EQU MEAS_EXPECTED_QTY$ TO 10
    EQU MEAS_PATTERN$ TO 11
    
    
    PSNRec = XLATE('PROD_SPEC', PsNo, '','X')
    
    SpecEpi = Get_Property(@Window : '.SPEC_EPI', 'DEFPROP')
    CONVERT CHAR(248) TO @RM IN SpecEpi
    CONVERT @VM TO @FM IN SpecEpi
    CONVERT @SVM TO @VM IN SpecEpi
    CONVERT '~' TO @VM IN SpecEpi
    //Split up SpecEpi into Individual Layers and Settings
    LayerOne = ''
    LayerTwo = ''
    LayerThree = ''
    LayerOneIndex = 1
    LayerTwoIndex = 1
    LayerThreeIndex = 1
    For FieldNum = 1 to 18
        LayerOne<LayerOneIndex> = SpecEpi<FieldNum>
        LayerOneIndex = LayerOneIndex + 1
    Next FieldNum
    
    For FieldNum = 20 to 37
        
        LayerTwo<LayerTwoIndex> = SpecEpi<FieldNum>
        LayerTwoIndex = LayerTwoIndex + 1
    Next FieldNum
    
    For FieldNum = 39 to 58
        
        LayerThree<LayerThreeIndex> = SpecEpi<FieldNum>
        LayerThreeIndex = LayerThreeIndex + 1
    Next FieldNum
    
    LayerKeys = PSNRec<PROD_SPEC_PRS_LAYER_KEY$>
    If LayerKeys EQ '' then
        Message = 'No Layers have been defined.'
        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
        Set_Property(@WINDOW:'.STATUS','VALUE','I')
        Error_Services('Add', Message)
        Return
    end
    For Each LayerKey in LayerKeys using @VM
        swap '*' with @FM in LayerKey
        LayerNum = LayerKey<2>
        
        //Layer 1 Checks
        If LayerNum EQ 1 then
            If LayerOne<THICK_MEASURES$> NE '' then
                //Check Thick Min and Max
                If LayerOne<THICK_MIN$> EQ '' then
                    Message = 'Thickness minimum value missing for Layer 1'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                If LayerOne<THICK_MIN$> EQ '' then
                    Message = 'Thickness maximum value missing for Layer 1'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Tool
                If LayerOne<THICK_MEASURES$,MEAS_TOOL$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Measurement Tool'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Type
                If LayerOne<THICK_MEASURES$,MEAS_TYPE$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Measurement Type'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Recipe
                If LayerOne<THICK_MEASURES$,MEAS_RECIPE$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Measurement Recipe'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Pattern
                If LayerOne<THICK_MEASURES$,MEAS_PATTERN$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Measurement Pattern'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Cassette Frequency
                If LayerOne<THICK_MEASURES$,MEAS_FREQ$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Measurement Frequency'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Prove In Type
                If LayerOne<THICK_MEASURES$,MEAS_PROVE_IN$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Prove-In Type'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Expected QTY
                If LayerOne<THICK_MEASURES$,MEAS_EXPECTED_QTY$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 1: Measurement Quantity'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
            end else
                Message = 'Thickness Measurement missing for Layer 1'
                Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                Set_Property(@WINDOW:'.STATUS','VALUE','I')
                Error_Services('Add', Message)
                return
            end
            If LayerOne<RES_MEASURE$> NE '' OR LayerOne<CRES_MEASURE$> NE '' then
                IF LayerOne<RES_MEASURE$> NE '' then
                    IF LayerOne<RES_MIN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end else
                        
                    end
                    IF LayerOne<RES_MAX$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Max Resistivity'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    IF LayerOne<RES_MIN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Min Resistivity'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Tool
                    If LayerOne<RES_MEASURE$,MEAS_TOOL$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Measurement Tool'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Type
                    If LayerOne<RES_MEASURE$,MEAS_TYPE$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Measurement Type'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Recipe
                    If LayerOne<RES_MEASURE$,MEAS_RECIPE$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Measurement Recipe'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Pattern
                    If LayerOne<RES_MEASURE$,MEAS_PATTERN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Measurement Pattern'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Cassette Frequency
                    If LayerOne<RES_MEASURE$,MEAS_FREQ$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Measurement Frequency'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Prove In Type
                    If LayerOne<RES_MEASURE$,MEAS_PROVE_IN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Measurement Prove-In'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Expected QTY
                    If LayerOne<RES_MEASURE$,MEAS_EXPECTED_QTY$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 1: Expected Quantity'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                end
                If LayerOne<CRES_MEASURE$> NE '' then
                    IF LayerOne<RES_MIN$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 1: CRes Min '
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end else
                        IF LayerOne<RES_MAX$> EQ '' then
                            Message = 'CRes Measurement info missing for Layer 1: CRes Max'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                        //Tool
                        If LayerOne<CRES_MEASURE$,MEAS_TOOL$> EQ '' then
                            Message = 'CRes Measurement info missing for Layer 1: Measurement Tool'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                        //Type
                        If LayerOne<CRES_MEASURE$,MEAS_TYPE$> EQ '' then
                            Message = 'Cres Measurement info missing for Layer 1: Measurement Type'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                        //Recipe
                        If LayerOne<CRES_MEASURE$,MEAS_RECIPE$> EQ '' then
                            Message = 'CRes Measurement info missing for Layer 1: Measurement Recipe'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                        //Pattern
                        If LayerOne<CRES_MEASURE$,MEAS_PATTERN$> EQ '' then
                            Message = 'CRes Measurement info missing for Layer 1: Measurement Pattern'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                        //Cassette Frequency
                        //Removed per Mark C. 7/15/2021
*                        If LayerOne<CRES_MEASURE$,MEAS_FREQ$> EQ '' then
*                            Message = 'CRes Measurement info missing for Layer 1: Measurement Frequency'
*                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
*                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
*                            Error_Services('Add', Message)
*                            return
*                        end
                        //Prove In Type
                        If LayerOne<CRES_MEASURE$,MEAS_PROVE_IN$> EQ '' then
                            Message = 'CRes Measurement info missing for Layer 1: Prove-In Type'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                        //Expected QTY
                        If LayerOne<CRES_MEASURE$,MEAS_EXPECTED_QTY$> EQ '' then
                            Message = 'CRes Measurement info missing for Layer 1: Expected Quantity'
                            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                            Set_Property(@WINDOW:'.STATUS','VALUE','I')
                            Error_Services('Add', Message)
                            return
                        end
                    end
                    
                end
            end else
                Message = 'Res Measurement info missing for Layer 1'
                Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                Set_Property(@WINDOW:'.STATUS','VALUE','I')
                Error_Services('Add', Message)
                return 
            end
        end
        
        //Layer 2 checks
        If LayerNum EQ 2 then
            //Layer 2 Thickness Parameters
            If LayerTwo<THICK_MEASURES$> NE '' then
                //Check Thick Min and Max
                If LayerTwo<THICK_MIN$> EQ '' then
                    Message = 'Thickness minimum value missing for Layer 2: Thickness Min'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                If LayerTwo<THICK_MIN$> EQ '' then
                    Message = 'Thickness maximum value missing for Layer 2: Thickness Max'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Tool
                If LayerTwo<THICK_MEASURES$,MEAS_TOOL$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Measurement Tool'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Type
                If LayerTwo<THICK_MEASURES$,MEAS_TYPE$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Measurement Type'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Recipe
                If LayerTwo<THICK_MEASURES$,MEAS_RECIPE$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Measurement Recipe'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Pattern
                If LayerTwo<THICK_MEASURES$,MEAS_PATTERN$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Measurement Pattern'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Cassette Frequency
                If LayerTwo<THICK_MEASURES$,MEAS_FREQ$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Measurement Frequency'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Prove In Type
                If LayerTwo<THICK_MEASURES$,MEAS_PROVE_IN$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Prove In Type'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
                //Expected QTY
                If LayerTwo<THICK_MEASURES$,MEAS_EXPECTED_QTY$> EQ '' then
                    Message = 'Thickness Measurement info missing for Layer 2: Expected Quantity'
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    Error_Services('Add', Message)
                    return
                end
            end else
                Message = 'Thickness Measurement info missing for Layer 2'
                Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                Set_Property(@WINDOW:'.STATUS','VALUE','I')
                Error_Services('Add', Message)
                return
            end
            //Layer 2 Res Checks
            If LayerTwo<RES_MEASURE$> NE '' OR LayerTwo<CRES_MEASURE$> NE '' then
                IF LayerOne<RES_MEASURE$> NE '' then
                    IF LayerTwo<RES_MIN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Resistivity Min'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end else
                        
                    end
                    IF LayerTwo<RES_MAX$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Resistivity Max'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Tool
                    If LayerTwo<RES_MEASURE$,MEAS_TOOL$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Measurement Tool'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Type
                    If LayerTwo<RES_MEASURE$,MEAS_TYPE$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Measurement Type'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Recipe
                    If LayerTwo<RES_MEASURE$,MEAS_RECIPE$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Measurement Recipe'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Pattern
                    If LayerTwo<RES_MEASURE$,MEAS_PATTERN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Measurement Pattern'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Cassette Frequency
                    If LayerTwo<RES_MEASURE$,MEAS_FREQ$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Measurement Frequency'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Prove In Type
                    If LayerTwo<RES_MEASURE$,MEAS_PROVE_IN$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Prove-In type'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Expected QTY
                    If LayerTwo<RES_MEASURE$,MEAS_EXPECTED_QTY$> EQ '' then
                        Message = 'Resistivity Measurement info missing for Layer 2: Expected Quantity'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    
                    
                end
                IF LayerTwo<CRES_MEASURE$> NE '' then
                    IF LayerTwo<RES_MIN$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: CRes Min'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end else
                        
                    end
                    IF LayerTwo<RES_MAX$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: CRes Max'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Tool
                    If LayerTwo<CRES_MEASURE$,MEAS_TOOL$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Measurement Tool'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Type
                    If LayerTwo<CRES_MEASURE$,MEAS_TYPE$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Measurement Type'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Recipe
                    If LayerTwo<CRES_MEASURE$,MEAS_RECIPE$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Measurement Recipe'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Pattern
                    If LayerTwo<CRES_MEASURE$,MEAS_PATTERN$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Measurement Pattern'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Cassette Frequency
                    If LayerTwo<CRES_MEASURE$,MEAS_FREQ$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Measurement Frequency'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Prove In Type
                    If LayerTwo<CRES_MEASURE$,MEAS_PROVE_IN$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Prove-In Type'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                    //Expected QTY
                    If LayerTwo<CRES_MEASURE$,MEAS_EXPECTED_QTY$> EQ '' then
                        Message = 'CRes Measurement info missing for Layer 2: Expected Qty'
                        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                        Set_Property(@WINDOW:'.STATUS','VALUE','I')
                        Error_Services('Add', Message)
                        return
                    end
                end
            end else
                Message = 'Res Measurement info missing for Layer 2'
                Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                Set_Property(@WINDOW:'.STATUS','VALUE','I')
                Error_Services('Add', Message)
                return 
            end
        end
        //Layer 3 checks
        If LayerNum EQ 3 then
            If LayerThree<THICK_MEASURES$> NE '' then
                
            end else
                Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', 'Thickness Measurement info missing for Layer 3')
                Set_Property(@WINDOW:'.STATUS','VALUE','I')
                return
            end
        end
    Next LayerKey
return

StageVerification:
    
    StageTable = Get_Property(@WINDOW:'.STAGE_SPEC', 'ARRAY')
    Stages = StageTable<1>
    IF Stages<1,1> EQ ''  then
        
            Message = 'No stages have been defined.' : CRLF$
            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
            Set_Property(@WINDOW:'.STATUS','VALUE','I')
            return

    end else
        
        For each Stage in Stages using @VM
            IF Stage NE '' then
                
                Psn_Services('CheckPSNStages',PsNo,Stage)
                Message = Error_Services('GetMessage')
                If Message NE '' then
                    //msg(@Window, Message)
                    
                    Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
                    Set_Property(@WINDOW:'.STATUS','VALUE','I')
                    return
                end
            end
            
        Next Stage
    end

return

ProdVerVerification:
    ProdVerTable = Get_Property(@Window:'.PROD_VER', 'DEFPROP')
    ProdVers = ProdVerTable<1>
    If ProdVers<1,1> EQ '' then
        Message = 'No Product Versions exist for selected PSN. Check usage tab.'
        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
        Set_Property(@WINDOW:'.STATUS','VALUE','I')
        Error_Services('Add', Message)
        return 
    end else
        FoundActive = 0
        For ProdVerSeq = 1 To DCOUNT(ProdVers, @VM)
            
            If ProdVerTable<3, ProdVerSeq> EQ 'A' then
                FoundActive = 1
            end
        Next ProdVer
        If FoundActive EQ 0 then
            Message = 'Product Versions exists, but none are active. Check usage tab.'
            Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
            Set_Property(@WINDOW:'.STATUS','VALUE','I')
            Error_Services('Add', Message)
            return
        end
    end
return

ReactorVerification:
    
    ReactorType = Get_Property(@Window:'.RTYPE', 'VALUE')
    If ReactorType EQ '' then
        Message = 'You must choose a reactor type...'
        Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', Message)
        Set_Property(@WINDOW:'.STATUS','VALUE','I')
        Error_Services('Add', Message)
        return
    end
    
return

