Compile function DBW_PROD_SPEC_GAN_EVENTS(CtrlEntId, Event, @PARAMS) /*********************************************************************************************************************** Name : DBW_PROD_SPEC_GAN_EVENTS Description : Commuter module for the DBW_PROD_SPEC_GAN form. Notes : Application errors should be logged using the Error Services module. There are a few methodological assumptions built into way errors are managed which are important to understand in order to properly work with Error Services: - The term 'top' refers to the originating procedure of a call stack and the term 'bottom' refers to the last routine (or the current routine) within a call stack. Within the OpenInsight Debugger this will appear backwards since the originating procedure always appears at the bottom of the list and the current routine appears at the top of the list. We are using this orientation because it is common to refer to the process of calling other procedures as 'drilling down'. - The reason for defining the orientation of the call stack is because Error_Services allows for multiple error conditions to be appended to an original error. In most cases this will happen when a procedure at the bottom of the stack generates an error condition and then returns to its calling procedure. This higher level procedure can optionally add more information relevant to itself. This continues as the call stack 'bubbles' its way back to the top to where the originating procedure is waiting. - Native OpenInsight commands that handle errors (e.g., Set_Status, Set_FSError, Set_EventStatus) preserve their error state until explicitly cleared. This can hinder the normal execution of code since subsequent procedures (usually SSPs) will fail if a pre-existing error condition exists. Our philosophy is that error conditions should automatically be cleared before a new procedure is executed to avoid this problem. However, the nature of Basic+ does not make this easy to automate for any given stored procedure. Therefore, if a stored procedure wants to conform to our philosophy then it should include a call into the 'Clear' service request at the top of the program. Alternatively this can be done through a common insert (see SERVICE_SETUP for example.) - Service modules will use the SERVICE_SETUP insert and therefore automatically clear out any error conditions that were set before. Parameters : Service [in] -- Name of the service being requested Param1-10 [in/out] -- Additional request parameter holders Response [out] -- Response to be sent back to the Controller (MCP) or requesting procedure Metadata : History : (Date, Initials, Notes) 06/06/20 djs Cutover to CR-004 and CR-005 ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #window DBW_PROD_SPEC_GAN $INSERT APP_INSERTS $INSERT QUOTE_SPEC_EQU $INSERT LSL_COMMON $INSERT PS_EQUATES $INSERT MSG_EQUATES $INSERT SECURITY_RIGHTS_EQU $INSERT RDS_EQU $INSERT REACT_RUN_EQUATES $INSERT GAN_PARAMS_EQUATES $INSERT PROD_SPEC_EQUATES $INSERT GAN_PARAM_CONFIG_EQUATES $INSERT PRS_STAGE_EQUATES $INSERT PROD_SPEC_REV_HIST_EQUATES EQU COL$MODE_CODE TO 1 EQU COL$MODE_SIG TO 2 EQU COL$MODE_SIG_DTM TO 3 EQU TOP$ROW to 9 EQU BOTTOM$ROW to 21 Declare subroutine Set_Property, Database_Services, Dialog_Box, ErrMsg, GaN_Services, Unlock, SQL_Services Declare subroutine Start_Window, Comm_Prod_Spec, Create_Dialog, PSN_Services Declare function Get_Property, Form_Services, Database_Services, Datetime, SQL_Services, SRP_Array, GaN_Services Declare function NextKey, SQL_Services SubclassInfo = Form_Services('FindSubclassControl') Subclass = SubclassInfo<1> If Assigned(Param8) else Param8 = '' // 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 // Convert ' ' to '_' for proper RADIO control event handling Convert ' ' to '_' in CtrlEntId GoToEvent Event for CtrlEntId else If Event EQ 'CHANGED' then GoSub EnableSaveButton end If Event EQ 'UpdateRevHist' then GoSub UpdateRevHist end Ctrl = CtrlEntID[-1, 'B.'] If ( (Ctrl[1, 8] EQ 'CHK_WFR_') or (Ctrl[1, 9] EQ 'CHK_CHAR_') ) then GoSub UpdateANKOGroups GoSub EnableSaveButton end end Return EventFlow or 1 //----------------------------------------------------------------------------- // EVENT HANDLERS //----------------------------------------------------------------------------- Event WINDOW.CREATE(CreateParam) SiliconFormVisible = Get_Property('PROD_SPEC', 'VISIBLE') If SiliconFormVisible EQ True$ then Utility('DESTROY', 'PROD_SPEC') end // Do not clear on write IOOptions = Get_Property(@Window, "IOOPTIONS") IOOptions<6> = True$ Set_Property(@Window, 'IOOPTIONS', IOOptions) SRP_Show_Window(@Window, 'SYSTEM', 'C', 'C', 1, '', False$, False$, '', 1) PSNo = CreateParam If RowExists('PROD_SPEC', PSNo) then Set_Property(@Window:'.PROD_SPEC_ID', 'TEXT', PSNo) Post_Event(@Window, 'READ') end End Event Event WINDOW.READ() PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') NewPSN = ( RowExists('PROD_SPEC', PSNo) EQ False$ ) Set_Property(@Window, '@NEW_PSN', NewPSN) ReactType = Xlate('PROD_SPEC', PSNo, 'REACTOR_TYPE', 'X') If ( (ReactType EQ 'GAN') or (NewPSN EQ True$) ) then If NewPSN EQ True$ then Set_Property(@Window:'.STATUS', 'DEFPROP', 'I') PSN_Services('InitializeCritParams', PSNo) end else Comm_Prod_Spec('Refresh') end Set_Property(@Window, 'REDRAW', False$) GoSub SetupOLEControls CharInterval = Get_Property(@Window:'.EDL_CHAR_INTERVAL', 'TEXT') CharInterval = Trim(CharInterval) If Num(CharInterval) then If ( (CharInterval NE '') and (CharInterval GE 1) ) then CurrInterval = 1 IntervalString = 1 For Interval = 1 to 3 IntervalString := ',':(CurrInterval + CharInterval) CurrInterval += CharInterval Next Interval IntervalString := '...' Set_Property(@Window:'.LBL_INTERVAL', 'TEXT', IntervalString) end else Set_Property(@Window:'.LBL_INTERVAL', 'TEXT', 'None') end end else Set_Property(@Window:'.LBL_INTERVAL', 'TEXT', 'None') end Set_Property(@Window, 'REDRAW', True$) GoSub FillRevHistEDT OrigRecord = Get_Property(@Window, 'ATRECORD') Set_Property(@Window, '@ORIG_RECORD', OrigRecord) end else RecLocked = Database_Services('IsKeyIDLocked', 'PROD_SPEC', PSNo) If RecLocked then Database_Services('ReleaseKeyIDLock', 'PROD_SPEC', PSNo) ParentWindow = Get_Property(@Window, "PARENT") Start_Window('PROD_SPEC', ParentWindow, PSNo) end end event Event WINDOW.WRITE() PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') OrigRecord = Get_Property(@Window, 'ATRECORD') Set_Property(@Window, '@ORIG_RECORD', OrigRecord) NewPSN = Get_Property(@Window, '@NEW_PSN') If NewPSN EQ True$ then // Mark PSN type as GaN PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) PSRec = 'GAN' PSRec = 'Q':@VM:'P' Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) // Create PRS_STAGE records and add PRS_STAGE keys to the new PROD_SPEC record ReqStages = Gan_Services('GetReqStages') For each StageID in ReqStages using @VM Gan_Services('AddStageToPSN', PSNo, StageID) Next StageID Set_Property(@Window, '@NEW_PSN', False$) end GoSub SaveAll // If PSN reactor type is "GAN", the tech type is "Production" (i.e. 'P'), and the status is "Active" (i.e. 'A'), // then ensure Candela Total Defects parameter is enabled in the GAN_PARAM_CONFIG record. Otherwise, force the // status to "Inactive" (i.e. 'I'). Database_Services('ActivateRecord', 'PROD_SPEC', PSNo) If ( ({REACTOR_TYPE} EQ 'GAN') and ({TECH_TYPE} EQ 'P') and ({STATUS} EQ 'A') and ({CURR_PART_NO} NE '') ) then ReadyToActivate = False$ // Need to ensure Candela Total Defects is enabled. GaNParamKeys = {GAN_PARAM_KEYS} CanPreKey = '' For each ParamKey in GaNParamKeys using @VM setting vPos Stage = Field(ParamKey, '*', 2) If Stage EQ 'CAN_PRE' then CanPreKey = ParamKey Until CanPreKey NE '' Next ParamKey If CanPreKey NE '' then CanPreParamRec = Database_Services('ReadDataRow', 'GAN_PARAMS', CanPreKey) If Error_Services('NoError') then MetNames = CanPreParamRec Locate 'Candela Total Defects' in MetNames using @VM setting vPos then ReadyToActivate = True$ end else ErrorMsg = 'Candela Total Defects not found in the Part & Parameters configuration record. PSN not eligible to be activated.' ErrMsg(ErrorMsg) end end else ErrorMsg = 'Error reading CAN_PRE parameter configuration record. PSN not eligible to be activated.' ErrMsg(ErrorMsg) end end else ErrorMsg = 'CAN_PRE parameter record not found.' ErrMsg(ErrorMsg) end If ReadyToActivate EQ False$ then ErrMessage = 'Candela Total Defects is required in order for the PSN to be active. Enable Candela ' ErrMessage := 'Total Defects in the Part & Parameter manager in order to activate this PSN.' ErrMsg(ErrMessage) {STATUS} = 'I' Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, @Record, True$, False$, True$) end end Post_Event(@Window, 'READ') end event Event CHK_ANKO.CLICK() GoSub EnableANKOGroups GoSub EnableSaveButton end event Event PUB_DUP_PSN.CLICK() PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') OrigRecord = Get_Property(@Window, 'ATRECORD') Set_Property(@Window, '@ORIG_RECORD', OrigRecord) NewRecord = OrigRecord // Clear GaN Param related columns as these are part number specific and the new PSN will not have // a part number associated with it until a PROD_VER record is created and associated with it. NewRecord = '' NewRecord = '' NewRecord = '' NewRecord = '' NewKey = NextKey('PROD_SPEC') Set_Property(@Window:'.PROD_SPEC_ID', 'TEXT', NewKey) Swap PSNo with NewKey in NewRecord NewRecord = 'GAN' NewRecord = 'Q':@VM:'P' Database_Services('WriteDataRow', 'PROD_SPEC', NewKey, NewRecord, True$, False$, True$) // Create PRS_STAGE records and add PRS_STAGE keys to the new PROD_SPEC record ReqStages = Gan_Services('GetReqStages') For each StageID in ReqStages using @VM Gan_Services('AddStageToPSN', NewKey, StageID) Next StageID Set_Property(@Window, '@NEW_PSN', False$) GoSub SaveAll Post_Event(@Window, 'READ') end event Event EDL_CHAR_INTERVAL.CHANGED(NewData) CharInterval = NewData CharInterval = Trim(CharInterval) If Num(CharInterval) then If ( (CharInterval NE '') and (CharInterval GE 1) ) then CurrInterval = 1 IntervalString = 1 For Interval = 1 to 3 IntervalString := ',':(CurrInterval + CharInterval) CurrInterval += CharInterval Next Interval IntervalString := '...' Set_Property(@Window:'.LBL_INTERVAL', 'TEXT', IntervalString) end else Set_Property(@Window:'.LBL_INTERVAL', 'TEXT', 'None') end end else Set_Property(@Window:'.LBL_INTERVAL', 'TEXT', 'None') end GoSub EnableSaveButton end event Event WINDOW.CLOSE(CancelFlag) Set_Property(@Window:'.OLE_TAB', "OLE.FlickerFree", False$) end event Event WINDOW.OMNIEVENT(Message, Param1, Param2, Param3, Param4) If Message _EQC 'EnableImportButton' then GoSub EnableImportButton end end event Event EXPORT_CONTROL.CLICK() GoSub EnableSaveButton end event Event STATUS.ACTIVE.CLICK() GoSub StatusClick GoSub EnableSaveButton end event Event STATUS.INACTIVE.CLICK() GoSub StatusClick GoSub EnableSaveButton end event Event STATUS.HOLD.CLICK() GoSub StatusClick GoSub EnableSaveButton end event Event RDO_TECH_TYPE.PRODUCTION.CLICK() GoSub EnableANKOGroups GoSub EnableAnkoCheckbox GoSub EnableSaveButton end event Event RDO_TECH_TYPE.ENGINEERING.CLICK() GoSub EnableANKOGroups GoSub EnableAnkoCheckbox GoSub EnableSaveButton end event Event PUB_PARAM_MANAGER.CLICK() PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') Create_Dialog('NDW_GAN_PARAM_MANAGER', @Window, True$, PSNo) end event Event PUB_IMPORT_CP.CLICK() GoSub UpdateLimits GoSub HideTabs GoSub FillPartParamCtrl GoSub ColorTabs GoSub EnableSaveButton end event Event PUB_SAVE.CLICK() Send_Event(@Window, 'WRITE') end event Event OLE_TAB.SelChanged(Index, PrevIndex) GoSub FillPartParamCtrl end event Event OLE_CHAR_STAGE_EDT.OnCheckChanged(Cell, OldValue, NewValue) Abort = False$ If NewValue = False$ then Row = Field(Cell, ';', 2) Col = Field(Cell, ';', 1) StageID = Get_Property(CtrlEntID, 'OLE.CellText[1;':Row:']') PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') GaNParamKeys = Xlate('PROD_SPEC', PSNo, 'GAN_PARAM_KEYS', 'X') GaNParamKeysPrime = SRP_Array('Rotate', GaNParamKeys, @VM, '*') GaNCritStages = GaNParamKeysPrime<1, 2> // Check if the StageID unchecked is configured in part parameters. // If it is, then block the change and warn the user. Locate StageID in GaNCritStages using '*' setting Dummy then Message = 'This stage is configured as a critical stage. ' Message := 'You must remove the parameters using the Parameter Manager before you can remove this stage.' ErrMsg(Message) Abort = True$ Set_Property(CtrlEntID, 'OLE.CellCheck[':Cell:']', True$) end end If Abort EQ False$ then StageEnabledArray = Get_Property(CtrlEntID, 'OLE.CellCheck[3;All]') Convert @RM to @VM in StageEnabledArray Set_Property(@Window, '@STAGE_ENABLED_LIST', StageEnabledArray) GoSub EnableSaveButton end end event Event OLE_CHAR_STAGE_EDT.PosChanged(Cell, PrevCell, Button, RepeatCount) Focus = Get_Property(CtrlEntID, 'OLE.Focus') StageOrderList = Get_Property(CtrlEntID, 'OLE.ColumnData[1]') Set_Property(@Window, '@STAGE_ORDER_LIST', StageOrderList) GoSub EnableArrowButtons end event Event TAB_MAIN.CLICK() TabIndex = Get_Property(@WINDOW:'.TAB_MAIN', 'VALUE') Set_Property(@WINDOW, 'VPOSITION', TabIndex) end event Event PUB_TOP_ARROW.CLICK() StageEDTCtrl = @Window:'.OLE_CHAR_STAGE_EDT' StageList = Get_Property(StageEDTCtrl, 'OLE.LIST') SelList = Get_Property(StageEDTCtrl, 'OLE.SelPos') SelRowIndex = SelList<2, 1> SelRow = StageList StageList = Delete(StageList, SelRowIndex, 0 ,0) StageList = Insert(StageList, TOP$ROW, 0, 0, SelRow) Set_Property(StageEDTCtrl, 'LIST', StageList) SelList<2, 1> = TOP$ROW Set_Property(StageEDTCtrl, 'OLE.SelPos', SelList) GoSub EnableArrowButtons Set_Property(StageEDTCtrl, 'OLE.Focus', True$) GoSub ColorCharStages GoSub UpdateCharStageOrder GoSub EnableSaveButton end event Event PUB_UP_ARROW.CLICK() StageEDTCtrl = @Window:'.OLE_CHAR_STAGE_EDT' StageList = Get_Property(StageEDTCtrl, 'OLE.LIST') SelList = Get_Property(StageEDTCtrl, 'OLE.SelPos') SelRowIndex = SelList<2, 1> NewRowIndex = SelRowIndex - 1 SelRow = StageList StageList = Delete(StageList, SelRowIndex, 0 ,0) StageList = Insert(StageList, NewRowIndex, 0, 0, SelRow) Set_Property(StageEDTCtrl, 'LIST', StageList) SelList<2, 1> = NewRowIndex Set_Property(StageEDTCtrl, 'OLE.SelPos', SelList) GoSub EnableArrowButtons Set_Property(StageEDTCtrl, 'OLE.Focus', True$) GoSub ColorCharStages GoSub UpdateCharStageOrder GoSub EnableSaveButton end event Event PUB_DOWN_ARROW.CLICK() StageEDTCtrl = @Window:'.OLE_CHAR_STAGE_EDT' StageList = Get_Property(StageEDTCtrl, 'OLE.LIST') SelList = Get_Property(StageEDTCtrl, 'OLE.SelPos') SelRowIndex = SelList<2, 1> NewRowIndex = SelRowIndex + 1 SelRow = StageList StageList = Delete(StageList, SelRowIndex, 0 ,0) StageList = Insert(StageList, NewRowIndex, 0, 0, SelRow) Set_Property(StageEDTCtrl, 'LIST', StageList) SelList<2, 1> = NewRowIndex Set_Property(StageEDTCtrl, 'OLE.SelPos', SelList) GoSub EnableArrowButtons Set_Property(StageEDTCtrl, 'OLE.Focus', 1) GoSub ColorCharStages GoSub UpdateCharStageOrder GoSub EnableSaveButton end event Event PUB_BOTTOM_ARROW.CLICK() StageEDTCtrl = @Window:'.OLE_CHAR_STAGE_EDT' StageList = Get_Property(StageEDTCtrl, 'OLE.LIST') SelList = Get_Property(StageEDTCtrl, 'OLE.SelPos') SelRowIndex = SelList<2, 1> SelRow = StageList StageList = Delete(StageList, SelRowIndex, 0 ,0) StageList = Insert(StageList, BOTTOM$ROW, 0, 0, SelRow) Set_Property(StageEDTCtrl, 'LIST', StageList) // Return focus to the new row index. SelList<2, 1> = BOTTOM$ROW Set_Property(StageEDTCtrl, 'OLE.SelPos', SelList) GoSub EnableArrowButtons Set_Property(StageEDTCtrl, 'OLE.Focus', 1) GoSub ColorCharStages GoSub UpdateCharStageOrder GoSub EnableSaveButton end event Event RDO_WAFER_SELECTION.PRESET_WAFER.CLICK() ANKOWaferSel = Get_Property(@Window:'.RDO_WAFER_SELECTION', 'VALUE') Set_Property(@Window, '@ANKO_WAFER_SELECTION', ANKOWaferSel) GoSub EnableSaveButton GoSub EnableANKOGroups end event Event RDO_WAFER_SELECTION.CANDELA_TOTAL_DEFECTS.CLICK() ANKOWaferSel = Get_Property(@Window:'.RDO_WAFER_SELECTION', 'VALUE') Set_Property(@Window, '@ANKO_WAFER_SELECTION', ANKOWaferSel) GoSub EnableANKOGroups GoSub EnableSaveButton end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// SetupOLEControls: GoSub SetupTabCtrl GoSub SetupPartParamCtrl GoSub ReadCurrParams GoSub FillPartParamCtrl GoSub ColorTabs GoSub HideTabs GoSub EnableImportButton GoSub DisplayTimestamps GoSub SetupCharStageCtrl GoSub FillCharStageCtrl GoSub SetupReactorStageCtrl GoSub FillReactorStageCtrl GoSub SetupDispStageCtrl GoSub FillDispStageCtrl GoSub FillANKOGroups GoSub EnableAnkoCheckbox GoSub EnableANKOGroups GoSub EnableSaveButton return SaveAll: // If this is a new GaN PSN then we need to setup (i.e. create) mandatory RUN_STAGE // and PRS_STAGE records. PartParamOrigVals = Get_Property(@Window, '@ORIG_VALUE_LIST') PartParamCurrVals = Get_Property(@Window, '@VALUE_LIST') PartParamChange = (PartParamOrigVals NE PartParamCurrVals) If PartParamChange EQ True$ then Response = Dialog_Box('NDW_VERIFY_USER', @WINDOW, @USER4 : @FM : 'GAN_PARAMETERS') Valid = Response<1> If (Valid EQ True$) then GoSub SavePartParams end else ErrMsg('Part parameters not saved. User not authorized to save part parameters.') end end GoSub FillDispStageCtrl StageOrigVals = Get_Property(@Window, '@ORIG_STAGE_ENABLED_LIST') StageCurrVals = Get_Property(@Window, '@STAGE_ENABLED_LIST') StageChange = (StageOrigVals NE StageCurrVals) If StageChange EQ True$ then GoSub SaveEnabledStageList OrigStageOrder = Get_Property(@Window, '@ORIG_STAGE_ORDER_LIST') CurrStageOrder = Get_Property(@Window, '@STAGE_ORDER_LIST') StageOrderChange = (OrigStageOrder NE CurrStageOrder) * If StageOrderChange EQ True$ then GoSub SaveStageOrder GoSub SaveStageOrder ANKOMetPocketsOrig = Get_Property(@Window, '@ORIG_ANKO_MET_POCKETS') ANKOMetPockets = Get_Property(@Window, '@ANKO_MET_POCKETS') ANKOMetPocketsChange = (ANKOMetPocketsOrig NE ANKOMetPockets) If ANKOMetPocketsChange EQ True$ then GoSub SaveANKOMetPockets ANKOFullCharPocketOrig = Get_Property(@Window, '@ORIG_ANKO_FULL_CHAR_POCKET') ANKOFullCharPocket = Get_Property(@Window, '@ANKO_FULL_CHAR_POCKET') ANKOCharPocketChange = Get_Property(ANKOFullCharPocketOrig NE ANKOFullCharPocket) If ANKOCharPocketChange EQ True$ then GoSub SaveANKOFullCharPocket GoSub EnableSaveButton return SavePartParams: GoSub SaveParameters GoSub ResetColorArrays GoSub FillPartParamCtrl GoSub ColorTabs GoSub DisplayTimestamps ParameterList = Get_Property(@Window, '@VALUE_LIST') Set_Property(@Window, '@ORIG_VALUE_LIST', ParameterList) Set_Property(@Window, '@ORIG_MET_LIST', NewParamNameList) return SaveEnabledStageList: // Save enabled stage list PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') StageList = Get_Property(@Window:'.OLE_CHAR_STAGE_EDT', 'OLE.LIST') For each Row in StageList using @FM setting RowIndex StageID = Row<0, 1> Enabled = Row<0, 3> PRSStageKey = PSNo:'*':StageID If Enabled EQ True$ then // Create PRS_STAGE record if it does not already exist If ( RowExists('PRS_STAGE', PRSStageKey) EQ False$ ) then // Create PRS_STAGE record PRSStageRec = '' PRSStageRec = Gan_Services('GetToolClassIDs', StageID) PRSStageRec = 'START':@VM:'STOP' Database_Services('WriteDataRow', 'PRS_STAGE', PRSStageKey, PRSStageRec, True$, False$, True$) end end else // Delete the PRS_STAGE record if it exists If ( RowExists('PRS_STAGE', PRSStageKey) EQ True$ ) then // Delete the PRS_STAGE record Database_Services('DeleteDataRow', 'PRS_STAGE', PRSStageKey) end end Next Row Set_Property(@Window, '@ORIG_STAGE_ENABLED_LIST', StageEnabledList) Set_Property(@Window, '@STAGE_ENABLED_LIST', StageEnabledList) return SetupReactorStageCtrl: ReactorStageCtrl = @Window:'.OLE_REACTOR_STAGE_EDT' HeaderRowTitles = 'Stage':@VM:'Description':@VM:'' CharStageDimArray = 3:@FM:4 Set_Property(ReactorStageCtrl, "OLE.Dimension", CharStageDimArray) Set_Property(ReactorStageCtrl, "OLE.TitleList", HeaderRowTitles) HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 Set_Property(ReactorStageCtrl, "OLE.HeaderFont[All; All]", HeaderFontArray) HeaderColArray = 40:@FM:False$:@FM:False$:@FM:False$ Set_Property(ReactorStageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(ReactorStageCtrl, "OLE.DataColumn[1]") StageColSize<1> = 70 StageColSize<3> = False$ Set_Property(ReactorStageCtrl, "OLE.DataColumn[1]", StageColSize) StageColSize<1> = 180 Set_Property(ReactorStageCtrl, "OLE.DataColumn[2]", StageColSize) StageColSize<1> = 36 Set_Property(ReactorStageCtrl, "OLE.DataColumn[3]", StageColSize) Set_Property(ReactorStageCtrl, "OLE.CellProtection[All; All]", 'Read Only') Set_Property(ReactorStageCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') // Disable scrollbars Set_Property(ReactorStageCtrl, "OLE.ScrollBarsVisible", 'N':@FM:'N') // Setup checkbox column CheckBoxArray = 'Check Box' CheckBoxArray<2,1> = True$ Set_Property(ReactorStageCtrl, "OLE.CellType[3; All]", CheckBoxArray) Set_Property(ReactorStageCtrl, "OLE.CellCheckEnabled[3; All]", False$) Set_Property(ReactorStageCtrl, "OLE.CellAlignment[3; All]", 'C':@FM:'C':@FM:'L') Set_Property(ReactorStageCtrl, "OLE.AllowDeletions", False$) Set_Property(ReactorStageCtrl, "OLE.AllowInserts", False$) // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(ReactorStageCtrl, 'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier) return SetupCharStageCtrl: CharStageCtrl = @Window:'.OLE_CHAR_STAGE_EDT' HeaderRowTitles = 'Stage':@VM:'Description':@VM:'' CharStageDimArray = 3:@FM:17 Set_Property(CharStageCtrl, "OLE.Dimension", CharStageDimArray) Set_Property(CharStageCtrl, "OLE.TitleList", HeaderRowTitles) HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 Set_Property(CharStageCtrl, "OLE.HeaderFont[All; All]", HeaderFontArray) HeaderColArray = 40:@FM:False$:@FM:False$:@FM:False$ Set_Property(CharStageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(CharStageCtrl, "OLE.DataColumn[1]") StageColSize<1> = 70 StageColSize<3> = False$ Set_Property(CharStageCtrl, "OLE.DataColumn[1]", StageColSize) StageColSize<1> = 180 Set_Property(CharStageCtrl, "OLE.DataColumn[2]", StageColSize) StageColSize<1> = 36 Set_Property(CharStageCtrl, "OLE.DataColumn[3]", StageColSize) Set_Property(CharStageCtrl, "OLE.CellProtection[All; All]", 'Read Only') Set_Property(CharStageCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') // Disable scrollbars Set_Property(CharStageCtrl, "OLE.ScrollBarsVisible", 'N':@FM:'N') // Setup checkbox column CheckBoxArray = 'Check Box' CheckBoxArray<2,1> = True$ Set_Property(CharStageCtrl, "OLE.CellType[3; All]", CheckBoxArray) Set_Property(CharStageCtrl, "OLE.CellAlignment[3; All]", 'C':@FM:'C':@FM:'L') Set_Property(CharStageCtrl, "OLE.AllowDeletions", False$) Set_Property(CharStageCtrl, "OLE.AllowInserts", False$) Set_Property(CharStageCtrl, "OLE.ResetSelPos", False$) SelStyleArray = Get_Property(CharStageCtrl, "OLE.SelectionStyle") SelStyleArray<8> = True$ ; // Always show selected row even when table loses focus Set_Property(CharStageCtrl, "OLE.SelectionStyle", SelStyleArray) // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(CharStageCtrl, 'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier) Send_Message(CharStageCtrl, 'QUALIFY_EVENT', 'OLE.PosChanged', Qualifier) return SetupDispStageCtrl: DispStageCtrl = @Window:'.OLE_DISP_STAGE_EDT' HeaderRowTitles = 'Stage':@VM:'Description':@VM:'' CharStageDimArray = 3:@FM:3 Set_Property(DispStageCtrl, "OLE.Dimension", CharStageDimArray) Set_Property(DispStageCtrl, "OLE.TitleList", HeaderRowTitles) HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 Set_Property(DispStageCtrl, "OLE.HeaderFont[All; All]", HeaderFontArray) HeaderColArray = 40:@FM:False$:@FM:False$:@FM:False$ Set_Property(DispStageCtrl, "OLE.HeaderColumn[1]", HeaderColArray) // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(DispStageCtrl, "OLE.DataColumn[1]") StageColSize<1> = 70 StageColSize<3> = False$ Set_Property(DispStageCtrl, "OLE.DataColumn[1]", StageColSize) StageColSize<1> = 180 Set_Property(DispStageCtrl, "OLE.DataColumn[2]", StageColSize) StageColSize<1> = 36 Set_Property(DispStageCtrl, "OLE.DataColumn[3]", StageColSize) Set_Property(DispStageCtrl, "OLE.CellProtection[All; All]", 'Read Only') Set_Property(DispStageCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') // Disable scrollbars Set_Property(DispStageCtrl, "OLE.ScrollBarsVisible", 'N':@FM:'N') // Setup checkbox column CheckBoxArray = 'Check Box' CheckBoxArray<2,1> = True$ Set_Property(DispStageCtrl, "OLE.CellType[3; All]", CheckBoxArray) Set_Property(DispStageCtrl, "OLE.CellCheckEnabled[3; All]", False$) Set_Property(DispStageCtrl, "OLE.CellAlignment[3; All]", 'C':@FM:'C':@FM:'L') Set_Property(DispStageCtrl, "OLE.AllowDeletions", False$) Set_Property(DispStageCtrl, "OLE.AllowInserts", False$) // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(DispStageCtrl, 'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier) return FillReactorStageCtrl: ReactorStageCtrl = @Window:'.OLE_REACTOR_STAGE_EDT' StageList = Gan_Services('GetGaNStages', 'Reactor') ReactorStageCtrlList = '' For each StageID in StageList using @VM setting RowIndex ReactorStageCtrlList = StageID ReactorStageCtrlList = GaN_Services('GetStageDesc', StageID) ReactorStageCtrlList = True$ Next StageID Set_Property(ReactorStageCtrl, 'OLE.LIST', ReactorStageCtrlList) // Color headers Set_Property(ReactorStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{180, 180, 180}") CellColorArray = 'None':@FM:"{220, 220, 220}" Set_Property(ReactorStageCtrl, "OLE.CellColors[All; All]", CellColorArray) return FillCharStageCtrl: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) PRSStageKeys = PSRec CharStageCtrl = @Window:'.OLE_CHAR_STAGE_EDT' ReqStages = Gan_Services('GetReqStages') CharStages = GaN_Services('GetGaNStages', 'Metrology', PSNo) CurrRecord = Get_Property(@Window, 'ATRECORD') CharStageCtrlList = '' For each StageID in CharStages using @VM setting RowIndex ToolClassKey = 'G_':StageID Destructive = GaN_Services('IsDestStage', StageID) CharStageCtrlList = StageID CharStageCtrlList = GaN_Services('GetStageDesc', StageID) PRSStageKey = PSNo:'*':StageID Locate PRSStageKey in PRSStageKeys using @VM setting Dummy then StageEnabled = True$ end else StageEnabled = False$ end Locate StageID in ReqStages using @VM setting Dummy then CellColorArray = 'None':@FM:"{220, 220, 220}" Set_Property(CharStageCtrl, "OLE.CellColors[All; ":RowIndex:"]", CellColorArray) Set_Property(CharStageCtrl, "OLE.CellCheckEnabled[3; ":RowIndex:"]", False$) end else Set_Property(CharStageCtrl, "OLE.CellCheckEnabled[3; ":RowIndex:"]", True$) end CharStageCtrlList = StageEnabled Next StageID Set_Property(CharStageCtrl, 'OLE.LIST', CharStageCtrlList) StageEnabledList = Get_Property(CharStageCtrl, 'OLE.ColumnData[3]') StageOrderList = Get_Property(CharStageCtrl, 'OLE.ColumnData[1]') Set_Property(@Window, '@ORIG_STAGE_ORDER_LIST', StageOrderList) Set_Property(@Window, '@STAGE_ORDER_LIST', StageOrderList) Set_Property(@Window, '@ORIG_STAGE_ENABLED_LIST', StageEnabledList) Set_Property(@Window, '@STAGE_ENABLED_LIST', StageEnabledList) // Color headers Set_Property(CharStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{180, 180, 180}") GoSub ColorCharStages return FillDispStageCtrl: ANKO = Get_Property(@Window:'.CHK_ANKO', 'DEFPROP') DispStageCtrl = @Window:'.OLE_DISP_STAGE_EDT' StageList = Gan_Services('GetGaNStages', 'Disposition') DispStageCtrlList = '' For each StageID in StageList using @VM setting RowIndex DispStageCtrlList = StageID DispStageCtrlList = GaN_Services('GetStageDesc', StageID) If ( (StageID EQ 'G_PACK') and (ANKO EQ True$) ) then DispStageCtrlList = False$ end else DispStageCtrlList = True$ end Next StageID Set_Property(DispStageCtrl, 'OLE.LIST', DispStageCtrlList) // Color headers Set_Property(DispStageCtrl, "OLE.HeaderColors[All; 1]", @FM:"{180, 180, 180}") CellColorArray = 'None':@FM:"{220, 220, 220}" Set_Property(DispStageCtrl, "OLE.CellColors[All; All]", CellColorArray) return FillANKOGroups: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) ANKO = PSRec ANKOMetPockets = PSRec ANKOFullCharPocket = PSRec ANKOWaferSel = PSRec If ( (ANKOWaferSel EQ '') or (ANKO and (ANKOWaferSel EQ 'PRESET') ) ) then If ANKO then ANKOWaferSel = 'CANDELA' end else ANKOWaferSel = 'PRESET' end PSRec = ANKOWaferSel Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) end If ANKOFullCharPocket EQ '' then ANKOFullCharPocket = 1 PSRec = ANKOFullCharPocket Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) end For Pocket = 1 to 8 Check = ANKOMetPockets<0, Pocket> Set_Property(@Window:'.CHK_WFR_':Pocket, 'CHECK', Check) If Check EQ True$ then ANKOMetPockets<0, Pocket> = True$ Set_Property(@Window:'.CHK_CHAR_':Pocket, 'ENABLED', True$) end else ANKOMetPockets<0, Pocket> = False$ Set_Property(@Window:'.CHK_CHAR_':Pocket, 'ENABLED', False$) end Next Pocket Set_Property(@Window:'.CHK_CHAR_':ANKOFullCharPocket, 'CHECK', True$) Set_Property(@Window:'.RDO_WAFER_SELECTION', 'VALUE', ANKOWaferSel) Set_Property(@Window, '@ORIG_ANKO_MET_POCKETS', ANKOMetPockets) Set_Property(@Window, '@ANKO_MET_POCKETS', ANKOMetPockets) Set_Property(@Window, '@ORIG_ANKO_FULL_CHAR_POCKET', ANKOFullCharPocket) Set_Property(@Window, '@ANKO_FULL_CHAR_POCKET', ANKOFullCharPocket) Set_Property(@Window, '@ORIG_ANKO_WAFER_SELECTION', ANKOWaferSel) Set_Property(@Window, '@ANKO_WAFER_SELECTION', ANKOWaferSel) return UpdateANKOGroups: ANKO = Get_Property(@Window:'.CHK_ANKO', 'CHECK') Pocket = Ctrl[-1, 1] Begin Case Case (Ctrl[1, 8] EQ 'CHK_WFR_') ANKOMetPockets = Get_Property(@Window, '@ANKO_MET_POCKETS') CheckVal = Get_Property(@Window:'.CHK_WFR_':Pocket, 'CHECK') ANKOMetPockets<0, Pocket> = CheckVal If ANKO then Set_Property(@Window:'.CHK_CHAR_':Pocket, 'ENABLED', CheckVal) Set_Property(@Window, '@ANKO_MET_POCKETS', ANKOMetPockets) If CheckVal EQ False$ then CharPocket = Get_Property(@Window:'.CHK_CHAR_':Pocket, 'CHECK') If CharPocket EQ True$ then // Reset char pocket to 1 Set_Property(@Window:'.CHK_CHAR_1', 'CHECK', True$) Set_Property(@Window:'.CHK_CHAR_':Pocket, 'CHECK', False$) end end Case (Ctrl[1, 9] EQ 'CHK_CHAR_') CheckVal = Get_Property(@Window:'.CHK_CHAR_':Pocket, 'CHECK') If CheckVal EQ True$ then ANKOCharPocket = Pocket end else ANKOCharPocket = 1 Set_Property(@Window:'.CHK_CHAR_':ANKOCharPocket, 'CHECK', True$) end Set_Property(@Window, '@ANKO_FULL_CHAR_POCKET', ANKOCharPocket) // Ensure all other char check boxes are cleared For CharPocket = 1 to 8 If CharPocket NE ANKOCharPocket then Set_Property(@Window:'.CHK_CHAR_':CharPocket, 'CHECK', False$) end Next CharPocket End Case return ResetColorArrays: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PartNo = Get_Property(@Window, '@CURR_PART_NO') GaNParamStages = Get_Property(@Window, '@GAN_PARAM_STAGES') CellColorArray = '' For each Stage in GaNParamStages using @VM setting TabIndex GaNParamConfigKey = PSNo:'*':PartNo:'*':Stage GaNParamConfigRec = Database_Services('ReadDataRow', 'GAN_PARAM_CONFIG', GaNParamConfigKey) ParamNames = GaNParamConfigRec For each ParamName in ParamNames using @VM setting RowPos CellColorArray = 'None' CellColorArray = 'None' CellColorArray = 'None' CellColorArray = 'None' CellColorArray = 'None' Next ParamName Next Stage Set_Property(@Window, '@COLOR_ARRAY', CellColorArray) return DisplayTimestamps: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') If PSNo NE '' then ProdSpecRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) RevCPDTM = ProdSpecRec RevOIDTM = ProdSpecRec RevUser = ProdSpecRec RevCPDTM = OConv(RevCPDTM, 'DT2/^H') RevOIDTM = OConv(RevOIDTM, 'DT2/^H') Set_Property(@Window:'.TXT_OI_DTM', 'TEXT', RevOIDTM) Set_Property(@Window:'.TXT_CP_DTM', 'TEXT', RevCPDTM) Set_Property(@Window:'.TXT_USER', 'TEXT', OConv(RevUser, '[XLATE_CONV,LSL_USERS*FIRST_LAST]')) end return SetupTabCtrl: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PartNos = Xlate('PROD_SPEC', PSNo, 'PROD_VER_EPI_PART_NO', 'X') NumPartNos = DCount(PartNos, @VM) CurrPartNo = Field(PartNos, @VM, NumPartNos) Set_Property(@Window, '@CURR_PART_NO', CurrPartNo) GaNParamStages = Xlate('APP_INFO', 'GAN_PARAM_STAGES', '', 'X') TabCtrl = @Window:'.OLE_TAB' NumTabs = DCount(GaNParamStages, @VM) Set_Property(TabCtrl, "OLE.TabCount", NumTabs) Convert @VM to ',' in GaNParamStages Convert '_' to ' ' in GaNParamStages Set_Property(TabCtrl, "OLE.CaptionList", GaNParamStages) FontArray = 'Segoe UI':@SVM:9:@SVM:700 Set_Property(TabCtrl, "OLE.Font", FontArray) Set_Property(TabCtrl, "OLE.SelectFont", FontArray) // Qualify OLE events that we want to intercept Qualifier = '' Qualifier<1> = 1 Qualifier<4> = 0 ; * process synchronously (i.e. immediately) Send_Message(TabCtrl, 'QUALIFY_EVENT', 'OLE.SelChanged', Qualifier) Set_Property(TabCtrl, "OLE.FlickerFree", True$) return UpdateLimits: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') If PSNo NE '' then CurrDTM = DateTime() PartNos = Xlate('PROD_SPEC', PSNo, 'PROD_VER_EPI_PART_NO', 'X') NumPartNos = DCount(PartNos, @VM) CurrPartNo = Field(PartNos, @VM, NumPartNos) If CurrPartNo EQ 'U014' then CurrPartNo = 'G5HTMV675AA' Response = GaN_Services('GetCurrLimits', CurrPartNo) ResponseParamList = Response<1> // Get Control Plan data GaNParamKeys = Xlate('PROD_SPEC', PSNo, 'GAN_PARAM_KEYS', 'X') Stages = Database_Services('ReadDataRow', 'APP_INFO', 'GAN_PARAM_STAGES', 'X') ParameterList = '' ParamNameList = '' CellColorArray = '' For each Stage in Stages using @VM setting TabIndex MetType = Stage GaNParamConfigKey = PSNo:'*':CurrPartNo:'*':MetType GaNParamConfigRec = Database_Services('ReadDataRow', 'GAN_PARAM_CONFIG', GaNParamConfigKey) If Error_Services('NoError') then ConfigMetNames = GaNParamConfigRec ConfigParams = GaNParamConfigRec EnabledArray = GaNParamConfigRec CurrVals = Get_Property(@Window, '@ORIG_VALUE_LIST') CurrNames = Get_Property(@Window, '@ORIG_MET_LIST') For each ParamName in ConfigParams using @VM setting RowPos ParamEnabled = EnabledArray<0, RowPos> If ParamEnabled EQ True$ then NextRow = DCount(ParamNameList, @VM) + 1 ParamNameList = ConfigMetNames<0, RowPos> Locate ParamName in CurrNames using @VM setting CurrRow then Locate ParamName in ResponseParamList using @VM setting vPos then NewLSL = Response<2, vPos> NewTarget = Response<3, vPos> NewUSL = Response<4, vPos> PrevLSL = CurrVals<0, CurrRow, 1> PrevTarget = CurrVals<0, CurrRow, 2> PrevUSL = CurrVals<0, CurrRow, 3> If (PrevLSL EQ NewLSL) then CellColorArray = 'None' end else CellColorArray = 'Yellow' end If (PrevTarget EQ NewTarget) then CellColorArray = 'None' end else CellColorArray = 'Yellow' end If (PrevUSL EQ NewUSL) then CellColorArray = 'None' end else CellColorArray = 'Yellow' end ParameterList = NewLSL ParameterList = NewTarget ParameterList = NewUSL end else ParameterList = 'None' ParameterList = 'None' ParameterList = 'None' end end else // New parameter being added Locate ParamName in ResponseParamList using @VM setting vPos then NewLSL = Response<2, vPos> NewTarget = Response<3, vPos> NewUSL = Response<4, vPos> ParameterList = NewLSL ParameterList = NewTarget ParameterList = NewUSL CellColorArray = 'Yellow' CellColorArray = 'Yellow' CellColorArray = 'Yellow' end end end Next ParamName end Next Stage end Set_Property(@Window, '@NAME_LIST', ParamNameList) Set_Property(@Window, '@VALUE_LIST', ParameterList) Set_Property(@Window, '@COLOR_ARRAY', CellColorArray) return SetupPartParamCtrl: PartParamCtrl = @Window:'.OLE_PART_PARAM_EDT' HeaderRowTitles = 'LSL':@VM:'Target':@VM:'USL' DispStageDimArray = 5:@FM:1 Set_Property(PartParamCtrl, "OLE.Dimension", DispStageDimArray) Set_Property(PartParamCtrl, "OLE.TitleList", HeaderRowTitles) HeaderFontArray = 'Segoe UI':@SVM:8:@SVM:700 Set_Property(PartParamCtrl, "OLE.HeaderFont[All; All]", HeaderFontArray) HeaderColArray = 180:@FM:True$:@FM:False$:@FM:False$ Set_Property(PartParamCtrl, "OLE.HeaderColumn[1]", HeaderColArray) Set_Property(PartParamCtrl, "OLE.HeaderText[1; 1]", "Metrology Limits") // Disable resizing of columns as there is no need for this on this form StageColSize = Get_Property(PartParamCtrl, "OLE.DataColumn[1]") StageColSize<1> = 100 StageColSize<3> = False$ Set_Property(PartParamCtrl, "OLE.DataColumn[All]", StageColSize) Set_Property(PartParamCtrl, "OLE.CellProtection[All; All]", 'Read Only') return ReadCurrParams: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') If PSNo NE '' then GaNParamStages = Xlate('APP_INFO', 'GAN_PARAM_STAGES', '', 'X') Set_Property(@Window, '@GAN_PARAM_STAGES', GaNParamStages) GaNParamKeys = Xlate('PROD_SPEC', PSNo, 'GAN_PARAM_KEYS', 'X') ParameterList = '' ParamNameList = '' MetNameList = '' For each GaNParamKey in GaNParamKeys using @VM MetType = Field(GaNParamKey, '*', 2) Locate MetType in GaNParamStages using @VM setting TabPos then GaNParamRec = Database_Services('ReadDataRow', 'GAN_PARAMS', GaNParamKey) PartNo = Field(GaNParamKey, '*', 1) ParamNames = GaNParamRec MetNames = GaNParamRec For each ParamName in ParamNames using @VM setting RowPos MetNameList = ParamName ParamNameList = MetNames<0, RowPos> ParameterList = GaNParamRec ParameterList = GaNParamRec ParameterList = GaNParamRec Next ParamName end Next GaNParamKey Set_Property(@Window, '@NAME_LIST', ParamNameList) Set_Property(@Window, '@VALUE_LIST', ParameterList) Set_Property(@Window, '@ORIG_VALUE_LIST', ParameterList) Set_Property(@Window, '@ORIG_MET_LIST', MetNameList) end return FillPartParamCtrl: PartParamCtrl = @Window:'.OLE_PART_PARAM_EDT' TabCtrl = @Window:'.OLE_TAB' TabIndex = Get_Property(TabCtrl, 'OLE.SelectedTab') HeaderTitles = Get_Property(@Window, '@NAME_LIST') ParameterList = Get_Property(@Window, '@VALUE_LIST') CellColorArray = Get_Property(@Window, '@COLOR_ARRAY') NumCols = 3 NumRows = DCount(ParameterList, @VM) DispStageDimArray = NumCols:@FM:NumRows Set_Property(PartParamCtrl, "OLE.Dimension", DispStageDimArray) Convert @VM to @FM in ParameterList Convert @SVM to @VM in ParameterList Set_Property(@Window:'.OLE_PART_PARAM_EDT', 'OLE.LIST', ParameterList) Convert @VM to @FM in HeaderTitles Convert @SVM to @VM in HeaderTitles For each HeaderTitle in HeaderTitles using @FM setting RowIndex Set_Property(PartParamCtrl, "OLE.HeaderText[1; ":RowIndex + 1:"]", HeaderTitle) Next HeaderTitle Set_Property(PartParamCtrl, "OLE.HeaderAlignment[1; 2-":NumRows + 1:"]", 'C':@FM:'L':@FM:'L') Set_Property(PartParamCtrl, "OLE.CellAlignment[All; All]", 'C':@FM:'R':@FM:'L') Set_Property(PartParamCtrl, "OLE.HeaderAlignment[All; 1]", 'C':@FM:'C':@FM:'L') GoSub ColorCells return EnableSaveButton: ChangeDetected = False$ PartParamOrigVals = Get_Property(@Window, '@ORIG_VALUE_LIST') PartParamCurrVals = Get_Property(@Window, '@VALUE_LIST') StageOrigVals = Get_Property(@Window, '@ORIG_STAGE_ENABLED_LIST') StageCurrVals = Get_Property(@Window, '@STAGE_ENABLED_LIST') StageOrderOrigVals = Get_Property(@Window, '@ORIG_STAGE_ORDER_LIST') StageOrderCurrVals = Get_Property(@Window, '@STAGE_ORDER_LIST') ANKOMetPocketsOrig = Get_Property(@Window, '@ORIG_ANKO_MET_POCKETS') ANKOMetPockets = Get_Property(@Window, '@ANKO_MET_POCKETS') ANKOCharPocketOrig = Get_Property(@Window, '@ORIG_ANKO_FULL_CHAR_POCKET') ANKOCharPocket = Get_Property(@Window, '@ANKO_FULL_CHAR_POCKET') ANKOWaferSelOrig = Get_Property(@Window, '@ORIG_ANKO_WAFER_SELECTION') ANKOWaferSel = Get_Property(@Window, '@ANKO_WAFER_SELECTION') FormOrigVals = Get_Property(@Window, '@ORIG_RECORD') FormCurrVals = Get_Property(@Window, 'ATRECORD') PartParamChange = (PartParamOrigVals NE PartParamCurrVals) DataboundChange = (FormOrigVals NE FormCurrVals) StageChange = (StageOrigVals NE StageCurrVals) StageOrderChange = (StageOrderOrigVals NE StageOrderCurrVals) ANKOMetPocketsChange = (ANKOMetPocketsOrig NE ANKOMetPockets) ANKOCharPocketChange = (ANKOCharPocketOrig NE ANKOCharPocket) ANKOWaferSelChange = (ANKOWaferSelOrig NE ANKOWaferSel) ChangeDetected = (PartParamChange or DataboundChange or StageChange or StageOrderChange or ANKOMetPocketsChange or ANKOCharPocketChange or ANKOWaferSelChange) NewPSN = Get_Property(@Window, '@NEW_PSN') SaveEnabled = (ChangeDetected or NewPSN) Set_Property(@Window:'.PUB_SAVE', 'ENABLED', SaveEnabled) Set_Property(@Window, 'SAVEWARN', ChangeDetected) return EnableImportButton: NameList = Get_Property(@Window, '@NAME_LIST') ChangeDetected = False$ PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') CurrPartNo = Get_Property(@Window, '@CURR_PART_NO') Stages = Get_Property(@Window, '@GAN_PARAM_STAGES') DataToImport = False$ For each Stage in Stages using @VM setting TabIndex ThisNameList = NameList GaNParamConfigKey = PSNo:'*':CurrPartNo:'*':Stage GaNParamConfigRec = Database_Services('ReadDataRow', 'GAN_PARAM_CONFIG', GaNParamConfigKey) If Error_Services('NoError') then MetNames = GaNParamConfigRec EnabledArray = GaNParamConfigRec If MetNames NE '' then For each MetName in MetNames using @VM setting vPos Enabled = EnabledArray<0, vPos> If Enabled EQ True$ then Locate MetName in ThisNameList using @VM setting nPos else ChangeDetected = True$ end end else Locate MetName in ThisNameList using @VM setting nPos then ChangeDetected = True$ end end Until ChangeDetected EQ True$ Next MetName end end Until ChangeDetected EQ True$ Next Stage Set_Property(@Window:'.PUB_IMPORT_CP', 'ENABLED', ChangeDetected) return EnableAnkoCheckbox: TechType = Get_Property(@Window:'.RDO_TECH_TYPE', 'DEFPROP') If TechType EQ 'P' then Set_Property(@Window:'.CHK_ANKO', 'ENABLED', True$) end else Set_Property(@Window:'.CHK_ANKO', 'ENABLED', False$) end return ColorCells: PartParamCtrl = @Window:'.OLE_PART_PARAM_EDT' DimArray = Get_Property(PartParamCtrl, "OLE.Dimension") NumCols = DimArray<1> NumRows = DimArray<2> For Row = 1 to NumRows For Col = 1 to NumCols CellColor = CellColorArray<0, Row, Col> Set_Property(PartParamCtrl, 'OLE.CellColors[':Col:';':Row:']', @FM:CellColor) Next Col Next Row return ColorTabs: GaNParamStages = Get_Property(@Window, '@GAN_PARAM_STAGES') CellColorArray = Get_Property(@Window, '@COLOR_ARRAY') For each Stage in GaNParamStages using @VM setting TabIndex ThisCellColorArray = CellColorArray GoSub ColorTab Next Stage return HideTabs: SelTabIndex = Get_Property(@Window:".OLE_TAB", "OLE.SelectedTab") GaNParamStages = Get_Property(@Window, '@GAN_PARAM_STAGES') NumTabs = DCount(GaNParamStages, @VM) NameArray = Get_Property(@Window, '@NAME_LIST') For each Stage in GaNParamStages using @VM setting TabIndex ThisNameArray = NameArray GoSub HideTab Next Stage SelTabVisible = Get_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':SelTabIndex:']') If SelTabVisible EQ False$ then For TabIndex = 1 to NumTabs TabVisible = Get_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':TabIndex:']') Until TabVisible EQ True$ Next TabIndex If TabVisible EQ True$ then Set_Property(@Window:".OLE_TAB", "OLE.SelectedTab", TabIndex) end return HideTab: If ThisNameArray EQ '' then Set_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':TabIndex:']', False$) end else Set_Property(@Window:'.OLE_TAB', 'OLE.TabVisible[':TabIndex:']', True$) end return ColorTab: NumRows = DCount(ThisCellColorArray, @VM) NumCols = DCount(ThisCellColorArray, @SVM) ChangeDetected = False$ For Row = 1 to NumRows For Col = 1 to NumCols CellColor = ThisCellColorArray<0, Row, Col> If CellColor EQ 'Yellow' then ChangeDetected = True$ end Until ChangeDetected EQ True$ Next Col Until ChangeDetected EQ True$ Next Row If ChangeDetected EQ False$ then Colors = "" Colors<1, 2> = "None" Colors<2, 2> = "None" Colors<3, 2> = "None" Colors<4, 1> = "None" Colors<4, 2> = "None" Colors<5> = "None" Set_Property(TabCtrl, "OLE.TabColors[":TabIndex:"]", Colors) end else Colors = "" Colors<1, 2> = "Vertical(Gradient(Yellow L=80, Yellow L=90), Border(Yellow))" Colors<2, 2> = "Vertical(Gradient(Yellow L=90, Yellow L=95), Border(Yellow))" Colors<3, 2> = "Vertical(Gradient(Yellow L=85, Yellow L=95), Border(Yellow))" Colors<4, 1> = "Gray" Colors<4, 2> = "Vertical(Gradient(Gray L=80, Gray L=90), Border(Gray))" Colors<5> = "Vertical(Gradient(Yellow L=95, Yellow L=80), Border(Yellow))" Set_Property(TabCtrl, "OLE.TabColors[":TabIndex:"]", Colors) end return SaveParameters: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PartNo = Get_Property(@Window, '@CURR_PART_NO') If ( (PSNo NE '') and (PartNo NE '') ) then CurrDTM = DateTime() // Get Control Plan data NewGaNParamKeys = '' ProdSpecRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) GaNParamKeys = ProdSpecRec GaNParamStages = Database_Services('ReadDataRow', 'APP_INFO', 'GAN_PARAM_STAGES') NewParamNameList = '' For each GaNParamStage in GaNParamStages using @VM setting TabIndex MetType = GaNParamStage GaNParamConfigKey = PSNo:'*':PartNo:'*':MetType GaNParamConfigRec = Database_Services('ReadDataRow', 'GAN_PARAM_CONFIG', GaNParamConfigKey) MetNames = GaNParamConfigRec ParamNames = GaNParamConfigRec HeaderTitles = Get_Property(@Window, '@NAME_LIST') ParameterList = Get_Property(@Window, '@VALUE_LIST') If ParameterList NE '' then // Create new GaN Param record. GaNParamRec = '' For each ParamName in HeaderTitles using @VM setting RowPos Locate ParamName in MetNames using @VM setting vPos then NewParamNameList = ParamNames<0, vPos> GaNParamRec = MetNames<0, vPos> GaNParamRec = ParamNames<0, vPos> GaNParamRec = ParameterList<0, RowPos, 1> GaNParamRec = ParameterList<0, RowPos, 2> GaNParamRec = ParameterList<0, RowPos, 3> end Next ParamName NewGaNParamKey = PartNo:'*':MetType:'*':CurrDTM NewGaNParamKeys<0, -1> = NewGaNParamKey Database_Services('WriteDataRow', 'GAN_PARAMS', NewGaNParamKey, GaNParamRec, True$, False$, True$) end Next GaNParamStage Query = "SELECT [Stamp] " | : "FROM [ControlPlans].[dbo].[Part_Parameter] " | : "WHERE [Part] = 'U012' " | : "GROUP BY [Stamp]" ControlPlanDTM = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) ControlPlanDTM[-3, 1] = '' ControlPlanDTM = IConv(ControlPlanDTM, "DT") ProdSpecRec = NewGaNParamKeys ProdSpecRec = ControlPlanDTM ProdSpecRec = CurrDTM ProdSpecRec = @User4 Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, ProdSpecRec, True$, False$, True$) GaNParamKeysPrime = SRP_Array('Rotate', NewGaNParamKeys, @VM, '*') GaNCritStages = GaNParamKeysPrime<1, 2> // Cross reference the PRS_STAGE records. MetStages = GaN_Services('GetGaNStages', 'Metrology') For each StageID in MetStages using @VM setting vPos Locate StageID in GaNCritStages using '*' setting Dummy then // Check if a PRS_STAGE record exists. If it does not, then create one. PRSStageKey = PSNo:'*':StageID If (RowExists('PRS_STAGE', PRSStageKey) EQ False$) then // Create PRS_STAGE record PRSStageRec = '' PRSStageRec = Gan_Services('GetToolClassIDs', StageID) PRSStageRec = 'START':@VM:'STOP' Database_Services('WriteDataRow', 'PRS_STAGE', PRSStageKey, PRSStageRec, True$, False$, True$) end end Next Stage end return StatusClick: /* DPC 1/28/19 - when PSN is statused (any status), want to add entry to PROD_SPEC_REV_HIST (history) table */ ReactorType = Get_Property(@WINDOW:'.RTYPE','DEFPROP') PSNo = Get_Property(@WINDOW:'.PROD_SPEC_ID','DEFPROP') NewStatus = Get_Property(@WINDOW:'.STATUS','DEFPROP') PSRec = Get_Property(@WINDOW, 'ATRECORD') IF PSNo = '' THEN RETURN Begin Case Case NewStatus EQ 'A' // Need to check if this PSN is eligible to be activated. ReadyToActivate = True$ TechType = Get_Property(@Window:'.RDO_TECH_TYPE', 'DEFPROP') If TechType EQ 'P' then ReadyToActivate = False$ PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') CurrPartNo = Get_Property(@Window:'.EDL_PART_NO', 'TEXT') If CurrPartNo NE '' then // Need to ensure Candela Total Defects is enabled. GaNParamKeys = PSRec CanPreKey = '' For each ParamKey in GaNParamKeys using @VM setting vPos Stage = Field(ParamKey, '*', 2) If Stage EQ 'CAN_PRE' then CanPreKey = ParamKey Until CanPreKey NE '' Next ParamKey If CanPreKey NE '' then CanPreParamRec = Database_Services('ReadDataRow', 'GAN_PARAMS', CanPreKey) If Error_Services('NoError') then MetNames = CanPreParamRec Locate 'Candela Total Defects' in MetNames using @VM setting vPos then ReadyToActivate = True$ end else ErrorMsg = 'Candela Total Defects not found in the Part & Parameters configuration record. PSN not eligible to be activated.' ErrMsg(ErrorMsg) end end else ErrorMsg = 'Error reading CAN_PRE parameter configuration record. PSN not eligible to be activated.' ErrMsg(ErrorMsg) end end else ErrorMsg = 'CAN_PRE parameter record not found.' ErrMsg(ErrorMsg) end end else ErrorMsg = 'A part number (i.e. PROD_VER) is required in order for the PSN to be activated.' ErrMsg(ErrorMsg) end end If ReadyToActivate EQ False$ then Set_Property(@Window:'.STATUS', 'DEFPROP', 'I') end Case Otherwise$ Null End Case return FillRevHistEDT: // 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 = Value Case fPos EQ 2 List = OConv(Value, 'D2/HS') Case fPos EQ 3 List = OConv(Value, 'MTH') Case fPos EQ 4 List = Value End Case Next Value Next Field Set_Property(@Window : '.EDT_REV_HIST', 'LIST', List) 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 CtrlName = @Window : '.PROD_SPEC_ID' 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 Dates = PSRevHistRec Times = PSRevHistRec Revisions = PSRevHistRec ModUser = OConv( @user4, '[XLATE_CONV,LSL_USERS*FIRST_LAST]' ) ModDate = Date() ModTime = Time() ModRevision = RevisionDetail PSRevHistRec = Insert(Usernames, 0, 1, 0, ModUser) PSRevHistRec = Insert(Dates, 0, 1, 0, ModDate) PSRevHistRec = Insert(Times, 0, 1, 0, ModTime) PSRevHistRec = 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 EnableArrowButtons: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') TechType = Get_Property(@Window:'.RDO_TECH_TYPE', 'VALUE') TopArrow = @Window:'.PUB_TOP_ARROW' UpArrow = @Window:'.PUB_UP_ARROW' DownArrow = @Window:'.PUB_DOWN_ARROW' BottomArrow = @Window:'.PUB_BOTTOM_ARROW' StageEDTCtrl = @Window:'.OLE_CHAR_STAGE_EDT' SelRow = '' SelList = Get_Property(StageEDTCtrl, 'OLE.SelPos') SelRows = SelList<2> NumSelRows = DCount(SelRows, @VM) SelRow = SelRows<0, 1> If TechType EQ 'E' then Set_Property(TopArrow, 'ENABLED', False$) Set_Property(UpArrow , 'ENABLED', False$) Set_Property(DownArrow, 'ENABLED', False$) Set_Property(BottomArrow, 'ENABLED', False$) end else Begin Case Case SelRow EQ TOP$ROW Set_Property(TopArrow, 'ENABLED', False$) Set_Property(UpArrow , 'ENABLED', False$) Set_Property(DownArrow, 'ENABLED', True$) Set_Property(BottomArrow, 'ENABLED', True$) Case (SelRow EQ BOTTOM$ROW) Set_Property(TopArrow, 'ENABLED', True$) Set_Property(UpArrow , 'ENABLED', True$) Set_Property(DownArrow, 'ENABLED', False$) Set_Property(BottomArrow, 'ENABLED', False$) Case ( (SelRow GT TOP$ROW) and (SelRow LT BOTTOM$ROW) ) Set_Property(TopArrow, 'ENABLED', True$) Set_Property(UpArrow , 'ENABLED', True$) Set_Property(DownArrow, 'ENABLED', True$) Set_Property(BottomArrow, 'ENABLED', True$) Case Otherwise$ Set_Property(TopArrow, 'ENABLED', False$) Set_Property(UpArrow , 'ENABLED', False$) Set_Property(DownArrow, 'ENABLED', False$) Set_Property(BottomArrow, 'ENABLED', False$) End Case end return ColorCharStages: CharStageCtrl = @Window:'.OLE_CHAR_STAGE_EDT' StageList = Get_Property(CharStageCtrl, 'OLE.List') DestColorArray = 'Red' DefColorArray = 'None' For RowIndex = TOP$ROW to BOTTOM$ROW Row = StageList StageID = Row<0, 1> Destructive = GaN_Services('IsDestStage', StageID) If Destructive EQ True$ then Set_Property(CharStageCtrl, "OLE.CellColors[All; ":RowIndex:"]", DestColorArray) end else Set_Property(CharStageCtrl, "OLE.CellColors[All; ":RowIndex:"]", DefColorArray) end Next RowIndex return SaveStageOrder: PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') If PSNo NE '' then StageOrderList = '' ReactorStageList = Get_Property(@Window:'.OLE_REACTOR_STAGE_EDT', 'OLE.LIST') For each Row in ReactorStageList using @FM setting RowIndex StageID = Row<0, 1> StageOrderList<0, -1> = StageID Next Row CharStageList = Get_Property(@Window:'.OLE_CHAR_STAGE_EDT', 'OLE.LIST') For each Row in CharStageList using @FM setting RowIndex StageID = Row<0, 1> StageOrderList<0, -1> = StageID Next Row DispStageList = Get_Property(@Window:'.OLE_DISP_STAGE_EDT', 'OLE.LIST') For each Row in DispStageList using @FM setting RowIndex StageID = Row<0, 1> StageOrderList<0, -1> = StageID Next Row PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) PSRec = StageOrderList Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) Set_Property(@Window, '@ORIG_STAGE_ORDER_LIST', StageOrderList) Set_Property(@Window, '@STAGE_ORDER_LIST', StageOrderList) end return UpdateCharStageOrder: CharStageCtrl = @Window:'.OLE_CHAR_STAGE_EDT' StageOrderList = Get_Property(CharStageCtrl, 'OLE.ColumnData[1]') Set_Property(@Window, '@STAGE_ORDER_LIST', StageOrderList) return EnableANKOGroups: TechType = Get_Property(@Window:'.RDO_TECH_TYPE', 'VALUE') ANKOFlag = Get_Property(@Window:'.CHK_ANKO', 'CHECK') GroupsEnabled = ( (ANKOFlag EQ True$) or (TechType EQ 'P') ) Set_Property(@Window:'.GRP_ANKO_MET_POCKETS', 'ENABLED', GroupsEnabled) Set_Property(@Window:'.GRP_ANKO_WAFER_SELECTION', 'ENABLED', GroupsEnabled) If GroupsEnabled EQ True$ then ANKOWaferSel = Get_Property(@Window:'.RDO_WAFER_SELECTION', 'VALUE') If ANKOWaferSel EQ 'PRESET' then Set_Property(@Window:'.GRP_ANKO_FULL_CHAR', 'ENABLED', True$) ANKOMetPockets = Get_Property(@Window, '@ANKO_MET_POCKETS') For Pocket = 1 to 8 Check = ANKOMetPockets<0, Pocket> If ( (Check EQ True$) and ANKOFlag ) then Set_Property(@Window:'.CHK_CHAR_':Pocket, 'ENABLED', True$) end else Set_Property(@Window:'.CHK_CHAR_':Pocket, 'ENABLED', False$) end Next Pocket end else Set_Property(@Window:'.GRP_ANKO_FULL_CHAR', 'ENABLED', False$) end end else Set_Property(@Window:'.GRP_ANKO_FULL_CHAR', 'ENABLED', ANKOFlag) end Begin Case Case ANKOFlag EQ True$ Set_Property(@Window:'.RDO_WAFER_SELECTION', 'ENABLED', True$) Case TechType EQ 'P' Set_Property(@Window:'.RDO_WAFER_SELECTION', 'VALUE', 'CANDELA') Set_Property(@Window:'.RDO_WAFER_SELECTION', 'ENABLED', -1) Case TechType EQ 'E' Set_Property(@Window:'.RDO_WAFER_SELECTION', 'ENABLED', False$) End Case return SaveANKOMetPockets: ANKOMetPockets = Get_Property(@Window, '@ANKO_MET_POCKETS') PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PSRec = Database_Services('ReadDataRow', 'PROD_SPEC', PSNo) PSRec = ANKOMetPockets Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) Set_Property(@Window, '@ORIG_ANKO_MET_POCKETS', ANKOMetPockets) return SaveANKOFullCharPocket: ANKOFullCharPocket = Get_Property(@Window, '@ANKO_FULL_CHAR_POCKET') PSNo = Get_Property(@Window:'.PROD_SPEC_ID', 'TEXT') PSRec = ANKOFullCharPocket Database_Services('WriteDataRow', 'PROD_SPEC', PSNo, PSRec, True$, False$, True$) Set_Property(@Window, '@ORIG_ANKO_FULL_CHAR_POCKET', ANKOFullCharPocket) return