Function Engineering_Services(@Service, @Params) /*********************************************************************************************************************** Name : Engineering_Services Description : Handler program for all Disposition services. 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) 08/24/20 djs Original programmer. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert SERVICE_SETUP $insert REACT_RUN_EQUATES $insert WO_WFR_EQUATES $insert RUN_STAGE_WFR_EQUATES $insert APP_INSERTS $insert RLIST_EQUATES $insert EA_REQUESTS_EQUATES $insert FILE_SERVICES_EQUATES Declare subroutine Error_Services, Database_Services, GaN_Services, Disposition_Services, Engineering_Services, RList Declare subroutine Excel_Services, Set_Status, Engineering_Services, Btree.Extract Declare subroutine Logging_Services, File_Services, GetTempPath Declare function Database_Services, Error_Services, DateTime, GaN_Services, Engineering_Services, Excel_Services Declare function Engineering_Services, Environment_Services, Logging_Services, File_Services, SQL_Services Declare Function Math_Services LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\EngineeringAnalysis' LogDate = Oconv(Date(), 'D4/') LogTime = Oconv(Time(), 'MTS') LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' PostToExcelLog.csv' Headers = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'Notes' objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$) QueueLogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' QueueLog.csv' QueueObjLog = Logging_Services('NewLog', LogPath, QueueLogFileName, CRLF$, Comma$, Headers, '', False$, False$) SQLLogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' SQL Response Log.csv' Headers = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'SQL Response' objSQLLog = Logging_Services('NewLog', LogPath, SQLLogFileName, CRLF$, Comma$, Headers, '', False$, False$) LoggingDTM = LogDate : ' ' : LogTime LogData = '' GoToService else Error_Services('Set', Service : ' is not a valid service request within the ' : ServiceModule : ' services module.') end Return Response else '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// * Options STAGES = 'GROWTH','UV','WARP','CAN','XRD','AFM','BV' * Options BV_PARAMETERS = 'Breakdown Voltage','Breakdown Voltage - Edge','Breakdown Voltage - Middle' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Services //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Service GetSpreadSheetInfo(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) WONo = ReactRunRec Reactor = ReactRunRec Voltage = Xlate('WO_LOG', WONo, 'GAN_COST_TYPE', 'X') EpiStructure = Xlate('WO_LOG', WONo, 'EPI_STRUCTURE', 'X') Begin Case Case (Reactor EQ '69') SpreadsheetName = '8-inch New HV Epi Development.xlsx' WorksheetName = '8inch HELENS' Password = 'IRMN2714' Directory = '\\messv02ecc1.ec.local\EC_GaN_Development\R69 EPI DEVELOPMENT\DAILY RUN RECORD\' Offset = 18 EndCol = 'CC' Case ( (Reactor EQ '71') and ( (Voltage _EQC 'Mid Voltage') or (EpiStructure EQ 'MV') ) ) SpreadsheetName = 'MV_R71_6-inch Epi Development.xlsx' WorksheetName = 'R71-MV_With CAN02' Password = 'IRMN2714' Directory = '\\messv02ecc1.ec.local\EC_GaN_Development\R71 EPI DEVELOPMENT\Daily Run Record\' Offset = 16 EndCol = 'CF' Case ( (Reactor EQ '71') and ( (Voltage _EQC 'High Voltage') or (EpiStructure EQ 'HV') ) ) SpreadsheetName = 'HV_R71_6-inch Epi Development.xlsx' WorksheetName = 'HV_with_CAN02' Password = 'IRMN2714' Directory = '\\messv02ecc1.ec.local\EC_GaN_Development\R71 EPI DEVELOPMENT\Daily Run Record\' Offset = 18 EndCol = 'CG' Case Otherwise$ ErrorMsg = 'Error in service ':Service:'. Failed to determine Excel Spreadsheet information.' Error_Services('Add', ErrorMsg) End Case end If Error_Services('NoError') then Response<1> = SpreadsheetName Response<2> = WorksheetName Response<3> = Password Response<4> = Directory Response<5> = Offset Response<6> = EndCol end end service Service GetSpreadSheets() SpreadsheetNames = '' WorksheetNames = '' Passwords = '' Directories = '' Offsets = '' EndCols = '' SpreadsheetNames<0, -1> = '8-inch New HV Epi Development.xlsx' WorksheetNames<0, -1> = '8inch HELENS' Passwords<0, -1> = 'IRMN2714' Offsets<0, -1> = 18 Directories<0, -1> = '\\messv02ecc1.ec.local\EC_GaN_Development\R69 EPI DEVELOPMENT\DAILY RUN RECORD\' EndCols<0, -1> = 'CC' SpreadsheetNames<0, -1> = 'MV_R71_6-inch Epi Development.xlsx' WorksheetNames<0, -1> = 'R71-MV_With CAN02' Passwords<0, -1> = 'IRMN2714' Offsets<0, -1> = 16 Directories<0, -1> = '\\messv02ecc1.ec.local\EC_GaN_Development\R71 EPI DEVELOPMENT\Daily Run Record\' EndCols<0, -1> = 'CF' SpreadsheetNames<0, -1> = 'HV_R71_6-inch Epi Development.xlsx' WorksheetNames<0, -1> = 'HV_with_CAN02' Passwords<0, -1> = 'IRMN2714' Offsets<0, -1> = 18 Directories<0, -1> = '\\messv02ecc1.ec.local\EC_GaN_Development\R71 EPI DEVELOPMENT\Daily Run Record\' EndCols<0, -1> = 'CG' If Error_Services('NoError') then Response<1> = SpreadsheetNames Response<2> = WorksheetNames Response<3> = Passwords Response<4> = Directories Response<5> = Offsets Response<6> = EndCols end end service Service PostGrowthData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo, True$, 0, False$) GaNRunID = ReactRunRec InWfrIDs = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec LoadDTM = ReactRunRec LoadDT = OConv(LoadDTM[1, 'F.'], 'D/') NewRun = False$ SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> EndCol = SpreadsheetInfo<6> // i.e. LOAD -> write the recipe, scribes, and satellite IDs to the appropriate spreadsheet If SpreadsheetRowIndex EQ '' then // RunID does not yet exist in the spreadsheet, so assign the next available row in the // worksheet to the REACT_RUN record SpreadsheetRowIndex = Database_Services('ReadDataRow', 'APP_INFO', WorksheetName) ReactRunRec = SpreadsheetRowIndex NewRun = True$ end If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then RunInfo = GaN_Services('GetRunInfo', GaNRunID) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = RunInfo Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( (RunInfo NE '') and (RunInfo NE 0) ) then Pockets = RunInfo<3> Scribes = RunInfo<4> SatIDs = RunInfo<5> DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Write the Run Recipe, Scribes, and Satellite IDs to the spreadsheet // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If ( (RowRunID EQ GaNRunID) or (NewRun EQ True$) ) then // Verified row index is correct or run is not yet in spreadsheet, so continue. If NewRun EQ True$ then // Copy formatted cell range (i.e. the cell "block") BeginRow = SpreadsheetRowIndex CellRangeBegin = 'A':BeginRow EndRow = SpreadsheetRowIndex + (Offset - 1) CellRangeEnd = EndCol:EndRow CopyToCell = 'A':(SpreadsheetRowIndex + Offset) Excel_Services('CopyCellRange', DocObj, WorksheetName, CellRangeBegin, CellRangeEnd, CopyToCell) Excel_Services('SetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex, GaNRunID) end // Run Recipe Excel_Services('SetCellValue', DocObj, WorksheetName, 'D', SpreadsheetRowIndex, RunRecipe) If WorksheetName EQ 'R71-MV_With CAN02' then DateCol = 'Z' DateCol2 = 'AA' SatCol = 'AB' ScribeCol = 'AC' end else DateCol = 'AA' DateCol2 = 'AB' SatCol = 'AC' ScribeCol = 'AD' end // Unload Date DateRow = (SpreadsheetRowIndex + 9) Excel_Services('SetCellValue', DocObj, WorksheetName, DateCol, DateRow, 'Date') Excel_Services('SetCellValue', DocObj, WorksheetName, DateCol2, DateRow, LoadDT) // Scribes and Satellite IDs For each Scribe in Scribes using @VM setting wPos SatID = SatIDs<0, wPos> WaferRowIndex = SpreadsheetRowIndex + (wPos - 1) Excel_Services('SetCellValue', DocObj, WorksheetName, ScribeCol, WaferRowIndex, Scribe) Excel_Services('SetCellValue', DocObj, WorksheetName, SatCol, WaferRowIndex, SatID) Next Scribe Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end else If NewRun EQ True$ then // Advance APP_INFO next row index for the worksheet NextSpreadsheetRowIndex = SpreadsheetRowIndex + (Offset + 1) Database_Services('WriteDataRow', 'APP_INFO', WorksheetName, NextSpreadsheetRowIndex, True$, False$, True$) // Save REACT_RUN record with row index. Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) end end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Run info for Run ID ':GaNRunID:' is not available in IQS at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostAFMData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then AFMData = Engineering_Services('GetAFMData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = AFMData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( (AFMData NE '') and (AFMData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then // Verified row index is correct so continue. // Write the AFM Pit Count and AFM Roughness to the spreadsheet If WorksheetName EQ 'R71-MV_With CAN02' then PitCountCol = 'Z' RoughnessCol = 'AA' end else PitCountCol = 'AA' RoughnessCol = 'AB' end For each Row in AFMData using @FM setting fPos Parameter = Row<0, 1> Pocket = Row<0, 2> Value = Row<0, 3> Begin Case Case Parameter EQ 'AFM Pit Count' Col = PitCountCol Case Parameter EQ 'AFM Roughness' Col = RoughnessCol Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + (Pocket - 1) Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':TempPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. AFM data for Run ID ':GaNRunID:' is not available in IQS at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument') If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostCHARData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec InWfrIDs = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then DestroyedList = '' For each WfrID in InWfrIDs using @VM setting wPos WaferDestroyed = GaN_Services('GetDestroyedStatus', WfrID) If WaferDestroyed EQ True$ then DestroyedList<0, -1> = wPos Next WfrID LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = DestroyedList Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then // Verified row index is correct so continue. If WorksheetName EQ 'R71-MV_With CAN02' then ScribeCol = 'AC' RowIndex = SpreadsheetRowIndex + Offset - 1 end else ScribeCol = 'AD' RowIndex = SpreadsheetRowIndex + Offset - 3 end CharString = '' If DestroyedList NE '' then For each WfrPos in DestroyedList using @VM CharString := 'W0':WfrPos:',' Next WfrPos end else CharString = '#N/A' end // Erase last comma CharString[-1, 1] = '' Excel_Services('SetCellValue', DocObj, WorksheetName, ScribeCol, RowIndex, CharString) // Attempt to save changes to spreadsheet Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument') If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostRPMData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then RPMData = Engineering_Services('GetRPMData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = RPMData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('NoError') and (RPMData NE '') and (RPMData NE 0) ) then PLData = Engineering_Services('GetPLData', RDSNo) If ( Error_Services('NoError') and (PLData NE '') and (PLData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then // Verified row index is correct so continue. Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' PLEdgeCol = 'AY' PLYellowCol = 'AZ' PLRatioCol = 'AZ' RPMThicknessCol = 'BA' RPMStdDevCol = 'BB' Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' PLEdgeCol = 'AZ' PLYellowCol = 'BA' PLRatioCol = 'BA' RPMThicknessCol = 'BB' RPMStdDevCol = 'BC' Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' PLEdgeCol = 'BC' PLYellowCol = 'BD' PLRatioCol = 'BD' RPMThicknessCol = 'BE' RPMStdDevCol = 'BF' End Case // Write constant values Excel_Services('SetCellValue', DocObj, WorksheetName, PLEdgeCol, (SpreadsheetRowIndex + 1), 'Ratio') // Write RPM values RowIndex = SpreadsheetRowIndex For each Row in RPMData using @FM setting fPos Parameter = Row<0, 1> Value = Row<0, 2> Begin Case Case Parameter EQ 'Epi Thickness Mean' Col = RPMThicknessCol Case Parameter EQ 'Epi Thickness Std Dev %' Col = RPMStdDevCol End Case Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row // Write PL values For each Row in PLData using @FM setting fPos Parameter = Row<0, 1> Value = Row<0, 2> Begin Case Case Parameter EQ 'PL Ratio' Col = PLRatioCol RowIndex = SpreadsheetRowIndex + 1 Case Parameter EQ 'BandEdge_V' RowIndex = SpreadsheetRowIndex Col = PLEdgeCol Case Parameter EQ 'YellowBand_V' RowIndex = SpreadsheetRowIndex Col = PLYellowCol Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. PL data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. RPM data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostPRData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then PRData = Engineering_Services('GetPRData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = PRData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('NoError') and (PRData NE '') and (PRData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then // Verified row index is correct so continue. Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' PRPeakCol = 'BC' PRBarrierCompCol = 'BD' PRStdDevCol = 'BD' NumValues = 9 Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' PRPeakCol = 'BD' PRBarrierCompCol = 'BE' NumValues = 5 Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' PRPosCol = 'BG' PRBarrierCompCol = 'BH' NumValues = 7 End Case // Write constant values Excel_Services('SetCellValue', DocObj, WorksheetName, PLEdgeCol, (SpreadsheetRowIndex + 1), 'Ratio') // Write PR values PeakCounter = 0 PRBarrCompCounter = 0 RPMBarrCompCounter = 0 PRBarrCompValues = '' YCoordCounter = 0 BarrierMax = 0 BarrierMin = 0 BarrierRange = 0 For each Row in PRData using @FM setting fPos Parameter = Row<0, 1> SBNo = Row<0, 2> Value = Row<0, 3> Begin Case Case Parameter EQ 'PR Peak' Col = PRPeakCol If SBNo GT 0 then RowOffset = PeakCounter end else RowOffset = 9 end PeakCounter += 1 Case Parameter EQ 'PR Barrier Composition' Col = PRBarrierCompCol If SBNo GT 0 then RowOffset = PRBarrCompCounter end else RowOffset = 9 end If ( (SBNo NE 0) and (Value NE '') ) then PRBarrCompValues<0, -1> = Value PRBarrCompCounter += 1 Case Parameter EQ 'Barrier_Composition_RPM_XY' Col = PRBarrierCompCol RowOffset = RPMBarrCompCounter If BarrierMax EQ 0 then BarrierMax = Value If BarrierMin EQ 0 then BarrierMin = Value If Value GT BarrierMax then BarrierMax = Value If Value LT BarrierMin then BarrierMin = Value If ( (SpreadsheetName EQ '8-inch New HV Epi Development.xlsx') and (SBNo EQ 0) ) then // Write the Barrier Comp average BarrierAvg = Value RowIndex = NumValues Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, BarrierAvg) end RPMBarrCompCounter += 1 Case Parameter EQ 'Y-Coord' Col = PRPosCol RowOffset = YCoordCounter YCoordCounter += 1 Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + RowOffset If ( (Parameter NE 'Y-Coord') or (SBNo GT 0) ) then Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) end Next Row If ErrorMessage EQ '' then If SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' then RowIndex = SpreadsheetRowIndex + NumValues + 1 BarrierRange = BarrierMax - BarrierMin Excel_Services('SetCellValue', DocObj, WorksheetName, PRBarrierCompCol, RowIndex, BarrierRange) end If SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' then RowIndex = SpreadsheetRowIndex + 10 PRCV = Math_Services('GetCoefficientOfVariation', PRBarrCompValues, 'SAMPLE') Excel_Services('SetCellValue', DocObj, WorksheetName, PRStdDevCol, RowIndex, PRCV) end Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. PR data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostXRDData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo XRDAlumData = Engineering_Services('GetXRDAlumData', RDSNo) LogData<3> = XRDAlumData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) XRDThicknessData = Engineering_Services('GetXRDThicknessData', RDSNo) LogData<3> = XRDThicknessData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If SpreadsheetName NE '8-inch New HV Epi Development.xlsx' then // 6-inch XRDCoordData = Engineering_Services('GetXRDXCoordData', RDSNo) LogData<3> = XRDCoordData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) XRDWtAvgData = Engineering_Services('GetXRDWtAvgData', RDSNo) LogData<3> = XRDWtAvgData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) end else // 8-inch XRDCoordData = Engineering_Services('GetXRDYCoordData', RDSNo) LogData<3> = XRDCoordData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) end If ( Error_Services('NoError') and (XRDAlumData NE '') and (XRDThicknessData NE '') and (XRDCoordData NE '') and (XRDAlumData NE 0) and (XRDThicknessData NE 0) and (XRDCoordData NE 0) ) then If SpreadsheetName NE '8-inch New HV Epi Development.xlsx' then XRDWtAvgData = Engineering_Services('GetXRDWtAvgData', RDSNo) LogData<3> = XRDWtAvgData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( (XRDWtAvgData EQ 0) or (XRDWtAvgData EQ '') ) then ErrorMessage = 'Error in service':Service:'. XRD data missing in IQS.' end end If ErrorMessage EQ '' then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' BBCol = 'BE' BarrierCol = 'BF' SLSCol = 'BG' TL1Col = 'BH' TL0Col = 'BI' AVECol = 'BJ' SLPeriodCol = 'BK' ThickCoordCol = 'AP' ThicknessCol = 'AQ' FWHM006Col = 'AW' FWHM105Col = 'AX' NumValues = 3 Excel_Services('SetCellValue', DocObj, WorksheetName, AVECol, (SpreadsheetRowIndex + 3), 'AVE') Excel_Services('SetCellValue', DocObj, WorksheetName, TL0Col, (SpreadsheetRowIndex + 6), 'Coordinate') Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' BBCol = 'BF' BarrierCol = 'BG' SLSCol = 'BH' TL1Col = 'BI' TL0Col = 'BJ' AVECol = 'BK' SLPeriodCol = 'BL' ThickCoordCol = 'AQ' ThicknessCol = 'AR' FWHM006Col = 'AX' FWHM105Col = 'AY' NumValues = 3 Excel_Services('SetCellValue', DocObj, WorksheetName, 'AP' , SpreadsheetRowIndex, 'XRR') Excel_Services('SetCellValue', DocObj, WorksheetName, AVECol , SpreadsheetRowIndex, 'SL thickness') Excel_Services('SetCellValue', DocObj, WorksheetName, AVECol, (SpreadsheetRowIndex + 3), 'AVE') Excel_Services('SetCellValue', DocObj, WorksheetName, TL0Col, (SpreadsheetRowIndex + 6), 'Coordinate') Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' BBCol = 'BI' BarrierCol = 'BJ' SLSCol = 'BK' TL2Col = 'BL' TL1Col = 'BM' TL0Col = 'BN' SLPeriodCol = 'BO' ThickCoordCol = 'AT' ThicknessCol = 'AU' FWHM006Col = 'BA' FWHM105Col = 'BB' NumValues = 4 RangeOffset = 5 Excel_Services('SetCellValue', DocObj, WorksheetName, 'AS' , SpreadsheetRowIndex, 'XRR') Excel_Services('SetCellValue', DocObj, WorksheetName, BBCol, (SpreadsheetRowIndex + 17), 'B.B.') Excel_Services('SetCellValue', DocObj, WorksheetName, BarrierCol, (SpreadsheetRowIndex + 17), 'Barrier') Excel_Services('SetCellValue', DocObj, WorksheetName, SLSCol, (SpreadsheetRowIndex + 17), 'SLS') Excel_Services('SetCellValue', DocObj, WorksheetName, TL2Col, (SpreadsheetRowIndex + 17), 'TL2') Excel_Services('SetCellValue', DocObj, WorksheetName, TL1Col, (SpreadsheetRowIndex + 17), 'TL1') Excel_Services('SetCellValue', DocObj, WorksheetName, TL0Col, (SpreadsheetRowIndex + 17), 'TL0') Excel_Services('SetCellValue', DocObj, WorksheetName, SLPeriodCol, (SpreadsheetRowIndex + 17), 'SL Period') End Case // Write Al% values BBMin = '' BBMax = '' BBRange = '' BarrierMin = '' BarrierMax = '' BarrierRange = '' SLSMin = '' SLSMax = '' SLSRange = '' TL1Min = '' TL1Max = '' TL1Range = '' SLPeriodMin = '' SLPeriodMax = '' SLPeriodRange = '' For each Row in XRDAlumData using @FM setting fPos Parameter = Row<0, 1> SBNo = Row<0, 2> Pocket = Row<0, 3> Value = Row<0, 4> Begin Case Case Parameter EQ 'Al% B.B.' Col = BBCol If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues end else RowOffset = SBNo - 1 If BBMin EQ '' then BBMin = Value If BBMax EQ '' then BBMax = Value If Value LT BBMin then BBMin = Value If Value GT BBMax then BBMax = Value end Case Parameter EQ 'Al% Barrier' Col = BarrierCol If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues end else RowOffset = SBNo - 1 If BarrierMin EQ '' then BarrierMin = Value If BarrierMax EQ '' then BarrierMax = Value If Value LT BarrierMin then BarrierMin = Value If Value GT BarrierMax then BarrierMax = Value end Case Parameter EQ 'Al% SLS' Col = SLSCol If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues end else RowOffset = SBNo - 1 If SLSMin EQ '' then SLSMin = Value If SLSMax EQ '' then SLSMax = Value If Value LT SLSMin then SLSMin = Value If Value GT SLSMax then SLSMax = Value end Case Parameter EQ 'Al% TL1' Col = TL1Col If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues end else RowOffset = SBNo - 1 If TL1Min EQ '' then TL1Min = Value If TL1Max EQ '' then TL1Max = Value If Value LT TL1Min then TL1Min = Value If Value GT TL1Max then TL1Max = Value end Case Parameter EQ 'SL Period' Col = SLPeriodCol If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues end else RowOffset = SBNo - 1 If SLPeriodMin EQ '' then SLPeriodMin = Value If SLPeriodMax EQ '' then SLPeriodMax = Value If Value LT SLPeriodMin then SLPeriodMin = Value If Value GT SLPeriodMax then SLPeriodMax = Value end Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + RowOffset Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then // Write Coordinate Data If SpreadsheetName NE '8-inch New HV Epi Development.xlsx' then // 6-inch spreadsheets Excel_Services('SetCellValue', DocObj, WorksheetName, ThickCoordCol, (SpreadsheetRowIndex + NumValues), 'Avg.') For each Row in XRDCoordData using @FM setting fPos SBNo = Row<0, 2> Value = Abs(Row<0, 4>) Excel_Services('SetCellValue', DocObj, WorksheetName, TL0Col, (SpreadsheetRowIndex + 6 + SBNo), Value) Excel_Services('SetCellValue', DocObj, WorksheetName, ThickCoordCol, ( SpreadsheetRowIndex + (SBNo - 1) ), Value:'mm') Next Row // Write Wt. Avg. Data (applies to 6-inch spreadsheets only) RowIndex = SpreadsheetRowIndex + NumValues + 3 For each Row in XRDWtAvgData using @FM setting fPos Parameter = Row<0, 1> SBNo = Row<0, 2> Pocket = Row<0, 3> Value = Row<0, 4> Begin Case Case Parameter EQ 'Al% B.B. WTAVG' Col = BBCol Case Parameter EQ 'Al% Barrier WTAVG' Col = BarrierCol Case Parameter EQ 'Al% SLS WTAVG' Col = SLSCol Case Parameter EQ 'Al% TL1 WTAVG' Col = TL1Col Case Parameter EQ 'SL Period WTAVG' Col = SLPeriodCol Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row end else // 8-inch spreadsheet Excel_Services('SetCellValue', DocObj, WorksheetName, ThickCoordCol, (SpreadsheetRowIndex + NumValues), 'Avg.') Excel_Services('SetCellValue', DocObj, WorksheetName, ThickCoordCol, (SpreadsheetRowIndex + NumValues + 1), 'Range') For each Row in XRDCoordData using @FM setting fPos SBNo = Row<0, 2> Value = Abs(Row<0, 4>) Excel_Services('SetCellValue', DocObj, WorksheetName, ThickCoordCol, ( SpreadsheetRowIndex + (SBNo - 1) ), Value:'mm') Next Row // Calculate Range Values BBRange = BBMax - BBMin BarrierRange = BarrierMax - BarrierMin SLSRange = SLSMax - SLSMin TL1Range = TL1Max - TL1Min SLPeriodRange = SLPeriodMax - SLPeriodMin // Write Range Values RowIndex = SpreadsheetRowIndex + RangeOffset Excel_Services('SetCellValue', DocObj, WorksheetName, BBCol, RowIndex, BBRange) Excel_Services('SetCellValue', DocObj, WorksheetName, BarrierCol, RowIndex, BarrierRange) Excel_Services('SetCellValue', DocObj, WorksheetName, SLSCol, RowIndex, SLSRange) Excel_Services('SetCellValue', DocObj, WorksheetName, TL1Col, RowIndex, TL1Range) Excel_Services('SetCellValue', DocObj, WorksheetName, SLPeriodCol, RowIndex, SLPeriodRange) end // Write thickness and FWHM data ThicknessMin = 0 ThicknessMax = 0 ThicknessRange = 0 FWHM006Min = 0 FWHM006Max = 0 FWHM006Range = 0 FWHM105Min = 0 FWHM105Max = 0 FWHM105Range = 0 For each Row in XRDThicknessData using @FM setting fPos Parameter = Row<0, 1> SBNo = Row<0, 2> Pocket = Row<0, 3> Value = Row<0, 4> Begin Case Case Parameter EQ 'XRR Thickness (nm)' Col = ThicknessCol If ThicknessMin EQ 0 then // Initialize min and max variables ThicknessMin = Value ThicknessMax = Value end If Value LT ThicknessMin then ThicknessMin = Value If Value GT ThicknessMax then ThicknessMax = Value Case Parameter EQ 'FWHM 006' Col = FWHM006Col If FWHM006Min EQ 0 then // Initialize min and max variables FWHM006Min = Value FWHM006Max = Value end If Value LT FWHM006Min then FWHM006Min = Value If Value GT FWHM006Max then FWHM006Max = Value Case Parameter EQ 'FWHM 105' Col = FWHM105Col If FWHM105Min EQ 0 then FWHM105Min = Value FWHM105Max = Value end If Value LT FWHM105Min then FWHM105Min = Value If Value GT FWHM105Max then FWHM105Max = Value Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' // The following code to used to place the average in the correct row If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues end else RowOffset = SBNo - 1 end RowIndex = SpreadsheetRowIndex + RowOffset If ( (SBNo NE 0) or (SpreadsheetName EQ '8-inch New HV Epi Development.xlsx') or (Parameter EQ 'XRR Thickness (nm)') ) then // Do not write the average values (i.e. SBNo = 0) for 6-inch spreadsheets Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) end If SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' then RowIndex = SpreadsheetRowIndex + NumValues + 1 ThicknessRange = ThicknessMax - ThicknessMin FWHM006Range = FWHM006Max - FWHM006Min FWHM105Range = FWHM105Max - FWHM105Min Excel_Services('SetCellValue', DocObj, WorksheetName, ThicknessCol, RowIndex, ThicknessRange) Excel_Services('SetCellValue', DocObj, WorksheetName, FWHM006Col, RowIndex, FWHM006Range) Excel_Services('SetCellValue', DocObj, WorksheetName, FWHM105Col, RowIndex, FWHM105Range) end Next Row end If ErrorMessage EQ '' then Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. XRD data is missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. XRD data is missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostHALLData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetName NE '8-inch New HV Epi Development.xlsx' then // Hall data is currently only recorded for 6-inch wafers If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then HallData = Engineering_Services('GetHallData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = HallData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( (HallData NE '') and (HallData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then Set_Status(0) // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' RSCol = 'AR' MobilityCol = 'AS' NSCol = 'AT' Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' RSCol = 'AS' MobilityCol = 'AT' NSCol = 'AU' End Case NumRSVals = 0 NumMobilityVals = 0 NumNSVals = 0 RSVals = '' MobilityVals = '' NSVals = '' RSDeviations = '' MobilityDeviations = '' NSDeviations = '' RSAvg = '' MobilityAvg = '' NSAvg = '' RSCV = '' MobilityCV = '' NSCV = '' // Write Hall values For each Row in HallData using @FM setting fPos Parameter = Row<0, 1> SBNo = Row<0, 2> Value = Row<0, 3> Begin Case Case Parameter EQ 'Hall Rs' Col = RSCol If SBNo EQ 0 then RowOffset = 7 RSAvg = Value end else RowOffset = SBNo - 1 NumRSVals += 1 RSVals<0, -1> = Value end Case Parameter EQ 'Mobility' Col = MobilityCol If SBNo EQ 0 then RowOffset = 7 MobilityAvg = Value end else RowOffset = SBNo - 1 NumMobilityVals += 1 MobilityVals<0, -1> = Value end Case Parameter EQ 'Sheet Concentration' Col = NSCol If SBNo EQ 0 then RowOffset = 7 NSAvg = Value end else RowOffset = SBNo - 1 NumNSVals += 1 NSVals<0, -1> = Value end Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + RowOffset Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then // Calculate Std Dev for RS For each Value in RSVals using @VM setting vPos Deviation = Value - RSAvg RSDeviations<0, vPos> = Deviation ** 2 Next Value RSDevsSum = Sum(RSDeviations) // Std Dev for a sample, not population If (NumRSVals - 1) GT 0 then Variance = RSDevsSum / (NumRSVals - 1) RSStdDev = Variance ** 0.5 // Coefficient of Variation If RSAvg GT 0 then RSCV = RSStdDev / RSAvg end // Calculate Std Dev for Mobility For each Value in MobilityVals using @VM setting vPos Deviation = Value - MobilityAvg MobilityDeviations<0, vPos> = Deviation ** 2 Next Value MobilityDevsSum = Sum(MobilityDeviations) If (NumMobilityVals - 1) GT 0 then Variance = MobilityDevsSum / (NumMobilityVals - 1) MobilityStdDev = Variance ** 0.5 // Coefficient of Variation If MobilityAvg GT 0 then MobilityCV = MobilityStdDev / MobilityAvg end // Calculate Std Dev for NS For each Value in NSVals using @VM setting vPos Deviation = Value - NSAvg NSDeviations<0, vPos> = Deviation ** 2 Next Value NSDevsSum = Sum(NSDeviations) // Std Dev for a sample, not population If (NumNSVals - 1) GT 0 then Variance = NSDevsSum / (NumNSVals - 1) NSStdDev = Variance ** 0.5 // Coefficient of Variation If NSAvg GT 0 then NSCV = NSStdDev / NSAvg end // Write Std Dev Values StdDevRow = 8 RowIndex = SpreadsheetRowIndex + StdDevRow Excel_Services('SetCellValue', DocObj, WorksheetName, RSCol, RowIndex, RSCV) Excel_Services('SetCellValue', DocObj, WorksheetName, MobilityCol, RowIndex, MobilityCV) Excel_Services('SetCellValue', DocObj, WorksheetName, NSCol, RowIndex, NSCV) // Save document Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Hall data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostBVData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then BVData = Engineering_Services('GetBVData', RDSNo, 'Breakdown Voltage') // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = BVData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('NoError') and (BVData NE '') and (BVData NE 0) ) then BVEdgeData = Engineering_Services('GetBVData', RDSNo, 'Breakdown Voltage - Edge') // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = BVEdgeData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('NoError') and (BVEdgeData NE '') and (BVEdgeData NE 0) ) then If SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' then // 8-inch spreadsheet - Middle = Left, Edge = Right BVMiddleData = Engineering_Services('GetBVData', RDSNo, 'Breakdown Voltage - Middle') // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = BVMiddleData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('HasError') or (BVMiddleData EQ '') or (BVMiddleData EQ 0) ) then ErrorMessage = 'Error in service ':Service:'. Breakdown Voltage - Middle data is missing in IQS.' end end If ErrorMessage EQ '' then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' LeftCol = 'BL' CenterCol = 'BM' RightCol = 'BN' AvgCol = 'BO' NumValues = 5 Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' LeftCol = 'BM' CenterCol = 'BN' RightCol = 'BO' AvgCol = 'BP' NumValues = 5 Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' LeftCol = 'BP' CenterCol = 'BQ' RightCol = 'BR' AvgCol = 'BS' NumValues = 5 End Case // Write Breakdown Voltage values BVAvgTotal = 0 BVAvgPoints = 0 BVAvgMax = 0 BVAvgMin = 0 Col = CenterCol For each Row in BVData using @FM setting fPos SBNo = Row<0, 2> Value = Row<0, 3> // The following code to used to place the average in the correct row If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues + 1 BVAvgTotal += Value BVAvgPoints += 1 // Initialize BV Avg Max and Min to the Center Avg BVAvgMax = Value BVAvgMin = Value end else RowOffset = SBNo - 1 end RowIndex = SpreadsheetRowIndex + RowOffset Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row // Write Left (or Middle) and Right (or Edge) BV Data If SpreadsheetName NE '8-inch New HV Epi Development.xlsx' then // 6-inch spreadsheets - SBNo = 1 -> Left, SBNo = 2 -> Right RowIndex = SpreadsheetRowIndex For each Row in BVEdgeData using @FM setting fPos SBNo = Row<0, 2> Value = Row<0, 3> Begin Case Case SBNo EQ 1 // Left Excel_Services('SetCellValue', DocObj, WorksheetName, LeftCol, RowIndex, Value) BVAvgTotal += Value BVAvgPoints += 1 If Value GT BVAvgMax then BVAvgMax = Value If Value LT BVAvgMin then BVAvgMin = Value Case SBNo EQ 2 // Right Excel_Services('SetCellValue', DocObj, WorksheetName, RightCol, RowIndex, Value) BVAvgTotal += Value BVAvgPoints += 1 If Value GT BVAvgMax then BVAvgMax = Value If Value LT BVAvgMin then BVAvgMin = Value Case Otherwise$ // 6 inch spreadsheets currently don't record the average (i.e. SBNo = 0) Null End Case Next Row // Calculate the average of the Left, Center average, and Right values If BVAvgPoints GT 0 then BVAvg = BVAvgTotal / BVAvgPoints RowIndex = SpreadsheetRowIndex + NumValues + 1 Excel_Services('SetCellValue', DocObj, WorksheetName, AvgCol, RowIndex, BVAvg) end // Calculate the range of the averages AvgRange = BVAvgMax - BVAvgMin RowIndex = SpreadsheetRowIndex + NumValues + 1 Excel_Services('SetCellValue', DocObj, WorksheetName, AvgCol, RowIndex, AvgRange) end else // 8-inch spreadsheet - Middle = Left, Edge = Right MiddleAvg = 0 For each Row in BVMiddleData using @FM setting fPos SBNo = Row<0, 2> Value = Row<0, 3> // The following code to used to place the average in the correct row If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues + 1 BVAvgTotal += Value BVAvgPoints += 1 If Value GT BVAvgMax then BVAvgMax = Value If Value LT BVAvgMin then BVAvgMin = Value end else RowOffset = SBNo - 1 end RowIndex = SpreadsheetRowIndex + RowOffset Excel_Services('SetCellValue', DocObj, WorksheetName, LeftCol, RowIndex, Value) Next Row For each Row in BVEdgeData using @FM setting fPos SBNo = Row<0, 2> Value = Row<0, 3> // The following code to used to place the average in the correct row If SBNo EQ 0 then // Average value is SBNo 0 RowOffset = NumValues + 1 BVAvgTotal += Value BVAvgPoints += 1 If Value GT BVAvgMax then BVAvgMax = Value If Value LT BVAvgMin then BVAvgMin = Value end else RowOffset = SBNo - 1 end RowIndex = SpreadsheetRowIndex + RowOffset Excel_Services('SetCellValue', DocObj, WorksheetName, RightCol, RowIndex, Value) Next Row // Calculate the average of the Middle, Center, and Edge average values If BVAvgPoints GT 0 then BVAvg = BVAvgTotal / BVAvgPoints RowIndex = SpreadsheetRowIndex + NumValues + 3 Excel_Services('SetCellValue', DocObj, WorksheetName, CenterCol, RowIndex, BVAvg) end // Calculate the range of the averages AvgRange = BVAvgMax - BVAvgMin RowIndex = SpreadsheetRowIndex + NumValues + 1 Excel_Services('SetCellValue', DocObj, WorksheetName, AvgCol, RowIndex, AvgRange) end Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end end else ErrorMessage = 'Error in ':Service:' service. Breakdown Voltage data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Breakdown Voltage data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument') If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostUVData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then UVData = Engineering_Services('GetUVData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = UVData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('NoError') and (UVData NE '') and (UVData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' BrokenCol = 'BW' NonRotationCol = 'BX' ScratchCol = 'BY' Cracking3to7Col = 'BZ' CrackingGT7Col = 'CA' TrueHazeCol = 'CB' CrazingCol = 'CC' SlipCountCol = 'CD' SPEGT1mmCol = 'CE' SPECountCol = 'CF' NumValues = 8 Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' BrokenCol = 'BX' NonRotationCol = 'BY' ScratchCol = 'BZ' Cracking3to7Col = 'CA' CrackingGT7Col = 'CB' TrueHazeCol = 'CC' CrazingCol = 'CD' SlipCountCol = 'CE' SPEGT1mmCol = 'CF' SPECountCol = 'CG' NumValues = 8 Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' BrokenCol = 'BT' NonRotationCol = 'BU' ScratchCol = 'BV' Cracking3to7Col = 'BW' CrackingGT7Col = 'BX' TrueHazeCol = 'BY' CrazingCol = 'BZ' SlipCountCol = 'CA' SPEGT1mmCol = 'CB' SPECountCol = 'CC' NumValues = 5 End Case // Write UV values SPEAvg = 0 For each Row in UVData using @FM setting fPos Parameter = Row<0, 1> Pocket = Row<0, 2> Value = Row<0, 3> Begin Case Case Parameter EQ 'UV Broken' Col = BrokenCol Case Parameter EQ 'UV Non-rotation' Col = NonRotationCol Case Parameter EQ 'UV Scratch (count)' Col = ScratchCol Case Parameter EQ 'UV Cracking (3-7mm)' Col = Cracking3to7Col Case Parameter EQ 'UV Cracking (>7mm)' Col = CrackingGT7Col Case Parameter EQ 'UV True Haze' Col = TrueHazeCol Case Parameter EQ 'UV Crazing' Col = CrazingCol Case Parameter EQ 'UV Slip (count)' Col = SlipCountCol Case Parameter EQ 'UV-SPE (>1mm) count' Col = SPEGT1mmCol Case Parameter EQ 'UV-SPE (count)' Col = SPECountCol SPEAvg += Value Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + Pocket - 1 Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then If SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' then // Write SPE Avg If NumValues GT 0 then SPEAvg = SPEAvg / NumValues RowIndex = SpreadsheetRowIndex + NumValues Excel_Services('SetCellValue', DocObj, WorksheetName, SPECountCol, RowIndex, SPEAvg) end Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. UV data missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostCANData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then CandelaData = Engineering_Services('GetCandelaData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = CandelaData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( (CandelaData NE '') and (CandelaData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' PitsCol = 'AD' LPDSmallCol = 'AE' LPDMedCol = 'AF' LPDLargeCol = 'AG' SPECol = 'AH' SpiralsCol = 'AI' CraterCol = 'AJ' CrackingAcceptCol = 'AK' CrackingCol = 'AL' TotalDefectsCol = '' ; // Currently not being recorded in spreadsheet Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' PitsCol = 'AE' LPDSmallCol = 'AF' LPDMedCol = 'AG' LPDLargeCol = 'AH' SPECol = 'AI' SpiralsCol = 'AJ' CraterCol = 'AK' CrackingAcceptCol = 'AL' CrackingCol = 'AM' TotalDefectsCol = '' ; // Currently not being recorded in spreadsheet Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' PitsCol = 'AL' LPDSmallCol = 'AJ' LPDMedCol = 'AI' LPDLargeCol = 'AH' SPECol = 'AG' SpiralsCol = 'AM' CraterCol = 'AK' CrackingAcceptCol = 'AO' CrackingCol = 'AN' TotalDefectsCol = 'AP' AvgRowOffset = 5 End Case // Write Candela values CrackingAvg = 0 NumCrackingVals = 0 CrackingAccAvg = 0 NumCrackingAccVals = 0 CraterAvg = 0 NumCraterVals = 0 LPDLargeAvg = 0 NumLPDLargeVals = 0 LPDMedAvg = 0 NumLPDMedVals = 0 LPDSmallAvg = 0 NumLPDSmallVals = 0 PitsAvg = 0 NumPitsVals = 0 SPEAvg = 0 NumSPEVals = 0 SpiralsAvg = 0 NumSpiralsVals = 0 CanTotDefAvg = 0 NumCanTotDefVals = 0 For each Row in CandelaData using @FM setting fPos Parameter = Row<0, 1> Pocket = Row<0, 2> Value = Row<0, 3> Begin Case Case Parameter EQ 'Candela Cracking' Col = CrackingCol CrackingAvg += Value NumCrackingVals += 1 Case Parameter EQ 'Candela Cracking Acceptable' Col = CrackingAcceptCol CrackingAccAvg += Value NumCrackingAccVals += 1 Case Parameter EQ 'Candela Crater' Col = CraterCol CraterAvg += Value NumCraterVals += 1 Case Parameter EQ 'Candela LPD Large' Col = LPDLargeCol LPDLargeAvg += Value NumLPDLargeVals += 1 Case Parameter EQ 'Candela LPD Medium' Col = LPDMedCol LPDMedAvg += Value NumLPDMedVals += 1 Case Parameter EQ 'Candela LPD Small' Col = LPDSmallCol LPDSmallAvg += Value NumLPDSmallVals += 1 Case Parameter EQ 'Candela Pits' Col = PitsCol PitsAvg += Value NumPitsVals += 1 Case Parameter EQ 'Candela SPE' Col = SPECol SPEAvg += Value NumSPEVals += 1 Case Parameter EQ 'Candela Spirals' Col = SpiralsCol SpiralsAvg += Value NumSpiralsVals += 1 Case Parameter EQ 'Candela Total Defects' Col = TotalDefectsCol CanTotDefAvg += Value NumCanTotDefVals += 1 Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + Pocket - 1 Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then If SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' then // Calculate averages If NumCrackingVals GT 0 then CrackingAvg = CrackingAvg / NumCrackingVals If NumCrackingAccVals GT 0 then CrackingAccAvg = CrackingAccAvg / NumCrackingAccVals If NumCraterVals GT 0 then CraterAvg = CraterAvg / NumCraterVals If NumLPDLargeVals GT 0 then LPDLargeAvg = LPDLargeAvg / NumLPDLargeVals If NumLPDMedVals GT 0 then LPDMedAvg = LPDMedAvg / NumLPDMedVals If NumLPDSmallVals GT 0 then LPDSmallAvg = LPDSmallAvg / NumLPDSmallVals If NumPitsVals GT 0 then PitsAvg = PitsAvg / NumPitsVals If NumSPEVals GT 0 then SPEAvg = SPEAvg / NumSPEVals If NumSpiralsVals GT 0 then SpiralsAvg = SpiralsAvg / NumSpiralsVals If NumCanTotDefVals GT 0 then CanTotDefAvg = CanTotDefAvg / NumCanTotDefVals // Write averages RowIndex = SpreadsheetRowIndex + AvgRowOffset Excel_Services('SetCellValue', DocObj, WorksheetName, CrackingCol, RowIndex, CrackingAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, CrackingAcceptCol, RowIndex, CrackingAccAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, CraterCol, RowIndex, CraterAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, LPDLargeCol, RowIndex, LPDLargeAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, LPDMedCol, RowIndex, LPDMedAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, LPDSmallCol, RowIndex, LPDSmallAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, PitsCol, RowIndex, PitsAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, SPECol, RowIndex, SPEAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, SpiralsCol, RowIndex, SpiralsAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, TotalDefectsCol, RowIndex, CanTotDefAvg) end Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':TempPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Candela data for Run ID ':GaNRunID:' is not available in IQS at this time.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service Service PostWARPData(RDSNo) DocObj = '' ErrorMessage = '' FileHandle = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) GaNRunID = ReactRunRec WONo = ReactRunRec Reactor = ReactRunRec SpreadsheetRowIndex = ReactRunRec RunRecipe = ReactRunRec SpreadsheetInfo = Engineering_Services('GetSpreadSheetInfo', RDSNo) SpreadsheetName = SpreadsheetInfo<1> WorksheetName = SpreadsheetInfo<2> SpreadsheetPW = SpreadsheetInfo<3> SpreadsheetDir = SpreadsheetInfo<4> Offset = SpreadsheetInfo<5> If SpreadsheetRowIndex NE '' then If GaNRunID NE '' then WarpData = Engineering_Services('GetWARPData', RDSNo) // Log SQL response LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = WarpData Logging_Services('AppendLog', objSQLLog, LogData, @RM, @FM) If ( Error_Services('NoError') and (WarpData NE '') and (WarpData NE 0) ) then DocumentPath = SpreadsheetDir:SpreadsheetName FileHandle = File_Services('LockFile', DocumentPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) If FileHandle NE FILE_ERROR$ then // Make a temporary backup in case the Excel file fails to save and becomes corrupted Datetime = OConv(Datetime(), 'DT') Swap ' ' with '-' in Datetime Swap ':' with ';' in Datetime TempFilename = GaNRunID:'-':Datetime:'.xlsx' TempDirectory = Str(\00\, 1024) GetTempPath(Len(TempDirectory), TempDirectory) Convert \00\ to '' in TempDirectory TempPath = TempDirectory:TempFilename File_Services('CopyFile', DocumentPath, TempPath) DocObj = Excel_Services('OpenDocument', TempPath, SpreadsheetPW) If Error_Services('NoError') then // Verify spreadsheet row index is correct RunIDCellText = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', SpreadsheetRowIndex) RowRunID = RunIDCellText[1, 12] If RowRunID EQ GaNRunID then Begin Case Case SpreadsheetName EQ 'MV_R71_6-inch Epi Development.xlsx' WarpCol = 'AM' BowCol = 'AN' AvgRow = SpreadsheetRowIndex + 10 RangeRow = SpreadsheetRowIndex + 11 Case SpreadsheetName EQ 'HV_R71_6-inch Epi Development.xlsx' WarpCol = 'AN' BowCol = 'AO' AvgRow = SpreadsheetRowIndex + 10 RangeRow = SpreadsheetRowIndex + 11 Case SpreadsheetName EQ '8-inch New HV Epi Development.xlsx' WarpCol = 'AQ' BowCol = 'AR' AvgRow = SpreadsheetRowIndex + 6 RangeRow = SpreadsheetRowIndex + 7 Excel_Services('SetCellValue', DocObj, WorksheetName, BowCol, (RangeRow + 2), 'BowCenter') End Case // Write Warp values BowMin = '' BowMax = '' WarpMin = '' WarpMax = '' BowTotal = 0 WarpTotal = 0 NumWarpVals = 0 NumBowVals = 0 For each Row in WarpData using @FM setting fPos Parameter = Row<0, 1> Pocket = Row<0, 2> Value = Row<0, 3> Begin Case Case ( (Parameter EQ 'Bow') or (Parameter EQ 'BowCenter') ) Col = BowCol BowTotal += Value If BowMin EQ '' then BowMin = Value If BowMax EQ '' then BowMax = Value If Value LT BowMin then BowMin = Value end If Value GT BowMax then BowMax = Value end NumBowVals += 1 Case Parameter EQ 'Warp' Col = WarpCol WarpTotal += Value If WarpMin EQ '' then WarpMin = Value If WarpMax EQ '' then WarpMax = Value If Value LT WarpMin then WarpMin = Value end If Value GT WarpMax then WarpMax = Value end NumWarpVals += 1 Case Otherwise$ ErrorMessage = 'Error in service ':Service:'. Unrecognized parameter ':Parameter:'.' End Case Until ErrorMessage NE '' RowIndex = SpreadsheetRowIndex + Pocket - 1 Excel_Services('SetCellValue', DocObj, WorksheetName, Col, RowIndex, Value) Next Row If ErrorMessage EQ '' then BowRange = BowMax - BowMin WarpRange = WarpMax - WarpMin If NumBowVals GT 0 then BowAvg = BowTotal / NumBowVals If NumWarpVals GT 0 then WarpAvg = WarpTotal / NumWarpVals Excel_Services('SetCellValue', DocObj, WorksheetName, WarpCol, AvgRow, WarpAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, WarpCol, RangeRow, WarpRange) Excel_Services('SetCellValue', DocObj, WorksheetName, BowCol, AvgRow, BowAvg) Excel_Services('SetCellValue', DocObj, WorksheetName, BowCol, RangeRow, BowRange) Excel_Services('SaveDocument', DocObj, TempPath, SpreadsheetPW) If Error_Services('NoError') then TempFileHandle = File_Services('LockFile', TempPath, GENERIC_WRITE$, FILE_SHARE_READ$, OPEN_EXISTING$) TempFileHandleCopy = TempFileHandle TempFileSize = 0 If FileHandle NE FILE_ERROR$ then // We were able to get the lock TempFileSize = File_Services('GetFileSize', TempFileHandle) File_Services('UnlockFile', TempFileHandle) end Begin Case Case TempFileHandleCopy EQ FILE_ERROR$ // Failed to lock file again to verify file size (i.e. that the save operation worked) ErrorMessage = 'Error in ':Service:' service. Failed to lock document ':TempPath:' to verify the save operation was successful.' Case TempFileSize EQ 0 // Save failed - file corrupted ErrorMessage = 'Error in ':Service:' service. File size equal to zero. Document ':TempPath:' failed to save.' Case Otherwise$ // Save successful, so copy temp file back to document (PROD) path. File_Services('UnlockFile', FileHandle) CopySucceeded = File_Services('CopyFile', TempPath, DocumentPath) If CopySucceeded EQ False$ then ErrorMessage = 'Error in ':Service:' service. Failed to copy ':TempPath:' to ':DocumentPath:'.' end End Case end else // SaveDocument call failed. Get internal error for logging purposes. ErrorMessage = Error_Services('GetMessage') end end end else // Row index did not match. Log error. ErrorMessage = 'Error in ':Service:' service. Run ID in row ':SpreadsheetRowIndex ErrorMessage := ' column A in 'SpreadsheetName:' worksheet ':WorksheetName ErrorMessage := ' did not match GaNRunID ':GaNRunID:' in REACT_RUN record ':RDSNo:'.' Excel_Services('CloseDocument', DocObj) end end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file could not be opened by Excel_Services.' end OSDelete TempPath end else ErrorMessage = 'Error in ':Service:' service. ':DocumentPath:' file is in use an cannot be updated at this time.' end end else ErrorMessage = 'Error in ':Service:' service. WARP data is missing in IQS.' end end else ErrorMessage = 'Error in ':Service:' service. Run ID for RDS ':RDSNo:' is null.' end end else ErrorMessage = 'Error in ':Service:' service. No Excel row index found for RDS ':RDSNo:' - Run ID ':GaNRunID:'.' end end else ErrorMessage = 'Error in ':Service:' service. RDSNo is null.' end If DocObj NE '' then Excel_Services('CloseDocument', DocObj) If ( (FileHandle NE '') and (FileHandle NE FILE_ERROR$) ) then File_Services('UnlockFile', FileHandle) If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) end service //---------------------------------------------------------------------------------------------------------------------- // GetAFMData // // //---------------------------------------------------------------------------------------------------------------------- Service GetAFMData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = "SELECT td.F_NAME, dd.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'AFM Pit Count' or td.F_NAME = 'AFM Roughness') AND " Query := " dd.F_DSGP = 1342510661 AND " Query := "dd.F_NAME IS NOT NULL AND " Query := "sd.F_SGRP = " Query := "(SELECT MAX(sd.F_SGRP) " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'AFM Pit Count' or td.F_NAME = 'AFM Roughness') AND " Query := " dd.F_DSGP = 1342510661 AND dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME" If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetUVData // // //---------------------------------------------------------------------------------------------------------------------- Service GetUVData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_TSNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'UV Broken' or td.F_NAME = 'UV Cracking (>7mm)' or " Query := " td.F_NAME = 'UV Cracking (3-7mm)' or td.F_NAME = 'UV Crazing' or " Query := " td.F_NAME = 'UV Non-rotation' or td.F_NAME = 'UV Scratch (count)' or " Query := " td.F_NAME = 'UV Slip (count)' or td.F_NAME = 'UV-SPE (>1mm) count' or " Query := " td.F_NAME = 'UV-SPE (count)' or td.F_NAME = 'UV True Haze') AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'UV Broken' or td.F_NAME = 'UV Cracking (>7mm)' or td.F_NAME = 'UV Cracking (3-7mm)' or " Query := " td.F_NAME = 'UV Crazing' or td.F_NAME = 'UV Non-rotation' or td.F_NAME = 'UV Scratch (count)' or " Query := " td.F_NAME = 'UV Slip (count)' or td.F_NAME = 'UV-SPE (>1mm) count' or td.F_NAME = 'UV-SPE (count)' or " Query := " td.F_NAME = 'UV True Haze') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_TSNO" If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetRPMData // // //---------------------------------------------------------------------------------------------------------------------- Service GetRPMData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Epi Thickness Mean' or td.F_NAME = 'Epi Thickness Std Dev %') AND " Query := " dd.F_DSGP = 1337859646 AND " Query := " dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Epi Thickness Mean' or td.F_NAME = 'Epi Thickness Std Dev %') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME" If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetPLData // // //---------------------------------------------------------------------------------------------------------------------- Service GetPLData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'PL Ratio' or td.F_NAME = 'BandEdge_V' or td.F_NAME = 'YellowBand_V') AND " Query := " dd.F_DSGP = 1337859646 AND " Query := " dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'PL Ratio' or td.F_NAME = 'BandEdge_V' or " Query := " td.F_NAME = 'YellowBand_V') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME" If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetPRData // // //---------------------------------------------------------------------------------------------------------------------- Service GetPRData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') EpiPartNo = Xlate('REACT_RUN', RDSNo, 'EPI_PART_NO', 'X') WfrSize = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X') If WfrSize EQ '200 mm 8 in' then Query = "SELECT td.F_NAME, se.F_SBNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND pr.F_NAME = '":Reactor:"' " Query := " AND pl.F_NAME = '":RunNo:"' AND se.F_FLAG = 0 " Query := " AND (td.F_NAME = 'Barrier_Composition_RPM_XY' or td.F_NAME = 'Y-Coord') " Query := " AND dd.F_DSGP = 1337859646 " Query := " AND dd.F_NAME IS NOT NULL " Query := " AND se.F_SGRP = " Query := " (SELECT TOP 1 se.F_SGRP " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND pr.F_NAME = '":Reactor:"' AND pl.F_NAME = '":RunNo:"' " Query := " AND se.F_FLAG = 0 AND (td.F_NAME = 'Barrier_Composition_RPM_XY' or td.F_NAME = 'Y-Coord') " Query := " AND dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_SBNO DESC" end else Query = "SELECT td.F_NAME, se.F_SBNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'PR Peak' or td.F_NAME = 'PR Barrier Composition') AND " Query := " dd.F_DSGP = 1337859592 AND " Query := " dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'PR Peak' or td.F_NAME = 'PR Barrier Composition') AND " Query := " dd.F_DSGP = 1337859592 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_SBNO DESC" end If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetWARPData // // //---------------------------------------------------------------------------------------------------------------------- Service GetWARPData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') EpiPartNo = Xlate('REACT_RUN', RDSNo, 'EPI_PART_NO', 'X') WfrSize = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_TSNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Warp' " If WfrSize EQ '200 mm 8 in' then Query := "or td.F_NAME = 'BowCenter') AND " end else Query := "or td.F_NAME = 'Bow') AND " end Query := " dd.F_DSGP = 1337859646 AND " Query := " dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Warp' " If WfrSize EQ '200 mm 8 in' then Query := "or td.F_NAME = 'BowCenter') AND " end else Query := "or td.F_NAME = 'Bow') AND " end Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME" If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetCandelaData // // //---------------------------------------------------------------------------------------------------------------------- Service GetCandelaData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec EpiPartNo = Xlate('REACT_RUN', RDSNo, 'EPI_PART_NO', 'X') WfrSize = Xlate('EPI_PART', EpiPartNo, 'SUB_WAFER_SIZE', 'X') PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_TSNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Candela Cracking' or td.F_NAME = 'Candela Cracking Acceptable' or " Query := " td.F_NAME = 'Candela Crater' or td.F_NAME = 'Candela LPD Large' or " Query := " td.F_NAME = 'Candela LPD Medium' or td.F_NAME = 'Candela LPD Small' or " Query := " td.F_NAME = 'Candela Pits' or td.F_NAME = 'Candela SPE' or " Query := " td.F_NAME = 'Candela Spirals' " If WfrSize EQ '200 mm 8 in' then Query := "or td.F_NAME = 'Candela Total Defects') AND " end else Query := ") AND " end Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 " Query := " AND (td.F_NAME = 'Candela Cracking' or td.F_NAME = 'Candela Cracking Acceptable' or td.F_NAME = 'Candela Crater' or " Query := " td.F_NAME = 'Candela LPD Large' or td.F_NAME = 'Candela LPD Medium' or td.F_NAME = 'Candela LPD Small' or td.F_NAME = 'Candela Pits' or " Query := " td.F_NAME = 'Candela SPE' or td.F_NAME = 'Candela Spirals' " If WfrSize EQ '200 mm 8 in' then Query := "or td.F_NAME = 'Candela Total Defects') AND " end else Query := ") AND " end Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetXRDAlumData // // //---------------------------------------------------------------------------------------------------------------------- Service GetXRDAlumData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, dd.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Al% B.B.' or td.F_NAME = 'Al% Barrier' or td.F_NAME = 'Al% SLS' or " Query := " td.F_NAME = 'Al% TL1' or td.F_NAME = 'SL Period') AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Al% B.B.' or td.F_NAME = 'Al% Barrier' or " Query := " td.F_NAME = 'Al% SLS' or td.F_NAME = 'Al% TL1' or td.F_NAME = 'SL Period') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_SBNO" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetXRDThicknessData // // //---------------------------------------------------------------------------------------------------------------------- Service GetXRDThicknessData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, dd.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'XRR Thickness (nm)' or td.F_NAME = 'FWHM 006' or " Query := " td.F_NAME = 'FWHM 105') AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'XRR Thickness (nm)' or td.F_NAME = 'FWHM 006' or " Query := " td.F_NAME = 'FWHM 105') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_SBNO" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetXRDWtAvgData // // //---------------------------------------------------------------------------------------------------------------------- Service GetXRDWtAvgData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, dd.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Al% B.B. WTAVG' or " Query := " td.F_NAME = 'Al% Barrier WTAVG' or td.F_NAME = 'Al% SLS WTAVG' or " Query := " td.F_NAME = 'Al% TL1 WTAVG' or td.F_NAME = 'SL Period WTAVG') AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Al% B.B. WTAVG' or " Query := " td.F_NAME = 'Al% Barrier WTAVG' or td.F_NAME = 'Al% SLS WTAVG' or " Query := " td.F_NAME = 'Al% TL1 WTAVG' or td.F_NAME = 'SL Period WTAVG') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_SBNO" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetXRDCoordData // // //---------------------------------------------------------------------------------------------------------------------- Service GetXRDXCoordData(RDSNo) Response = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, dd.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " td.F_NAME = 'X-Coord' AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND se.F_SBNO > 0 AND " Query := " sd.F_TRTM = " Query := " (SELECT MAX(sd.F_TRTM) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND td.F_NAME = 'X-Coord' AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL)" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetXRDCoordData // // //---------------------------------------------------------------------------------------------------------------------- Service GetXRDYCoordData(RDSNo) Response = '' If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, dd.F_NAME, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " td.F_NAME = 'Y-Coord' AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND se.F_SBNO > 0 AND " Query := " sd.F_TRTM = " Query := " (SELECT MAX(sd.F_TRTM) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND td.F_NAME = 'Y-Coord' AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL)" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetBVData // // //---------------------------------------------------------------------------------------------------------------------- Service GetBVData(RDSNo, Parameter=BV_PARAMETERS) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " td.F_NAME = '":Parameter:"' AND " Query := " dd.F_DSGP = 1337859646 AND " Query := "dd.F_NAME IS NOT NULL " Query := "AND sd.F_SGRP = " Query := "(SELECT MIN(sd.F_SGRP) " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND td.F_NAME = '":Parameter:"' AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL)" If Query NE '' then Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // GetHallData // // //---------------------------------------------------------------------------------------------------------------------- Service GetHallData(RDSNo) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RunNo = ReactRunRec Reactor = 'R':ReactRunRec PartNo = Xlate('REACT_RUN', RDSNo, 'WFR_TRACK_PART', 'X') Query = '' Query = "SELECT td.F_NAME, se.F_SBNO, se.F_VAL " Query := "FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := "JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := "JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := "JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := "JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := "JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := "LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := "WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Hall Rs' or td.F_NAME = 'Mobility' or " Query := " td.F_NAME = 'Sheet Concentration') AND " Query := " dd.F_DSGP = 1337859646 AND dd.F_NAME IS NOT NULL AND " Query := " sd.F_SGRP = " Query := " (SELECT MAX(sd.F_SGRP) " Query := " FROM [IRMNSPC].[dbo].[SGRP_EXT] se " Query := " JOIN [IRMNSPC].[dbo].[PART_LOT] pl on se.F_LOT = pl.F_LOT " Query := " JOIN [IRMNSPC].[dbo].[TEST_DAT] td on se.F_TEST = td.F_TEST " Query := " JOIN [IRMNSPC].[dbo].[PART_DAT] pd on se.F_PART = pd.F_PART " Query := " JOIN [IRMNSPC].[dbo].[PRCS_DAT] pr on se.F_PRCS = pr.F_PRCS " Query := " JOIN [IRMNSPC].[dbo].[SGRP_DSC] sd on se.F_SGRP = sd.F_SGRP " Query := " LEFT JOIN [IRMNSPC].[dbo].[DESC_DAT] dd on sd.F_DESC = dd.F_DESC " Query := " WHERE pd.F_NAME = '":PartNo:"' AND " Query := " pr.F_NAME = '":Reactor:"' AND " Query := " pl.F_NAME = '":RunNo:"' AND " Query := " se.F_FLAG = 0 AND " Query := " (td.F_NAME = 'Hall Rs' or td.F_NAME = 'Mobility' or " Query := " td.F_NAME = 'Sheet Concentration') AND " Query := " dd.F_DSGP = 1337859646 and dd.F_NAME IS NOT NULL) " Query := "ORDER BY td.F_NAME, se.F_SBNO" Response = SQL_Services('PostSQLRequest', 'IQSDMS1', Query) Convert @FM to @VM in Response Convert @RM to @FM in Response end end end service //---------------------------------------------------------------------------------------------------------------------- // UpdateExcelIndexes // // //---------------------------------------------------------------------------------------------------------------------- Service UpdateExcelIndexes() StartRow = 5 ; // All spreadsheets use the first four rows for header information SpreadsheetInfo = Engineering_Services('GetSpreadSheets') SpreadsheetNames = SpreadsheetInfo<1> WorksheetNames = SpreadsheetInfo<2> SpreadsheetPWs = SpreadsheetInfo<3> SpreadsheetDirs = SpreadsheetInfo<4> Offsets = SpreadsheetInfo<5> hDict = Database_Services('GetTableHandle', 'DICT.REACT_RUN') If Error_Services('NoError') then For each SpreadSheetName in SpreadsheetNames using @VM setting sPos WorksheetName = WorksheetNames<0, sPos> SpreadsheetPW = SpreadsheetPWs<0, sPos> SpreadSheetDir = SpreadsheetDirs<0, sPos> Offset = Offsets<0, sPos> DocumentPath = SpreadsheetDir:SpreadsheetName DocObj = Excel_Services('OpenDocument', DocumentPath, SpreadsheetPW) If Error_Services('NoError') then // Process Spreadsheet MaxValidRow = '' NumExcelRows = Excel_Services('GetNumRows', DocObj, WorksheetName) StartRow = (NumExcelRows - (30 * Offset) ) If StartRow LT 5 then StartRow = 5 If Error_Services('NoError') then Row = StartRow RunIDRow = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', Row) ExcelRunID = RunIDRow[1, 12] RunNo = ExcelRunID[1, 7] PrevRunNo = RunNo Row += 1 Loop RunIDRow = Excel_Services('GetCellValue', DocObj, WorksheetName, 'A', Row) ExcelRunID = RunIDRow[1, 12] RunNo = ExcelRunID[1, 7] ValidRunID = ( (ExcelRunID Matches "'69'5N'hvfet'") or (ExcelRunID Matches "'69'5N'mvfet'") or (ExcelRunID Matches "'71'5N'hvfet'") or (ExcelRunID Matches "'71'5N'mvfet'") ) If ( (ValidRunID EQ True$) and (RunNo NE PrevRunNo) ) then MaxValidRow = Row GoSub ClearCursors Query = 'GAN_RUN_ID' : @VM : ExcelRunID : @FM RDSNo = '' Option = '' Flag = '' Btree.Extract(Query, 'REACT_RUN', hDict, RDSNo, Option, Flag) If RDSNo NE '' then ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) If Error_Services('NoError') then RRIndex = ReactRunRec If RRIndex NE Row then ReactRunRec = Row Database_Services('WriteDataRow', 'REACT_RUN', RDSNo, ReactRunRec, True$, False$, True$) end end end end Row += 1 PrevRunNo = RunNo Until Row GT NumExcelRows Repeat end // Update APP_INFO table containing max row counters NextValidRow = MaxValidRow + Offset Database_Services('WriteDataRow', 'APP_INFO', WorksheetName, NextValidRow, True$, False$, True$) Excel_Services('CloseDocument', DocObj) end else ErrMsg = Error_Services('GetMessage') end Next SpreadSheetName end end service //---------------------------------------------------------------------------------------------------------------------- // PostEARequest // // Input: // RDSNo - [Required] // Stage - [Required] // WfrID - [Optional] // ToolID - [Optional] // //---------------------------------------------------------------------------------------------------------------------- Service PostEARequest(RDSNo, Stage=STAGES, WfrID, ToolID) If ( (RDSNo NE '') and (Stage NE '') ) then ErrorMessage = '' LogData = '' LogData<1> = LoggingDTM LogData<2> = RDSNo LogData<3> = Stage // Look for a pre-existing request in the queue hDict = Database_Services('GetTableHandle', 'DICT.EA_REQUESTS') If Error_Services('NoError') then RequestKeyID = '' Query = 'RDS_NO' : @VM : RDSNo : @FM : 'STAGE' : @VM : Stage : @FM Option = '' Flag = '' Btree.Extract(Query, 'EA_REQUESTS', hDict, RequestKeyID, Option, Flag) If RequestKeyID EQ '' then // This is a new request RequestDate = Date() RequestTime = Time() RequestKeyID = RDSNo:'*':Stage:'*':RequestDate :'*':RequestTime RequestRow = '' RequestRow = WfrID RequestRow = ToolID Database_Services('WriteDataRow', 'EA_REQUESTS', RequestKeyID, RequestRow, False$, False$, False$) LogData<4> = 'EA request posted' end else LogData<4> = 'Duplicate EA request found, request ignored.' end Logging_Services('AppendLog', QueueObjLog, LogData, @RM, @FM) end end else Error_Services('Add', 'Null parameter passed into service call. All parameters are required.') end end service //---------------------------------------------------------------------------------------------------------------------- // ProcessEARequests // //---------------------------------------------------------------------------------------------------------------------- Service ProcessEARequests() hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then Tablename = 'EA_REQUESTS' hEARequests = Database_Services('GetTableHandle', Tablename) If Error_Services('NoError') then Sentence = 'SELECT ':Tablename:' BY RESPONSE_DATE BY RESPONSE_TIME BY REQUEST_DATE BY REQUEST_TIME' Set_Status(0) GoSub ClearCursors RList(Sentence, TARGET_ACTIVELIST$, '', '', '') // Just process one request at a time so that this service doesn't tie up an OEngine for too long. ReadNext RequestKeyID then Lock hEARequests, RequestKeyID then RequestRow = Database_Services('ReadDataRow', 'EA_REQUESTS', RequestKeyID) RDSNo = Field(RequestKeyID, '*', 1) Stage = Field(RequestKeyID, '*', 2) * If ( (RDSNo EQ 463119) and (Stage EQ 'GROWTH') ) then debug WfrID = RequestRow ToolID = RequestRow RDSClosed = False$ ; //Xlate('REACT_RUN', RDSNo, REACT_RUN_DISP_COMPLETE$, 'X') If RDSClosed EQ True$ then // No need to process this request // Request was successful, so remove the request from the queue Database_Services('DeleteDataRow', 'EA_REQUESTS', RequestKeyID, True$) LogData = '' LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') LogData<2> = RDSNo LogData<3> = Stage LogData<4> = 'Run closed. Deleting EA request from queue.' Logging_Services('AppendLog', QueueObjLog, LogData, @RM, @FM) end else If Stage EQ 'GROWTH' then // Ensure this GROWTH request is the oldest GROWTH request (i.e. ensure the GROWTH requests // are processed in order). Sentence = 'SELECT ':Tablename:' WITH STAGE EQ "GROWTH" BY REQUEST_DATE BY REQUEST_TIME' Set_Status(0) GoSub ClearCursors RList(Sentence, TARGET_ACTIVELIST$, '', '', '') ReadNext GrowthKeyID then If GrowthKeyID NE RequestKeyID then // This is not the oldest GROWTH request. Push this request to the back of the queue. Error_Services('Add', 'Older GROWTH request found in queue. Pushing this request to back of queue.') end end end If Error_Services('NoError') then Engineering_Services('ProcessEARequest', RDSNo, Stage, WfrID, ToolID) If Error_Services('NoError') then // Request was successful, so remove the request from the queue Database_Services('DeleteDataRow', 'EA_REQUESTS', RequestKeyID, True$) LogData = '' LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') LogData<2> = RDSNo LogData<3> = Stage LogData<4> = 'Request successfully processed. Deleting EA request from queue.' Logging_Services('AppendLog', QueueObjLog, LogData, @RM, @FM) end else ErrorMsg = Error_Services('GetMessage') LogData = '' LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') LogData<2> = RDSNo LogData<3> = Stage LogData<4> = 'Request failed to process. Error message: ':ErrorMsg Logging_Services('AppendLog', QueueObjLog, LogData, @RM, @FM) // Keep request in the queue (i.e. do not delete it) RequestRow = Time() RequestRow = Date() RequestRow = ErrorMsg Database_Services('WriteDataRow', 'EA_REQUESTS', RequestKeyID, RequestRow, True$, False$, True$) Unlock hEARequests, RequestKeyID else Error_Services('Add', 'Error unlocking ':RequestKeyID:', ':Tablename:' within ':Service) end end end else ErrorMsg = Error_Services('GetMessage') LogData = '' LogData<1> = Oconv(Date(), 'D4/') : ' ' : Oconv(Time(), 'MTS') LogData<2> = RDSNo LogData<3> = Stage LogData<4> = 'Request failed to process. Error message: ':ErrorMsg Logging_Services('AppendLog', QueueObjLog, LogData, @RM, @FM) // Keep request in the queue (i.e. do not delete it) RequestRow = Time() RequestRow = Date() RequestRow = ErrorMsg Database_Services('WriteDataRow', 'EA_REQUESTS', RequestKeyID, RequestRow, True$, False$, True$) Unlock hEARequests, RequestKeyID else Error_Services('Add', 'Error unlocking ':RequestKeyID:', ':Tablename:' within ':Service) end end end end end end else ErrorMsg = Error_Services('GetMessage') end Unlock hSysLists, ServiceKeyID else Null end end service //---------------------------------------------------------------------------------------------------------------------- // ProcessEARequest // // Input: // RDSNo - [Required] // Stage - [Required] // WfrID - [Optional] // ToolID - [Optional] // //---------------------------------------------------------------------------------------------------------------------- Service ProcessEARequest(RDSNo, Stage, WfrID, ToolID) If ( (RDSNo NE '') and (Stage NE '') ) then Begin Case Case Stage EQ 'CHAR' Engineering_Services('PostCHARData', RDSNo) Case Stage EQ 'GROWTH' Engineering_Services('PostGrowthData', RDSNo) Case ( (Stage EQ 'UV') or (Stage EQ 'UV_PRE') or (Stage EQ 'UV_PST') ) Engineering_Services('PostUVData', RDSNo) Case Stage EQ 'WARP' Engineering_Services('PostWARPData', RDSNo) Case ( (Stage EQ 'CAN') or (Stage EQ 'CAN_PRE') or (Stage EQ 'CAN_PST') ) Engineering_Services('PostCANData', RDSNo) Case Stage EQ 'XRD' Engineering_Services('PostXRDData', RDSNo) Case Stage EQ 'AFM' Engineering_Services('PostAFMData', RDSNo) Case Stage EQ 'RPM' Engineering_Services('PostRPMData', RDSNo) Case Stage EQ 'PR' Engineering_Services('PostPRData', RDSNo) Case Stage EQ 'BV' Engineering_Services('PostBVData', RDSNo) Case ( (Stage EQ 'HALL') or (Stage EQ 'RTA_HALL') or (Stage EQ 'HALL_PGAN') ) Engineering_Services('PostHALLData', RDSNo) End Case end else Error_Services('Add', 'Null RDSNo passed into service ':Service:'.') end end service //---------------------------------------------------------------------------------------------------------------------- // ClearEARequests // // Input: // RDSNo - [Required] // //---------------------------------------------------------------------------------------------------------------------- Service ClearEARequests(RDSNo) If RDSNo NE ''then LogData = '' LogData<1> = LoggingDTM LogData<2> = RDSNo // Look for a pre-existing request in the queue hDict = Database_Services('GetTableHandle', 'DICT.EA_REQUESTS') If Error_Services('NoError') then RequestKeyIDs = '' Query = 'RDS_NO' : @VM : RDSNo : @FM Option = '' Flag = '' Btree.Extract(Query, 'EA_REQUESTS', hDict, RequestKeyIDs, Option, Flag) If RequestKeyIDs NE '' then LogKeys = RequestKeyIDs Swap @VM with ',' in LogKeys LogData<3> = 'Removing the following requests from the queue: ':LogKeys For each RequestKeyID in RequestKeyIDs using @VM setting vPos Database_Services('DeleteDataRow', 'EA_REQUESTS', RequestKeyID) Next RequestKeyID end Logging_Services('AppendLog', QueueObjLog, LogData, @RM, @FM) end end else Error_Services('Add', 'Null parameter passed into service call. All parameters are required.') end end service Service UpdateAll(RDSNo) ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSNo) WfrIDs = ReactRunRec WfrStages = ReactRunRec EAStages = 'UV,UV_PRE,WARP,CAN,CAN_PRE,UV_PST,CAN_PST,HALL,XRD,AFM,RPM,PR,BV' // All runs must complete the GROWTH stage so simply submit a request for that stage. Engineering_Services('PostEARequest', RDSNo, 'GROWTH') // The remaining stages may or may not be completed, so ensure at least one wafer has completed // the stage before submitting a request. For each Stage in EAStages using ',' StageComp = False$ Locate Stage in WfrStages using @VM setting vPos then For each WfrID in WfrIDs using @VM FormattedWfrID = WfrID Swap '*' with '.' in FormattedWfrID RunStageWfrID = RDSNo:'*':Stage:'*':FormattedWfrID StageStatus = Xlate('RUN_STAGE_WFR', RunStageWfrID, 'STATUS', 'X') StageComp = (StageStatus EQ 'COMP') Until StageComp EQ True$ Next WfrID end If StageComp EQ True$ then Engineering_Services('PostEARequest', RDSNo, Stage) Next Stage end service Service GetQueueReport(Stage) Sentence = 'SELECT EA_REQUESTS WITH STAGE EQ "':Stage:'"' Set_Status(0) GoSub ClearCursors RList(Sentence, TARGET_ACTIVELIST$, '', '', '') EOF = False$ ReportPath = Environment_Services('GetReportsRootPath') Filename = @User4:' - ':Stage:' - Queue Report.csv' SavePath = ReportPath:'\':Filename ReportText = '' LineNo = 0 Loop ReadNext RequestKeyID else EOF = True$ If RequestKeyID NE '' then LineNo += 1 RDSNo = Field(RequestKeyID, '*', 1) GaNRunID = Xlate('REACT_RUN', RDSNo, 'GAN_RUN_ID', 'X') ReportText = GaNRunID ReportText = RDSNo end Until EOF EQ True$ Repeat Swap @VM with ',' in ReportText Swap @FM with CRLF$ in ReportText OSWrite ReportText to SavePath end service //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ClearCursors: For counter = 0 to 8 ClearSelect counter Next counter return