open-insight/LSL2/STPROC/NDW_WAFER_COUNTER_EVENTS.txt
2024-10-31 14:22:20 -07:00

601 lines
28 KiB
Plaintext

Compile function NDW_WAFER_COUNTER_EVENTS(CtrlEntId, Event, @PARAMS)
/***********************************************************************************************************************
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 : NDW_Wafer_Counter_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)
03/14/24 djs Created initial commuter module.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_PACKAGING
$insert APP_INSERTS
$insert EVENT_SETUP
$insert MSG_EQUATES
$insert LSL_USERS_EQUATES
$insert MESSAGE_BOX_EQUATES
$insert SRP_POPUP_EQUATES
$INSERT LOGICAL
Equ MSG_WIDTH$ to 650
Equ Comma$ to ','
Declare function MemberOf, Form_Services, Wafer_Counter_Services, SRP_Json, WO_Mat_Services, Wm_Out_Services, Datetime
Declare function Logging_Services, Environment_Services
Declare subroutine SRP_Json, PlaceDialog, Wafer_Counter_Services, Logging_Services
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WaferCounter'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Wafer Counter Verify Log.csv'
Headers = 'Logging DTM':@FM:'Logging Text'
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
SubclassInfo = Form_Services('FindSubclassControl')
Subclass = SubclassInfo<1>
// Update the arguments so that the OpenInsight OLE event will treate the ActiveX event as a native event handler.
If Event EQ 'OLE' then
Transfer Event to OIEvent
Transfer Param1 to Event
Transfer Param2 to Param1
Transfer Param3 to Param2
Transfer Param4 to Param3
Transfer Param5 to Param4
Transfer Param6 to Param5
Transfer Param7 to Param6
Transfer Param8 to Param7
end
GoToEvent Event for CtrlEntId else
// Event not implemented
end
Return EventFlow or 1
//-----------------------------------------------------------------------------
// EVENT HANDLERS
//-----------------------------------------------------------------------------
Event WINDOW.CREATE(CreateParam)
ReturnVal = ''
ErrorMsg = ''
CassID = CreateParam<1>
WfrCntAdj = CreateParam<2>
ToolLoc = CreateParam<3>
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = CassID
LogData<4> = WfrCntAdj
LogData<5> = ToolLoc
LogData<6> = @Window:'.CREATE'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
Convert '.' to '*' in CassID
ExpectedQty = ''
ExpectedWfrMap = ''
If WfrCntAdj EQ '' then WfrCntAdj = 0
Set_Property(@Window:'.EDL_CASS_ID', 'TEXT', CassID)
Begin Case
Case ( (CassID EQ '') and (ToolLoc EQ '') )
// Alternate workflow
Set_Property(@Window:'.LBL_CASS_ID', 'TEXT', 'Cass ID')
Set_Property(@Window:'.LBL_CASS_BARCODE', 'TEXT', 'Cass ID 2D')
Set_Property(@Window, '@ALTERNATE', True$)
Case CassID EQ ''
ErrorMsg = 'Verify wafer count error. Null CassID passed into form.'
Case Index('MU,QA,EPR-EAST,EPR-WEST', ToolLoc, 1) EQ ''
ErrorMsg = 'Verify wafer count error. Invalid tool location, "':ToolLoc:'" passed in.'
Case RowExists('RDS', CassID)
// Non-EpiPro
ExpectedQty = Xlate('RDS', CassID, 'WFRS_OUT', 'X') - WfrCntAdj
If ExpectedQty GT 0 then
WOMatKey = Xlate('RDS', CassID, 'WO_MAT_KEY', 'X')
// Determine which tool to check the status of. (e.g. 6INCH|MU, 8INCH|FQA, etc.)
// Check if tool is down. If so, prompt for manual wafer count.
WaferSize = Xlate('RDS', CassID, 'WAFER_SIZE', 'X')
WaferSize = Field(WaferSize, ' ', 3, 1)
If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then
WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', ToolLoc)
If Error_Services('NoError') then
WCCurrMode = ''
If RowExists('TOOL', WCToolID) then
WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X')
WCCurrMode = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X')
If WCCurrMode EQ 'PROD' then
CurrWfrMap = WO_Mat_Services('GetWaferMap', WOMatKey)
If Error_Services('NoError') then
ExpectedWfrMap = CurrWfrMap
If WfrCntAdj GT 0 then
ReduceCnt = 0
For SlotIndex = 25 to 1 Step -1
If ExpectedWfrMap<0, SlotIndex> EQ 1 then
ExpectedWfrMap<0, SlotIndex> = 0
ReduceCnt += 1
end
Until ReduceCnt EQ WfrCntAdj
Next SlotIndex
end
end else
ErrorMsg = Error_Services('GetMessage')
end
end else
// Prompt for manual wafer count
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = WCToolID:' tool down. Start manual wafer count entry.'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
ReturnVal = False$
ManCount = Dialog_Box('NDW_MANUAL_WAFER_COUNT', @Window, ExpectedQty)
If ManCount NE '' then
Wafer_Counter_Services('AddScan', CassID, ManCount, Datetime(), '', @User4, ToolLoc, '')
If Error_Services('NoError') then ReturnVal = True$
end
Set_Property(@Window, '@RETURNVAL', ReturnVal)
Post_Event(@Window, 'CLOSE')
end
end else
ErrorMsg = 'Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".'
end
end else
ErrorMsg = Error_Services('GetMessage')
end
end else
ErrorMsg = 'Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for cassette ID "':CassID:'".'
end
end else
// Don't require a wafer counter measurement if cassette is now empty.
ReturnVal = True$
Set_Property(@Window, '@RETURNVAL', ReturnVal)
Post_Event(@Window, 'CLOSE')
end
Case RowExists('WM_OUT', CassID)
// EpiPro
Set_Property(@Window:'.LBL_CASS_ID', 'TEXT', 'Cass WMO')
Set_Property(@Window:'.LBL_CASS_BARCODE', 'TEXT', 'Cass WMO 2D')
ExpectedQty = Xlate('WM_OUT', CassID, 'WAFER_CNT', 'X') - WfrCntAdj
If ExpectedQty GT 0 then
// Determine which tool to check the status of. (e.g. 6INCH|MU, 8INCH|FQA, etc.)
// Check if tool is down. If so, prompt for manual wafer count.
WaferSize = Xlate('WM_OUT', CassID, 'WAFER_SIZE', 'X')
WaferSize = Field(WaferSize, ' ', 3, 1)
If ( (WaferSize EQ 6) or (WaferSize EQ 8) ) then
WCToolId = Wafer_Counter_Services('GetWaferCounterToolID', WaferSize:'INCH', ToolLoc)
If Error_Services('NoError') then
WCCurrMode = ''
If RowExists('TOOL', WCToolID) then
WCCurrModeKey = Xlate('TOOL', WCToolID, 'CURR_MODE_KEY', 'X')
WCCurrMode = Xlate('TOOL_LOG', WCCurrModeKey, 'TOOL_MODE', 'X')
If WCCurrMode EQ 'PROD' then
CurrWfrMap = WM_Out_Services('GetWaferMap', CassID)
If Error_Services('NoError') then
ExpectedWfrMap = CurrWfrMap
If WfrCntAdj GT 0 then
ReduceCnt = 0
For SlotIndex = 25 to 1 Step -1
If ExpectedWfrMap<0, SlotIndex> EQ 1 then
ExpectedWfrMap<0, SlotIndex> = 0
ReduceCnt += 1
end
Until ReduceCnt EQ WfrCntAdj
Next SlotIndex
end
end else
ErrorMsg = Error_Services('GetMessage')
end
end else
// Prompt for manual wafer count
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = WCToolID:' tool down. Start manual wafer count entry.'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
ReturnVal = False$
ManCount = Dialog_Box('NDW_MANUAL_WAFER_COUNT', @Window, ExpectedQty)
If ManCount NE '' then
Wafer_Counter_Services('AddScan', CassID, ManCount, Datetime(), '', @User4, ToolLoc, '')
If Error_Services('NoError') then ReturnVal = True$
end
Set_Property(@Window, '@RETURNVAL', ReturnVal)
Post_Event(@Window, 'CLOSE')
end
end else
ErrorMsg = 'Verify wafer count error. Invalid wafer counter tool ID "':WCToolID:'".'
end
end else
ErrorMsg = Error_Services('GetMessage')
end
end else
ErrorMsg = 'Verify wafer count error. Invalid wafer size "':WaferSize:'" returned for cassette ID "':CassID:'".'
end
end else
// Don't require a wafer counter measurement if cassette is now empty.
ReturnVal = True$
Set_Property(@Window, '@RETURNVAL', ReturnVal)
Post_Event(@Window, 'CLOSE')
end
Case Otherwise$
// Throw error
ErrorMsg = 'Verify Wafer Count error. Unsupported CassID ':Quote(CassID):'.'
End Case
Convert @VM to '' in ExpectedWfrMap
Set_Property(@Window, '@EXPECTED_WFR_MAP', ExpectedWfrMap)
If ErrorMsg EQ '' then
If ReturnVal EQ '' then
List = ''
For SlotIndex = 25 to 1 Step -1
List<-1> = SlotIndex
Next SlotIndex
Set_Property(@Window:'.EDT_WAFER_COUNTER', 'LIST', List)
Set_Property(@Window:'.EDL_EXPECTED_QTY', 'TEXT', ExpectedQty)
PlaceDialog(-2, -2)
Set_Property(@Window, 'VISIBLE', True$)
end
end else
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = ErrorMsg
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
MsgStruct = ''
MsgStruct<MTEXTWIDTH$> = MSG_WIDTH$
Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', ErrorMsg)
End_Dialog(@Window, False$)
end
End Event
Event EDL_CASS_BARCODE.LOSTFOCUS(Flag, FocusID)
If ( (Flag EQ 1) and (FocusID NE @Window:'.PUB_CANCEL') ) then
ErrorMsg = ''
ScanData = Get_Property(CtrlEntID, 'TEXT')
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = ScanData
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
Cnt = DCount(ScanData, '|')
If Cnt NE 8 then
ErrorMsg = 'Invalid Lot Label Scan.'
end else
// RDS should be 3rd position
CassetteID = Field(ScanData, '|', 3)
end
If ErrorMsg EQ '' then
// Strip '1T', 'I', and 'O' prefixes.
If CassetteID[1, 2] EQ '1T' then
CassetteID[1, 2] = ''
If ((CassetteID[1, 1] EQ 'O') or (CassetteID[1, 1] EQ 'I')) then CassetteID[1, 1] = ''
end
If ( (CassetteID[1, 1] EQ 'O') or (CassetteID[1, 1] EQ 'I') ) then CassetteID[1, 1] = ''
Convert '.' to '*' in CassetteID
VerifyCassID = Get_Property(@Window:'.EDL_CASS_ID', 'TEXT')
Set_Property(CtrlEntID, 'TEXT', CassetteID)
AltFlow = Get_Property(@Window, '@ALTERNATE')
If AltFlow then
Set_Property(@Window:'.EDL_CASS_ID', 'TEXT', CassetteID)
ExpectedWfrMap = ''
Set_Property(@Window:'.EDL_CASS_ID', 'TEXT', CassetteID)
Begin Case
Case RowExists('RDS', CassetteID)
ExpectedQty = Xlate('RDS', CassetteID, 'WFRS_OUT', 'X')
Set_Property(@Window:'.EDL_EXPECTED_QTY', 'TEXT', ExpectedQty)
Set_Property(@Window:'.LBL_CASS_ID', 'TEXT', 'Cass RDS')
Set_Property(@Window:'.LBL_CASS_BARCODE', 'TEXT', 'Cass RDS 2D')
WOMatKey = Xlate('RDS', CassetteID, 'WO_MAT_KEY', 'X')
CurrWfrMap = WO_Mat_Services('GetWaferMap', WOMatKey)
If Error_Services('NoError') then
ExpectedWfrMap = CurrWfrMap
end else
ErrorMsg = Error_Services('GetMessage')
end
Case RowExists('WM_OUT', CassetteID)
ExpectedQty = Xlate('WM_OUT', CassetteID, 'WAFER_CNT', 'X')
Set_Property(@Window:'.EDL_EXPECTED_QTY', 'TEXT', ExpectedQty)
Set_Property(@Window:'.LBL_CASS_ID', 'TEXT', 'Cass WMO')
Set_Property(@Window:'.LBL_CASS_BARCODE', 'TEXT', 'Cass WMO 2D')
CurrWfrMap = WM_Out_Services('GetWaferMap', CassetteID)
If Error_Services('NoError') then
ExpectedWfrMap = CurrWfrMap
end else
ErrorMsg = Error_Services('GetMessage')
end
End Case
Convert @VM to '' in ExpectedWfrMap
Set_Property(@Window, '@EXPECTED_WFR_MAP', ExpectedWfrMap)
end else
If CassetteID NE VerifyCassID then
ErrorMsg = 'Scanned cassette ID does not match cassette to verify!'
end
end
end
If ErrorMsg NE '' then
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = ErrorMsg
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
MsgStruct = ""
MsgStruct<MTEXTWIDTH$> = MSG_WIDTH$
MsgStruct<MCOL$> = -300
MsgStruct<MROW$> = 500
Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', ErrorMsg)
GoSub ClearForm
end else
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = 'Cassette scan OK'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
Set_Property(@Window, 'FOCUS', @Window:'.EDL_TOOL_BARCODE')
end
end else
If FocusID EQ @Window:'.PUB_CANCEL' then
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = 'Verification process canceled'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
End_Dialog(@Window, False$)
end
end
end event
Event EDL_TOOL_BARCODE.LOSTFOCUS(Flag, FocusID)
If Flag EQ 1 then
ErrorMsg = ''
ScanData = Get_Property(CtrlEntID, 'TEXT')
If ScanData NE '' then
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = ScanData
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
Cnt = DCount(ScanData, '|')
If Cnt EQ 2 then
WaferSize = Field(ScanData, '|', 1)
Area = Field(ScanData, '|', 2)
Def = ""
Def<MTEXT$> = "Retreiving Wafer Counter Data..."
Def<MTYPE$> = "U"
CassID = Get_Property(@Window:'.EDL_CASS_BARCODE', 'TEXT')
MsgUp = Msg(@window, Def) ;* display the processing message
WcJson = Wafer_Counter_Services('GetWaferCounterJSON', WaferSize, Area, CassID)
Msg(@window, MsgUp) ;* take down the processing message
If Error_Services('NoError') then
objJSON = ''
If SRP_JSON(objJSON, 'Parse', WcJson) EQ '' then
ScanDtm = SRP_JSON(objJSON, 'GetValue', 'dateTimeFormatted')
ToolID = SRP_JSON(objJSON, 'GetValue', 'equipmentId')
WaferCount = SRP_JSON(objJSON, 'GetValue', 'total')
SlotMap = SRP_JSON(objJSON, 'GetValue', 'slotMap')
SRP_JSON(objJSON, 'Release')
Wafer_Counter_Services('AddScan', CassID, WaferCount, ScanDtm, ToolID, @User4, Area, SlotMap)
If Error_Services('NoError') then
Set_Property(@Window:'.EDL_SCAN_DTM', 'TEXT', ScanDtm)
Set_Property(@Window:'.EDL_TOOL_ID', 'TEXT', ToolID)
Set_Property(@Window:'.EDL_WAFER_COUNT', 'TEXT', WaferCount)
EmptyColorArray = RED$ : @FM : '' : @FM : '' : @FM : ''
FilledColorArray = GREEN$ : @FM : '' : @FM : '' : @FM : ''
RowIndex = 1
ResultArray = ''
ExpectedWfrMap = Get_Property(@Window, '@EXPECTED_WFR_MAP')
For SlotIndex = 1 to 25
SlotFilled = SlotMap[SlotIndex, 1]
ExpectedVal = ExpectedWfrMap[SlotIndex, 1]
ResultArray<1, SlotIndex> = 26 - SlotIndex
If SlotFilled EQ ExpectedVal then
ResultArray<2, SlotIndex> = ''
end else
ResultArray<2, SlotIndex> = 'Error'
end
RowIndex += 1
Next SlotIndex
ExpectedQty = Get_Property(@Window:'.EDL_EXPECTED_QTY', 'TEXT')
Set_Property(@Window:'.EDT_WAFER_COUNTER', 'ARRAY', ResultArray)
RowIndex = 1
For SlotIndex = 1 to 25
SlotFilled = SlotMap[SlotIndex, 1]
If SlotFilled then
CellColorArray = FilledColorArray
end else
CellColorArray = EmptyColorArray
end
Send_Message(@Window:'.EDT_WAFER_COUNTER', 'COLOR_BY_POS', 2, RowIndex, CellColorArray)
RowIndex += 1
Next SlotIndex
Begin Case
Case WaferCount NE ExpectedQty
ErrorMsg = 'Scanned wafer count "':WaferCount:'" does not match expected quantity "':ExpectedQty:'".'
Case SlotMap NE ExpectedWfrMap
ErrorMsg = 'Scanned wafer map does not match expected wafer map.'
Case Otherwise$
SuccessMessage = 'Wafer count verification complete!'
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = SuccessMessage
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
MsgStruct = ""
MsgStruct<MTEXTWIDTH$> = MSG_WIDTH$
MsgStruct<MCOL$> = -300
MsgStruct<MROW$> = 500
MsgStruct<MTYPE$> = "T4"
Msg(@Window, MsgStruct, 'PROCESS_COMPLETE', '', SuccessMessage)
AltFlow = Get_Property(@Window, '@ALTERNATE')
If AltFlow then
GoSub ClearForm
end else
End_Dialog(@Window, True$)
end
End Case
end else
ErrorMsg = Error_Services('GetMessage')
end
end else
ErrorMsg = 'Error parsing tool scan data.'
end
end else
ErrorMsg = Error_Services('GetMessage')
end
end else
ErrorMsg = 'Invalid Tool Barcode Scan.'
end
end else
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = 'Verification process canceled'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
End_Dialog(@Window, False$)
end
If ErrorMsg NE '' then
MsgStruct = ""
MsgStruct<MTEXTWIDTH$> = MSG_WIDTH$
MsgStruct<MCOL$> = -300
MsgStruct<MROW$> = 500
Msg(@Window, MsgStruct, 'PROCESS_ERROR', '', ErrorMsg)
GoSub ClearForm
If ErrorMsg EQ 'Scanned wafer map does not match expected wafer map.' then
ErrorMsg = 'Scanned wafer map "':SlotMap:'" does not match expected wafer map "':ExpectedWfrMap:'".'
end
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = ErrorMsg
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
end
end
end event
Event PUB_CANCEL.CLICK()
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = 'Verification process canceled'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
End_Dialog(@Window, False$)
end event
Event WINDOW.CLOSE(CancelFlag)
ReturnVal = Get_Property(@Window, '@RETURNVAL')
LogData = ''
LogData<1> = OConv(Datetime(), 'DT2/^H')
LogData<2> = @User4
LogData<3> = @Window:'.CLOSE - ReturnVal: "':ReturnVal:'"'
Logging_Services('AppendLog', objLog, LogData, @RM, @FM)
End_Dialog(@Window, ReturnVal)
end event
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ClearForm:
AltFlow = Get_Property(@Window, '@ALTERNATE')
If AltFlow then
Set_Property(@Window:'.LBL_CASS_ID', 'TEXT', 'Cass ID')
Set_Property(@Window:'.LBL_CASS_BARCODE', 'TEXT', 'Cass ID 2D')
Set_Property(@Window:'.EDL_CASS_ID', 'TEXT', '')
Set_Property(@Window:'.EDL_EXPECTED_QTY', 'TEXT', '')
end
Set_Property(@Window:'.EDL_TOOL_BARCODE' , 'TEXT' , '')
Set_Property(@Window:'.EDL_CASS_BARCODE' , 'TEXT' , '')
Set_Property(@Window:'.EDL_SCAN_DTM' , 'TEXT' , '')
Set_Property(@Window:'.EDL_TOOL_ID' , 'TEXT' , '')
Set_Property(@Window:'.EDL_WAFER_COUNT' , 'TEXT' , '')
EmptyList = ''
EmptyColorArray = WHITE$ : @FM : '' : @FM : '' : @FM : ''
For SlotIndex = 25 to 1 Step -1
EmptyList<-1> = SlotIndex
Send_Message(@Window:'.EDT_WAFER_COUNTER', 'COLOR_BY_POS', 2, SlotIndex, EmptyColorArray)
Next SlotIndex
Set_Property(@Window:'.EDT_WAFER_COUNTER', 'LIST', EmptyList)
Set_Property(@Window:'.EDL_CASS_BARCODE' , 'FOCUS', True$)
return