open-insight/LSL2/STPROC/NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_EVENTS.txt
Infineon\StieberD 7762b129af pre cutover push
2024-09-04 20:33:41 -07:00

909 lines
44 KiB
Plaintext

Compile function NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_EVENTS(CtrlEntId, Event, @PARAMS)
/***********************************************************************************************************************
Name : NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT_EVENTS
Description : Commuter module for the NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT 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)
03/27/20 cn Original programmer.
06/23/20 cn Deployed filtering logic to production
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
#window NDW_GAN_RETAIN_MANAGER_SEARCH_EDIT
$Insert LOGICAL
$Insert APPCOLORS
$Insert RETAINED_WAFERS_EQUATES
$Insert MSG_EQUATES
// Control Name equates
Equ SearchTable$ To @Window : '.OLE_EDT_SEARCH'
Equ BreadcrumbBar$ To @Window : '.OLE_BREADCRUMBBAR'
Equ StatusBar$ To @Window : '.OLE_STATUSBAR'
// OLE Edit Table Columns
Equ RUN_ID$ To 1
Equ RECIPE$ To 2
Equ POCKET$ To 3
Equ SCRIBE$ To 4
Equ GRADE$ To 5
Equ PART$ To 6
Equ WO_NO$ To 7
Equ RETAIN_BOX$ To 8
Equ RETAIN_SLOT$ To 9
Equ RETAIN_LOC$ To 10
Equ STATUS$ To 11
Equ COMMENT$ To 12
Equ OPERATOR$ To 13
Equ RETAIN_DATE$ To 14
Equ DESTROY_SIG$ To 15
Equ DESTROY_DATE$ To 16
Equ WAFER_ID$ To 17
// Reduce modes (for Select statement)
Equ NEW_EXIST$ To 0
Equ NEXT_CUR$ To 1
Equ ADD_EXIST$ To 2
// Carriage Return and Line Feed for CSV report
EQU CRLF$ TO \0D0A\
Declare Function Form_Services, Get_Property, Utility, Database_Services, Error_Services, Send_Message
Declare Function Memory_Services, Create_Dialog, Dialog_Box, SRP_FastArray, SRP_Array, Msg
Declare Function Retain_Manager_Services, SRP_Trim, SRP_BreadcrumbBar, Gan_Services, DateTime, SRP_Run_Command
Declare Subroutine SRP_Show_Window, Set_Property, Send_Message, Post_Event, Reduce, FSMsg, Btree.Extract
Declare Subroutine SRP_Stopwatch, SRP_Edittable_Manager, Error_Services, Memory_Services, Utility, SRP_FastArray
Declare Subroutine SRP_BreadcrumbBar, SRP_Set_MinMaxInfo, OConv, Form_Services
SubclassInfo = Form_Services('FindSubclassControl')
Subclass = SubclassInfo<1>
If Assigned(Param8) else Param8 = ''
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
Type = Get_Property(CtrlEntId, 'TYPE')
If Type EQ 'RADIOBUTTON' then
Convert ' ' to '_' in CtrlEntID
end
GoToEvent Event for CtrlEntId else
// Event not implemented
end
Return EventFlow or 1
//-----------------------------------------------------------------------------
// EVENT HANDLERS
//-----------------------------------------------------------------------------
Event WINDOW.CREATE(CreateParam)
GoSub SetupOLEControls
Set_Property(@Window, 'TIMER', 30000 : @FM : 30000)
SRP_Set_MinMaxInfo(@Window, 'DEF', 'DEF', 'DEF')
SRP_Show_Window(@Window, '', 'C', 'C', 1, '', False$, False$, '', 1)
End Event
Event WINDOW.TIMER()
GoSub UpdateServiceLastRunTime
end event
Event WINDOW.CLOSE(CancelFlag)
Memory_Services('RemoveKey', 'SelectedFilterItems')
Memory_Services('RemoveKey', 'Cell_Size')
Memory_Services('RemoveKey', 'AllowFilter')
SRP_BreadcrumbBar(BreadcrumbBar$, 'Close')
end event
Event PUB_UPDATE.CLICK()
GoSub UpdateWaferDetails
GoSub UpdateCachedDataValues
end event
Event RAG_WAFER_TYPE.150_MM_6_IN.CLICK()
Event RAG_WAFER_TYPE.200_MM_8_IN.CLICK()
Event CHB_SHOW_DESTROYED.CLICK()
Form_Services('DisplayWaitScreen', '', 'Refreshing Data')
Set_Property(SearchTable$, 'OLE.Redraw', False$)
Gosub ClearData
GoSub LoadSearchData
GoSub ResetFocusToBottomRow
Set_Property(SearchTable$, 'OLE.Redraw', True$)
Form_Services('CloseWaitScreen')
end event
Event PUB_EXPORT.CLICK()
GoSub ExportWaferReport
end event
Event PUB_CLIPBOARD.CLICK()
ReportHeaderArrray = ''
ReportRowArrray = ''
HeaderCounter = ''
HeaderArray = Get_Property(SearchTable$, 'OLE.TitleList')
CurrentWaferArray = Get_Property(SearchTable$, 'OLE.ARRAY')
For Each Header In HeaderArray using @VM
HeaderCounter += 1
HeaderVisibility = Get_Property(SearchTable$, 'OLE.DataColumn[' : HeaderCounter : ']')<2>
If HeaderVisibility EQ True$ then
ReportHeaderArrray := Header : @VM
ReportRowArrray := CurrentWaferArray<HeaderCounter> : @FM
end
Next Header
ReportHeaderArrray[-1, 1] = ''
ReportRowArrray[-1, 1] = ''
ReportRowArrray = SRP_Array('Rotate', ReportRowArrray, @FM, @VM)
FullReport = ReportHeaderArrray : @FM : ReportRowArrray
Swap @VM with CHAR(9) in FullReport
Swap @FM with CRLF$ in FullReport
Set_Property('CLIPBOARD', 'TEXT', FullReport)
Message = ''
Message<MTEXT$> = 'Search data has been copied to clipboard.'
Message<MTYPE$> = 'BO'
Status = Msg(@Window, Message)
end event
Event OLE_EDT_SEARCH.OnHeaderClick(Cell, Point, Button, Shift, Ctrl)
Set_Property(SearchTable$, 'OLE.Redraw', False$)
FilterOptions = ''
CellxPos = Cell[1, ';']
CellyPos = Cell[Col2() + 1, ';']
// Remove 1 cell position due to the hidden header column
CellSize = Send_Message(SearchTable$, "OLE.GetCellRect", (CellxPos - 1) : ';' CellyPos)
Memory_Services('SetValue', 'Cell_Size', CellSize)
Begin Case
Case Button EQ 'Left'
Header = Get_Property(SearchTable$, 'HeaderText[' : Cell : ']')
ColumnPos = CellxPos - 1
AllowedFilters = Get_Property(@Window, '@ALLOWEDFILTERS')
// Check to see if the current active segment is equal to the header. If not, set a flag so we don't
// allow the user to save new filters against an existing header. Only the current active segment can
// receive new filter items.
Locate Header in AllowedFilters using @VM setting pos then
SegmentKey = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetActiveSegment')
Convert '-' to @FM in SegmentKey
// Create a segment key to keep track of existing filters and results.
Locate Header in SegmentKey using @FM setting dummypos then
TotalSegments = Count(SegmentKey, @FM) + 1
LastSegment = SegmentKey<TotalSegments>
If Header EQ LastSegment then
Memory_Services('SetValue', 'AllowFilter', True$)
end else
Memory_Services('SetValue', 'AllowFilter', Fasle$)
end
end else
SegmentKey = SegmentKey : @FM : Header
Memory_Services('SetValue', 'AllowFilter', True$)
end
Convert @FM to '-' in SegmentKey
SegmentExists = SRP_Breadcrumbbar(BreadcrumbBar$, 'SegmentExists', SegmentKey)
If SegmentExists EQ False$ then
// Build Filter Options
FilterArray = Get_Property(SearchTable$, 'OLE.ColumnData[' : ColumnPos : ']')
Swap @VM with @FM in FilterArray
FilterArray = SRP_Array('SortSimpleList', FilterArray, 'AscendingText', @FM)
FilterArray = SRP_Array('Clean', FilterArray, 'TrimAndMakeUnique')
FormattedFilterArray = ''
// Build filter list in SRP Tree Control format
For Each Filter in FilterArray using @FM
FormattedFilterArray := 1 : @VM : SRP_Trim(Filter, 'FA', '0') : @VM : Filter : @VM : @VM : @VM : @VM : @VM : @VM : @VM : @VM : 'Left' : @VM : @FM
Next FilterArray
// Place all filter options into memory using SegmentKey for reference
Set_Property(@Window, '@' : SegmentKey : '*FORMATTEDFILTERARRAY', FormattedFilterArray)
DataList = Get_Property(SearchTable$, 'OLE.ARRAY')
Set_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST', DataList)
// Set PreviousSelectedFilters to null as this is a new segment
PreviousSelectedFilters = ''
end else
UnfilteredDataList = Get_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST')
FilteredDataList = Get_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST')
FormattedFilterArray = Get_Property(@Window, '@' : SegmentKey : '*FORMATTEDFILTERARRAY')
PreviousSelectedFilters = Get_Property(@Window, '@' : SegmentKey : '*PREVIOUSSELECTEDFILTERS')
end
// Set SelectedFilterItems in memory services to NDW_Tree_Filter can display them
Memory_Services('SetValue', 'SelectedFilterItems', PreviousSelectedFilters)
// Call the Tree_Filter Window and place it under the column header. Pass in Tree Control formatted list
SelectedFilterItems = Dialog_Box('NDW_TREE_FILTER', @Window, FormattedFilterArray)
CurrentActiveSegment = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetActiveSegment')
If SelectedFilterItems NE 'Cancel' then
Set_Property(@Window, '@' : SegmentKey : '*PREVIOUSSELECTEDFILTERS', SelectedFilterItems)
Begin Case
Case SegmentExists EQ True$ AND SelectedFilterItems EQ ''
SRP_Breadcrumbbar(BreadcrumbBar$, 'RemoveSegment', SegmentKey, True$)
// Load parent's cached data into FilteredDataList
CurrentActiveSegment = SRP_BreadcrumbBar(BreadcrumbBar$, 'GetActiveSegment')
CachedDataHandle = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetSegmentMisc', CurrentActiveSegment)
DataList = Get_Property(@Window, CachedDataHandle)
Case SegmentExists EQ True$
SRP_BreadcrumbBar(BreadcrumbBar$, 'SetActiveSegment', Header)
DataList = Get_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST')
Case SelectedFilterItems NE ''
SRP_BreadcrumbBar(BreadcrumbBar$, 'AddSegment', SegmentKey : @VM : Header : @VM : '@' : SegmentKey : '*FILTEREDDATALIST', CurrentActiveSegment, True$)
Case Otherwise$
End Case
DataList = SRP_Array('Rotate', DataList, @FM, @VM)
DataListHandle = SRP_FastArray('Create', DataList)
FilteredDataList = Retain_Manager_Services('UpdateRetainList', DataListHandle, SelectedFilterItems)
Set_Property(SearchTable$, 'OLE.ARRAY', FilteredDataList)
Set_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST', FilteredDataList)
GoSub ResetFocusToBottomRow
end
end else
Error_Services('Set' , 'Filtering not allowed on this column.')
Error_Services('DisplayError', 'C')
end
End Case
SRP_FastArray("Release", DataListHandle)
Set_Property(SearchTable$, 'OLE.Redraw', True$)
end event
Event OLE_BREADCRUMBBAR.OnSegmentClick(CurrentCell)
Set_Property(SearchTable$, 'OLE.Redraw', False$)
PrevActiveSegment = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetPrevActiveSegment')
If CurrentCell NE PrevActiveSegment then
FieldCount = DCount(PrevActiveSegment, '-')
SegmentKey = Field(PrevActiveSegment, '-', 1, FieldCount)
Loop
Set_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST', '')
Set_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST', '')
Set_Property(@Window, '@' : SegmentKey : '*FORMATTEDFILTERARRAY', '')
Set_Property(@Window, '@' : SegmentKey : '*PREVIOUSSELECTEDFILTERS', '')
Fieldcount = FieldCount-1
SegmentKey = Field(PrevActiveSegment, '-', 1, FieldCount)
Until SegmentKey EQ CurrentCell
Repeat
SRP_Breadcrumbbar(BreadcrumbBar$, 'RemoveAllChildrenSegments', CurrentCell, True$)
// Display Cached Data
CachedDataHandle = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetSegmentMisc', SegmentKey)
CachedHeaderData = Get_Property(@Window, CachedDataHandle)
Set_Property(SearchTable$, 'OLE.ARRAY', CachedHeaderData)
GoSub ResetFocusToBottomRow
end
Set_Property(SearchTable$, 'OLE.Redraw', True$)
end event
Event OLE_EDT_SEARCH.OnClick(Cell, Point, Button, Shift, Ctrl)
If Button EQ 'Right' then
Menu = ''
ColPos = Cell[1, ';']
RowPos = Cell[Col2() + 1, ';']
RetainBox = Get_Property(SearchTable$, 'OLE.CellText[' : RETAIN_BOX$ : ';' : RowPos : ']')
Menu<-1> = 'Warehouse' : @VM : 'Set location to Warehouse for all wafers in box ' : RetainBox : @VM : 1
Menu<-1> = 'Cleanroom' : @VM : 'Set location to Cleanroom for all wafers in box ' : RetainBox : @VM : 1
Send_Message(SearchTable$, 'OLE.ShowContextMenu', Point, Menu, RetainBox)
end
end event
Event OLE_EDT_SEARCH.OnContextMenuClick(Item, UserData)
Form_Services('DisplayWaitScreen', '', 'Relocating Wafers')
Set_Property(SearchTable$, 'OLE.Redraw', False$)
Location = Item
RetainedBox = UserData
CurrentViewWaferArray = Get_Property(SearchTable$, 'OLE.ARRAY')
MasterRetainWaferList = Get_Property(@Window, '@MASTERRETAINWAFERLIST')
// Update data in MasterRetainWaferList cache
For Each Wafer in MasterRetainWaferList<RETAIN_BOX$> using @VM setting WaferPos then
If RetainedBox EQ MasterRetainWaferList<RETAIN_BOX$, WaferPos> then
WaferID = MasterRetainWaferList<WAFER_ID$, WaferPos>
Status = MasterRetainWaferList<STATUS$, WaferPos>
Comment = MasterRetainWaferList<COMMENT$, WaferPos>
Response = Gan_Services('UpdateRetainedWaferDetails', WaferID, Location, Status, Comment)
MasterRetainWaferList<RETAIN_LOC$, WaferPos> = Location
Set_Property(@Window, '@MASTERRETAINWAFERLIST', MasterRetainWaferList)
end
Next Wafer
// Update current display in SearchTable$
For Each Wafer in CurrentViewWaferArray<RETAIN_BOX$> using @VM setting WaferPos then
If RetainedBox EQ CurrentViewWaferArray<RETAIN_BOX$, WaferPos> then
Set_Property(SearchTable$, 'OLE.CellText[' : RETAIN_LOC$ :';' : WaferPos : ']', Location)
end
Next Wafer
// Update data in filter caches
PrevActiveSegment = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetActiveSegment')
FieldCount = DCount(PrevActiveSegment, '-')
SegmentKey = Field(PrevActiveSegment, '-', 1, FieldCount)
Loop
UnFilteredDataList = Get_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST')
For Each Wafer in UnFilteredDataList<RETAIN_BOX$> using @VM setting WaferPos then
If RetainedBox EQ UnFilteredDataList<RETAIN_BOX$, WaferPos> then
UnFilteredDataList<RETAIN_LOC$, WaferPos> = Location
Set_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST', UnFilteredDataList)
end
Next Wafer
FilteredDataList = Get_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST')
For Each Wafer in FilteredDataList<RETAIN_BOX$> using @VM setting WaferPos then
If RetainedBox EQ FilteredDataList<RETAIN_BOX$, WaferPos> then
FilteredDataList<RETAIN_LOC$, WaferPos> = Location
Set_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST', FilteredDataList)
end
Next Wafer
Fieldcount = FieldCount-1
SegmentKey = Field(PrevActiveSegment, '-', 1, FieldCount)
Until SegmentKey EQ 'RootKey'
Repeat
GoSub LoadWaferDetails
Set_Property(SearchTable$, 'OLE.Redraw', True$)
Form_Services('CloseWaitScreen')
end event
Event OLE_EDT_SEARCH.PosChanged(Cell, PrevCell, Button, RepeatCount)
PrevColPos = PrevCell[1, ';']
PrevRowPos = PrevCell[Col2() + 1, ';']
ColPos = Cell[1, ';']
RowPos = Cell[Col2() + 1, ';']
If PrevRowPos NE RowPos then
GoSub LoadWaferDetails
end
end event
Event COB_STATUS.CHANGED(NewData)
OldStatus = Get_Property(@Window, '@WAFERSTATUS')
NewStatus = NewData
Location = Get_Property(@Window : '.COB_LOCATION', 'TEXT')
If Location EQ 'Wafer Destroyed' AND NewStatus EQ 'Do Not Destroy' then
Message = ''
Message<MTEXT$> = 'Cannot set Status to "Do Not Destroy" when Location is "Wafer Destroyed".'
Message<MTYPE$> = 'BO'
Status = Msg(@Window, Message)
Set_Property(@Window : '.COB_STATUS', 'TEXT', OldStatus)
end
end event
Event COB_LOCATION.CHANGED(NewData)
OldLocation = Get_Property(@Window, '@WAFERLOCATION')
NewLocation = NewData
Status = Get_Property(@Window : '.COB_STATUS', 'TEXT')
If Status EQ 'Do Not Destroy' AND NewLocation EQ 'Wafer Destroyed' then
Message = ''
Message<MTEXT$> = 'Cannot set Location to "Wafer Destroyed" when Status is "Do Not Destroy".'
Message<MTYPE$> = 'BO'
Status = Msg(@Window, Message)
Set_Property(@Window : '.COB_LOCATION', 'TEXT', OldLocation)
end
end event
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
SetupOLEControls:
Set_Property(@Window : '.STA_DESTROYED_SIGN', 'VISIBLE', False$)
Set_Property(@Window : '.EDL_DESTROYED_SIGN', 'VISIBLE', False$)
Set_Property(@Window : '.STA_DESTROYED_DATE', 'VISIBLE', False$)
Set_Property(@Window : '.EDL_DESTROYED_DATE', 'VISIBLE', False$)
// Recreating EditTable format using SRP_EditTable_Manager for better control
ArrayDimension = 17 : @FM : 50
TitleList = 'Run ID' : @VM : 'Recipe' : @VM : 'Pocket' : @VM : 'Scribe' : @VM : 'Grade' : @VM : 'Part' : @VM
ColumnWidths = '80' : @FM : '160' : @FM : '55' : @FM : '70' : @FM : '50' : @FM : '120' : @FM
ColumnAlignments = 'L' : @FM : 'L' : @FM : 'C' : @FM : 'C' : @FM : 'C' : @FM : 'L' : @FM
TitleList := 'WO' : @VM : 'Retain Box' : @VM : 'Slot' : @VM : 'Location' : @VM : 'Status' : @VM : 'Comment' : @VM
ColumnWidths := '45' : @FM : '75' : @FM : '40' : @FM : '100' : @FM : '105' : @FM : 'A' : @FM
ColumnAlignments := 'C' : @FM : 'C' : @FM : 'C' : @FM : 'L' : @FM : 'L' : @FM : 'L' : @FM
TitleList := 'Retained Sign' : @VM : 'Retain Date' : @VM : 'Destroy Sign' : @VM : 'Destroy Date' : @VM : 'Wafer ID'
ColumnWidths := '90' : @FM : '80' : @FM : '85' : @FM : '85' : @FM : ''
ColumnAlignments := 'C' : @FM : 'C' : @FM : 'C' : @FM : 'C' : @FM : 'C'
VirtualPos = ''
RowsAsColumns = ''
CellsAsFields = ''
ClearFill = ''
OIEditTable = ''
SRP_EditTable_Manager('Setup1', SearchTable$, ArrayDimension, TitleList, ColumnWidths, ColumnAlignments, VirtualPos, RowsAsColumns, CellsAsFields, ClearFill, OIEditTable)
Set_Property(SearchTable$, 'OLE.SelectionStyle', 'Black' : @VM : OI_HOT_BLUE$ : ' L=70' : @FM : 'Black' : @VM : OI_HOT_BLUE$) ; // Automatically highlight the current row with one color and highlight the current row with another color.
Set_Property(SearchTable$, 'OLE.HeaderFont[All; All]', 'Segoe UI' : @SVM : 8)
Set_Property(SearchTable$, 'OLE.CellFont[All; All]', 'Segoe UI' : @SVM : 8)
Set_Property(SearchTable$, 'OLE.HeaderColumn[1]', '' : @FM : False$ : @FM : False$ : @FM)
Set_Property(SearchTable$, 'OLE.CellProtection[ALL; All]', 'SEL')
Set_Property(SearchTable$, 'OLE.NewRowCount', 0)
Set_Property(SearchTable$, 'OLE.HeaderRow[ALL]', '' : @FM : '' : @FM : False$ : @FM)
Set_Property(SearchTable$, 'OLE.DataColumn[ALL]', '' : @FM : '' : @FM : False$ : @FM)
Set_Property(SearchTable$, 'OLE.DataRow[ALL]', '' : @FM : '' : @FM : False$ : @FM)
Set_Property(SearchTable$, 'OLE.HeaderColors[All; All]', 'Auto' : @FM : 'None' : @FM : 'None' : @FM : OI_HOT_BLUE$ : @FM : False$)
Set_Property(SearchTable$, 'OLE.ResetSelPos', False$)
// Add drop down arrows to columns
Set_Property(SearchTable$, 'OLE.HeaderArrow[All; 1]', 'Down')
// Remove columns that do not allow filtering.
// Note: Add one column value due to HeaderArrow property picking up the hidden first column.
Set_Property(SearchTable$, 'OLE.HeaderArrow[' : RETAIN_SLOT$ + 1 : '; 1]', '')
Set_Property(SearchTable$, 'OLE.HeaderArrow[' : STATUS$ + 1 : '; 1]', '')
Set_Property(SearchTable$, 'OLE.HeaderArrow[' : COMMENT$ + 1 : '; 1]', '')
Set_Property(SearchTable$, 'OLE.AllowDeletions', False$)
Set_Property(SearchTable$, 'OLE.AllowInserts', False$)
// Begin with hidden destroyed sig and date
Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_SIG$ : ']', '' : @FM : False$)
Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_DATE$ : ']', '' : @FM : False$)
Set_Property(SearchTable$, 'OLE.DataColumn[' : WAFER_ID$ : ']', '' : @FM : False$)
Set_Property(SearchTable$, 'OLE.SelectionStyle', '' : @FM : '' : @FM : '' : @FM : '' : @FM : '' : @FM : '' : @FM : '' : @FM : True$ : @FM)
// Qualify OLE events that we want to intercept
Qualifier = ''
Qualifier<1> = 1
Qualifier<4> = 0 ; * process synchronously (i.e. immediately)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.AfterUpdate', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnClick', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnButtonClick', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.PosChanged', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnComboClicked', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnHeaderClick', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnCheckChanged', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.AfterUpdate', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnContextMenuClick', Qualifier)
Send_Message(SearchTable$, 'QUALIFY_EVENT', 'OLE.OnDblClick', Qualifier)
// Configure columns that have filtering requirements
AllowedFilters = 'Run ID' : @VM : 'Recipe' : @VM : 'Pocket' : @VM : 'Scribe' : @VM : 'Grade' : @VM : 'Part' : @VM
AllowedFilters := 'WO' : @VM : 'Retain Box' : @VM : 'Retained Sign' : @VM : 'Retain Date' : @VM : 'Location'
Set_Property(@Window, '@ALLOWEDFILTERS', AllowedFilters)
SRP_BreadcrumbBar(BreadcrumbBar$, 'Init', SystemFont$)
GoSub UpdateWaferStatistics
Set_Property(StatusBar$, 'OLE.PaneCount', 1)
Set_Property(StatusBar$, 'OLE.Resizable', False$)
Set_Property(StatusBar$, 'OLE.PaneType[1]', 'NOR')
GoSub UpdateServiceLastRunTime
Set_Property(SearchTable$, 'OLE.Redraw', False$)
GoSub LoadSearchData
Set_Property(SearchTable$, 'OLE.Redraw', True$)
return
LoadSearchData:
WaferSize = Get_Property(@Window : '.RAG_WAFER_TYPE', 'VALUE')
ShowDestroyed = Get_Property(@Window : '.CHB_SHOW_DESTROYED', 'CHECK')
WaferList = Retain_Manager_Services('GetWaferDataWithFilter', WaferSize, ShowDestroyed)
WaferList<14> = OConv(WaferList<14>, 'D2/')
WaferList<16> = OConv(WaferList<16>, 'D2/')
WaferList = SRP_Array('SortRows', WaferList, 'AN8' : @FM : 'DN9')
Set_Property(SearchTable$, 'OLE.ARRAY', WaferList)
GoSub ResetFocusToBottomRow
// Save the whole retain list to global variable for later reference by primary filter
Set_Property(@Window, '@MASTERRETAINWAFERLIST', WaferList)
SRP_BreadcrumbBar(BreadcrumbBar$, 'AddSegment', 'RootKey' : @VM : 'All Data' : @VM : '@MASTERRETAINWAFERLIST', '', True$)
// Set Destroy Signature and Destroy Date columns based off of Show Destroyed checkbox
Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_SIG$ : ']', '' : @FM : ShowDestroyed)
Set_Property(SearchTable$, 'OLE.DataColumn[' : DESTROY_DATE$ : ']', '' : @FM : ShowDestroyed)
Set_Property(@Window : '.STA_DESTROYED_SIGN', 'VISIBLE', ShowDestroyed)
Set_Property(@Window : '.EDL_DESTROYED_SIGN', 'VISIBLE', ShowDestroyed)
Set_Property(@Window : '.STA_DESTROYED_DATE', 'VISIBLE', ShowDestroyed)
Set_Property(@Window : '.EDL_DESTROYED_DATE', 'VISIBLE', ShowDestroyed)
return
UpdateWaferDetails:
Set_Property(SearchTable$, 'OLE.Redraw', False$)
WaferID = Get_Property(@Window :'.EDL_WAFER_ID', 'TEXT')
Location = Get_Property(@Window :'.COB_LOCATION', 'TEXT')
Status = Get_Property(@Window :'.COB_STATUS', 'TEXT')
Comment = Get_Property(@Window :'.EDB_COMMENTS', 'TEXT')
Response = Gan_Services('UpdateRetainedWaferDetails', WaferID, Location, Status, Comment)
CurrentCellyPos = Get_Property(SearchTable$, 'OLE.SelPos')<2>
Set_Property(SearchTable$, 'OLE.CellText[' : RETAIN_LOC$ :';' : CurrentCellyPos : ']', Location)
Set_Property(SearchTable$, 'OLE.CellText[' : STATUS$ :';' : CurrentCellyPos : ']', Status)
Set_Property(SearchTable$, 'OLE.CellText[' : COMMENT$ :';' : CurrentCellyPos : ']', Comment)
If Location EQ 'Wafer Destroyed' then
Set_Property(SearchTable$, 'OLE.CellText[' : DESTROY_SIG$ :';' : CurrentCellyPos : ']', @User4)
Set_Property(SearchTable$, 'OLE.CellText[' : DESTROY_DATE$ :';' : CurrentCellyPos : ']', OConv(Date(), 'D2/'))
end
Set_Property(SearchTable$, 'OLE.Redraw', True$)
return
LoadWaferDetails:
CellPos = Get_Property(SearchTable$, 'OLE.SelPos')
ColPos = CellPos<1>
RowPos = CellPos<2>
// Load RunID data to wafer details area
RunID = Get_Property(SearchTable$, 'OLE.CellText[' : RUN_ID$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_RUN_ID', 'TEXT', RunID)
// Load Recipe data to wafer details area
Recipe = Get_Property(SearchTable$, 'OLE.CellText[' : RECIPE$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_RECIPE', 'TEXT', Recipe)
// Load Pocket data to wafer details area
Pocket = Get_Property(SearchTable$, 'OLE.CellText[' : POCKET$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_POCKET', 'TEXT', Pocket)
// Load Scribe data to wafer details area
Scribe = Get_Property(SearchTable$, 'OLE.CellText[' : SCRIBE$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_SCRIBE', 'TEXT', Scribe)
// Load Grade data to wafer details area
Grade = Get_Property(SearchTable$, 'OLE.CellText[' : GRADE$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_GRADE', 'TEXT', Grade)
// Load Part data to wafer details area
Part = Get_Property(SearchTable$, 'OLE.CellText[' : PART$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_PART', 'TEXT', Part)
// Load WO data to wafer details area
WO = Get_Property(SearchTable$, 'OLE.CellText[' : WO_NO$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_WO', 'TEXT', WO)
// Load RetainBox data to wafer details area
RetainBox = Get_Property(SearchTable$, 'OLE.CellText[' : RETAIN_BOX$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_RETAIN_BOX', 'TEXT', RetainBox)
// Load Slot data to wafer details area
Slot = Get_Property(SearchTable$, 'OLE.CellText[' : RETAIN_SLOT$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_SLOT', 'TEXT', Slot)
// Load Retained Sign data to wafer details area
RetainedSign = Get_Property(SearchTable$, 'OLE.CellText[' : OPERATOR$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_RETAINED_SIGN', 'TEXT', RetainedSign)
// Load Retain Date data to wafer details area
RetainedDate = Get_Property(SearchTable$, 'OLE.CellText[' : RETAIN_DATE$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_RETAINED_DATE', 'TEXT', RetainedDate)
// Load Destroy Sign data to wafer details area
DestroyedSign = Get_Property(SearchTable$, 'OLE.CellText[' : DESTROY_SIG$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_DESTROYED_SIGN', 'TEXT', DestroyedSign)
// Load Destroy Date data to wafer details area
DestroyedDate = Get_Property(SearchTable$, 'OLE.CellText[' : DESTROY_DATE$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_DESTROYED_DATE', 'TEXT', DestroyedDate)
// Load Location data to wafer details area
Location = Get_Property(SearchTable$, 'OLE.CellText[' : RETAIN_LOC$ :';' : RowPos : ']')
Set_Property(@Window :'.COB_LOCATION', 'TEXT', Location)
// Store Location for comparison when updating wafer details
Set_Property(@Window, '@WAFERLOCATION', Location)
// Load Status data to wafer details area
Status = Get_Property(SearchTable$, 'OLE.CellText[' : STATUS$ :';' : RowPos : ']')
Set_Property(@Window :'.COB_STATUS', 'TEXT', Status)
// Store Status for comparison when updating wafer details
Set_Property(@Window, '@WAFERSTATUS', Status)
// Load Comment data to wafer details area
Comment = Get_Property(SearchTable$, 'OLE.CellText[' : COMMENT$ :';' : RowPos : ']')
Set_Property(@Window :'.EDB_COMMENTS', 'TEXT', Comment)
// Load Comment data to wafer details area
WaferID = Get_Property(SearchTable$, 'OLE.CellText[' : WAFER_ID$ :';' : RowPos : ']')
Set_Property(@Window :'.EDL_WAFER_ID', 'TEXT', WaferID)
return
UpdateWaferStatistics:
// Cleanroom Location
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_6IN')
ListHandle = SRP_FastArray('Create', WaferList)
Filter = 'Cleanroom'
CleanroomRetained6in = Retain_Manager_Services('GetWaferCount', ListHandle, Filter)
Set_Property(@Window : '.EDL_RETAINED_CLEANROOM_6IN', 'TEXT', CleanroomRetained6in)
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_8IN')
ListHandle = SRP_FastArray('Create', WaferList)
Filter = 'Cleanroom'
CleanroomRetained8in = Retain_Manager_Services('GetWaferCount', ListHandle, Filter)
Set_Property(@Window : '.EDL_RETAINED_CLEANROOM_8IN', 'TEXT', CleanroomRetained8in)
TotalCleanroom = CleanroomRetained6in + CleanroomRetained8in
Set_Property(@Window : '.EDL_CLEANROOM_TOTAL', 'TEXT', TotalCleanroom)
// Warehouse Location
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_6IN')
ListHandle = SRP_FastArray('Create', WaferList)
Filter = 'Warehouse'
WarehouseRetained6in = Retain_Manager_Services('GetWaferCount', ListHandle, Filter)
Set_Property(@Window : '.EDL_RETAINED_WAREHOUSE_6IN', 'TEXT', WarehouseRetained6in)
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_8IN')
ListHandle = SRP_FastArray('Create', WaferList)
Filter = 'Warehouse'
WarehouseRetained8in = Retain_Manager_Services('GetWaferCount', ListHandle, Filter)
Set_Property(@Window : '.EDL_RETAINED_WAREHOUSE_8IN', 'TEXT', WarehouseRetained8in)
TotalWarehouse = WarehouseRetained6in + WarehouseRetained8in
Set_Property(@Window : '.EDL_WAREHOUSE_TOTAL', 'TEXT', TotalWarehouse)
// Wafer Destroyed Total
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_6IN')
ListHandle = SRP_FastArray('Create', WaferList)
Filter = 'Wafer Destroyed'
Destroyed6in = Retain_Manager_Services('GetWaferCount', ListHandle, Filter)
Set_Property(@Window : '.EDL_DESTROYED_6IN', 'TEXT', Destroyed6in)
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_8IN')
ListHandle = SRP_FastArray('Create', WaferList)
Filter = 'Wafer Destroyed'
Destroyed8in = Retain_Manager_Services('GetWaferCount', ListHandle, Filter)
Set_Property(@Window : '.EDL_DESTROYED_8IN', 'TEXT', Destroyed8in)
TotalDestroyed = Destroyed6in + Destroyed8in
Set_Property(@Window : '.EDL_DESTROYED_TOTAL', 'TEXT', TotalDestroyed)
// Retained Wafers
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_6IN')
ListHandle = SRP_FastArray('Create', WaferList)
Retained6in = Retain_Manager_Services('GetWaferCount', ListHandle)
TotalRetained6in = Retained6in - Destroyed6in
Set_Property(@Window : '.EDL_RETAINED_6IN', 'TEXT', TotalRetained6in)
WaferList = Database_Services('ReadDataRow', 'APP_INFO', 'RETAINED_WAFERS_8IN')
ListHandle = SRP_FastArray('Create', WaferList)
Retained8in = Retain_Manager_Services('GetWaferCount', ListHandle)
TotalRetained8in = Retained8in - Destroyed8in
Set_Property(@Window : '.EDL_RETAINED_8IN', 'TEXT', TotalRetained8in)
TotalRetained = TotalRetained6in + TotalRetained8in
Set_Property(@Window : '.EDL_RETAINED_TOTAL', 'TEXT', TotalRetained)
// To Be Retained Total
ToBeRetained6inWaferCount = Retain_Manager_Services('GetToBeRetainedCount', '150 mm 6 in')
Set_Property(@Window : '.EDL_TO_BE_RETAINED_6IN', 'TEXT', ToBeRetained6inWaferCount)
ToBeRetained8inWaferCount = Retain_Manager_Services('GetToBeRetainedCount', '200 mm 8 in')
Set_Property(@Window : '.EDL_TO_BE_RETAINED_8IN', 'TEXT', ToBeRetained8inWaferCount)
TotalToBeRetainedWaferCount = ToBeRetained6inWaferCount + ToBeRetained8inWaferCount
Set_Property(@Window : '.EDL_TO_BE_RETAINED_TOTAL', 'TEXT', TotalToBeRetainedWaferCount)
// To Be Destroyed Total
ToBeDestroyed6inWaferCount = Retain_Manager_Services('GetToBeDestroyedCount', '150 mm 6 in')
Set_Property(@Window : '.EDL_TO_BE_DESTROYED_6IN', 'TEXT', ToBeDestroyed6inWaferCount)
ToBeDestroyed8inWaferCount = Retain_Manager_Services('GetToBeDestroyedCount', '200 mm 8 in')
Set_Property(@Window : '.EDL_TO_BE_DESTROYED_8IN', 'TEXT', ToBeDestroyed8inWaferCount)
TotalToBeDestroyedWaferCount = ToBeDestroyed6inWaferCount + ToBeDestroyed8inWaferCount
Set_Property(@Window : '.EDL_TO_BE_DESTROYED_TOTAL', 'TEXT', TotalToBeDestroyedWaferCount)
return
UpdateServiceLastRunTime:
LastRunDTM = Retain_Manager_Services('GetRetainServiceLastRunTime')
Set_Property(StatusBar$, 'OLE.PaneCaption[1]', 'Retain Wafer Service last ran at: ' : LastRunDTM)
return
ExportWaferReport:
ReportHeaderArrray = ''
ReportRowArrray = ''
HeaderCounter = ''
HeaderArray = Get_Property(SearchTable$, 'OLE.TitleList')
CurrentWaferArray = Get_Property(SearchTable$, 'OLE.ARRAY')
For Each Header In HeaderArray using @VM
HeaderCounter += 1
HeaderVisibility = Get_Property(SearchTable$, 'OLE.DataColumn[' : HeaderCounter : ']')<2>
If HeaderVisibility EQ True$ then
ReportHeaderArrray := Header : @VM
ReportRowArrray := CurrentWaferArray<HeaderCounter> : @FM
end
Next Header
ReportHeaderArrray[-1, 1] = ''
ReportRowArrray[-1, 1] = ''
ReportRowArrray = SRP_Array('Rotate', ReportRowArrray, @FM, @VM)
FullReport = ReportHeaderArrray : @FM : ReportRowArrray
Swap @VM with ',' in FullReport
Swap @FM with CRLF$ in FullReport
DialogParams = True$ : @FM : '' : @FM : '' : @FM : 'Retained Wafer Export.csv'
SaveLocation = Utility('CHOOSEFILE', @Window, DialogParams)
If SaveLocation NE '' then
OSWrite FullReport To SaveLocation
// Add quotes for the CMD command
RunCommand = 'explorer.exe /select,"' : SaveLocation : '"'
Output = SRP_Run_Command(RunCommand, 'DOS')
end
return
ResetFocusToBottomRow:
// Set focus to bottom row for both SearchTable$ and Wafer Detail
DataList = Get_Property(SearchTable$, 'OLE.ARRAY')
DataList = SRP_Array('Rotate', DataList, @FM, @VM)
// Reset position to 1,1 so empty space does not reappear when setting to bottom row
Set_Property(SearchTable$, 'OLE.SelPos', 1 : @FM : 1)
// Get total amount of records and set position to bottom record
RecordCount = Count(DataList, @FM) + 1
Set_Property(SearchTable$, 'OLE.SelPos', 1 : @FM : RecordCount)
Send_Message(SearchTable$, 'OLE.FireEvent', 'PosChanged', 1 : ';' : RecordCount)
return
UpdateCachedDataValues:
CellPos = Get_Property(SearchTable$, 'OLE.SelPos')
ColPos = CellPos<1>
RowPos = CellPos<2>
RowData = Get_Property(SearchTable$, 'OLE.RecordData[' : RowPos : ']')
WaferID = RowData<1, WAFER_ID$>
Comment = RowData<1, COMMENT$>
Status = RowData<1, STATUS$>
Location = RowData<1, RETAIN_LOC$>
MasterRetainWaferList = Get_Property(@Window, '@MASTERRETAINWAFERLIST')
Locate WaferID In MasterRetainWaferList<WAFER_ID$> using @VM setting WaferPos then
MasterRetainWaferList<COMMENT$, WaferPos> = Comment
MasterRetainWaferList<STATUS$, WaferPos> = Status
MasterRetainWaferList<RETAIN_LOC$, WaferPos> = Location
Set_Property(@Window, '@MASTERRETAINWAFERLIST', MasterRetainWaferList)
end
PrevActiveSegment = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetActiveSegment')
FieldCount = DCount(PrevActiveSegment, '-')
SegmentKey = Field(PrevActiveSegment, '-', 1, FieldCount)
Loop
UnFilteredDataList = Get_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST')
Locate WaferID In UnFilteredDataList<WAFER_ID$> using @VM setting WaferPos then
UnFilteredDataList<COMMENT$, WaferPos> = Comment
UnFilteredDataList<STATUS$, WaferPos> = Status
UnFilteredDataList<RETAIN_LOC$, WaferPos> = Location
Set_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST', UnFilteredDataList)
end
FilteredDataList = Get_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST')
Locate WaferID In FilteredDataList<WAFER_ID$> using @VM setting WaferPos then
FilteredDataList<COMMENT$, WaferPos> = Comment
FilteredDataList<STATUS$, WaferPos> = Status
FilteredDataList<RETAIN_LOC$, WaferPos> = Location
Set_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST', FilteredDataList)
end
Fieldcount = FieldCount-1
SegmentKey = Field(PrevActiveSegment, '-', 1, FieldCount)
Until SegmentKey EQ 'RootKey'
Repeat
return
ClearData:
ActiveSegment = SRP_Breadcrumbbar(BreadcrumbBar$, 'GetActiveSegment')
FieldCount = DCount(ActiveSegment, '-')
SegmentKey = Field(ActiveSegment, '-', 1, FieldCount)
Loop
Set_Property(@Window, '@' : SegmentKey : '*UNFILTEREDDATALIST', '')
Set_Property(@Window, '@' : SegmentKey : '*FILTEREDDATALIST', '')
Set_Property(@Window, '@' : SegmentKey : '*FORMATTEDFILTERARRAY', '')
Set_Property(@Window, '@' : SegmentKey : '*PREVIOUSSELECTEDFILTERS', '')
Fieldcount = FieldCount-1
SegmentKey = Field(ActiveSegment, '-', 1, FieldCount)
Until SegmentKey EQ 'RootKey'
Repeat
SRP_Breadcrumbbar(BreadcrumbBar$, 'RemoveAllSegments', True$)
return