Compile function TOOL_PARMS_EVENTS(CtrlEntId, Event, @PARAMS) ! This form has been deprecated in favor of NDW_TOOL_PARMS_EVENTS /*********************************************************************************************************************** This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written permission from Infineon. Name : TOOL_PARMS_EVENTS Description : This function acts as a commuter module for all events related to this window. Notes : Commuter Modules are automatically called from the Promoted_Events function which is called by the application-specific promoted event handler. This makes it possible to add QuickEvents that need to execute Basic+ logic without having use the Form Designer to make the association, although this is limited to the events which are currently promoted. If the form needs to call the commuter module directly then the QuickEvent parameters should be formatted like this: '@SELF','@EVENT',['@PARAM1','@PARAMx'] Parameters : CtrlEntId [in] -- The fully qualified name of the control calling the promoted event Event [in] -- The event being executed. See the Notes section regarding "PRE" events Param1-15 [in] -- Additional event parameter holders EventFlow [out] -- Set to 1 or 0 so the calling event knows whether or not to chain forward. See comments in EVENT_SETUP insert History : (Date, Initials, Notes) 08/31/18 djs Created initial commuter module. 09/11/18 djs Form and commuter module ready for UAT. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #window TOOL_PARMS $Insert RDS_EQUATES $Insert LOGICAL $Insert EVENT_SETUP $Insert RLIST_EQUATES $Insert RECIPE_EQUATES $Insert RDS_LAYER_EQUATES $Insert TOOL_PARMS_EQUATES $Insert RECIPE_PARMS_EQU $Insert DICT_EQUATES $Insert MSG_EQUATES EQU HIDDEN$ TO 32 Equ COL.LAYER_ID To 1 Equ COL.DEPOSIT To 2 Equ COL.DILUENT To 3 Equ COL.DOPANT_FLOW To 4 Equ COL.HCL_FLOW To 5 Equ COL.BAKE_TIME To 6 Equ COL.H2_FLOW To 7 Equ COL.TCS_FLOW To 8 Equ COL.DCS_FLOW To 9 Equ COL.AUX_1_FLOW To 10 Equ COL.AUX_2_FLOW To 11 Equ COL.F_OFFSET To 12 Equ COL.S_OFFSET To 13 Equ COL.R_OFFSET To 14 Equ COL.SUSC_ETCH To 15 Equ COL.ETCH_1 To 16 Equ COL.ETCH_2 To 17 Equ COL.ETCH_3 To 18 Equ COL.UNLOAD_TEMP To 19 Declare Subroutine Set_Property, End_Dialog, Send_Event, Set_Status, obj_WO_Mat, Btree.Extract, Send_Message Declare Subroutine ErrMsg, Set_Property, obj_AppWindow, Send_Event, obj_WO_Mat_QA, obj_Tables, Msg Declare Subroutine Start_Window, End_Window, Database_Services Declare Subroutine SRP_EditTable_Manager, SRP_Show_Window, Rds_Services, Form_Services, Error_Services Declare Function Get_Property, Get_Status, Dialog_Box, obj_WM_Out, set_WinMsgVal, Form_Services, Error_Services Declare Function Msg, obj_WO_Mat, Send_Message, obj_Tables, Start_Window, End_Window, QA_Services Declare Function SRP_EditTable_Manager, Database_Services, Material_Services, Rds_Services, RGB, Obj_Recipe ErrTitle = 'Error in NDW_QA_Met_Result_Events' ErrorMsg = '' Result = '' SubclassInfo = Form_Services('FindSubclassControl') Subclass = SubclassInfo<1> // Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler. If Event EQ 'OLE' then Transfer Event to OIEvent Transfer Param1 to Event Transfer Param2 to Param1 Transfer Param3 to Param2 * Transfer Param4 to Param3 * Transfer Param5 to Param4 * Transfer Param6 to Param5 * Transfer Param7 to Param6 * Transfer Param8 to Param7 end GoToEvent Event for CtrlEntId else // Event not implemented end Return EventFlow else EVENT_CONTINUE$ //----------------------------------------------------------------------------- // EVENT HANDLERS //----------------------------------------------------------------------------- Event WINDOW.CREATE(CreateParam) // Fill Reactor Combo Box Query = 'SELECT REACTOR WITH REACT_NO GT 0 AND WITH REACT_NO LT 100 BY REACT_NO' RList(Query, TARGET_SAVELIST$, 'REACTOR_LIST', 'Current List of Reactors', False$) ReactorList = Database_Services('ReadDataRow', 'SYSLISTS', 'REACTOR_LIST') // Remove field containing list description ReactorList = Delete(ReactorList, 1, 0, 0) Set_Property(@Window : '.COMBO_REACTOR', 'LIST', ReactorList) // Fill Recipe Combo Box Query = 'SELECT RECIPE BY SEQ' RList(Query, TARGET_SAVELIST$, 'RECIPE_LIST', 'Current List of Recipes', False$) RecipeList = Database_Services('ReadDataRow', 'SYSLISTS', 'RECIPE_LIST') // Remove field containing list description RecipeList = Delete(RecipeList, 1, 0, 0) Set_Property(@Window : '.COMBO_RECIPE', 'LIST', RecipeList) Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', False$) Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', False$) GoSub Setup_OLE_Controls SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, FormSize) End Event Event COMBO_REACTOR.CHANGED(NewData) GoSub FillForm Set_Property(CtrlEntId, 'MODIFIED', False$) end event Event COMBO_REACTOR.CHAR(VirtCode, ScanCode, CtrlKey, ShiftKey, AltKey) Set_Property(CtrlEntId, 'MODIFIED', True$) end event Event COMBO_REACTOR.LOSTFOCUS(Flag, FocusID) ModifiedFlag = Get_Property(CtrlEntID, 'MODIFIED') If ModifiedFlag EQ True$ then GoSub FillForm Set_Property(CtrlEntId, 'MODIFIED', False$) end end event Event COMBO_RECIPE.CHANGED(NewData) GoSub FillRecipeInfo // Clear the rest of the form until the user selects a PSN by which we can further, // which is required to identify any TOOL_PARMS records. Set_Property(@Window : '.COMBO_PSN', 'TEXT', '') Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', '') Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', '') Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', '') Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY', '') end event Event COMBO_PSN.CHANGED(NewData) Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', '') Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', '') Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', '') Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY', '') GoSub FillDatetimeInfo GoSub FillRecipeParms GoSub FillRecipeLimits GoSub FormatEditTableColumns end event Event EDT_RECIPE_PARMS.INSERTROW(RowNum) Array = Get_Property(CtrlEntID, 'ARRAY') Layers = Array NumRows = DCount(Layers, @VM) Begin Case Case NumRows EQ 0 LayerID = 'L1' NewRowNum = 1 Case NumRows EQ 1 If Index(Layers, 'L1', 1) then LayerID = 'L2' NewRowNum = 2 end else LayerID = 'L1' NewRowNum = 1 end Case NumRows EQ 2 Begin Case Case Index(Layers, 'L1', 1) and Index(Layers, 'L2', 1) LayerID = '2' NewRowNum = 3 Case Index(Layers, 'L1', 1) and Index(Layers, '2', 1) LayerID = 'L2' NewRowNum = 2 Case Index(Layers, 'L2', 1) and Index(Layers, '2', 1) LayerId = 'L1' NewRowNum = 1 End Case Case Otherwise$ LayerID = -1 End Case If LayerID NE -1 then Array = Insert(Array, COL.LAYER_ID, NewRowNum, 0, LayerID) Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', Array) Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$) Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', True$) end end event Event EDT_RECIPE_PARMS.CHANGED(NewData) Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$) Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', True$) end event Event EDT_RECIPE_PARMS.DELETEROW(RowNum, RowData) Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$) Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', True$) end event Event BTN_LOAD_CURR_RUN_PARMS.CLICK() ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT') If ReactorNo NE '' then GoSub FillForm Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', False$) Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', False$) end end event Event BTN_SET_CURR_RUN_PARMS.CLICK() ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT') PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT') RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT') If ReactorNo NE '' and PSN NE '' and RecipeID NE '' then CurrentDTM = Date():'.':Time() FormattedDTM = OConv(CurrentDTM, 'DT/^3H') Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', FormattedDTM) InternalDTMList = Get_Property(@Window, '@INTERNALDTMS', InternalDTMList) ExternalDTMList = Get_Property(@Window, '@EXTERNALDTMS', ExternalDTMList) InternalDTMList = Insert(InternalDTMList, 1, 0, 0, CurrentDTM) ExternalDTMList = Insert(ExternalDTMList, 1, 0, 0, FormattedDTM) Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', ExternalDTMList) Set_Property(@Window, '@INTERNALDTMS', InternalDTMList) Set_Property(@Window, '@EXTERNALDTMS', ExternalDTMList) NewToolParmKey = RecipeID:'*':PSN:'*':ReactorNo:'*':CurrentDTM NewToolParmRec = '' RecipeParmsArray = Get_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY') LayerIDs = RecipeParmsArray Dopant = Get_Property(@Window : '.EDL_DOPANT', 'TEXT') EpiDiluent = Get_Property(@Window : '.EDL_DILUTENT', 'TEXT') // Format Data to save parameters in internal format ColNames = 'LS_ID':@FM:'EPI_TIME':@FM:'DILUENT_ADJ_PARAM':@FM:'DOPANT_FLOW':@FM:'HCL_FLOW':@FM ColNames := 'BAKE_TIME':@FM:'EPI_H2_FLOW':@FM:'TCS_FLOW':@FM:'DCS_FLOW':@FM:'AUX1':@FM:'AUX2':@FM:'F_OFFSET' ColNames := @FM:'S_OFFSET':@FM:'R_OFFSET':@FM:'SUSC_ETCH':@FM:'ETCH1':@FM:'ETCH2':@FM:'ETCH3':@FM:'UNLOAD_TEMP' For each ColName in ColNames using @FM Setting Col ParamData = RecipeParmsArray Conversion = Xlate('DICT.TOOL_PARMS', ColName, DICT_CONV$, 'X') If Conversion NE '' then ParamData = IConv(ParamData, Conversion) RecipeParmsArray = ParamData end next ColName For each LayerID in LayerIDs using @VM setting vPos NewToolParmRec = LayerID NewToolParmRec = Dopant NewToolParmRec = EpiDiluent NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray NewToolParmRec = False$ ; // This field appears not be used at the moment NewToolParmRec = @USER4 NewToolParmRec = RecipeParmsArray NewToolParmRec = RecipeParmsArray Next LayerID Database_Services('WriteDataRow', 'TOOL_PARMS', NewToolParmKey, NewToolParmRec, True$) // Disable the Load and Set buttons so that the user knows these are the current run parameters Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', False$) Set_Property(@Window : '.BTN_SET_CURR_RUN_PARMS', 'ENABLED', False$) end end event Event COMBO_PARM_DTM.CHANGED(NewData) GoSub FillRecipeParms GoSub FormatEditTableColumns Set_Property(@Window : '.BTN_LOAD_CURR_RUN_PARMS', 'ENABLED', True$) end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Setup_OLE_Controls: Qualify = '' Qualify<1> = 1 Qualify<4> = 0 return ClearCursors: For counter = 0 to 8 ClearSelect counter Next counter return FillRecipeInfo: RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT') If RecipeID NE '' then RecipeRec = Database_Services('ReadDataRow', 'RECIPE', RecipeID) RecipeName = RecipeRec RecipePSNs = RecipeRec RecipeDopant = RecipeRec RecipeDiluent = RecipeRec Set_Property(@Window : '.EDL_RECIPE_NAME', 'TEXT', RecipeName) Set_Property(@Window : '.EDL_DOPANT', 'TEXT', RecipeDopant) Set_Property(@Window : '.EDL_DILUENT', 'TEXT', RecipeDiluent) Convert @VM to @FM in RecipePSNs Set_Property(@Window : '.COMBO_PSN', 'LIST', RecipePSNs) end return FillDatetimeInfo: ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT') PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT') RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT') If ReactorNo NE '' and PSN NE '' and RecipeID NE '' then // Lookup associated TOOL_PARMS records Query = 'SELECT TOOL_PARMS WITH REACTOR EQ ':ReactorNo:' AND WITH PSN EQ ':PSN:' AND WITH RECIPE EQ ' Query := RecipeID:' BY-DSND DATETIME' GoSub ClearCursors Set_Status(0) RList(Query, TARGET_ACTIVELIST$, '', '' '') ErrorCode = '' If Get_Status(ErrorCode) then ErrorMsg = 'Error calling RList(): error code ':ErrorCode Error_Services('Add', ErrorMsg) return end Done = False$ InternalDTMList = '' ExternalDTMList = '' Loop Readnext ToolParmKey Else Done = True$ Until Done ThisDTM = ToolParmKey[-1, 'B*'] InternalDTMList<-1> = ThisDTM ExternalDTMList<-1> = OConv(ThisDTM,'DT/^3H') Repeat If ExternalDTMList NE '' then // TOOL_PARM records found -> Populate form with the latest configuration. Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', ExternalDTMList) MostRecentInternalDTM = InternalDTMList<1> MostRecentExternalDTM = ExternalDTMList<1> Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', MostRecentExternalDTM) // Read most recent Tool Parameter record ToolParmKey = RecipeID:'*':PSN:'*':ReactorNo:'*':MostRecentInternalDTM ToolParmRec = Database_Services('ReadDataRow', 'TOOL_PARMS', ToolParmKey) end else // Datetime query returned zero records, therefore there are no configuration records for this // reactor, recipe, and PSN combination. Query RDS table for the most recent RDS that matches this // criteria to reference as the last known configuration. Then create and save the configuration // record to the TOOL_PARMS database table. MsgDef = '' MsgDef = 'Building tool parameter record.' :@SVM: 'Please wait...' MsgDef = 'U' MsgDef = 'C' MsgUp = Msg(@Window, MsgDef) GoSub CreateToolParmsRec Msg(@Window, MsgUp) ToolParmRec = NewToolParmRec InternalDTMList = CurrentDTM ExternalDTMList = FormattedDTM end // Save internal and external Datetime lists for use elsewhere. This is necessary to correctly // identify records due to floating point rounding errors associated with Datetime types. Set_Property(@Window, '@INTERNALDTMS', InternalDTMList) Set_Property(@Window, '@EXTERNALDTMS', ExternalDTMList) end return CreateToolParmsRec: ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT') PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT') RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT') CurrentDTM = Date():'.':Time() FormattedDTM = OConv(CurrentDTM, 'DT/^3H') Set_Property(@Window : '.COMBO_PARM_DTM', 'TEXT', FormattedDTM) Set_Property(@Window : '.COMBO_PARM_DTM', 'LIST', FormattedDTM) NewToolParmKey = RecipeID:'*':PSN:'*':ReactorNo:'*':CurrentDTM NewToolParmRec = '' Query = 'SELECT RDS WITH RECIPE_NO EQ ':RecipeID:' AND WITH PROD_SPEC_ID EQ ':PSN:' AND WITH REACTOR EQ ' Query := ReactorNo:' BY-DSND DATE_IN' GoSub ClearCursors Set_Status(0) RList(Query, TARGET_ACTIVELIST$, '', '', '') If Get_Status(ErrorCode) then ErrorMsg = 'Error calling RList(): error code ':ErrorCode Error_Services('Add', ErrorMsg) return end NumResultRows = @RecCount If NumResultRows GT 0 then Readnext RDSKey then RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey) RDSLayerKeys = RDSRec For each RDSLayerKey in RDSLayerKeys using @VM setting vPos RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey) LayerID = RDSLayerKey[-1, 'B*'] NewToolParmRec = LayerID NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = @USER4 NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec Next RDSLayerKey GoSub ClearCursors end end else // No RDS records found that match this criteria. Widen the query to search the most recent // RDS that matches the Recipe ID and PSN, but to any reactor. Query = 'SELECT RDS WITH RECIPE_NO EQ ':RecipeID:' AND WITH PROD_SPEC_ID EQ ':PSN:' BY-DSND DATE_IN' GoSub ClearCursors Set_Status(0) RList(Query, TARGET_ACTIVELIST$, '', '', '') If Get_Status(ErrorCode) then ErrorMsg = 'Error calling RList(): error code ':ErrorCode Error_Services('Add', ErrorMsg) return end Readnext RDSKey then RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKey) RDSLayerKeys = RDSRec For each RDSLayerKey in RDSLayerKeys using @VM setting vPos RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKey) LayerID = RDSLayerKey[-1, 'B*'] NewToolParmRec = LayerID NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec NewToolParmRec = @USER4 NewToolParmRec = RDSLayerRec NewToolParmRec = RDSLayerRec Next RDSLayerKey GoSub ClearCursors end end Database_Services('WriteDataRow', 'TOOL_PARMS', NewToolParmKey, NewToolParmRec) If Error_Services('NoError') else Error_Services('Add', 'Error writing TOOL_PARMS record: ':NewToolParmKey) end return FillForm: ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT') MostRecentRDS = Xlate('REACT_STATE', ReactorNo, 'LAST_RDS_NO', 'X') PSN = Xlate('RDS', MostRecentRDS, 'PROD_SPEC_ID', 'X') PRSLayerKey = Xlate('PROD_SPEC', PSN, 'PRS_LAYER_KEY', 'X') FirstLayerKey = PRSLayerKey<1,1> RecipeID = Xlate('PRS_LAYER', FirstLayerKey, 'RECIPE_ID', 'X') If ReactorNo NE '' and PSN NE '' and RecipeID NE '' then // Fill most recent PSN, Recipe, and DateTime associated with the selected reactor Set_Property(@Window : '.COMBO_PSN', 'TEXT', PSN) Set_Property(@Window : '.COMBO_RECIPE', 'TEXT', RecipeID) GoSub FillRecipeInfo GoSub FillDatetimeInfo GoSub FillRecipeParms GoSub FillRecipeLimits GoSub FormatEditTableColumns end return FillRecipeParms: ReactorNo = Get_Property(@Window : '.COMBO_REACTOR', 'TEXT') PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT') RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT') ExternalDTM = Get_Property(@Window : '.COMBO_PARM_DTM', 'TEXT') InternalDTMList = Get_Property(@Window, '@INTERNALDTMS') ExternalDTMList = Get_Property(@Window, '@EXTERNALDTMS') InternalDTM = '' Locate ExternalDTM in ExternalDTMList using @FM setting fPos then InternalDTM = InternalDTMList end ToolParmKey = RecipeID:'*':PSN:'*':ReactorNo:'*':InternalDTM ToolParmRec = Database_Services('ReadDataRow', 'TOOL_PARMS', ToolParmKey) If ToolParmRec NE '' then RecipeParmsArray = '' RecipeLayerKeys = ToolParmRec For each LayerKey in RecipeLayerKeys using @VM setting vPos RecipeParmsArray = LayerKey RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec RecipeParmsArray = ToolParmRec Next LayerKey Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', RecipeParmsArray) end return FillRecipeLimits: PSN = Get_Property(@Window : '.COMBO_PSN', 'TEXT') RecipeID = Get_Property(@Window : '.COMBO_RECIPE', 'TEXT') RecipeRec = Database_Services('ReadDataRow', 'RECIPE', RecipeID) RecipeParms = Get_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY') LayerIDs = '' If RecipeParms NE '' then LayerIDs = RecipeParms end else // New Tool Parms record -> fetch recipe layer ids PRSLayerNos = Xlate('PROD_SPEC', PSN, 'LAYER_NO', 'X') For each LayerNo in PRSLayerNos using @VM setting vPos PRSLayerKey = PSN:'*':LayerNo LSID = Xlate('PRS_LAYER', PRSLayerKey, 'LS_ID', 'X') LayerIDs<1,-1> = LSID Next LayerNo // Fill Recipe Parms edit table layer IDs for user Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', LayerIDs) end LimitsArray = '' For each LayerID in LayerIDs using @VM setting LayerIndex RecipeLimits = Obj_Recipe('GetLimits', RecipeID:@RM:PSN:@RM:LayerID) LimitsArray = LayerID If RecipeLimits NE '' and RecipeLimits NE '' then Deposit = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD1') Swap @SVM with ' ~ ' in Deposit end else Deposit = '' end If RecipeLimits NE '' and RecipeLimits NE '' then Diluent = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD2') Swap @SVM with ' ~ ' in Diluent end else Diluent = '' end If RecipeLimits NE '' and RecipeLimits NE '' then DopantFlow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD2') Swap @SVM with ' ~ ' in DopantFlow end else DopantFlow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then HCLFlow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD2') Swap @SVM with ' ~ ' in HCLFlow end else HCLFlow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then BakeTime = OCONV(RecipeLimits:@SVM:RecipeLimits,'[SECONDS_CONV]') Swap @SVM with ' ~ ' in BakeTime end else BakeTime = '' end If RecipeLimits NE '' and RecipeLimits NE '' then H2Flow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD0') Swap @SVM with ' ~ ' in H2Flow end else H2Flow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then TCSFlow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD1') Swap @SVM with ' ~ ' in TCSFlow end else TCSFlow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then DCSFlow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD0') Swap @SVM with ' ~ ' in DCSFlow end else DCSFlow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then AUX1Flow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD2') Swap @SVM with ' ~ ' in AUX1Flow end else AUX1Flow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then AUX2Flow = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD2') Swap @SVM with ' ~ ' in AUX2Flow end else AUX2Flow = '' end If RecipeLimits NE '' and RecipeLimits NE '' then FOffset = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD0') Swap @SVM with ' ~ ' in FOffset end else FOffset = '' end If RecipeLimits NE '' and RecipeLimits NE '' then SOffset = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD0') Swap @SVM with ' ~ ' in SOffset end else SOffset = '' end If RecipeLimits NE '' and RecipeLimits NE '' then ROffset = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD0') Swap @SVM with ' ~ ' in ROffset end else ROffset = '' end If RecipeLimits NE '' and RecipeLimits NE '' then SuscEtch = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD1') Swap @SVM with ' ~ ' in SuscEtch end else SuscEtch = '' end If RecipeLimits NE '' and RecipeLimits NE '' then Etch1 = OCONV(RecipeLimits:@SVM:RecipeLimits,'[SECONDS_CONV]') Swap @SVM with ' ~ ' in Etch1 end else Etch1 = '' end If RecipeLimits NE '' and RecipeLimits NE '' then Etch2 = OCONV(RecipeLimits:@SVM:RecipeLimits,'[SECONDS_CONV]') Swap @SVM with ' ~ ' in Etch2 end else Etch2 = '' end If RecipeLimits NE '' and RecipeLimits NE '' then Etch3 = OCONV(RecipeLimits:@SVM:RecipeLimits,'[SECONDS_CONV]') Swap @SVM with ' ~ ' in Etch3 end else Etch3 = '' end If RecipeLimits NE '' and RecipeLimits NE '' then UnloadTemp = OCONV(RecipeLimits:@SVM:RecipeLimits,'MD0') Swap @SVM with ' ~ ' in UnloadTemp end else UnloadTemp = '' end LimitsArray = Deposit LimitsArray = Diluent LimitsArray = DopantFlow LimitsArray = HCLFlow LimitsArray = BakeTime LimitsArray = H2Flow LimitsArray = TCSFlow LimitsArray = DCSFlow LimitsArray = AUX1Flow LimitsArray = AUX2Flow LimitsArray = FOffset LimitsArray = SOffset LimitsArray = ROffset LimitsArray = SuscEtch LimitsArray = Etch1 LimitsArray = Etch2 LimitsArray = Etch3 LimitsArray = UnloadTemp Next LayerID Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY', LimitsArray) return FormatEditTableColumns: RecipeParms = Get_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY') RecipeLimits = Get_Property(@Window : '.EDT_RECIPE_LIMITS', 'ARRAY') ParameterStyles = Send_Message(@Window : '.EDT_RECIPE_PARMS', 'COLSTYLE', 0, '') LimitStyles = Send_Message(@Window : '.EDT_RECIPE_LIMITS', 'COLSTYLE', 0, '') ColNames = 'LS_ID':@FM:'EPI_TIME':@FM:'DILUENT_ADJ_PARAM':@FM:'DOPANT_FLOW':@FM:'HCL_FLOW':@FM ColNames := 'BAKE_TIME':@FM:'EPI_H2_FLOW':@FM:'TCS_FLOW':@FM:'DCS_FLOW':@FM:'AUX1':@FM:'AUX2':@FM:'F_OFFSET' ColNames := @FM:'S_OFFSET':@FM:'R_OFFSET':@FM:'SUSC_ETCH':@FM:'ETCH1':@FM:'ETCH2':@FM:'ETCH3':@FM:'UNLOAD_TEMP' For each ColName in ColNames using @FM Setting Col RecipeLimitsColData = RecipeLimits RecipeParmsColData = RecipeParms Convert @VM to '' in RecipeLimitsColData Convert @VM to '' in RecipeParmsColData If RecipeLimitsColData = '' and RecipeParmsColData = '' then ParameterStyles = BitOr( ParameterStyles, HIDDEN$ ) ;* Column not used -> Hide LimitStyles = BitOr( LimitStyles, HIDDEN$ ) end else ParameterStyles = BitAnd( ParameterStyles, BitNot(HIDDEN$) ) ;* Column used -> Show LimitStyles = BitAnd( LimitStyles, BitNot(HIDDEN$) ) ParamData = RecipeParms Conversion = Xlate('DICT.TOOL_PARMS', ColName, DICT_CONV$, 'X') If Conversion NE '' then ParamData = OConv(ParamData, Conversion) RecipeParms = ParamData end end next ColName ParameterStyles = Send_Message(@WINDOW : '.EDT_RECIPE_PARMS', 'COLSTYLE', 0, ParameterStyles) LimitStyles = Send_Message(@WINDOW : '.EDT_RECIPE_LIMITS', 'COLSTYLE', 0, LimitStyles) Set_Property(@Window : '.EDT_RECIPE_PARMS', 'ARRAY', RecipeParms) Set_Property(@Window : '.EDT_RECIPE_PARMS', 'AUTOSIZECOL', 16 ) Set_Property(@Window : '.EDT_RECIPE_LIMITS', 'AUTOSIZECOL', 16 ) return