Function Scheduler_Events(CtrlEntId, Event, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) /*********************************************************************************************************************** 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 : Scheduler_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) 06/01/17 dmb Created initial commuter module. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler #Window SCHEDULER $insert APP_INSERTS $insert EVENT_SETUP $insert MSG_EQUATES $insert SCHED_DET_EQUATES $insert WO_LOG_EQUATES $insert PRS_LAYER_EQU $insert POPUP_EQUATES $INSERT LOGICAL $insert SECURITY_RIGHTS_EQU $insert REACTOR_EQUATES $insert WO_STEP_EQUATES $insert SCHEDULE_EVENT_SUMMMARY_EQUATES Equ LightGrey$ TO 239 + (239*256) + (239*65536) Equ HIDE$ To 0 Equ NORMAL$ To 1 Equ MINIMIZE$ To 2 Equ MAXIMIZE$ To 3 Declare function SRP_Array, Schedule_Services, Epi_Part_Services, MemberOf, Reactor_Services, SRP_JSON Declare function EntId, MemberOf, Repository, Security_Check, Security_Err_Msg, Obj_Prod_Spec, Rds_Supplement_Maint Declare function Scheduling_Services, Windows_Services Declare subroutine obj_Appwindow, Schedule_Services, Epi_Part_Services, SRP_Stopwatch, SRP_JSON, ShowWindow Declare subroutine Security_Err_Msg, Windows_Services, Start_Window SubclassInfo = Form_Services('FindSubclassControl') Subclass = SubclassInfo<1> If @Station[1, 11] EQ 'MESIRWAP002' then UseBeta = True$ else UseBeta = False$ // 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 Return EventFlow else EVENT_CONTINUE$ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Events //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Event WINDOW.CREATE(CreateParam) If UseBeta then call Start_Window('WO_SCHEDULER', '') Post_Event(@Window, 'CLOSE') return end // Update UI based on security membership rights. Begin Case Case MemberOf(@USER4, 'SCHEDULER_ADMIN') // Allowed to access everything. Case MemberOf(@USER4, 'SCHEDULER_MASTER') // Reactor utilization is view only. Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_ASM_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_HTR_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'ENABLED', False$) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'BACKCOLOR', LightGrey$) Size = Get_Property(@Window : '.EDL_GAN_UTILIZATION', 'SIZE') Size<3> = Size<3> + 48 Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'SIZE', Size) Set_Property(@Window : '.OLE_PUB_UPDATE_GAN_UTILIZATION', 'VISIBLE', False$) Case Otherwise$ // Reactor utilization is not visible. Set_Property(@Window : '.OLE_DIV_REACTOR_TYPE_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_HTR_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_EPIPRO_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.STA_GAN_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'VISIBLE', False$) Set_Property(@Window : '.OLE_PUB_UPDATE_GAN_UTILIZATION', 'VISIBLE', False$) Size = Get_Property(@Window : '.OLE_DIV_BOTTOM', 'SIZE') Size<2> = Size<2> - 162 Set_Property(@Window : '.OLE_DIV_BOTTOM', 'SIZE', Size) End Case Set_Property(@Window, 'VISIBLE', 3) GoSub Setup_OLE_Controls Set_Property('SYSTEM', 'BLOCK_EVENTS', True$) ASMUtil = Epi_Part_Services('GetReactorUtilization', 'ASM') ASMPlusUtil = Epi_Part_Services('GetReactorUtilization', 'ASM+') HTRUtil = Epi_Part_Services('GetReactorUtilization', 'HTR') EpiProUtil = Epi_Part_Services('GetReactorUtilization', 'EpiPro') GaNUtil = Epi_Part_Services('GetReactorUtilization', 'GaN') Set_Property(@Window : '.EDL_ASM_UTILIZATION', 'INVALUE', ASMUtil) Set_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'INVALUE', ASMPlusUtil) Set_Property(@Window : '.EDL_HTR_UTILIZATION', 'INVALUE', HTRUtil) Set_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'INVALUE', EpiProUtil) Set_Property(@Window : '.EDL_GAN_UTILIZATION', 'INVALUE', GaNUtil) Set_Property('SYSTEM', 'BLOCK_EVENTS', False$) * If @Username EQ 'MESCATXMUSER' OR @Username _EQC 'crisp' OR @Username _EQC 'RIVARD' then * SRP_Stopwatch('ShowAll') * end end event Event WINDOW.READ() end event Event WINDOW.WRITE_PRE() end event Event WINDOW.WRITE() end event Event WINDOW.CLEAR(bSaveKey, bSuppressWarning, bMaintainFocus, CtrlIDFocus) end event Event EDL_REACTOR_FILTER.LOSTFOCUS(Flag, FocusID) PrevFilterType = Get_Property(CtrlEntId, '@PREV_FILTER_TYPE') FilterType = Get_Property(CtrlEntId, 'TEXT') If FilterType NE PrevFilterType then Begin Case Case FilterType _EQC 'Reactor Type' FilterOptions = 'ASM' : @FM FilterOptions := 'ASM+' : @FM FilterOptions := 'HTR' : @FM FilterOptions := 'EpiPro' : @FM FilterOptions := 'GaN' Case FilterType _EQC 'Reactor Assignment' FilterOptions = 'Dedicated' : @FM FilterOptions := 'Non-Dedicated' : @FM FilterOptions := 'GaN' : @FM FilterOptions := 'Out of Service' Case FilterType _EQC 'Wafer Size' FilterOptions = '125 mm 5 in' : @FM FilterOptions := '150 mm 6 in' : @FM FilterOptions := '200 mm 8 in' : @FM Case FilterType _EQC 'Cleanroom Area' FilterOptions = 'Front-Evens' : @FM FilterOptions := 'Front-Odds' : @FM FilterOptions := 'Front-Evens-HTR' : @FM FilterOptions := 'Front-Odds-HTR' : @FM FilterOptions := 'Tunnel' : @FM FilterOptions := 'EpiPro Room' : @FM FilterOptions := 'Back-Evens' : @FM FilterOptions := 'Back-Odds' : @FM FilterOptions := 'GaN' End Case Set_Property(CtrlEntId, '@PREV_FILTER_TYPE', FilterType) Ctrl = @Window : '.OLE_TRE_REACTOR_FILTER_OPTIONS' ItemList = '' For Each FilterOption in FilterOptions using @FM ItemList := 1 : @VM : FilterOption : @VM : FilterOption : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : 'Left' : @FM Next FilterOption ItemList[-1, 1] = '' Set_Property(Ctrl, 'OLE.ItemList', ItemList) Set_Property(Ctrl, 'OLE.ItemChecked[All]', True$) Post_Event(Ctrl, 'OLE', 'OnItemCheck') end end event Event EDL_WORK_ORDER_SEARCH.LOSTFOCUS(Flag, FocusID) PrevWorkOrderNo = Get_Property(CtrlEntId, '@PREV_WORK_ORDER_NO') SearchWorkOrderNo = Get_Property(CtrlEntId, 'TEXT') If SearchWorkOrderNo NE PrevWorkOrderNo then // Restore already selected appointments to their normal backcolor. Set_Property(@Window, 'REDRAW', False$) SearchAppointmentKeys = Get_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS') If SearchAppointmentKeys NE '' then For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral' Case Flags<3> BackColor = 'LightGray' Case Otherwise$ BackColor = 'LightSteelBlue' End Case Appt<4> = BackColor Appt<5> = 'Black' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey end SearchAppointmentKeys = '' AppointmentList = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.AppointmentList') AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AllAppointmentKeys = AppointmentArray<2> For Each AppointmentKey in AllAppointmentKeys using @VM setting vPos WorkOrderNo = Field(AppointmentKey, '*', 1, 1) If WorkOrderNo EQ SearchWorkOrderNo then SearchAppointmentKeys := AppointmentKey : @FM end Next AppointmentKey SearchAppointmentKeys[-1, 1] = '' For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral L=40' Case Flags<3> BackColor = 'LightGray L=40' Case Otherwise$ BackColor = 'LightSteelBlue L=40' End Case Appt<4> = BackColor Appt<5> = 'White' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey Set_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS', SearchAppointmentKeys) Send_Message(@Window : '.OLE_SCHEDULE', 'OLE.EnsureVisible', SearchAppointmentKeys<1>) Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.SelAppt[' : SearchAppointmentKeys<1> : ']') Set_Property(CtrlEntId, '@PREV_WORK_ORDER_NO', SearchWorkOrderNo) Set_Property(@Window : '.EDL_EPI_PART_SEARCH', 'TEXT', '') Set_Property(@Window, 'REDRAW', True$) end end event Event EDL_EPI_PART_SEARCH.LOSTFOCUS(Flag, FocusID) PrevEpiPartNo = Get_Property(CtrlEntId, '@PREV_EPI_PART_NO') SearchEpiPartNo = Get_Property(CtrlEntId, 'TEXT') If SearchEpiPartNo NE PrevEpiPartNo then // Restore already selected appointments to their normal backcolor. Set_Property(@Window, 'REDRAW', False$) SearchAppointmentKeys = Get_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS') If SearchAppointmentKeys NE '' then For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral' Case Flags<3> BackColor = 'LightGray' Case Otherwise$ BackColor = 'LightSteelBlue' End Case Appt<4> = BackColor Appt<5> = 'Black' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey end SearchAppointmentKeys = '' AppointmentList = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.AppointmentList') AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AllAppointmentKeys = AppointmentArray<2> For Each AppointmentKey in AllAppointmentKeys using @VM setting vPos EpiPartNo = Field(AppointmentKey, '*', 2, 1) If EpiPartNo EQ SearchEpiPartNo then SearchAppointmentKeys := AppointmentKey : @FM end Next AppointmentKey SearchAppointmentKeys[-1, 1] = '' For Each AppointmentKey in SearchAppointmentKeys using @FM Appt = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']') Flags = Appt<18> Convert @SVM to @FM in Flags Begin Case Case Flags<1> BackColor = 'LightCoral L=40' Case Flags<3> BackColor = 'LightGray L=40' Case Otherwise$ BackColor = 'LightSteelBlue L=40' End Case Appt<4> = BackColor Appt<5> = 'White' Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Appt[' : AppointmentKey : ']', Appt) Next AppointmentKey Set_Property(@Window : '.OLE_SCHEDULE', '@SELECTED_KEYIDS', SearchAppointmentKeys) Send_Message(@Window : '.OLE_SCHEDULE', 'OLE.EnsureVisible', SearchAppointmentKeys<1>) Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.SelAppt[' : SearchAppointmentKeys<1> : ']') Set_Property(CtrlEntId, '@PREV_EPI_PART_NO', SearchEpiPartNo) Set_Property(@Window : '.EDL_WORK_ORDER_SEARCH', 'TEXT', '') Set_Property(@Window, 'REDRAW', True$) end end event Event OLE_SCHEDULE.OnApptDblClick(ApptID, Button, Shift, Ctrl) If Button EQ 'Left' then WorkOrderNo = ApptID[1, '*'] EpiPartNo = ApptID[Col2() + 1, '*'] ReactorNo = ApptID[Col2() + 1, '*'] StartDate = ApptID[Col2() + 1, '*'] Sequence = ApptID[Col2() + 1, '*'] WOStepKey = WorkOrderNo : '*1' PopupId = entid( @appid<1>, 'POPUP', '', 'DAILY_SCHED_OPTS' ) OverRide = '' Display = xlate( 'SYSREPOSPOPUPS', 'LSL2**DAILY_SCHED_OPTS', pdisplay$, 'X' ) if MemberOf(@USER4, 'ENGINEERING') OR MemberOf(@USER4, 'SUPERVISOR') OR MemberOf(@USER4, 'LEAD') then ;* Added LEAD security group to allow asign supplements -dkk 12/5/14 * ADD OPTION TO ASSIGN SUPPLEMENTS Display := @vm:'Assign Supplements':@tm:'SUPPLEMENTS' end OverRide = Display ChosenOpt = repository( 'EXECUTE', PopupId, @window, OverRide ) RdsKeys = '' BEGIN CASE CASE ChosenOpt = 'QUOTE' IF security_check( 'Quote', Read$ ) THEN WORec = XLATE('WO_LOG',WorkOrderNo,'','X') OrderNo = WORec OrderItemNos = WORec QuoteNo = XLATE('ORDER_DET',OrderNo:'*':OrderItemNos<1,1>,1,'X') Void = start_window( 'QUOTE2', @window, QuoteNo:'*CENTER', '', '' ) END ELSE security_err_msg( 'Quote', Read$ ) END CASE ChosenOpt = 'PSN' IF security_check( 'Prod Spec', Read$ ) THEN PSNId = XLATE('WO_STEP',WOStepKey,WO_STEP_PROD_SPEC_ID$,'X') Void = start_window( 'PROD_SPEC', @window, PSNId:'*CENTER', '', '' ) END ELSE security_err_msg( 'Prod Spec', Read$ ) END CASE ChosenOpt = 'RECIPE' if security_check( 'Recipe', Read$ ) then PSN = XLATE('WO_STEP',WOStepKey,1,'X') LayerSpecs = obj_Prod_Spec('GetLayerProp',PSN:@RM:@RM:1) ;* Returns specs for all layers in internal format LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet RecipeNo = LayerSpec Void = start_window( 'RECIPE', @window, RecipeNo:'*CENTER', '', '' ) end else security_err_msg( 'Recipe', Read$ ) end CASE ChosenOpt = 'RDS' if security_check( 'RDS', Read$ ) then SchedDetKeys = Schedule_Services('GetScheduleDetailKeys', StartDate, StartDate, ReactorNo, '', False$) WOStepKeys = '' For Each SchedDetKey in SchedDetKeys using @FM SchedDet = Schedule_Services('GetScheduleDetail', SchedDetKey) WorkOrderNo = SchedDet Locate WorkOrderNo : '*1' in WOStepKeys using @FM setting fPos else WOStepKeys := WorkOrderNo : '*1' : @FM end Next SchedDetKey WOStepKeys[-1, 1] = '' RDSKeys = XLATE('WO_STEP',WOStepKeys,WO_STEP_RDS_KEY$,'X') Convert @FM to @VM in RDSKeys TypeOver = '' TypeOver = 'K' TypeOver = RDSKeys NewForm = Xlate('APP_INFO', 'NEW_RDS_LIST_FORM', '', 'X') If NewForm then RDSKeys = Dialog_Box('NDW_RDS_QUERY', @Window, RDSKeys) end else RDSKeys = Popup(@WINDOW,TypeOver,'RDS_QUERY') end IF RDSKeys NE '' THEN Void = start_window( 'RDS', @window, RDSKeys:'*CENTER', '', '' ) END end else security_err_msg( 'RDS', Read$ ) end CASE ChosenOpt = 'WO' if security_check( 'WO Log', Read$ ) then NewForm = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X') If NewForm then Start_Window('NDW_WO_LOG', @Window, WorkOrderNo) end else Start_window( 'WO_LOG2', @window, WorkOrderNo:'*CENTER', '', '' ) end end else security_err_msg( 'WO Log', Read$ ) end CASE ChosenOpt = 'WO_STAT' PSN = XLATE('WO_STEP',WOStepKey,1,'X') ReactorType = XLATE('PROD_SPEC',PSN,80,'X') BEGIN CASE CASE ReactorType = 'P' Or ReactorType = 'EPP' obj_Appwindow('ViewRelated','WO_PROD_EPI':@RM:WOStepKey) CASE ReactorType = 'GAN' obj_Appwindow('ViewRelated','WO_PROD_GAN':@RM:WOStepKey) CASE 1 obj_Appwindow('ViewRelated','WO_PROD':@RM:WOStepKey) END CASE case ChosenOpt = 'SUPPLEMENTS' Void = rds_supplement_maint( WorkOrderNo ) case 1 Null end case end Set_Property('SCHEDULER', 'FOCUS', True$) end event Event OLE_SCHEDULE.OnScheduleClick(EntityId, Button, Location, Point, Shift, Ctrl) ContextMenu = '' If MemberOf(@USER4, 'SCHEDULER_ADMIN') OR MemberOf(@USER4, 'SCHEDULER_MASTER') then If Button EQ 'Right' AND Location EQ 'Entity' then ContextMenu := 'ADD' : @VM : 'Add Work Order Events...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'ADDBLOCK' : @VM : 'Add Block Out Events...' : @VM : 1 : @FM end end If (@UserName _EQC 'DANIEL_ST') OR (@Station[1, 11] _EQC 'MESIRWAP001') OR (@Station[1, 9] _EQC 'MESSA01EC') then If Button EQ 'Right' AND Location EQ 'Entity' then If ContextMenu NE '' then ContextMenu := '' : @FM end ContextMenu := 'ADJUSTREACTOR' : @VM : 'Auto Adjust Reactor ' : EntityId : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'ADJUSTREACTORLOGONLY' : @VM : 'Auto Adjust Reactor ' : EntityId : ' (Log Only)' : @VM : 1 : @FM ContextMenu := 'ADJUSTALLREACTORSLOGONLY' : @VM : 'Auto Adjust All Reactors (Log Only)' : @VM : 1 : @FM end end If ContextMenu NE '' then ContextMenu[-1, 1] = '' X = Field(Point, ',', 1) DateTime = Send_Message(CtrlEntId, 'OLE.MapClientToTime', X, 1) StartDate = DateTime[1, '.'] Send_Message(CtrlEntId, 'OLE.ShowContextMenu', Point, ContextMenu, '**' : EntityId : '*' : StartDate) end end event Event OLE_SCHEDULE.OnApptClick(ApptID, Button, Shift, Ctrl, Point) Begin Case Case Button EQ 'Left' PopupCtrl = @Window : '.OLE_POPUP' PrevApptID = Get_Property(CtrlEntId, '@PREVAPPTID') AllowPopup = False$ PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then GoSub DismissPopup end GoSub DisplayPopup Case Button EQ 'Right' ContextMenu = '' If MemberOf(@USER4, 'SCHEDULER_ADMIN') OR MemberOf(@USER4, 'SCHEDULER_MASTER') then WorkOrderNo = ApptID[1, '*'] EpiPartNo = ApptID[Col2() + 1, '*'] ReactorNo = ApptID[Col2() + 1, '*'] StartDate = ApptID[Col2() + 1, '*'] Sequence = ApptID[Col2() + 1, '*'] SchedDetKeyID = ReactorNo : '*' : StartDate : '*' : Sequence ScheduleDetail = Schedule_Services('GetScheduleDetail', SchedDetKeyID) BlockOut = ScheduleDetail If BlockOut then ContextMenu := 'CANCELBLOCK' : @VM : 'Cancel Block Out Event...' : @VM : 1 : @FM end else ContextMenu := 'ADD' : @VM : 'Add Work Order Events...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'MODIFY' : @VM : 'Modify Work Order Event...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'CANCEL' : @VM : 'Cancel Work Order Event...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'ADDBLOCK' : @VM : 'Add Block Out Events...' : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'FORCEADJUST' : @VM : 'Force Auto-Adjustment for ' : WorkOrderNo : @VM : 1 : @FM end If MemberOf(@USER4, 'SCHEDULER_MASTER') then SchedDetKeyIDs = Schedule_Services('GetScheduleDetailKeys', Date(), '', '', WorkOrderNo, False$) If SchedDetKeyIDs[-1, 'B' : @FM] EQ SchedDetKeyID then ContextMenu := '' : @FM ContextMenu := 'REMOVEEVENT' : @VM : 'Remove This Work Order Event' : @VM : 1 : @FM end end end If (@UserName _EQC 'DANIEL_ST') OR (@Station[1, 11] _EQC 'MESIRWAP001') OR (@Station[1, 9] _EQC 'MESSA01EC') then WorkOrderNo = ApptID[1, '*'] EpiPartNo = ApptID[Col2() + 1, '*'] ReactorNo = ApptID[Col2() + 1, '*'] StartDate = ApptID[Col2() + 1, '*'] Sequence = ApptID[Col2() + 1, '*'] If ContextMenu NE '' then ContextMenu := '' : @FM end ContextMenu := 'ADJUSTREACTOR' : @VM : 'Auto Adjust Reactor ' : ReactorNo : @VM : 1 : @FM ContextMenu := '' : @FM ContextMenu := 'ADJUSTREACTORLOGONLY' : @VM : 'Auto Adjust Reactor ' : ReactorNo : ' (Log Only)' : @VM : 1 : @FM ContextMenu := 'ADJUSTALLREACTORSLOGONLY' : @VM : 'Auto Adjust All Reactors (Log Only)' : @VM : 1 : @FM end If ContextMenu NE '' then ContextMenu[-1, 1] = '' X = Field(Point, ',', 1) DateTime = Send_Message(CtrlEntId, 'OLE.MapClientToTime', X, 1) StartDate = DateTime[1, '.'] Send_Message(CtrlEntId, 'OLE.ShowContextMenu', Point, ContextMenu, ApptID) end End Case end event Event OLE_SCHEDULE.OnContextMenuClick(Item, OrigApptID) OrigWorkOrderNo = OrigApptID[1, '*'] OrigEpiPartNo = OrigApptID[Col2() + 1, '*'] OrigReactorNo = OrigApptID[Col2() + 1, '*'] OrigScheduleDate = OrigApptID[Col2() + 1, '*'] OrigSequence = OrigApptID[Col2() + 1, '*'] Begin Case Case Item EQ 'ADD' AddEventDetails = Dialog_Box('SCHEDULER_ACTIONS', @Window, Item : @FM : OrigApptID) If AddEventDetails NE '' then Caption = 'Please wait...adding new events' GoSub ShowWaitMessage ReactorNo = AddEventDetails[1, @FM] WorkOrderNo = AddEventDetails[Col2() + 1, @FM] Days = AddEventDetails[Col2() + 1, @FM] StartDate = AddEventDetails[Col2() + 1, @FM] Description = AddEventDetails[Col2() + 1, @FM] UpdatedEvents = Schedule_Services('AdjustScheduleEvents', ReactorNo, WorkOrderNo, Days, StartDate, Description) If Error_Services('NoError') then RemoveEventKeyIDs = UpdatedEvents[1, @RM] AddEvents = UpdatedEvents[Col2() + 1, @RM] Send_Message(CtrlEntId, 'RemoveAppts', RemoveEventKeyIDs) Send_Message(CtrlEntId, 'AddAppts', AddEvents) AddEvents = SRP_Array('Rotate', AddEvents, @FM, @VM) AppointmentKeys = AddEvents<2> Convert @VM to @FM in AppointmentKeys Flags = AddEvents<19> Convert @VM to @FM in Flags Convert @SVM to @VM in Flags For Each AppointmentKey in AppointmentKeys using @FM setting fPos FlagVals = Flags If Sum(FlagVals) GT 0 then Convert @VM to @FM in FlagVals Set_Property(CtrlEntId, 'OLE.ApptFlags[' : AppointmentKey : ']', FlagVals) end Next AppointmentKey end GoSub HideWaitMessage end Case Item EQ 'MODIFY' NewEventDetails = Dialog_Box('SCHEDULER_ACTIONS', @Window, Item : @FM : OrigApptID) If NewEventDetails NE '' then // User updated the schedule detail. Caption = 'Please wait...updating events' GoSub ShowWaitMessage NewReactorNo = NewEventDetails[1, @FM] NewWorkOrderNo = NewEventDetails[Col2() + 1, @FM] NewStartDate = NewEventDetails[Col2() + 1, @FM] NewDescription = NewEventDetails[Col2() + 1, @FM] OrigAppt = Get_Property(CtrlEntId, 'Appt[' : OrigApptID : ']') NewSchedulerKeyID = OrigWorkOrderNo : '*' : OrigEpiPartNo : '*' : NewReactorNo : '*' : NewStartDate : '*' : OrigSequence OrigScheduleKeyID = OrigReactorNo : '*' : OrigScheduleDate : '*' : OrigSequence ScheduleDetail = Schedule_Services('GetScheduleDetail', OrigScheduleKeyID) OrigDescription = ScheduleDetail If NewDescription EQ '' then NewDescription = ' ' If (OrigReactorNo NE NewReactorNo) OR (OrigScheduleDate NE NewStartDate) then // This work order event is being moved to another reactor or date. Assume all following work order events related to the // same work order number will also be moved. RemoveEventKeyIDs = '' AddEvents = '' OrigWorkOrderEvents = Schedule_Services('GetScheduleEvents', OrigScheduleDate, '', OrigReactorNo, OrigWorkOrderNo, False$) NumberOfEvents = DCount(OrigWorkOrderEvents, @FM) UpdatedEvents = Schedule_Services('AdjustScheduleEvents', OrigReactorNo, OrigWorkOrderNo, Neg(NumberOfEvents), OrigScheduleDate) If Error_Services('NoError') then // Remove the relevant appointments from the scheduler form. RemoveEventKeyIDs := UpdatedEvents[1, @RM] : @FM AddEvents := UpdatedEvents[Col2() + 1, @RM] : @FM If Error_Services('NoError') then // Add the work order events to the schedulers. UpdatedEvents = Schedule_Services('AdjustScheduleEvents', NewReactorNo, NewWorkOrderNo, NumberOfEvents, NewStartDate) RemoveEventKeyIDs := UpdatedEvents[1, @RM] : @FM AddEvents := UpdatedEvents[Col2() + 1, @RM] : @FM end end RemoveEventKeyIDs[-1, 1] = '' AddEvents[-1, 1] = '' If RemoveEventKeyIDs NE '' then Send_Message(CtrlEntId, 'RemoveAppts', RemoveEventKeyIDs) If AddEvents NE '' then Send_Message(CtrlEntId, 'AddAppts', AddEvents) end else If OrigDescription NE NewDescription then // This work order event is simply getting an updated description. Update the schedule detail in the database and // refresh the scheduler display. ScheduleDetail = NewDescription Schedule_Services('SetScheduleDetail', OrigScheduleKeyID, ScheduleDetail) OrigAppt<7> = NewDescription Set_Property(CtrlEntId, 'Appt[' : OrigApptID : ']', OrigAppt) end end GoSub HideWaitMessage end Case Item EQ 'CANCEL' CancelledScheduleEvents = Dialog_Box('SCHEDULER_ACTIONS', @Window, Item : @FM : OrigApptID) If CancelledScheduleEvents NE '' then UserConfirmed = Msg(@Window, '', 'OK_CANCEL', '', 'Scheduler' : @FM : 'Are you sure you want to cancel events for work order ' : OrigWorkOrderNo : '?') If UserConfirmed NE Esc$ then Caption = 'Please...cancelling events' GoSub ShowWaitMessage SchedulerKeyIDs = SRP_Array('Rotate', CancelledScheduleEvents, @FM, @VM) SchedulerKeyIDs = SchedulerKeyIDs<2> Convert @VM to @FM in SchedulerKeyIDs ScheduleKeyIDs = SRP_Array('Rotate', SchedulerKeyIDs, @FM, '*') ScheduleKeyIDs = Delete(ScheduleKeyIDs, 1, 0, 0) ScheduleKeyIDs = Delete(ScheduleKeyIDs, 1, 0, 0) ScheduleKeyIDs = SRP_Array('Rotate', ScheduleKeyIDs, @FM, '*') // Remove the schedule detail records first. ReactorNo = Field(OrigApptID, '*', 3) NumberOfEvents = Neg(DCount(SchedulerKeyIDs, @FM)) StartDate = Field(SchedulerKeyIDs<1>, '*', 4, 1) UpdatedEvents = Schedule_Services('AdjustScheduleEvents', ReactorNo, OrigWorkOrderNo, NumberOfEvents, StartDate) If Error_Services('NoError') then // Remove the relevant appointments from the scheduler form. RemoveEventKeyIDs = UpdatedEvents[1, @RM] AddEvents = UpdatedEvents[Col2() + 1, @RM] Send_Message(CtrlEntId, 'RemoveAppts', RemoveEventKeyIDs) Send_Message(CtrlEntId, 'AddAppts', AddEvents) end GoSub HideWaitMessage If @User4 EQ 'DEBRA_D' then If Error_Services('HasError') then Error_Services('DisplayError') end end end end Case Item EQ 'ADDBLOCK' AddEventDetails = Dialog_Box('SCHEDULER_ACTIONS', @Window, Item : @FM : OrigApptID) If AddEventDetails NE '' then Caption = 'Please wait...adding new events' GoSub ShowWaitMessage ReactorNo = AddEventDetails[1, @FM] StartDate = AddEventDetails[Col2() + 1, @FM] EndDate = AddEventDetails[Col2() + 1, @FM] Description = AddEventDetails[Col2() + 1, @FM] UpdatedEvents = Schedule_Services('AddBlockOutEvents', ReactorNo, StartDate, EndDate, Description) If Error_Services('NoError') then RemoveEventKeyIDs = UpdatedEvents[1, @RM] AddEvents = UpdatedEvents[Col2() + 1, @RM] Send_Message(CtrlEntId, 'RemoveAppts', RemoveEventKeyIDs) Send_Message(CtrlEntId, 'AddAppts', AddEvents) end GoSub HideWaitMessage end Case Item EQ 'CANCELBLOCK' CancelledBlockOutEvent = Dialog_Box('SCHEDULER_ACTIONS', @Window, Item : @FM : OrigApptID) If CancelledBlockOutEvent NE '' then Caption = 'Please wait...cancelling block out event' GoSub ShowWaitMessage BlockOutEventKeyID = '**' : CancelledBlockOutEvent UpdatedEvents = Schedule_Services('CancelBlockOutEvent', BlockOutEventKeyID) If Error_Services('NoError') then // Remove the relevant appointments from the scheduler form. RemoveEventKeyIDs = UpdatedEvents[1, @RM] AddEvents = UpdatedEvents[Col2() + 1, @RM] Send_Message(CtrlEntId, 'RemoveAppts', RemoveEventKeyIDs) Send_Message(CtrlEntId, 'AddAppts', AddEvents) end GoSub HideWaitMessage end Case Item EQ 'FORCEADJUST' Caption = 'Please wait...adjusting work order events' GoSub ShowWaitMessage AdjustedDays = Schedule_Services('GetAdjustedDays', OrigWorkOrderNo, OrigReactorNo) If Error_Services('NoError') then If AdjustedDays NE '' AND AdjustedDays NE 0 then UpdatedEvents = Schedule_Services('AdjustScheduleEvents', OrigReactorNo, OrigWorkOrderNo, AdjustedDays, '') If Error_Services('NoError') then RemoveEventKeyIDs = UpdatedEvents[1, @RM] AddEvents = UpdatedEvents[Col2() + 1, @RM] Send_Message(CtrlEntId, 'RemoveAppts', RemoveEventKeyIDs) Send_Message(CtrlEntId, 'AddAppts', AddEvents) AddEvents = SRP_Array('Rotate', AddEvents, @FM, @VM) AppointmentKeys = AddEvents<2> Convert @VM to @FM in AppointmentKeys Flags = AddEvents<19> Convert @VM to @FM in Flags Convert @SVM to @VM in Flags For Each AppointmentKey in AppointmentKeys using @FM setting fPos FlagVals = Flags If Sum(FlagVals) GT 0 then Convert @VM to @FM in FlagVals Set_Property(CtrlEntId, 'OLE.ApptFlags[' : AppointmentKey : ']', FlagVals) end Next AppointmentKey end end end GoSub HideWaitMessage Case Item EQ 'REMOVEEVENT' Schedule_Services('DeleteScheduleDetail', OrigReactorNo : '*' : OrigScheduleDate : '*' : OrigSequence) Send_Message(CtrlEntId, 'RemoveAppts', OrigApptID) Case Item EQ 'ADJUSTREACTOR' Schedule_Services('AutoScheduler', OrigReactorNo, False$) Case Item EQ 'ADJUSTREACTORLOGONLY' Schedule_Services('AutoScheduler', OrigReactorNo, True$) Case Item EQ 'ADJUSTALLREACTORSLOGONLY' Schedule_Services('AutoScheduler', '', True$) End Case end event Event OLE_SCHEDULE.OnDateChange(Date) DateList = Get_Property(CtrlEntId, '@DATE_LIST') ReloadStartDate = Date - 7 ReloadEndDate = Date + 7 ReloadWorkOrders = False$ For Date = ReloadStartDate to ReloadEndDate Locate Date in DateList using @FM setting fPos else ReloadWorkOrders = True$ Until ReloadWorkOrders EQ True$ Next Date If ReloadWorkOrders then // The ShowWaitMessage gosub hides the schedule control and displays the picture contorl with the indicated caption. Caption = 'Please wait...updating schedule' GoSub ShowWaitMessage // Update the work orders AppointmentList = Schedule_Services('GetScheduleEvents', ReloadStartDate, ReloadEndDate) Send_Message(CtrlEntId, 'OLE.AddAppts', AppointmentList) // The SetScheduleFlags gosub loops through the AppointmentKeys array and parses the AppointmentFlags // array for the ApptFlags property. AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AppointmentKeys = AppointmentArray<2> Convert @VM to @FM in AppointmentKeys AppointmentFlags = AppointmentArray<19> Convert @VM to @FM in AppointmentFlags GoSub SetScheduleFlags For Date = ReloadStartDate to ReloadEndDate Locate Date in DateList using @FM setting fPos else DateList = Insert(DateList, fPos, 0, 0, Date) end Next Date Set_Property(CtrlEntId, '@DATE_LIST', DateList) GoSub HideWaitMessage end end event Event OLE_DATEPICKER.OnSelChange(FirstDate) SelectedDate = Get_Property(CtrlEntId, 'OLE.Selection') Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.Date', SelectedDate) Send_Event(@Window : '.OLE_SCHEDULE', 'OLE', 'OnDateChange', SelectedDate) end event Event OLE_TRE_REACTOR_FILTER_OPTIONS.OnItemCheck(Item, Checked) Set_Property(@Window, 'REDRAW', False$) FilterType = Get_Property(@Window : '.EDL_REACTOR_FILTER', 'TEXT') FilterOptions = Get_Property(CtrlEntId, 'OLE.RootChildren') ItemsChecked = '' For Each FilterOption in FilterOptions using @FM setting fPos If Get_Property(CtrlEntId, 'OLE.ItemChecked[' : FilterOption : ']') then ItemsChecked := FilterOption : @FM end Next FilterOption ItemsChecked[-1, 1] = '' // Make sure all reactors are visible again. EntityList = Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityList') For Each Entity in EntityList using @FM EntityID = Entity<0, 3> If Not(Get_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : EntityID : ']')) then Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : EntityID : ']', True$) end Next Entity // Now apply the filter optons and hide those entities which should be hidden. Reactors = Reactor_Services('GetReactors') If SRP_JSON(objReactors, 'PARSE', Reactors) EQ '' then objReactorArray = SRP_JSON(objReactors, 'GET', 'Reactors') NumObjects = SRP_JSON(objReactorArray, 'GETCOUNT') For ObjectCount = 1 to NumObjects ReactorNo = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].ReactorNumber') Begin Case Case FilterType _EQC 'Reactor Type' Type = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].TypeVerbose') Locate Type in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Reactor Assignment' AssignmentDescription = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].AssignmentDescription') Locate AssignmentDescription in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Cleanroom Area' Location = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].Location') Locate Location in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Wafer Size' WaferSize = SRP_JSON(objReactorArray, 'GETVALUE', '[' : ObjectCount : '].SusceptorSize') Locate WaferSize in ItemsChecked using @FM setting fPos else Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.EntityChecked[' : ReactorNo : ']', False$) end Case FilterType _EQC 'Cleanroom Area' Null End Case Next ObjectCount SRP_JSON(objReactorArray, 'RELEASE') end SRP_JSON(objReactors, 'RELEASE') Set_Property(@Window, 'REDRAW', True$) end event Event EDL_ASM_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_ASM_PLUS_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_HTR_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_EPIPRO_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event EDL_GAN_UTILIZATION.CHANGED(NewData) OrigValue = Get_Property(CtrlEntId, 'GOTFOCUS_VALUE') CurrValue = Get_Property(CtrlEntId, 'DEFPROP') If OrigValue NE CurrValue then ButtonCtrl = CtrlEntId Swap 'EDL' with 'OLE_PUB_UPDATE' in ButtonCtrl Set_Property(ButtonCtrl, 'ENABLED', True$) end end event Event OLE_PUB_UPDATE_ASM_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) ASMUtil = Get_Property(@Window : '.EDL_ASM_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'ASM', ASMUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) ASMPlusUtil = Get_Property(@Window : '.EDL_ASM_PLUS_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'ASM+', ASMPlusUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_HTR_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) HTRUtil = Get_Property(@Window : '.EDL_HTR_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'HTR', HTRUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_EPIPRO_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) EpiProUtil = Get_Property(@Window : '.EDL_EPIPRO_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'EpiPro', EpiProUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_UPDATE_GAN_UTILIZATION.OnClick(Point, Button, Shift, Ctrl) GaNUtil = Get_Property(@Window : '.EDL_GAN_UTILIZATION', 'INVALUE') Epi_Part_Services('SetReactorUtilization', 'GaN', GaNUtil) Set_Property(CtrlEntId, 'ENABLED', False$) EditCtrl = CtrlEntId Swap 'OLE_PUB_UPDATE' with 'EDL' in EditCtrl Set_Property(EditCtrl, 'FOCUS', True$) end event Event OLE_PUB_REFRESH_SCHEDULE.OnClick(Point, Button, Shift, Ctrl) // The ShowWaitMessage gosub hides the schedule control and displays the picture contorl with the indicated caption. Caption = 'Please wait...refreshing schedule' GoSub ShowWaitMessage StartDate = Date() - 7 EndDate = Date() + 30 // The GetScheduleAppointments gosub populates the AppointmentList, AppointmentKeys, and AppointmentFlags variables. GoSub GetScheduleAppointments * Send_Message(@Window : '.OLE_SCHEDULE', 'OLE.AddAppts', AppointmentList) Set_Property(@Window : '.OLE_SCHEDULE', 'OLE.AppointmentList', AppointmentList) // The SetScheduleFlags gosub loops through the AppointmentKeys array and parses the AppointmentFlags // array for the ApptFlags property. GoSub SetScheduleFlags GoSub HideWaitMessage end event Event OLE_SUBCLASS.OnOptionClick(CtrlId) Send_Event(CtrlId, 'OPTIONS') end event Event OLE_SUBCLASS.OnComboClick(CtrlId) Send_Event(CtrlId, 'LOSTFOCUS') end event Event OLE_POPUP.OnItemClick(Item) ApptID = Get_Property(CtrlEntId, '@APPTID') WorkOrderNo = ApptID[1, '*'] EpiPartNo = ApptID[Col2() + 1, '*'] ReactorNo = ApptID[Col2() + 1, '*'] StartDate = ApptID[Col2() + 1, '*'] Sequence = ApptID[Col2() + 1, '*'] WOStepKey = WorkOrderNo : '*1' // Item is the index value of the item being clicked on from the ItemList property. PreviousItemArray = Get_Property(CtrlEntId, 'OLE.Item[' : Item - 1 : ']') PreviousCaption = PreviousItemArray<2> CurrentItemArray = Get_Property(CtrlEntId, 'OLE.Item[' : Item : ']') CurrentCaption = CurrentItemArray<2> GoSub DismissPopup Begin Case Case PreviousCaption _EQC 'Work Order:' if security_check( 'WO Log', Read$ ) then NewForm = Xlate('APP_INFO', 'NEW_WO_FORM', '', 'X') If NewForm then Start_Window('NDW_WO_LOG', @Window, WorkOrderNo) end else Start_window( 'WO_LOG2', @window, WorkOrderNo:'*CENTER', '', '' ) end end else security_err_msg( 'WO Log', Read$ ) end Case PreviousCaption _EQC 'Epi Part:' * IF security_check( 'Prod Spec', Read$ ) THEN Void = start_window( 'EPI_PART', @window, EpiPartNo : '*CENTER', '', '' ) * END ELSE * security_err_msg( 'Prod Spec', Read$ ) * END Case PreviousCaption _EQC 'PSN:' IF security_check( 'Prod Spec', Read$ ) THEN PSNId = XLATE('WO_STEP',WOStepKey,WO_STEP_PROD_SPEC_ID$,'X') Void = start_window( 'PROD_SPEC', @window, PSNId:'*CENTER', '', '' ) END ELSE security_err_msg( 'Prod Spec', Read$ ) END Case PreviousCaption _EQC 'Recipe:' if security_check( 'Recipe', Read$ ) then PSN = XLATE('WO_STEP',WOStepKey,1,'X') LayerSpecs = obj_Prod_Spec('GetLayerProp',PSN:@RM:@RM:1) ;* Returns specs for all layers in internal format LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet RecipeNo = LayerSpec Void = start_window( 'RECIPE', @window, RecipeNo:'*CENTER', '', '' ) end else security_err_msg( 'Recipe', Read$ ) end Case PreviousCaption _EQC 'SCHED_DET Key:' SchedDetKeyID = CurrentCaption call SRP_Editor_Open('Record', 'SCHED_DET' : @FM : SchedDetKeyID, 1) End Case end event //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Setup_OLE_Controls: Ctrl = @Window : '.OLE_PICTURE' Set_Property(Ctrl, 'OLE.BackgroundColor', 'Vertical(Gradient(LightSteelBlue L=90, LightSteelBlue L=80, 30%), Gradient(LightSteelBlue L=75, LightSteelBlue L=80), Border(LightSteelBlue L=50, LightSteelBlue L=50, LightSteelBlue L=50, LightSteelBlue L=50))') Set_Property(Ctrl, 'OLE.Font', SystemTypeface$ : @SVM : 30 : @SVM : 700) // The ShowWaitMessage gosub hides the schedule control and displays the picture contorl with the indicated caption. Caption = 'Please wait...loading schedule' GoSub ShowWaitMessage Ctrl = @Window : '.OLE_SCHEDULE' // Setup the inital date range during the 'Create' StartDate = Date() - 7 EndDate = Date() + 30 DateList = '' For Date = StartDate to EndDate DateList := Date : @FM Next Date DateList[-1, 1] = '' Set_Property(Ctrl, '@DATE_LIST', DateList) Set_Property(Ctrl, 'OLE.Border', 'XP Flat') Set_Property(Ctrl, 'OLE.View', 'MultiDayHorz') ; // Landscape mode Set_Property(Ctrl, 'OLE.DateHeaderFormat', 'DDDD - mmm DD, YYYY') Set_Property(Ctrl, 'OLE.CurrentTimeColor', 'Blue') Set_Property(Ctrl, 'OLE.ShowCalendar', False$) Set_Property(Ctrl, 'OLE.ShowTree', False$) Set_Property(Ctrl, 'OLE.AllowLeadTime', False$) Set_Property(Ctrl, 'OLE.AllowTrailTime', False$) Set_Property(Ctrl, 'OLE.EnableLeadTrailDisplay', Trail$) Set_Property(Ctrl, 'OLE.AppointmentMetrics', 4 : @FM : 4) Set_Property(Ctrl, 'OLE.Interval', 60) ; // Number of minutes per interval Set_Property(Ctrl, 'OLE.IntervalSize', 10) ; // Space (width) for each time increment (in pixels) * Set_Property(Ctrl, 'OLE.ConflictColor', 'Crimson') Set_Property(Ctrl, 'OLE.TimeRange', 0 :@FM: 24 :@FM: 4) ; // <3> is hour display increment * Set_Property(Ctrl, 'OLE.RightTimeBar', Yes$) Fonts = '' Fonts<1> = 'Segoe UI' : @SVM : '10' ; // Column Hours Fonts<2> = 'Segoe UI' : @SVM : '6' ; // Column Minutes Fonts<3> = 'Segoe UI' : @SVM : '12' : @SVM : '700' ; // Reactor No Fonts<4> = 'Segoe UI' : @SVM : '8' ; // Reactor Meta Fonts<5> = 'Segoe UI' : @SVM : '12' : @SVM : '700' ; // Column Date and Day Set_Property(Ctrl, 'OLE.ScheduleFonts', Fonts) // Setup the initial reactors list. This populates the EntityList variable. GoSub GetReactorEntities Set_Property(Ctrl, 'OLE.EntityList', EntityList) Set_Property(Ctrl, 'OLE.AutoSize', 0) Set_Property(Ctrl, 'OLE.EntitySize[All]', 75) Set_Property(Ctrl, 'OLE.Date', Date()-1) Layout = '' Layout<1, 1> = 'APPTDATA' Layout<1, 2> = 0 : @SVM : 0 : @SVM : -1 : @SVM : -1 Layout<1, 3> = 'NAME' Layout<1, 4> = '' Layout<1, 5> = 'Segoe UI' : @SVM : 9 : @SVM : 700 Layout<1, 6> = 'Left' Layout<1, 7> = 'Top' Layout<1, 8> = 0 Layout<1, 10> = 1 Layout<2, 1> = 'APPTDATA' Layout<2, 2> = 0 : @SVM : 0 : @SVM : -1 : @SVM : -1 Layout<2, 3> = 'DESC' Layout<2, 4> = '' Layout<2, 6> = 'Left' Layout<2, 7> = 'Bottom' Layout<2, 8> = 1 Layout<2, 10> = 0 Layout<3, 1> = 'FLAGS' Layout<3, 2> = 0 : @SVM : 0 : @SVM : -1 : @SVM : -1 Layout<3, 3> = 'bmps\scheduler.png' Layout<3, 4> = 4 : @SVM : @SVM : 0 Layout<3, 6> = 'Right' Layout<3, 7> = '' Layout<3, 8> = '' Layout<3, 10> = 0 Set_Property(Ctrl, 'OLE.Layout', Layout) // The GetScheduleAppointments gosub populates the AppointmentList, AppointmentKeys, and AppointmentFlags variables. GoSub GetScheduleAppointments Set_Property(Ctrl, 'OLE.AppointmentList', AppointmentList) // The SetScheduleFlags gosub loops through the AppointmentKeys array and parses the AppointmentFlags // array for the ApptFlags property. GoSub SetScheduleFlags Qualify = '' Qualify<1> = 1 Qualify<4> = 0 Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptDblClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnScheduleClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnDateChange', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptHover', 1) GoSub HideWaitMessage Ctrl = @Window : '.OLE_DATEPICKER' Set_Property(Ctrl, 'OLE.Border', 'XP Flat') Set_Property(Ctrl, 'OLE.Font', 'Segoe UI' : @SVM : '9') Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnSelChange', 1) Ctrl = @Window : '.OLE_SUBCLASS' EditLine = @Window : '.EDL_REACTOR_FILTER' Set_Property(EditLine, 'TEXT', 'Reactor Type') Post_Event(EditLine, 'LOSTFOCUS') Handle = Get_Property(EditLine, 'HANDLE') Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine) EditLine = @Window : ';EDL_REACTOR_FILTER' FilterTypes = 'Reactor Type' : @STM : 'Reactor Assignment' : @STM : 'Wafer Size' : @STM : 'Cleanroom Area' Combo = '' Combo<1> = 1 Combo<2, 1> = '' Combo<2, 2> = 'L' : @STM : 'DYN' Combo<2, 3> = FilterTypes Combo<2, 4> = 1 Combo<2, 5> = 1 Combo<2, 6> = 0 Combo<2, 9> = 1 Combo<2,11> = 0 Set_Property(Ctrl, 'OLE.Combo[' : EditLine : ']', Combo) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnOptionClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnComboClick', 1) EditLine = @Window : '.EDL_WORK_ORDER_SEARCH' Handle = Get_Property(EditLine, 'HANDLE') Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine) EditLine = @Window : ';EDL_WORK_ORDER_SEARCH' WorkOrders = AppointmentArray<2> Convert @VM to @FM in WorkOrders Convert '*' to @VM in WorkOrders WorkOrders = SRP_Array('Rotate', WorkOrders, @FM, @VM) WorkOrders = WorkOrders<1> Convert @VM to @FM in WorkOrders WorkOrders = SRP_Array('Clean', WorkOrders, 'TrimAndMakeUnique', @FM) WorkOrders = SRP_Array('SortRows', WorkOrders, 'AR1', 'LIST', @FM, @VM) Convert @FM to @STM in WorkOrders Combo = '' Combo<1> = 1 Combo<2, 1> = '' Combo<2, 2> = 'L' : @STM : 'DYN' Combo<2, 3> = WorkOrders Combo<2, 4> = 1 Combo<2, 5> = 1 Combo<2, 6> = 0 Combo<2, 9> = 1 Combo<2,10> = 0 Combo<2,11> = 0 Set_Property(Ctrl, 'OLE.Combo[' : EditLine : ']', Combo) * Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnOptionClick', 1) * Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnComboClick', 1) EditLine = @Window : '.EDL_EPI_PART_SEARCH' Handle = Get_Property(EditLine, 'HANDLE') Send_Message(Ctrl, 'OLE.Subclass', Handle, EditLine) EditLine = @Window : ';EDL_EPI_PART_SEARCH' EpiParts = AppointmentArray<2> Convert @VM to @FM in EpiParts Convert '*' to @VM in EpiParts EpiParts = SRP_Array('Rotate', EpiParts, @FM, @VM) EpiParts = EpiParts<2> Convert @VM to @FM in EpiParts EpiParts = SRP_Array('Clean', EpiParts, 'TrimAndMakeUnique', @FM) OSWrite EpiParts to 'E:\apps\Temp\TEMP\EpiParts.txt' EpiParts = SRP_Array('SortRows', EpiParts, 'AR1', 'LIST', @FM, @VM) Convert @FM to @STM in EpiParts Combo = '' Combo<1> = 1 Combo<2, 1> = '' Combo<2, 2> = 'L' : @STM : 'DYN' Combo<2, 3> = EpiParts Combo<2, 4> = 1 Combo<2, 5> = 1 Combo<2, 6> = 0 Combo<2, 9> = 1 Combo<2,10> = 0 Combo<2,11> = 0 Set_Property(Ctrl, 'OLE.Combo[' : EditLine : ']', Combo) * Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnOptionClick', 1) * Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnComboClick', 1) Ctrl = @Window : '.OLE_TRE_REACTOR_FILTER_OPTIONS' Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnItemCheck', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnApptDblClick', 1) Ctrls = 'OLE_PUB_UPDATE_ASM_UTILIZATION,OLE_PUB_UPDATE_ASM_PLUS_UTILIZATION,OLE_PUB_UPDATE_HTR_UTILIZATION,OLE_PUB_UPDATE_EPIPRO_UTILIZATION,OLE_PUB_UPDATE_GAN_UTILIZATION' For Each ButtonCtrl in Ctrls using ',' Ctrl = @Window : '.' : ButtonCtrl Set_Property(Ctrl, 'OLE.Icon', '.\BMPS\Save.png') Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnClick', 1) Next ButtonCtrl Ctrl = @Window : '.OLE_PUB_REFRESH_SCHEDULE' Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnClick', 1) Ctrl = @Window : '.OLE_POPUP' Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnItemClick', 1) Send_Message(Ctrl, 'QUALIFY_EVENT', 'OLE.OnHide', 1) return DisplayPopup: Utility('CURSOR', 'H') Set_Property(PopupCtrl, '@APPTID', ApptID) Appt = Get_Property(CtrlEntID, 'OLE.Appt[' : ApptID : ']') HoverData = '' BackColor = Appt<4> ; // Use the same BackColor of the current appointment as the base. WorkOrderNo = ApptID[1, '*'] EpiPartNo = ApptID[Col2() + 1, '*'] ReactorNo = ApptID[Col2() + 1, '*'] Date = ApptID[Col2() + 1, '*'] Sequence = ApptID[Col2() + 1, '*'] Summary = Schedule_Services('GetScheduleEventSummary', ReactorNo, WorkOrderNo, Date, Sequence, True$) HoverData := 'Reactor:' : @VM : ReactorNo : @FM HoverData := 'Type:' : @VM : Summary : @FM HoverData := 'Susceptor:' : @VM : Summary : @FM HoverData := 'Work Order:' : @VM : WorkOrderNo : @FM HoverData := 'Customer:' : @VM : Summary : @FM HoverData := 'Epi Part:' : @VM : EpiPartNo : @FM HoverData := 'PSN:' : @VM : Summary : @FM HoverData := 'Recipe:' : @VM : Summary : @FM HoverData := 'Start Date:' : @VM : Summary : @FM HoverData := 'End Date:' : @VM : Summary : @FM HoverData := 'Total Days:' : @VM : Summary : @FM HoverData := 'Total Wafers:' : @VM : Summary : @FM HoverData := 'Remaining Wafers:' : @VM : Summary : @FM HoverData := 'Complete:' : @VM : Summary Note = Summary If Note NE '' then HoverData := @FM : 'Note:' : @VM : Summary end If MemberOf(@USER4, 'OI_ADMIN') then HoverData := @FM : 'SCHED_DET Key:' : @VM : ReactorNo : '*' : Date : '*' : Sequence end BackColor := ' L=40' NumLines = DCount(HoverData, @FM) ForeColor = 'White' Linkcolor = 'LightGray' // Calculate the size and position of the popup. By default it will appear to the right of the // appointment (order), but if it will display off the screen then move it to the left. DesktopWidth = Get_Property('SYSTEM', 'SIZE')<1> ApptRect = Get_Property(CtrlEntId, 'OLE.ApptRect[' : ApptId : ']') RectLeft = ApptRect<1> RectTop = ApptRect<2> RectRight = ApptRect<3> RectBottom = ApptRect<4> If Note NE '' then ItemWidth = 480 end else ItemWidth = 240 end // For popups with a top pointer * PopupWidth = ItemWidth + 4 // For popups with a left pointer PopupWidth = ItemWidth + 4 + 30 * ItemHeight = NumLines * 20 ItemHeight = 20 PopupHeight = NumLines * ItemHeight + 14 If (RectRight + PopupWidth) LE DesktopWidth then // SRP Popup will fit if displayed on the right. TailPosition = 'Left' ItemMargin = 28 PopupX = RectRight end else // SRP Popup will have to be positioned on the left. TailPosition = 'Right' ItemMargin = 12 PopupX = RectLeft - PopupWidth end // Calculate the center point of the appointment. Necessary to position the SRP Popup properly in the middle. ApptHCenter = RectTop + ((RectBottom - RectTop) / 2) ApptVCenter = RectLeft + ((RectRight - RectLeft) / 2) PopupY = ApptHCenter - (PopupHeight / 2) // Use these coordinates to place the popup under the order. * PopupX = ApptVCenter - (PopupWidth / 2) * PopupY = RectBottom + 0 ItemList = '' If HoverData NE '' then For Each Item in HoverData using @FM setting ItemCnt // Add the label. Label = Item<0, 1> If Note NE '' then ItemList := ItemMargin : @SVM : 5 + (ItemCnt - 1) * ItemHeight : @SVM : ItemWidth / 4 : @SVM : ItemHeight : @VM end else ItemList := ItemMargin : @SVM : 5 + (ItemCnt - 1) * ItemHeight : @SVM : ItemWidth / 2 : @SVM : ItemHeight : @VM end ItemList := Label : @VM ItemList := Forecolor : @VM ItemList := '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' : @VM ItemList := 'Left' : @SVM : 'Center' : @VM ItemList := @FM // Add the value. Value = Item<0, 2> If Note NE '' then ItemList := ItemMargin + (ItemWidth / 4) : @SVM : 5 + (ItemCnt - 1) * ItemHeight : @SVM : 3 * ItemWidth / 4 : @SVM : ItemHeight : @VM end else ItemList := ItemMargin + (ItemWidth / 2) : @SVM : 5 + (ItemCnt - 1) * ItemHeight : @SVM : ItemWidth / 2 : @SVM : ItemHeight : @VM end ItemList := Value : @VM If Label _EQC 'Work Order:' OR Label _EQC 'Epi Part:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' OR Label _EQC 'SCHED_DET Key:' then ItemList := Linkcolor : @VM end else ItemList := Forecolor : @VM end If Label _EQC 'Work Order:' OR Label _EQC 'Epi Part:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' OR Label _EQC 'SCHED_DET Key:' then ItemList := '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '1' : @VM end else ItemList := '' : @SVM : '' : @SVM : '700' : @SVM : '0' : @SVM : '0' : @VM end ItemList := 'Left' : @SVM : 'Center' : @VM * If Label _EQC 'Work Order:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' then If Label _EQC 'Work Order:' OR Label _EQC 'Epi Part:' OR Label _EQC 'PSN:' OR Label _EQC 'Recipe:' OR Label _EQC 'SCHED_DET Key:' then ItemList := True$ : @VM : False$ : @VM end ItemList := @FM Next Item ItemList[-1, 1] = '' end Set_Property(PopupCtrl, 'OLE.Theme', 'Custom') Set_Property(PopupCtrl, 'OLE.Opacity', 255) Set_Property(PopupCtrl, 'OLE.Animation', 'N') Set_Property(PopupCtrl, 'OLE.Background', 'Vertical(Gradient(' : Backcolor : ', ' : Backcolor : '), Border(' : Backcolor : ' L=20))' : @FM : 'None' : @FM : 'None') Set_Property(PopupCtrl, 'OLE.ItemList', ItemList) Set_Property(PopupCtrl, 'OLE.ShowDelay', 1500) Set_Property(PopupCtrl, 'OLE.Size', 0 : @FM : 0 : @FM : PopupWidth : @FM : PopupHeight) // This identifies the position of the tail. Options are: // Left, Top, Right, Bottom Set_Property(PopupCtrl, 'OLE.Pointer', TailPosition) Utility('CURSOR', 'A') // This tells the popup to appear at the designated X and Y coordinates which // have been calculated above based on the relative location of the order. Send_Message(PopupCtrl, 'OLE.ShowAt', PopupX, PopupY) return DismissPopup: PopupCtrl = @Window : '.OLE_POPUP' PopupVisible = Get_Property(PopupCtrl, 'OLE.Visible') If PopupVisible EQ True$ then Send_Message(PopupCtrl, 'OLE.Close') Set_Property(CtrlEntId, '@PREVAPPTID', '') end return ShowWaitMessage: Set_Property(@Window : '.OLE_PICTURE', 'OLE.Caption', Caption) Set_Property(@Window : '.OLE_PICTURE', 'VISIBLE', 1) Set_Property(@Window : '.OLE_SCHEDULE', 'VISIBLE', 0) Set_Property(@Window, 'REDRAW', 0) return HideWaitMessage: Set_Property(@Window : '.OLE_SCHEDULE', 'VISIBLE', 1) Set_Property(@Window : '.OLE_PICTURE', 'OLE.Caption', '') Set_Property(@Window : '.OLE_PICTURE', 'VISIBLE', 0) Set_Property(@Window, 'REDRAW', 1) return GetScheduleAppointments: Ctrl = @Window : '.OLE_SCHEDULE' AppointmentList = '' AppointmentKeys = '' AppointmentFlags = '' AppointmentList = Schedule_Services('GetScheduleEvents', StartDate, EndDate) AppointmentArray = SRP_Array('Rotate', AppointmentList, @FM, @VM) AppointmentKeys = AppointmentArray<2> Convert @VM to @FM in AppointmentKeys AppointmentFlags = AppointmentArray<19> Convert @VM to @FM in AppointmentFlags return SetScheduleFlags: Ctrl = @Window : '.OLE_SCHEDULE' For Each AppointmentKey in AppointmentKeys using @FM setting fPos Flags = AppointmentFlags If Sum(Flags) GT 0 then Convert @SVM to @FM in Flags Set_Property(Ctrl, 'OLE.ApptFlags[' : AppointmentKey : ']', Flags) end Next AppointmentKey return GetReactorEntities: Ctrl = @Window : '.OLE_SCHEDULE' If Memory_Services('IsValueCurrent', Ctrl : '*EntityList', 3600, True$) then EntityList = Memory_Services('GetValue', Ctrl : '*EntityList') end else EntityList = '' Reactors = Reactor_Services('GetReactors') If SRP_JSON(objReactors, 'PARSE', Reactors) EQ '' then objReactorArray = SRP_JSON(objReactors, 'GET', 'Reactors') objReactorList = SRP_JSON(objReactorArray, 'GETELEMENTS') For Each objReactor in objReactorList using @FM ReactorNo = SRP_JSON(objReactor, 'GETVALUE', 'ReactorNumber') Type = SRP_JSON(objReactor, 'GETVALUE', 'TypeVerbose') Size = SRP_JSON(objReactor, 'GETVALUE', 'SusceptorSize') Assignment = SRP_JSON(objReactor, 'GETVALUE', 'AssignmentCode') SecondChamber = SRP_JSON(objReactor, 'GETVALUE', 'SecondChamber') PickPlace = SRP_JSON(objReactor, 'GETVALUE', 'PickPlace') NotRepairable = SRP_JSON(objReactor, 'GETVALUE', 'NotRepairable') EpiPro = (Type EQ 'EpiPro') Begin Case Case Assignment EQ 'G' // GaN Background = 'SkyBlue' Case Assignment EQ 'O' // Out-of-Service Background = 'Silver' Case Not(NotRepairable) Background = 'LightGreen' Case NotRepairable Background = 'Orange' Case Otherwise$ Background = 'Silver' End Case If (Type NE 'EpiPro') OR (SecondChamber NE '') then EntityName = ReactorNo If SecondChamber NE '' then EntityName := '/' : SecondChamber EntityList := 'ENT' : @VM : 1 : @VM : ReactorNo : @VM : EntityName : @VM : Type : CRLF$ : Size : @VM : 'Black' : @VM : Background : @FM end SRP_JSON(objReactor, 'RELEASE') Next objReactor EntityList[-1, 1] = '' SRP_JSON(objReactorArray, 'RELEASE') end SRP_JSON(objReactors, 'RELEASE') Memory_Services('SetValue', Ctrl : '*EntityList', EntityList) end return ParseScheduleEvent: If Assigned(objScheduleEvent) else objScheduleEvent = '' If objScheduleEvent EQ '' then SRP_JSON(objScheduleEvent, 'PARSE', ScheduleEvent) end If objScheduleEvent GT 0 then ReactorNo = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Reactor.ReactorNumber') ReactorType = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Reactor.Type') SusceptorSize = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Reactor.SusceptorSize') ScheduleDate = SRP_JSON(objScheduleEvent, 'GETVALUE', 'ScheduleDate') ScheduleDate = Iconv(ScheduleDate, 'D') Sequence = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Sequence') BackColor = SRP_JSON(objScheduleEvent, 'GETVALUE', 'BackColor') ForeColor = SRP_JSON(objScheduleEvent, 'GETVALUE', 'ForeColor') ModifiedDTM = SRP_JSON(objScheduleEvent, 'GETVALUE', 'ModifiedDTM') BlockOut = Iconv(SRP_JSON(objScheduleEvent, 'GETVALUE', 'BlockOut'), 'BYes,No') BlockOutType = SRP_JSON(objScheduleEvent, 'GETVALUE', 'BlockOutType') Description = SRP_JSON(objScheduleEvent, 'GETVALUE', 'Note') objWorkOrder = SRP_JSON(objScheduleEvent, 'GET', 'WorkOrder') WorkOrderNo = SRP_JSON(objWorkOrder, 'GETVALUE', 'WorkOrderNumber') EpiPartNo = SRP_JSON(objWorkOrder, 'GETVALUE', 'EpiPartNumber') PSN = SRP_JSON(objWorkOrder, 'GETVALUE', 'PSN') Recipe = SRP_JSON(objWorkOrder, 'GETVALUE', 'Recipe') HotLot = Iconv(SRP_JSON(objWorkOrder, 'GETVALUE', 'HotLot'), 'BYes,No') Closed = Iconv(SRP_JSON(objWorkOrder, 'GETVALUE', 'Closed'), 'BYes,No') CustNameShort = SRP_JSON(objWorkOrder, 'GETVALUE', 'Company.NameShort') SRP_JSON(objWorkOrder, 'RELEASE') If BackColor EQ '' then Begin Case Case BackColor NE '' // Set in the schedule detail record. Use current color. Case HotLot BackColor = 'LightCoral' Case Closed BackColor = 'LightGray' Case BlockOut BackColor = 'Plum' Case Otherwise$ BackColor = 'LightSteelBlue' End Case end Current = False$ ; // Assume false for now. If (ScheduleDate GE Date()) then If (ModifiedDTM NE '') then CurrentDTM = Iconv(Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTH'), 'DTM') ElapseTime = (CurrentDTM - ModifiedDTM) * 24 IF (ElapseTime LE 12) then CurrentFlag = True$ end end end If ForeColor EQ '' then ForeColor = 'Black' FirstSchedDetKeyID = SRP_JSON(objScheduleEvent, 'GETVALUE', 'FirstSchedDetKeyID') FirstReactorNo = FirstSchedDetKeyID[1, '*'] FirstScheduleDate = Oconv(FirstSchedDetKeyID[Col2() + 1, '*'], 'D4/') LastSchedDetKeyID = SRP_JSON(objScheduleEvent, 'GETVALUE', 'LastSchedDetKeyID') LastReactorNo = LastSchedDetKeyID[1, '*'] LastScheduleDate = Oconv(LastSchedDetKeyID[Col2() + 1, '*'], 'D4/') TotalScheduledDays = SRP_JSON(objScheduleEvent, 'GETVALUE', 'TotalScheduledDays') TotalWafers = SRP_JSON(objScheduleEvent, 'GETVALUE', 'WorkOrder.TotalWafers') WafersRemaining = SRP_JSON(objScheduleEvent, 'GETVALUE', 'WorkOrder.WafersRemaining') PercentComplete = SRP_JSON(objScheduleEvent, 'GETVALUE', 'WorkOrder.PercentComplete') ScheduleEvent = SRP_JSON(objScheduleEvent, 'STRINGIFY', 'FAST') SRP_JSON(objScheduleEvent, 'RELEASE') end else end return