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

