diff --git a/LSL2/STPROC/METROLOGY_SERVICES.txt b/LSL2/STPROC/METROLOGY_SERVICES.txt index 61c434c..69f3c80 100644 --- a/LSL2/STPROC/METROLOGY_SERVICES.txt +++ b/LSL2/STPROC/METROLOGY_SERVICES.txt @@ -2089,18 +2089,19 @@ end service Service ImportTencorData(RunData) + ErrorMessage = '' Machine = 'Tencor' Timestamp = RunData<9> HazeAvg = RunData<10> - RDSKeyID = RunData<28> + LegacyLotId = RunData<28> ScanRecipe = RunData<30> SoDAvg = RunData<39> SoDMax = RunData<40> SoDMin = RunData<41> ScanTool = RunData<43> Swap '%' with ' ' in ScanTool - LegacyLotId@ = RDSKeyID + LegacyLotId@ = LegacyLotId Convert @Lower_Case to @Upper_Case in ScanTool Swap ' AM' with 'AM' in Timestamp @@ -2112,7 +2113,7 @@ Service ImportTencorData(RunData) SODVals = '' SortVals = '' SODStartTime = Time() - SODWaferArray = QA_Services('GetSODPerWafer', RDSKeyID, ScanRecipe, Timestamp) + SODWaferArray = QA_Services('GetSODPerWafer', LegacyLotId, ScanRecipe, Timestamp) SODStopTime = Time() TimeTaken = SODStopTime - SODStartTime LogData = '' @@ -2121,20 +2122,61 @@ Service ImportTencorData(RunData) LogData<3> = LegacyLotId@ LogData<4> = 'Time taken to import SOD data: ':TimeTaken:' seconds.' Logging_Services('AppendLog', objSODPerfLog, LogData, @RM, @FM) + If SODWaferArray NE '' then WaferNos = SODWaferArray<1> SODVals = SODWaferArray<2> SortVals = SODWaferArray<3> For each WaferNo in WaferNos using @VM - If WaferNo NE '' then QA_Services('PostWaferImageRequest', RDSKeyID, WaferNo, ScanRecipe) + If WaferNo NE '' then QA_Services('PostWaferImageRequest', LegacyLotId, WaferNo, ScanRecipe) Next Wafer end - LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', RDSKeyID, 'RDS') - + + Swap '.' with '*' in LegacyLotId ; // Swap . with * used on labels + Swap 'O' with '' in LegacyLotId ; // Remove 'O' prefix used on labels for WM_OUT lots + + Begin Case + Case RowExists('RDS', LegacyLotId) + + LegacyLotType = 'RDS' + ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', LegacyLotId) + If Error_Services('NoError') then + CIKeyStages = ReactRunRec + CIKeyIDs = ReactRunRec + PSN = Xlate('RDS', LegacyLotId, 'PROD_SPEC_ID', 'X') + If PSN EQ '' then + ErrorMessage = 'Error in ':Service:' service. Null PSN returned from RDS ':LegacyLotId + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID001', Service : ' : Error reading PSN from RDS.') + end + end else + ErrorMessage = Error_Services('GetMessage') + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID001', Service : ' : ' : ErrorMessage) + end + + Case RowExists('WM_OUT', LegacyLotId) + + LegacyLotType = 'WM_OUT' + CIKeyStages = '' + CIKeyIDs = Xlate('WM_OUT', LegacyLotId, 'EPO_CI_NO', 'X') + If CIKeyIDs NE '' then CIKeyStages = Xlate('CLEAN_INSP', CIKeyIDs, CLEAN_INSP_STAGE$, 'X') + PSN = Xlate('WM_OUT', LegacyLotId, 'PS_NO', 'X') + If PSN EQ '' then + ErrorMessage = 'Error in ':Service:' service. Null PSN returned from WM_OUT ':LegacyLotId + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID001', Service : ' : Error reading PSN from WM_OUT.') + end + + Case Otherwise$ + LegacyLotType = '' + ErrorMessage = 'Error in ':Service:' services. Legacy lot id not found in RDS or WM_OUT tables.' + + End Case + + LotId = Lot_Services('GetLotIdByLegacyLotIdAndType', LegacyLotId, LegacyLotType) + If LotId NE '' then If DCount(LotId, @VM) EQ 1 then // Import into new metrology data structures - MetTestId = Met_Test_Services('CreateMetTest', LotId, RDSKeyID, '', ScanRecipe) + MetTestId = Met_Test_Services('CreateMetTest', LotId, LegacyLotId, '', ScanRecipe) If Error_Services('NoError') then Met_Test_Services('SetPropsAndLimits', MetTestId) If Error_Services('HasError') then @@ -2187,169 +2229,184 @@ Service ImportTencorData(RunData) end end else Swap @VM with ',' in LotId - ErrorMsg = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId - Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : ErrorMsg) + MetTestErrorMessage = 'Error in ':Service:' service. Number of lot ids returned does not equal 1. Lot ids: ':LotId + Metrology_Services('LogResults', LegacyLotId@, Machine, 'UID001', Service : ' : ' : MetTestErrorMessage) end end - If RowExists('RDS', RDSKeyID) then - // Try to read the CleanInsp datarow. Use this to identify the RDSKeyID. - ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSKeyID) - If Error_Services('NoError') then - // Get the PSN to determine if this recipe is part of the LWI stage or the POST stage. - PSN = Xlate('RDS', RDSKeyID, 'PROD_SPEC_ID', 'X') - PRSStageKeys = Xlate('PROD_SPEC', PSN, 'PRS_STAGE_KEY', 'X') - StageFound = False$ - Stage = '' - For each PRSStageKey in PRSStageKeys using @VM setting kPos - SSRecipes = Xlate('PRS_STAGE', PRSStageKey, 'SURFSCAN_RECIPE', 'X') - Locate ScanRecipe in SSRecipes using @VM setting rPos then - StageFound = True$ - Stage = Field(PRSStageKey, '*', 2, 1) - end - Next PRSStageKey - CIKeyStages = ReactRunRec - CIKeyIDs = ReactRunRec - Locate Stage in CIKeyStages using @VM setting vPos then - // Stage is prescribed or user created the record from the UI. - CIKeyID = CIKeyIDs<0, vPos> - If (CIKeyID NE '') then - HaveLock = Database_Services('GetKeyIDLock', 'CLEAN_INSP', CIKeyID) - If HaveLock EQ True$ then - If ScanRecipe NE '' then - CleanInspRec = Database_Services('ReadDataRow', 'CLEAN_INSP', CIKeyID) - NumRecipes = DCount(CleanInspRec, @VM) - ScanIndex = NumRecipes + 1 - NumTools = DCount(CleanInspRec, @VM) - SpecRecipeList = CleanInspRec - NumWfrs = 0 - Locate ScanRecipe In SpecRecipeList Using @VM Setting RecipeIndex then - // Recipe found in spec list - If SODWaferArray NE '' then - For each WaferNo in WaferNos using @VM - If WaferNo NE '' then - CleanInspRec = SODVals<1,WaferNo> - CleanInspRec = SortVals<1,WaferNo> - end - Next Wafer - end - // Since a matching recipe was found, clear the recipe mismatch field in case it was - // previously set by a user attempting to load rundata with the wrong recipe name. - CleanInspRec = '' - If NumTools GT NumRecipes then - NumRecipes = NumTools - end - NumRecipes += 1 - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_RECIPE$, NumRecipes, 0, ScanRecipe) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_TOOL$, NumRecipes, 0, ScanTool) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MIN$, NumRecipes, 0, SoDMin) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MAX$, NumRecipes, 0, SoDMax) - SoDAvg = Iconv(SoDAvg, 'MD3') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_AVG$, NumRecipes, 0, SoDAvg) - HazeAvg = Iconv(HazeAvg, 'MD3') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_HAZE_AVG_AVG$, NumRecipes, 0, HazeAvg) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG$, NumRecipes, 0, '') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG_DTM$, NumRecipes, 0, '') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, NumRecipes, 0, Timestamp) - // Save results (this will trigger an ROTR_REQUEST via CLEAN_INSP_ACTIONS) - Database_Services('WriteDataRow', 'CLEAN_INSP', CIKeyID, CleanInspRec, True$, False$, True$) - end else - ErrorMessage = 'Tencor recipe ' : ScanRecipe : ' not found in SurfScan recipe list.' - Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) - // Set recipe mismatch flag for MFS purposes - CleanInspRec = ScanRecipe - Database_Services('WriteDataRow', 'CLEAN_INSP', CIKeyID, CleanInspRec, True$, False$, True$) + If (ErrorMessage EQ '') then + PRSStageKeys = Xlate('PROD_SPEC', PSN, 'PRS_STAGE_KEY', 'X') + StageFound = False$ + Stage = '' + For each PRSStageKey in PRSStageKeys using @VM setting kPos + SSRecipes = Xlate('PRS_STAGE', PRSStageKey, 'SURFSCAN_RECIPE', 'X') + Locate ScanRecipe in SSRecipes using @VM setting rPos then + StageFound = True$ + Stage = Field(PRSStageKey, '*', 2, 1) + end + Next PRSStageKey + Locate Stage in CIKeyStages using @VM setting vPos then + // Stage is prescribed or user created the record from the UI. + CIKeyID = CIKeyIDs<0, vPos> + If (CIKeyID NE '') then + HaveLock = Database_Services('GetKeyIDLock', 'CLEAN_INSP', CIKeyID) + If HaveLock EQ True$ then + If ScanRecipe NE '' then + CleanInspRec = Database_Services('ReadDataRow', 'CLEAN_INSP', CIKeyID) + NumRecipes = DCount(CleanInspRec, @VM) + ScanIndex = NumRecipes + 1 + NumTools = DCount(CleanInspRec, @VM) + SpecRecipeList = CleanInspRec + NumWfrs = 0 + Locate ScanRecipe In SpecRecipeList Using @VM Setting RecipeIndex then + // Recipe found in spec list + If SODWaferArray NE '' then + For each WaferNo in WaferNos using @VM + If WaferNo NE '' then + CleanInspRec = SODVals<1,WaferNo> + CleanInspRec = SortVals<1,WaferNo> + end + Next Wafer + end + // Since a matching recipe was found, clear the recipe mismatch field in case it was + // previously set by a user attempting to load rundata with the wrong recipe name. + CleanInspRec = '' + If NumTools GT NumRecipes then + NumRecipes = NumTools end + NumRecipes += 1 + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_RECIPE$, NumRecipes, 0, ScanRecipe) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_TOOL$, NumRecipes, 0, ScanTool) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MIN$, NumRecipes, 0, SoDMin) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MAX$, NumRecipes, 0, SoDMax) + SoDAvg = Iconv(SoDAvg, 'MD3') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_AVG$, NumRecipes, 0, SoDAvg) + HazeAvg = Iconv(HazeAvg, 'MD3') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_HAZE_AVG_AVG$, NumRecipes, 0, HazeAvg) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG$, NumRecipes, 0, '') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG_DTM$, NumRecipes, 0, '') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, NumRecipes, 0, Timestamp) + // Save results (this will trigger an ROTR_REQUEST via CLEAN_INSP_ACTIONS) + Database_Services('WriteDataRow', 'CLEAN_INSP', CIKeyID, CleanInspRec, True$, False$, True$) end else - ErrorMessage = 'Scan Recipe is missing.' - Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) + ErrorMessage = 'Tencor recipe ' : ScanRecipe : ' not found in SurfScan recipe list.' + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID001', Service : ' : ' : ErrorMessage) + // Set recipe mismatch flag for MFS purposes + CleanInspRec = ScanRecipe + Database_Services('WriteDataRow', 'CLEAN_INSP', CIKeyID, CleanInspRec, True$, False$, True$) end - Database_Services('ReleaseKeyIDLock', 'CLEAN_INSP', CIKeyID) end else - // 01/31/23 - djs - Modified error message to use UID002 instead of UID001 to ensure the - // metrology file is not deleted so that the service can try to import it - // again once the lock is released. - ErrorMessage = 'Error in service ':Service:'. Failed to lock CLEAN_INSP record: ':CIKeyID:'.' - Metrology_Services('LogResults', RDSKeyID, Machine, 'UID002', Service : ' : ' : ErrorMessage) + ErrorMessage = 'Scan Recipe is missing.' + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID001', Service : ' : ' : ErrorMessage) end + Database_Services('ReleaseKeyIDLock', 'CLEAN_INSP', CIKeyID) end else - ErrorMessage = 'CI Key ID is missing.' - Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) + // 01/31/23 - djs - Modified error message to use UID002 instead of UID001 to ensure the + // metrology file is not deleted so that the service can try to import it + // again once the lock is released. + ErrorMessage = 'Error in service ':Service:'. Failed to lock CLEAN_INSP record: ':CIKeyID:'.' + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID002', Service : ' : ' : ErrorMessage) end end else - // Added 8/13/2020 JRO - // We can enter in some conditional logic here for Production UAT - // If statement to gate from production below - PostStartTime = Time() - if Indexc(ScanRecipe, 'POST', 1) then - // Locate 'POST' in ScanRecipe Using "" setting pPos then - ReactRunRec = Xlate('REACT_RUN',RDSKeyID, '', 'X') - WONo = ReactRunRec;//WONo - WOStep = ReactRunRec;//WOStep - CassNo = ReactRunRec;//CassNo - Stage = 'POST';//Stages - PSNo = XLATE('RDS',RDSKeyID,RDS_PROD_SPEC_ID$,'X');//PSNo - DefectSpec = Xlate('PRS_STAGE', PSNo : '*LWI', PRS_STAGE_SURF_DEFECTS$, 'X');//Since there is no set spec for a non-existent stage we need to take one from the unloading step. - HazeSpec = Xlate('PRS_STAGE', PSNo : '*LWI', PRS_STAGE_SURF_HAZE$, 'X');//Since there is no set spec for a non-existent stage we need to take one from the unloading step. - // Check if CI was created already(usually during cleans) JRO-9-28 - CIStages = ReactRunRec - Locate 'POST' in CIStages using @VM setting sPos then - // Existing POST CI record found, fetch it. - CINo = ReactRunRec - CleanInspRec = Xlate('CLEAN_INSP', CINo,'','X') - IF CleanInspRec NE '' THEN - // Append a value mark to the end of the field so that we can add another set of data - CleanInspRec = CleanInspRec : @VM - END - exists = True$ - end else - // No Exisiting POST CI record found, Create new CI record - exists = False$ - oCIParms = '' - oCIParms = WONo:@RM - oCIParms := WOStep:@RM - oCIParms := CassNo:@RM - oCIParms := Stage:@RM - oCIParms := RDSKeyID:@RM - oCIParms := PSNo:@RM - CleanInspRec = '' - CleanInspRec = WONo - CleanInspRec = WOStep - CleanInspRec = CassNo - CleanInspRec = Stage - CleanInspRec = RDSKeyID - end - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_RECIPE$, -1, 0, ScanRecipe) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_TOOL$, -1, 0, ScanTool) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MIN$, -1, 0, SoDMin) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MAX$, -1, 0, SoDMax) - SoDAvg = Iconv(SoDAvg, 'MD3') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_AVG$, -1, 0, SoDAvg) - HazeAvg = Iconv(HazeAvg, 'MD3') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_HAZE_AVG_AVG$, -1, 0, HazeAvg) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG$, -1, 0, '') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG_DTM$, -1, 0, '') - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, -1, 0, Timestamp) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURFSCAN_RECIPE$, -1, 0, ScanRecipe) - CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURF_DEFECTS$, -1, 0, DefectSpec) + ErrorMessage = 'CI Key ID is missing.' + Metrology_Services('LogResults', LegacyLotId, Machine, 'UID001', Service : ' : ' : ErrorMessage) + end + end else + // Added 8/13/2020 JRO + // Ad-hoc POST stage SURFSCAN logic + PostStartTime = Time() + if IndexC(ScanRecipe, 'POST', 1) then + + Begin Case + Case LegacyLotType EQ 'RDS' + ReactRunRec = Xlate('REACT_RUN', LegacyLotId, '', 'X') + WONo = ReactRunRec + WOStep = ReactRunRec + CassNo = ReactRunRec + Case LegacyLotType EQ 'WM_OUT' + WONo = Field(LegacyLotId, '*', 1, 1) + WOStep = Field(LegacyLotId, '*', 2, 1) + CassNo = Field(LegacyLotId, '*', 3, 1) + Case Otherwise$ + ErrorMessage = 'Error in ':Service:' services. Invalid LegacyLotType.' + End Case + + Stage = 'POST' + DefectSpec = Xlate('PRS_STAGE', PSN : '*LWI', PRS_STAGE_SURF_DEFECTS$, 'X');//Since there is no set spec for a non-existent stage we need to take one from the unloading step. + HazeSpec = Xlate('PRS_STAGE', PSN : '*LWI', PRS_STAGE_SURF_HAZE$, 'X');//Since there is no set spec for a non-existent stage we need to take one from the unloading step. + // Check if CI was created already(usually during cleans) JRO-9-28 + Locate 'POST' in CIKeyStages using @VM setting sPos then + // Existing POST CI record found, fetch it. + CINo = CIKeyIDs<0, sPos> + CleanInspRec = Xlate('CLEAN_INSP', CINo,'','X') + IF CleanInspRec NE '' THEN + // Append a value mark to the end of the field so that we can add another set of data + CleanInspRec = CleanInspRec : @VM + END + Exists = True$ + end else + // No Exisiting POST CI record found, Create new CI record + Exists = False$ + oCIParms = '' + oCIParms = WONo:@RM + oCIParms := WOStep:@RM + oCIParms := CassNo:@RM + oCIParms := Stage:@RM + If LegacyLotType EQ 'RDS' then oCIParms := LegacyLotId:@RM + oCIParms := PSN:@RM + CleanInspRec = '' + CleanInspRec = WONo + CleanInspRec = WOStep + CleanInspRec = CassNo + CleanInspRec = Stage + If LegacyLotType EQ 'RDS' then CleanInspRec = LegacyLotId + end + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_RECIPE$, -1, 0, ScanRecipe) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_TOOL$, -1, 0, ScanTool) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MIN$, -1, 0, SoDMin) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_MAX$, -1, 0, SoDMax) + SoDAvg = Iconv(SoDAvg, 'MD3') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SUM_OF_DEF_AVG$, -1, 0, SoDAvg) + HazeAvg = Iconv(HazeAvg, 'MD3') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_HAZE_AVG_AVG$, -1, 0, HazeAvg) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG$, -1, 0, '') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG_DTM$, -1, 0, '') + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, -1, 0, Timestamp) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURFSCAN_RECIPE$, -1, 0, ScanRecipe) + CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SPEC_SURF_DEFECTS$, -1, 0, DefectSpec) + + // Here I am attempting to create the scan details. + If SODWaferArray NE '' then + NumRecipes = DCount(CleanInspRec, @VM) + For each WaferNo in WaferNos using @VM + If WaferNo NE '' then + CleanInspRec = SODVals<1,WaferNo> + CleanInspRec = SortVals<1,WaferNo> + end + Next Wafer + end + + If exists EQ False$ then - // Here I am attempting to create the scan details. - If SODWaferArray NE '' then - NumRecipes = DCount(CleanInspRec, @VM) - For each WaferNo in WaferNos using @VM - If WaferNo NE '' then - CleanInspRec = SODVals<1,WaferNo> - CleanInspRec = SortVals<1,WaferNo> - end - Next Wafer - end - If exists EQ False$ then - oCIParms := CleanInspRec - CINo = obj_Clean_Insp('Create',oCIParms) - If Error_Services('NoError') then - ReactRunRec = INSERT(ReactRunRec,REACT_RUN_CI_NO$,-1,0,CINo) - ReactRunRec = INSERT(ReactRunRec,REACT_RUN_CI_STAGE$,-1,0,Stage) - obj_Tables('WriteRec','REACT_RUN':@RM:RDSKeyID:@RM:@RM:ReactRunRec) + oCIParms := CleanInspRec ; + CINo = obj_Clean_Insp('Create',oCIParms) + If Error_Services('NoError') then + Begin Case + Case LegacyLotType EQ 'RDS' + ReactRunRec = INSERT(ReactRunRec,REACT_RUN_CI_NO$,-1,0,CINo) + ReactRunRec = INSERT(ReactRunRec,REACT_RUN_CI_STAGE$,-1,0,Stage) + obj_Tables('WriteRec','REACT_RUN':@RM:LegacyLotId:@RM:@RM:ReactRunRec) + Case LegacyLotType EQ 'WM_OUT' + WOMatRec = Database_Services('ReadDataRow', 'WO_MAT', WONo:'*':CassNo) + If Error_Services('NoError') then + WOMatRec = Insert(WOMatRec, WO_MAT_EPO_CI_NO$, -1, 0, CINo) + Database_Services('WriteDataRow', 'WO_MAT', WONo:'*':CassNo, WOMatRec, True$, False$, False$) + end + Case Otherwise$ + ErrorMessage = 'Error in ':Service:' services. Invalid LegacyLotType.' + End Case + + If ErrorMessage EQ '' then obj_Tables('WriteRec','CLEAN_INSP':@RM:CINo:@RM:@RM:CleanInspRec) PostStopTime = Time() TimeTaken = PostStopTime - PostStartTime @@ -2359,39 +2416,35 @@ Service ImportTencorData(RunData) LogData<3> = LegacyLotId@ LogData<4> = 'Time taken to import POST data: ':TimeTaken:' seconds.' Logging_Services('AppendLog', objPOSTPerfLog, LogData, @RM, @FM) - end else - // Record error. Ensure metrology run data file is not deleted by including UID002 in the - // error message that is placed onto error stack in Error_Services. - ErrorMessage = 'Failed to create CLEAN_INSP record. Error UID002.' end + end else - // Write to existing CI rec. - obj_Tables('WriteRec','CLEAN_INSP':@RM:CINo:@RM:@RM:CleanInspRec) + // Record error. Ensure metrology run data file is not deleted by including UID002 in the + // error message that is placed onto error stack in Error_Services. + ErrorMessage = 'Failed to create CLEAN_INSP record. Error UID002.' end end else - // Unexpected recipe -> notify users if not a QUAL scan - QualScan = (Indexc(ScanRecipe, 'QUAL', 1) GT 0) - If QualScan EQ False$ then - Recipients = XLATE('NOTIFICATION','TENCOR_NOTIFICATIONS',NOTIFICATION_USER_ID$,'X') - SentFrom = 'OI Admin' - Subject = 'Tencor SurfScan Import Failure for RDS ':RDSKeyID:'.' - Message = 'Scanned recipe ':ScanRecipe:' not found in PSN ':PSN:' for RDS ':RDSKeyID:'.' - AttachWindow = '' - AttachKey = '' - SendToGroup = '' - Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup - obj_Notes('Create',Parms) - end + // Write to existing CI rec. + obj_Tables('WriteRec','CLEAN_INSP':@RM:CINo:@RM:@RM:CleanInspRec) + end + end else + // Unexpected recipe -> notify users if not a QUAL scan + QualScan = (Indexc(ScanRecipe, 'QUAL', 1) GT 0) + If QualScan EQ False$ then + Recipients = XLATE('NOTIFICATION','TENCOR_NOTIFICATIONS',NOTIFICATION_USER_ID$,'X') + SentFrom = 'OI Admin' + Subject = 'Tencor SurfScan Import Failure for ':LegacyLotType:' ':LegacyLotId:'.' + Message = 'Scanned recipe ':ScanRecipe:' not found in PSN ':PSN:' for ':LegacyLotType:' ':LegacyLotId:'.' + AttachWindow = '' + AttachKey = '' + SendToGroup = '' + Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup + obj_Notes('Create',Parms) end end - end else - ErrorMessage = Error_Services('GetMessage') - Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) end - end else - ErrorMessage = 'Invalid RDS Key ID.' - Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) - end + end + If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service @@ -3680,3 +3733,4 @@ LoadRunDataToDatabase: return + diff --git a/LSL2/STPROC/QA_SERVICES.txt b/LSL2/STPROC/QA_SERVICES.txt index ffe0962..213e01e 100644 --- a/LSL2/STPROC/QA_SERVICES.txt +++ b/LSL2/STPROC/QA_SERVICES.txt @@ -1012,7 +1012,7 @@ Service GetSODPerWafer(RDSKey, TencorRecipe, ScanDTM) If RDSKey NE '' and TencorRecipe NE '' then If Num(ScanDTM) then ScanDTM = OConv(ScanDTM, 'DT/^S') - Query = "DECLARE @RDS varchar(10) " + Query = "DECLARE @RDS varchar(255) " Query := "DECLARE @RECIPE varchar(30) " Query := "DECLARE @INSERT_DT datetime " Query := "SET @RDS = '":RDSKey:"' " @@ -1199,7 +1199,7 @@ Service ProcessWaferImageRequests() PSN = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X') // Format Wafer Number for SQL Query WaferNo = Fmt(TrimF(WaferNo), 'R(0)#2') - Query = "DECLARE @RDS varchar(10) " | + Query = "DECLARE @RDS varchar(255) " | : "DECLARE @RECIPE varchar(30) " | : "DECLARE @WFRID varchar(10) " | : "SET @RDS = '":RDSNo:"' " | @@ -3833,13 +3833,3 @@ ClearCursors: return - - - - - - - - - -