function rds_comm(Branch) #pragma precomp SRP_PreCompiler declare function set_property, fieldcount, get_property, msg, dialog_box, entid, findwindow declare function memberof, send_event, post_event, repository, start_window, utility, popup declare function security_check, send_message, next_key, Get_Property, NextKey declare subroutine make.list, yield, security_err_msg, btree.extract, Set_Property, Comm_RDS, obj_RDS_Audit, obj_AppWindow $insert rds_equ $insert wo_verify_equ $insert rds_layer_info_equ $insert msg_equates $insert lsl_users_equ $insert logical $insert quote_sigs_equ $insert popup_equates $insert dict_equates $insert security_rights_equ $insert tw_info_array_equ $insert tw_codes_equ $insert recipe_info_array_equ $insert recipe_layer_info_equ $insert recipe_equ $insert wo_daily_sched_equ equ Hidden$ to 32 equ White$ to 16777215 equ Gray$ to 12632256 equ Black$ to 1 equ Conex$ to 6448 ReturnVar = 0 Branches = 'CALC_STAT_INFO,OVERRIDE,CHECK_NCR_SAVE,WO_VERIFY_CHK,CALC_ALL_RES,RDS_NO_OPTIONS,SEND_MESSAGE,CALL_WINDOW,STAMP_MOD,SURFACE_VALID,RDS_VIEW,READ_STORE,WRITE_STAMP,VIEW_MOD_INFO,CALL_SURF_INSP,' Branches:= 'CALL_CLEAN,CALL_RDS_METROLOGY,TW_ACCT_ROW_VAL,SET_ADJUST_PARAMS,SET_ML_LIMITS' convert ',' to @fm in Branches locate Branch in Branches using @fm setting Bpos then on Bpos gosub CALC_STAT_INFO, OVERRIDE, CHECK_NCR_SAVE, WO_VERIFY_CHK, CALC_ALL_RES, RDS_NO_OPTIONS, SEND_MESSAGE, CALL_WINDOW, STAMP_MOD, SURFACE_VALID, RDS_VIEW, READ_STORE, WRITE_STAMP, VIEW_MOD_INFO, CALL_SURF_INSP, CALL_CLEAN, CALL_RDS_METROLOGY, TW_ACCT_ROW_VAL, SET_ADJUST_PARAMS, SET_ML_LIMITS end else Void = msg( '', 'Invalid Branch ':Bpos:' passed to rds_comm' ) end return ReturnVar *============================================================================* CALC_STAT_INFO: return *============================================================================* OVERRIDE: if xlate( 'LSL_USERS', @user4, lsl_users_rds_master$, 'X' ) then ReturnVar = dialog_box( 'PWD_ENTRY', @window, '' ) end else MsgInfo = '' MsgInfo = 'You do not have security rights to override Run Data Sheet information.' MsgInfo = 'H' Void = msg( '', MsgInfo ) end return *============================================================================* CHECK_NCR_SAVE: NCRMustSave = get_property( @window, '@NCRMustSave' ) if NCRMustSave = true$ then MsgInfo = '' Tvar = 'This RDS must be saved due to the NCRs that were generated and/or deleted. ' Tvar:= 'If the reject information that you have entered is not correct then please modify ' Tvar:= 'and account for them properly. This will also generate and/or delete the proper ' Tvar:= 'NCRs. At that point you may then save. Do you wish to save this RDS now, as is?' MsgInfo = Tvar MsgInfo = '!' MsgInfo = 'BNY' Resp = msg( '', MsgInfo ) if Resp = true$ then Void = send_event( @window, 'WRITE' ) ReturnVar = false$ * SET TO FALSE CAUSE THE USER DECIDED TO SAVE end else ReturnVar = true$ * SET TO TRUE CAUSE THE USER SAID THEY DO NOT WANT TO SAVE AND WE MUST * SO DON't FORWARD THE EVENT end end else ReturnVar = false$ end return *============================================================================* WO_VERIFY_CHK: RDSID = get_property( @window:'.RDS_NO', 'TEXT' ) WOVerifyId = xlate( 'RDS', RDSId, rds_wo_verify_id$, 'X' ) OffOn = 1 if WOVerifyId then TechSig = xlate( 'WO_VERIFY', WOVerifyId, wo_verify_tech_sig$, 'X' ) if TechSig = '' then * TECHNICIAN HAS NOT SIGNED SO DISABLE ALL IN AND OUT CONTROLS * AND CALL THE WORK ORDER VERIFICATION WINDOW OffOn = 0 if get_property( @window, '@VerifyViewOmni' ) then * DON'T FORCE THE WINDOW BACK UP CAUSE THE USER HAS SAVED FROM * WO_VERIFY WINDOW AND MAY COME BACK TO IT LATER AND DOES NOT WANT TO SIGN Void = set_property( @window, '@VerifyViewOmni', '' ) end else Void = post_event( @window:'.WO_VERIFY_VIEW', 'CLICK' ) end Void = set_property( @window:'.WO_VERIFY_VIEW', 'FOCUS', 1 ) end end if OffOn = 1 and ( get_property( @window:'.DATE_IN', 'ENABLED' ) ) then * THEY ARE ALREADY ENABLED return end ReturnVar = OffOn return *============================================================================* CALC_ALL_RES: * CALLED FROM RDS_LAYERS CAUSE WE SheetRHO = get_property( @window:'.SHEETRHO_READINGS', 'ARRAY' ) Thickness = iconv( get_property( @window:'.THICKNESS_READINGS', 'ARRAY' ), 'MD2' ) Tcnt = fieldcount( Thickness, @vm ) Res = '' for i = 1 to Tcnt Tres = oconv( SheetRHO<1,i> *** Thickness<1,i> *** .001, 'MD3' ) if Tres = 0 then Res<1,i> = ''; * DON'T SHOW ZEROS end else Res<1,i> = Tres end next i Void = set_property( @window:'.RES_READINGS', 'ARRAY', Res ) return *============================================================================* RDS_NO_OPTIONS: RDSKeys = get_property( @window, '@CurQuery' ) if RDSKeys then PopId = entid( @appid<1>, 'POPUP', '', 'RDS_RET_QUERY' ) Opt = repository( 'EXECUTE', PopId, @window, '' ) if Opt = 'NEW' then *RDSKeys = dialog_box( 'RDS_QUERY', @window, '' ) RDSKeys = Dialog_Box('DIALOG_RDS_QUERY',@WINDOW,'') end else if Opt = 'CURRENT' else return 0 ;* nothing choosen end end end else *RDSKeys = dialog_box( 'RDS_QUERY', @window, '' ) RDSKeys = Dialog_Box('DIALOG_RDS_QUERY',@WINDOW,'') end Void = set_property( @window, '@CurQuery', '' ) if RDSKeys then Void = set_property( @window, '@CurQuery', RDSKeys ) PopId = entid( @appid<1>, 'POPUP', '', 'RDS_QUERY' ) OverRide = '' make.list( 0, RDSKeys, '', '' ) ChoosenKeys = repository( "EXECUTE", PopId, @window, OverRide ) if ChoosenKeys then convert @vm to @fm in ChoosenKeys if fieldcount( ChoosenKeys, @fm ) > 1 then Void = set_property( @window, 'QBFLIST', ChoosenKeys ) Void = set_property( @window, '@NoRead', 1 ) Void = set_property( @window:'.RDS_NO', 'TEXT', ChoosenKeys<1> ) Void = send_event( @window, 'READ' ) Void = set_property( @window, '@NoRead', 0 ) end else Void = set_property( @window, 'QBFLIST', '' ) Void = set_property( @window:'.RDS_NO', 'TEXT', ChoosenKeys ) Void = send_event( @window:'.RDS_NO', 'LOSTFOCUS', '' ) *Void = send_event( @window:'.RDS_NO', 'GOTFOCUS', '' ) end end end return *============================================================================* SEND_MESSAGE: RdsNo = get_property( @window:'.RDS_NO', 'TEXT' ) if RdsNo then if rowexists( 'RDS', RdsNo ) then Qbf = get_property( @window, 'QBFLIST' ) if Qbf then convert @fm to @vm in Qbf end else Qbf = '' end NoteID = NextKey('NOTES') obj_AppWindow('ViewRelated','NOTE_MESSAGE':@RM:NoteID:@RM:@WINDOW:@FM:RdsNo) end else MsgInfo = '' MsgInfo = 'You must save this run data sheet first...' MsgInfo = 'H' Void = msg( '', MsgInfo ) end end else MsgInfo = '' MsgInfo = 'You must have a run data sheet present...' MsgInfo = 'H' Void = msg( '', MsgInfo ) end return *============================================================================* CALL_WINDOW: WindowToCall = get_property( @window, '@WindowToCall' ) RDSId = get_property( @window:'.RDS_NO', 'TEXT' ) begin case case WindowToCall = 'PROD_SPEC' if security_check( 'Prod Spec', Read$ ) then IdToUse = xlate( 'RDS', RDSId, rds_prod_spec_id$, 'X' ) end else IdToUse = '' security_err_msg( 'Prod Spec', Read$ ) end case WindowToCall = 'RECIPE' if security_check( 'Recipe', Read$ ) then IdToUse = xlate( 'RDS', RDSId, 'RECIPE_NO', 'X' ) end else IdToUse = '' security_err_msg( 'Recipe', Read$ ) end case WindowToCall = 'RDS_PROVEIN' IdToUse = xlate( 'RDS', RDSId, rds_prod_spec_id$, 'X' ) end case if IdToUse <> '' then Void = Start_Window ( WindowToCall, @window, IdToUse:'*CENTER', '', '' ) end return *============================================================================* STAMP_MOD: RDSId = get_property( @window:'.RDS_NO', 'TEXT' ) ModIds = xlate( 'RDS', RDSId, rds_mod_id$, 'X' ) ModNames = oconv( ModIds, '[XLATE_CONV,LSL_USERS*FIRST_LAST]' ) ModDates = oconv( xlate( 'RDS', RDSId, rds_mod_date$, 'X' ), 'D2/' ) ModIds = insert( ModIds, 1, 1, 0, @user4 ) ModNames = insert( ModNames, 1, 1, 0, oconv( @user4, '[XLATE_CONV,LSL_USERS*FIRST_LAST]' ) ) ModDates = insert( ModDates, 1, 1, 0, oconv( date(), 'D2/' ) ) NewArray = ModIds:@fm:ModNames:@fm:ModDates Void = set_property( @window:'.MOD_INFO', 'ARRAY', NewArray ) return *============================================================================* SURFACE_VALID: * THIS IS CALLED FROM RDS_PRE_EPI2 AND RDS_SURF_ENT * WE ARE VALIDATING THE PRE AND POST SURFACE ENTRIES CurControl = get_property( @window, '@CurControl' ) CurValue = get_property( CurControl, 'TEXT' ) SpecControl = CurControl * FIRST HANDLE ALL CONTROLS swap '_R' with '_S' in SpecControl * TO HANDLE THE LPD IN AND OUT swap '_IN_' with '_' in SpecControl swap '_OUT_' with '_' in SpecControl * GET THE SPEC LIMIT FOR THIS FIELD SpecLimit = get_property( SpecControl, 'TEXT' ) if index( CurControl, 'FOV', 1 ) or index( CurControl, 'SCRATCH_LEN', 1 ) then AddMsg = 'NOT TO EXCEED' SpecLimit += 1 ;* CAUSE ON THESE TWO CONTROLS THEY CAN EQUAL THE SPEC, THEY DON'T HAVE TO BE LESS MinusOne = 1 end else AddMsg = 'LESS THAN' MinusOne = 0 end if CurValue >= SpecLimit then MsgInfo = '' MsgInfo = CurValue:' is out of the surface specifiaction of ':quote( AddMsg ):' ':SpecLimit-MinusOne:'.' MsgInfo = '!' Void = msg( '', MsgInfo ) end return *============================================================================* RDS_VIEW: SkipSavewarn = Get_Property(@WINDOW,'@SKIP_SAVEWARN') IF SkipSaveWarn THEN Set_Property(@WINDOW,'SAVEWARN',0) Set_Property(@WINDOW,'@SKIP_SAVEWARN','') END *IF Get_Property( @window, 'SAVEWARN' ) THEN * MsgInfo = '' * MsgInfo = 'You must either save this first or clear the form.' * MsgInfo = '!' * Void = msg( '', MsgInfo ) *END ELSE RdsWindowToCall = Get_Property( @window, '@RdsWindowToCall' ) QbfList = Get_Property( @window, 'QBFLIST' ) QbfPos = Get_Property( @window, 'QBFPOS' ) IF QbfList THEN convert @fm to @vm in QbfList END ELSE QbfList = Get_Property( @window:'.RDS_NO', 'TEXT' ) END IF Get_Property( @window, 'SAVEWARN' ) THEN ;*************** ;* JCH Void = Send_Event(@WINDOW,'WRITE') ;*************** END ;*************** Parent = Get_Property(@Window, 'PARENT') Void = Send_Event( @window, 'CLOSE' ) Void = Start_Window( RdsWindowToCall, Parent, QbfList:'*CENTER', '', '' ) IF QbfPos THEN Void = Set_Property( RdsWindowToCall, 'QBFPOS', QbfPos ) Void = Send_Event( RdsWindowToCall, 'READ' ) * The reason we have to fill in the title with the qbf stuff is * when setting the qbfpos and then calling read it does not show * N of N in the title - OI bug a boo CurTitle = Get_Property( RdsWindowToCall, 'TEXT' ) CurTitle:= ' - ' Void = Set_Property( RdsWindowToCall, 'TEXT', CurTitle ) END *END RETURN *============================================================================* READ_STORE: * GET ARRAY OF ALL UNIQUE FIELDS gosub get_fields_values Void = set_property( @window, '@Fields', Fields ) ;* List of database associated fields in this control Void = set_property( @window, '@Values', Values ) ;* Field values after record read (before changes) if memberof( @user4, 'SUPERVISOR' ) or memberof( @user4, 'LEAD' ) then begin case case @window = 'RDS_PRE_EPI' *DateTimeCtls = 'PRE_EPI_SIG_DATE/PRE_EPI_SIG_TIME' DateTimeCtls = '' * THIS IS NOW A GRID FOR MULTIPLE CLEANINGS case @window = 'RDS_POST_EPI' DateTimeCtls = 'POST_EPI_SIG_DATE/POST_EPI_SIG_TIME/POST_EPI_SUP_SIG_DATE/POST_EPI_SUP_SIG_TIME' case @window = 'RDS_UNLOAD' DateTimeCtls = 'OP_OUT_DATE/OP_OUT_TIME' case @window = 'RDS' DateTimeCtls = 'FW_SIG_DATE/FW_SIG_TIME/OP_IN_DATE/OP_IN_TIME' case Otherwise$ Null end case swap '/' with @rm:@window:'.' in DateTimeCtls DateTimeCtls = @window:'.':DateTimeCtls Void = set_property( DateTimeCtls, 'ENABLED', 1 ) end return *============================================================================* WRITE_STAMP: * Get array of all unique fields OrigFields = Get_Property( @window, '@Fields' ) ;* Fields with database columns in this form OrigValues = Get_Property( @window, '@Values' ) ;* Post-Read values of associated columns GOSUB Get_Fields_Values ;* Returns same list of associated values as in @FIELDS ;* but @VALUES is now Pre_Write values Acnt = FieldCount( OrigFields, @FM ) UpdateFields = '' UpdateUserNames = '' FOR I = 1 TO Acnt FieldToCheck = OrigFields IF Values <> OrigValues THEN UpdateFields<1,-1> = FieldToCheck UpdateUserNames<1,-1> = @USER4 END NEXT I * * * * * * * This is the new hook to the RDS_Audit system * * * * * * * RDSNo = Get_Property(@WINDOW,'ID') parms = RDSNo:@RM:UpdateUserNames:@RM:UpdateFields obj_RDS_Audit('Update',parms) IF Get_Status(errCode) THEN CALL ErrMsg(errCode) END Void = set_property( @window, '@Fields', '' ) Void = set_property( @window, '@Values', '' ) RETURN *============================================================================* Get_Fields_Values: Fields = '' Values = '' FieldNos = '' *AllControls = utility( 'OBJECTLIST', @window, '' ) ;* This returns all of the menu items in it AllControls = Get_Property(@WINDOW,'CTRLMAP') Acnt = FieldCount( AllControls, @fm ) FOR I = 1 TO Acnt ThisControl = AllControls thisControls = ThisControl:@RM:ThisControl:@RM:ThisControl:@RM:ThisControl thisProps = 'TYPE':@RM:'COLUMN':@RM:'POS':@RM:'PART' thisVals = Get_Property(thisControls,thisProps) Type = thisVals[1,@RM] Column = thisVals[COL2()+1,@RM] Pos = thisVals[COL2()+1,@RM] Part = thisVals[COL2()+1,@RM] IF Type = 'EDITTABLE' or Type = 'EDITFIELD' or Type = 'EDITBOX' or Type = 'COMBOBOX' THEN * Need to loop through the column cause it will be multi valued * If it is an edittable CCnt = fieldcount( Column, @svm ) FOR J = 1 TO CCnt ThisColumn = Column<1,1,J> thisPos = Pos<1,1,J> thisPart = Part<1,1,J> IF ThisPos NE '' THEN thisFieldNo = thisPos ELSE thisFieldNo = '' IF thisPart NE '' AND thisPart NE 0 THEN thisFieldNo := '.':thisPart IF ThisColumn <> '' then LOCATE ThisColumn in Fields by 'AL' USING @FM SETTING Fpos ELSE Fields = INSERT( Fields, Fpos, 0, 0, ThisColumn ) FieldNos = INSERT( FieldNos, FPos, 0, 0, thisFieldNo ) IF Type = 'EDITTABLE' THEN Values = insert( Values, FPos, 0, 0, get_property( ThisControl, 'ARRAY' ) ) END ELSE Values = insert( Values, FPos, 0, 0, get_property( ThisControl, 'TEXT' ) ) END END ;* End of Locate END NEXT J END NEXT I RETURN *============================================================================* VIEW_MOD_INFO: RDSNo = Get_Property(@WINDOW,'ID') Comm_RDS('ViewAudit',RDSNo) RETURN *============================================================================* CALL_SURF_INSP: PsnId = get_property( @window:'.PSN', 'TEXT' ) Void = dialog_box( 'RDS_SURF_INSP', @window, PsnId:char(245):'CENTER' ) return *============================================================================* CALL_CLEAN: PsnId = get_property( @window:'.PSN', 'TEXT' ) Void = dialog_box( 'RDS_CLEAN', @window, PsnId:char(245):'CENTER' ) return *============================================================================* CALL_RDS_METROLOGY: PsnId = get_property( @window:'.PSN', 'TEXT' ) RDSId = get_property( @window:'.RDS_NO', 'TEXT' ) Void = dialog_box( 'RDS_METROLOGY', @window, PsnId:char(245):RDSId:char(245):'*CENTER' ) return *============================================================================* TW_ACCT_ROW_VAL: AllTools = get_property( @window, '@Tools' ) AllTypes = get_property( @window, '@Types' ) convert @lower_case to @upper_case in AllTypes AllProves = get_property( @window, '@Proves' ) convert @lower_case to @upper_case in AllProves AllMeas = get_property( @window, '@AllMeas' ) * GET THE TYPE THAT THEY ARE ACCOUNTING FOR Type = get_property( @window, '@TWType' ) InfoArray = get_property( @window:'.TW_INFO', 'ARRAY' ) ICnt = fieldcount( InfoArray<1>, @vm ) TCnt = fieldcount( AllTools, @vm ) DataCols = '' ValidPos = '' for i = 1 to ICnt ToolEntered = InfoArray CurCode = InfoArray if xlate( 'TW_CODES', CurCode, tw_codes_run_data_required$, 'X' ) then for j = 1 to TCnt if ToolEntered = AllTools<1,j> then if ( Type = AllTypes<1,j> ) or ( Type = AllProves<1,j> ) then * if ( CurCode = 5 ) then * CODE IS FIRST WAFER INSPECTION ONLY ALLOW ENTRY IF IT IS THE * HgCv OR SRP OTHERWISE THE DATA IS REDUNDANT WITH THE FIRSTWAFER AREA OF RDS if ToolEntered = 'HgCv' or ToolEntered = 'SRP' then DataCols<-1> = AllMeas<1,j> ValidPos> = true$ end end else * THEY HAVE GOT THE RIGHT TOOL AND THE RIGHT FIRST WAFER OR PROVE-IN TYPE DataCols<-1> = AllMeas<1,j> ValidPos> = true$ end end end next j end else * USAGE CODE DOES NOT REQUIRE DATA end next i MCnt = fieldcount( DataCols, @fm ) Styles = send_message( @window:'.TW_INFO', "COLSTYLE", 0, '' ) for i = 1 to Mcnt Styles> = bitand( Styles>, bitnot(Hidden$) ) next i Styles = send_message( @window:'.TW_INFO', "COLSTYLE", 0, Styles ) Void = set_property( @window:'.TW_INFO', "AUTOSIZECOL", 4 ) ValidArray = '' for i = 1 to ICnt for j = TWInfoArrayThick$ to TWInfoArrayRHO$ ;* LOOP THROUGH THE COLUMNS THAT ARE DYNAMIC if ValidPos then Void = send_message( @window:'.TW_INFO', 'COLOR_BY_POS', j, i, White$ ) ValidArray = 0 end else Void = send_message( @window:'.TW_INFO', 'COLOR_BY_POS', j, i, Black$ ) ValidArray = 1 end next j next i Void = set_property( @window, '@ValidArray', ValidArray ) return *===============================================================================================* SET_ADJUST_PARAMS: return *===============================================================================================* SET_ML_LIMITS: CurLayer = get_property( @window, '@CurLayer' ) RecipeID = get_property( @window:'.RECIPE_NO', 'TEXT' ) LayerInfo = xlate( 'RECIPE', RecipeID, recipe_layer_info$, 'X' ) convert char(248) to @fm in LayerInfo LayToUse = LayerInfo DepTimeMin = LayToUse<1,RecLEpiDepTimeMin$> DepTimeMax = LayToUse<1,RecLEpiDepTimeMax$> DopFlowMin = LayToUse<1,RecLEpiDopantFlowMin$> DopFlowMax = LayToUse<1,RecLEpiDopantFlowMax$> DepTimeLimits = oconv( DepTimeMin, 'MD1' ):'~':oconv( DepTimeMax, 'MD1' ) DopFlowLimits = oconv( DopFlowMin, 'MD2' ):'~':oconv( DopFlowMax, 'MD2' ) Void = set_property( @window:'.DEP_TIME_LIMITS', 'TEXT', DepTimeLimits ) Void = set_property( @window:'.DOP_FLOW_LIMITS', 'TEXT', DopFlowLimits ) return *===============================================================================================*