1474 lines
48 KiB
Plaintext
1474 lines
48 KiB
Plaintext
COMPILE FUNCTION obj_RDS(Method,Parms)
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
/*
|
|
Methods for RDS table
|
|
|
|
08/21/2004 JCH - Initial Coding
|
|
|
|
Properties:
|
|
|
|
Methods:
|
|
|
|
Create(DataStruct) ;* Create new record
|
|
|
|
|
|
*/
|
|
|
|
|
|
DECLARE FUNCTION Get_Status, Msg, Utility, obj_Tables, NextKey, obj_WO_Verify, obj_Prod_Spec, Send_Dyn, obj_RDS_Makeup
|
|
DECLARE FUNCTION obj_RDS2, obj_RDS_Test, obj_WO_Mat, obj_Clean_Insp, obj_PRS_Prop, Database_Services
|
|
DECLARE FUNCTION Logging_Services, Environment_Services, Error_Services, Signature_Services
|
|
DECLARE SUBROUTINE Set_Status, Msg, obj_Tables, Send_Dyn, obj_WO_Step, obj_RDS_Layer, obj_RDS_Test, obj_WM_In
|
|
DECLARE SUBROUTINE Btree.Extract, RDS_React_Run, Environment_Services, Logging_Services, Error_Services, Send_Info
|
|
DECLARE SUBROUTINE SRP_Stopwatch, Database_Services
|
|
|
|
$INSERT MSG_EQUATES
|
|
$INSERT WO_VERIFY_EQU
|
|
$INSERT WO_LOG_EQUATES
|
|
$INSERT RDS_EQUATES
|
|
$INSERT RDS_MAKEUP_EQU
|
|
$INSERT RDS_LAYER_INFO_EQU
|
|
$INSERT QUOTE_SPEC_EQU
|
|
$INSERT PROD_SPEC_EQUATES
|
|
$INSERT SCHEDULE_EQU
|
|
$INSERT WO_STEP_EQU
|
|
$INSERT NCR_EQU
|
|
$INSERT WO_MAT_EQUATES
|
|
$INSERT REACT_RUN_EQUATES
|
|
$INSERT CLEAN_INSP_EQUATES
|
|
$INSERT EPI_PART_EQUATES
|
|
$INSERT WO_REACT_EQUATES
|
|
$INSERT PRS_LAYER_EQU ;* Used to return obj_Prod_Spec values
|
|
$INSERT LOGICAL
|
|
|
|
ErrTitle = 'Error in Stored Procedure "obj_RDS"'
|
|
ErrorMsg = ''
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\RDS'
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' RDS Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'RDS Key ID' : @FM : 'Notes'
|
|
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\RemoveMetrology'
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : '.log'
|
|
Headers = 'Logging DTM' : @FM : 'Results'
|
|
ColumnWidths = 20 : @FM : 50
|
|
objLog2 = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ' ', Headers, ColumnWidths, False$, False$)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_LOG'
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' Release Log.csv'
|
|
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Work Order No' : @FM : 'Notes'
|
|
objReleaseLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, COMMA$, Headers, '', False$, False$)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\RDS'
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' WAFERS_IN.csv'
|
|
Headers = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'WAFERS_IN'
|
|
objWafersLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\RDS'
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' RDS_TEST_DELETE.csv'
|
|
Headers = 'Logging DTM' : @FM : 'RDS Test Key ID' : @FM : 'Message'
|
|
objRDSTestDeleteLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$)
|
|
|
|
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
IF NOT(ASSIGNED(Method)) THEN ErrorMsg = 'Unassigned parameter "Method" passed to subroutine'
|
|
IF NOT(ASSIGNED(Parms)) THEN Parms = ''
|
|
|
|
IF ErrorMsg NE '' THEN
|
|
Set_Status(-1,ErrTitle:@SVM:ErrorMsg)
|
|
RETURN ''
|
|
END
|
|
|
|
Result = ''
|
|
|
|
BEGIN CASE
|
|
CASE Method = 'CurrStatus' ; GOSUB CurrStatus
|
|
CASE Method = 'Create' ; GOSUB Create
|
|
CASE Method = 'VerifySpecInfo' ; GOSUB VerifySpecInfo
|
|
* CASE Method = 'Update' ; GOSUB Update
|
|
CASE Method = 'SchedWfrQty' ; GOSUB SchedWfrQty
|
|
CASE Method = 'TestRejWfrQty' ; GOSUB TestRejWfrQty
|
|
CASE Method = 'MUSrcWfrQty' ; GOSUB MUSrcWfrQty
|
|
CASE Method = 'MUDestWfrQty' ; GOSUB MUDestWfrQty
|
|
CASE Method = 'RemMUWafers' ; GOSUB RemMUWafers
|
|
CASE Method = 'WafersOut' ; GOSUB WafersOut
|
|
CASE Method = 'YieldOutThruput' ; GOSUB YieldOutThruput
|
|
CASE Method = 'WafersPerHour' ; GOSUB WafersPerHour
|
|
CASE Method = 'AddShip' ; GOSUB AddShip
|
|
CASE Method = 'RemShip' ; GOSUB RemShip
|
|
CASE Method = 'RefreshRDSSpec' ; GOSUB RefreshRDSSpec
|
|
CASE Method = 'WMInKeys' ; GOSUB WMInKeys
|
|
CASE Method = 'WMOutKeys' ; GOSUB WMOutKeys
|
|
CASE Method = 'SetSchedWfrQty' ; GOSUB SetSchedWfrQty
|
|
CASE Method = 'MU_ADE_Reads' ; GOSUB MU_ADE_Reads
|
|
CASE Method = 'MetPropFlag' ; GOSUB MetPropFlag
|
|
CASE 1
|
|
Result = obj_RDS2(Method,Parms)
|
|
|
|
END CASE
|
|
|
|
IF ErrorMsg NE '' THEN
|
|
Set_Status(-1,ErrTitle:@SVM:ErrorMsg)
|
|
END
|
|
|
|
RETURN Result
|
|
|
|
|
|
* * * * * * *
|
|
CurrStatus:
|
|
* * * * * * *
|
|
|
|
IF NOT(ASSIGNED(RDSNos)) THEN
|
|
RDSNos = Parms[1,@RM]
|
|
RDSRec = Parms[COL2()+1,@RM]
|
|
END
|
|
|
|
IF RDSNos = '' THEN RETURN ;* 9/9/2014 JCH *** This routine has multiple Keys in with only a single record **** AWS__T! needs to be fixed
|
|
|
|
ReturnVals = ''
|
|
|
|
|
|
RDSCnt = COUNT(RDSNos,@VM) + (RDSNos NE '')
|
|
FOR R = 1 TO RDSCnt
|
|
|
|
NCRStatuses = XLATE('NCR',RDSRec<RDS_NCR_KEYS$>,7,'X')
|
|
|
|
IF INDEX(NCRStatuses,'O',1) THEN
|
|
ReturnVals<1,R> = 'NCR' ;* Open NCR on RDS *
|
|
GOTO StatusHere
|
|
END
|
|
|
|
* ROTR inspection failure check -> Set status to PSTC (PostCleans)
|
|
|
|
RotrAction = XLATE('RDS',RDSNos,'ROTR_ACTION','X')
|
|
|
|
|
|
IF RotrAction = 'F' Then ;* Drive the CURR_STATUS to PostEpi Clean if the ROTR fails
|
|
ReturnVals<1,R> = 'PSTC'
|
|
GOTO StatusHere
|
|
END
|
|
|
|
|
|
* Check for out of spec
|
|
|
|
OutOfSpec = 0 ;
|
|
OutOfSpecThick = ''
|
|
OutOfSpecRes = ''
|
|
|
|
LSKeys = RDSRec<RDS_RDS_LAYER_KEYS$>
|
|
|
|
MetOutOfSpec = SUM(XLATE('RDS_LAYER',LSKeys,'TEST_OUT_OF_SPEC','X')) ;* Updated for Metrology update 4/16/2006 JCH
|
|
|
|
IF MetOutOfSpec > 0 THEN ;* Added check for F(ailed) ROTR_ACTION value.
|
|
ReturnVals<1,R> = 'SPEC' ;* Run is out of spec *
|
|
GOTO StatusHere
|
|
END
|
|
|
|
* Check for Metrology Complete
|
|
|
|
MetComplete = SUM(XLATE('RDS_LAYER',LSKeys,'TEST_MET_COMPLETE','X')) ;* Added with DKK 11/3/2015 JCH
|
|
|
|
IF NOT(MetComplete) THEN ;* Added check for F(ailed) ROTR_ACTION value.
|
|
ReturnVals<1,R> = 'MET' ;* Run is missing metrology *
|
|
GOTO StatusHere
|
|
END
|
|
|
|
|
|
* * * * * * *
|
|
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
WOStepKey = RDSRec<RDS_WO_STEP_KEY$>
|
|
|
|
WOMatRec = XLATE('WO_MAT',WONo:'*':CassNo,'','X')
|
|
|
|
WOStep = FIELD(WOStepKey,'*',2)
|
|
|
|
RDSKeys = ''
|
|
RSCnt = 0
|
|
RunSigProfs = ''
|
|
RunSignatures = ''
|
|
RunSigDTMs = ''
|
|
|
|
WOMatKey = WONo:'*':CassNo
|
|
SigArray = Signature_Services('GetSigProfile', WOMatKey)
|
|
RunSigProfs = SigArray<1>
|
|
RunSignatures = SigArray<2>
|
|
|
|
ProcessStart = 0
|
|
ProcessComp = 0
|
|
|
|
LOOP
|
|
RunSignature = RunSignatures<1,1>
|
|
RunSigProf = RunSigProfs<1,1>
|
|
UNTIL RunSignature = ''
|
|
ProcessStart = 1
|
|
RunSignatures = DELETE(RunSignatures,1,1,0)
|
|
RunSigProfs = DELETE(RunSigProfs,1,1,0)
|
|
REPEAT
|
|
|
|
IF RunSignature = '' AND RunSigProf = '' AND ProcessStart = 1 THEN
|
|
ReturnVals<1,R> = 'COMP'
|
|
GOTO StatusHere
|
|
END ELSE
|
|
ReturnVals<1,R> = RunSigProf[2,20]
|
|
GOTO StatusHere
|
|
END
|
|
|
|
* EpiPRO specific (unload)
|
|
|
|
TestPockets = RDSRec<RDS_POCKET$>
|
|
TestOutCassNos = RDSRec<RDS_OUT_CASS_NO$>
|
|
|
|
CONVERT @VM TO '' IN TestPockets
|
|
CONVERT @VM TO '' IN TestOutCassNos
|
|
|
|
IF TestPockets NE '' AND TestOutCassNos NE '' THEN
|
|
ReturnVals<1,R> = 'COMP' ;* EpiPRO RDS is complete with wafer unload
|
|
END
|
|
|
|
StatusHere:
|
|
|
|
NEXT R
|
|
|
|
Result = ReturnVals
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
* * * * * * *
|
|
Create:
|
|
* * * * * * *
|
|
WONo = Parms[1,@RM]
|
|
WOStep = Parms[COL2()+1,@RM]
|
|
LastStep = Parms[COL2()+1,@RM]
|
|
CassNo = Parms[COL2()+1,@RM]
|
|
QuoteNo = Parms[COL2()+1,@RM]
|
|
OrderNo = Parms[COL2()+1,@RM]
|
|
OrderItem = Parms[COL2()+1,@RM]
|
|
CustNo = Parms[COL2()+1,@RM]
|
|
PONo = Parms[COL2()+1,@RM]
|
|
PS_No = Parms[COL2()+1,@RM]
|
|
SubSuppliedBy = Parms[COL2()+1,@RM]
|
|
SubPreClean = Parms[COL2()+1,@RM]
|
|
SubPostClean = Parms[COL2()+1,@RM]
|
|
SchedDt = Parms[COL2()+1,@RM]
|
|
LotNo = Parms[COL2()+1,@RM]
|
|
CustPartNo = Parms[COL2()+1,@RM]
|
|
WaferQty = Parms[COL2()+1,@RM]
|
|
SubPartNo = Parms[COL2()+1,@RM]
|
|
QXJFlag = Parms[COL2()+1,@RM]
|
|
|
|
ErrorMsg = ''
|
|
IF WONo = '' THEN ErrorMsg := 'Null Parameter "WONo" passed to routine. (':Method:')'
|
|
IF WOStep = '' THEN ErrorMsg := 'Null Parameter "WOStep" passed to routine. (':Method:')'
|
|
IF CassNo = '' THEN ErrorMsg := 'Null Parameter "CassNo" passed to routine. (':Method:')'
|
|
IF CustNo = '' THEN ErrorMsg := 'Null Parameter "CustNo" passed to routine. (':Method:')'
|
|
IF PS_No = '' THEN ErrorMsg := 'Null Parameter "PS_No" passed to routine. (':Method:')'
|
|
IF SchedDt = '' THEN ErrorMsg := 'Null Parameter "SchedDt" passed to routine. (':Method:')'
|
|
IF LotNo = '' THEN ErrorMsg := 'Null Parameter "LotNo" passed to routine. (':Method:')'
|
|
IF WaferQty = '' THEN ErrorMsg := 'Null Parameter "WaferQty" passed to routine. (':Method:')'
|
|
|
|
If ErrorMsg NE '' then
|
|
Logging_Services('AppendLog', objLog, LoggingDTM : ',' : @USER4 : ',' : 'RDSKey Not Yet Assigned' : ',' : 'Error occured in OBJ_RDS(CREATE): ' : ErrorMsg)
|
|
Return
|
|
end
|
|
|
|
RDSNo = NextKey('RDS')
|
|
errCode = ''
|
|
|
|
If RDSNo EQ '' or RDSNo EQ 0 or Error_Services('HasError') or Get_Status(errCode) then
|
|
Logging_Services('AppendLog', objLog, LoggingDTM : ',' : @USER4 : ',' : RDSNo : ',' : 'NextKey(RDS) returned NULL or 0 for KeyID')
|
|
Error_Services('Add', 'Error retrieving next RDS key from NextKey("RDS"). ' : Error_Services('GetMessage'))
|
|
Result = RDSNo
|
|
return
|
|
end
|
|
|
|
// Delete old instance of this RDS if it exists ------------------------------------------------------------------------
|
|
If RowExists('RDS', RDSNo) then
|
|
Database_Services('DeleteDataRow', 'RDS', RDSNo, True$, False$)
|
|
If Error_Services('NoError') then
|
|
Results = 'RDS ' : RDSNo : ' deleted'
|
|
end else
|
|
Results = 'RDS ' : RDSNo : ' not deleted. Error : ' : Error_Services('GetMessage')
|
|
end
|
|
end
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// Delete related RDS_LAYER records ------------------------------------------------------------------------------------
|
|
Layers = 'L1,L2,2'
|
|
For each Layer in Layers using ','
|
|
RDSLayerKey = RDSNo:'*':Layer
|
|
If RowExists('RDS_LAYER', RDSLayerKey) then
|
|
// Look for related RDS_TEST records and delete them first
|
|
RDSTestKeys = Xlate('RDS_LAYER', RDSLayerKey, 'RDS_TEST_KEYS', 'X')
|
|
If RDSTestKeys NE '' then
|
|
For each RDSTestKey in RDSTestKeys using @VM setting vPos
|
|
// Look for related TW_USE records and delete them first
|
|
TWKeys = Xlate('RDS_TEST', RDSTestKey, 'TW_USE_ID', 'X')
|
|
If TWKeys NE '' then
|
|
For each TWKey in TWKeys using @VM setting vPos
|
|
Database_Services('DeleteDataRow', 'TW_USE', TWKey, True$, True$)
|
|
Next TWKey
|
|
end
|
|
Database_Services('DeleteDataRow', 'RDS_TEST', RDSTestKey, True$, True$)
|
|
If Error_Services('NoError') then
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = RDSTestKey
|
|
LogData<3> = 'RDS_Test record deleted without error.'
|
|
Logging_Services('AppendLog', objRDSTestDeleteLog , LogData, @RM, @FM, False$)
|
|
end else
|
|
ErrorMessage = Error_Services('GetMessage')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = ErrorMessage
|
|
Logging_Services('AppendLog', objRDSTestDeleteLog , LogData, @RM, @FM, False$)
|
|
end
|
|
Next RDSTestKey
|
|
end
|
|
Database_Services('DeleteDataRow', 'RDS_LAYER', RDSLayerKey, True$, False$)
|
|
If Error_Services('NoError') then
|
|
Results = 'RDS_LAYER ' : RDSLayerKey : ' deleted'
|
|
end else
|
|
Results = 'RDS_LAYER ' : RDSLayerKey : ' not deleted. Error : ' : Error_Services('GetMessage')
|
|
end
|
|
end
|
|
Next Layer
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// Delete old REACT_RUN record if it exists ----------------------------------------------------------------------------
|
|
If RowExists('REACT_RUN', RDSNo) then
|
|
// Delete old CLEAN_INSP record(s) if they exist
|
|
CIKeys = Xlate('REACT_RUN', RDSNo, 'CI_NO', 'X')
|
|
For each CIKey in CIKeys using @VM setting vPos
|
|
If RowExists('CLEAN_INSP', CIKey) then
|
|
Database_Services('DeleteDataRow', 'CLEAN_INSP', CIKey, True$, False$)
|
|
If Error_Services('NoError') then
|
|
Results = 'CLEAN_INSP ' : CIKey : ' deleted'
|
|
end else
|
|
Results = 'CLEAN_INSP ' : CIKey : ' not deleted. Error : ' : Error_Services('GetMessage')
|
|
end
|
|
end
|
|
Next CIKey
|
|
Database_Services('DeleteDataRow', 'REACT_RUN', RDSNo, True$, False$)
|
|
If Error_Services('NoError') then
|
|
Results = 'REACT_RUN ' : RDSNo : ' deleted'
|
|
end else
|
|
Results = 'REACT_RUN ' : RDSNo : ' not deleted. Error : ' : Error_Services('GetMessage')
|
|
end
|
|
end
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// Create new record
|
|
RDSRec = ''
|
|
RDSRec<RDS_ENTRY_ID$> = @USER4
|
|
RDSRec<RDS_ENTRY_DATE$> = Date()
|
|
RDSRec<RDS_ENTRY_TIME$> = Time()
|
|
RDSRec<RDS_STATUS$> = 'C' ;* Received
|
|
RDSRec<RDS_WO$> = WONo
|
|
RDSRec<RDS_WO_STEP_KEY$> = WONo:'*':WOStep
|
|
RDSRec<RDS_CASS_NO$> = CassNo
|
|
RDSRec<RDS_QUOTE_NO$> = QuoteNo
|
|
RDSRec<RDS_ORDER_NO$> = OrderNo
|
|
RDSRec<RDS_ORDER_ITEM$> = OrderItem
|
|
RDSRec<RDS_CUST_NO$> = CustNo
|
|
RDSRec<RDS_PO$> = PONo
|
|
RDSRec<RDS_PROD_SPEC_ID$> = PS_No
|
|
RDSRec<RDS_COMMIT_DATE_FINAL$> = SchedDt
|
|
RDSRec<RDS_LOT_NUM$> = LotNo
|
|
RDSRec<RDS_PART_NUM$> = CustPartNo
|
|
|
|
RDSRec<RDS_CASS_WAFER_QTY$> = WaferQty
|
|
RDSRec<RDS_SUB_PART_NO$> = SubPartNo
|
|
RDSRec<RDS_LAST_STEP$> = LastStep
|
|
RDSRec<RDS_SUB_SUPPLIED_BY$> = SubSuppliedBy
|
|
RDSRec<RDS_SUB_PRE_CLEAN$> = SubPreClean
|
|
RDSRec<RDS_SUB_POST_CLEAN$> = SubPostClean
|
|
|
|
|
|
IF CassNo = 1 THEN
|
|
WOVStatus = 'O' ;* Open status (?)
|
|
WOVNotes = ''
|
|
WOVNo = obj_WO_Verify('Create',RDSNo:@RM:WOVStatus:@RM:WOVNotes) ;* Create a WO_Verify record on 1st run order
|
|
RDSRec<RDS_WO_VERIFY_ID$> = WOVNo ;* Add pointer to RDS record
|
|
IF Get_Status(errCode) THEN
|
|
Logging_Services('AppendLog', objLog, LoggingDTM : ',' : @USER4 : ',' : RDSNo : ',' : 'Error calling OBJ_WO_VERIFY within OBJ_RDS(CREATE)')
|
|
end
|
|
End
|
|
|
|
|
|
PSRec = XLATE('PROD_SPEC',PS_No,'','X')
|
|
|
|
ReactorType = PSRec<PROD_SPEC_REACTOR_TYPE$> ;* This isn't used anwhere in the program 8/27/2014 JCH
|
|
RDSRec<RDS_SPECIAL_INST$> = PSRec<PROD_SPEC_SPEC_INST$> ;* 3/25/2013 jch
|
|
RDSRec<RDS_SPEC_TYPE_ORIG$> = XLATE('PROD_SPEC',PS_No,'SPEC_TYPE','X')
|
|
|
|
Send_Info('Retrieving PSN Layer Properties...')
|
|
|
|
LayerSpecs = obj_Prod_Spec('GetLayerProp',PS_No:@RM:@RM:1) ;* Returns specs for all layers in internal format
|
|
|
|
|
|
* LayerSpecs is @RM between layers, @FM between fields, LayerSet ID is in the first Field and needs to peeled off
|
|
* before the equates match up correctly
|
|
|
|
* Prod_Spec table has layer specs all in one field
|
|
* RDS has First layer stuff in individual fields and then has 2 and 3 shoved into Field 33 (Layer Info)
|
|
|
|
LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer
|
|
LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity
|
|
LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
|
|
RecipeNo = LayerSpec<PRS_LAYER_RECIPE$>
|
|
RecipeRec = XLATE('RECIPE',RecipeNo,'','X') ;* This used in 2nd and 3rd layer stuff (in error it appears)
|
|
|
|
RDSRec<RDS_OVERGROW_REQ$> = LayerSpec<PRS_LAYER_RES_MEASUREMENT$,9> ;* JCH 2/27/2006
|
|
|
|
|
|
IF QXJFlag THEN
|
|
RDSRec<RDS_QXJ_POST$> = 0 ;* And here a couple of minor cluster operations
|
|
END
|
|
|
|
IF CustNo = '621' AND CassNo = 1 THEN
|
|
RDSRec<RDS_QXJ_POST$> = 0
|
|
END
|
|
|
|
NoCombinedLayerFlag = ''
|
|
FOR I = 1 TO COUNT(LayerSpecs,@RM) + (LayerSpecs NE '')
|
|
LayerSpec = FIELD(LayerSpecs,@RM,I) ;* Take the Ith Layer
|
|
LayerSet = FIELD(LayerSpec,@FM,1)
|
|
LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
|
|
IF LayerSet = I THEN NoCombinedLayerFlag = 1 ELSE NoCombinedLayerFlag = 0
|
|
|
|
Send_Info('Creating RDS Layer ':LayerSet:'...')
|
|
|
|
obj_RDS_Layer('Create',RDSNo:@RM:LayerSet:@RM:PS_No:@RM:NoCombinedLayerFlag)
|
|
|
|
RDSRec<RDS_RDS_LAYER_KEYS$,I> = RDSNo:'*':LayerSet ;* Added 4/17/2006 JCH
|
|
|
|
Send_Info('Creating Metrology for Layer Set ':LayerSet:'...')
|
|
|
|
obj_RDS_Test('Create',RDSNo:@RM:LayerSet:@RM:PS_No)
|
|
|
|
NEXT I
|
|
|
|
|
|
********************************
|
|
*Automatically Apply Supplement*
|
|
********************************
|
|
// If first cassette in work order, then there is no supplement in place, therefore skip this step.
|
|
If RDSRec<RDS_CASS_NO$> GT 1 then
|
|
WoStepKey = RDSRec<RDS_WO_STEP_KEY$>
|
|
WoStepRec = Database_Services('ReadDataRow', 'WO_STEP', WoStepKey)
|
|
If Error_Services('NoError') then
|
|
LastRDSKey = WoStepRec<WO_STEP_RDS_KEY$>[-1, 'B' : @VM]
|
|
LastRDSRec = Database_Services('ReadDataRow', 'RDS', LastRDSKey)
|
|
If Error_Services('NoError') then
|
|
HasSupplement = LastRDSRec<RDS_SUPPLEMENT$>
|
|
If HasSupplement then
|
|
RDSRec<RDS_SUPPLEMENT$> = True$
|
|
RDSRec<RDS_SUPPL_INST$> = LastRDSRec<RDS_SUPPL_INST$>
|
|
RDSRec<RDS_SUPPL_ENTRY_ID$> = LastRDSRec<RDS_SUPPL_ENTRY_ID$>
|
|
RDSRec<RDS_SUPPL_ENTRY_DATE$> = LastRDSRec<RDS_SUPPL_ENTRY_DATE$>
|
|
RDSRec<RDS_SUPPL_ENTRY_TIME$> = LastRDSRec<RDS_SUPPL_ENTRY_TIME$>
|
|
end
|
|
end else
|
|
Logging_Services('AppendLog', objLog, LoggingDTM : ',' : @USER4 : ',' : RDSNo : ',' : 'Error automatically applying supplement to new RDS.')
|
|
end
|
|
end else
|
|
Logging_Services('AppendLog', objLog, LoggingDTM : ',' : @USER4 : ',' : RDSNo : ',' : 'Error automatically applying supplement to new RDS.')
|
|
end
|
|
end
|
|
|
|
|
|
Send_Info('Saving RDS record...')
|
|
|
|
obj_Tables('WriteRec','RDS':@RM:RDSNo:@RM:@RM:RDSRec)
|
|
|
|
IF Get_Status(errCode) THEN
|
|
Logging_Services('AppendLog', objLog, LoggingDTM : ',' : @USER4 : ',' : RDSNo : ',' : 'Error writing new RDS record. Error code: ':errCode)
|
|
Result = ''
|
|
END ELSE
|
|
Result = RDSNo
|
|
END
|
|
|
|
* * * * * * *
|
|
|
|
Send_Info('Conversion to REACT_RUN record...')
|
|
|
|
RDS_React_Run(RDSNo) ;********************************** Conversion stuff JCH 9/26/2008 *********************
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
VerifySpecInfo:
|
|
* * * * * * *
|
|
|
|
RDSNo = Parms[1,@RM]
|
|
RDSRec = Parms[COL2()+1,@RM]
|
|
|
|
IF NOT(ASSIGNED(RDSNo)) THEN ErrorMsg = 'Unassigned Parm "RDSNo" passed to routine. (':Method:')'
|
|
IF NOT(ASSIGNED(RDSRec)) THEN RDSRec = ''
|
|
|
|
IF ErrorMsg NE '' THEN RETURN
|
|
|
|
IF RDSNo = '' THEN RETURN ;* used in dictionary - no error messages
|
|
|
|
IF RDSRec = '' THEN RDSRec = XLATE('RDS',RDSNo,'','X')
|
|
IF RDSRec = '' THEN RETURN
|
|
|
|
PS_No = RDSRec<RDS_PROD_SPEC_ID$>
|
|
PSRec = XLATE('PROD_SPEC',PS_No,'','X')
|
|
|
|
LayerSpecs = obj_Prod_Spec('GetLayerProp',PS_No) ;* Returns specs for all layers
|
|
|
|
IF RDSRec<RDS_SPECIAL_INST$> NE PSRec<PROD_SPEC_SPEC_INST$> THEN Matches = 0
|
|
|
|
LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer
|
|
LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity
|
|
LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
|
|
RecipeNo = LayerSpec<PRS_LAYER_RECIPE$>
|
|
RecipeRec = XLATE('RECIPE',RecipeNo,'','X') ;* This used in 2nd and 3rd layer stuff (in error it appears)
|
|
|
|
ErrNum = 1
|
|
|
|
* IF RDSRec<RDS_RECIPE_NO$> NE RecipeNo THEN ErrNum = -11
|
|
|
|
|
|
* This section is here because the targets calculated in the existing SCHEDULE*WRITE event are not done correctly
|
|
* There is a last decimal point difference in the calculation that causes a mismatch whenever a remainder of .5
|
|
* is generated during the division by 2. WRITE event code doesn't drop the remainder like it should
|
|
* This section calculates the targets based on the min and max on the RDS. We can remove this after the WRITE
|
|
* event is replaced and the data has had enough time to move through the system.
|
|
* JCH 8/23/2004
|
|
|
|
RDSConMin = RDSRec<RDS_CON_MIN_ORG$,1> ;* Record in internal format
|
|
RDSConMax = RDSRec<RDS_CON_MAX_ORG$,1> ;* Record in internal format
|
|
|
|
GOSUB CalcConTarget ;* Returns RDSTarget in internal format
|
|
|
|
RDSResMin = RDSRec<RDS_RES_MIN_ORG$>
|
|
RDSResMax = RDSRec<RDS_RES_MAX_ORG$>
|
|
|
|
GOSUB CalcResTarget
|
|
|
|
RDSThickMin = RDSRec<RDS_THICK_MIN_ORG$>
|
|
RDSThickMax = RDSRec<RDS_THICK_MAX_ORG$>
|
|
|
|
GOSUB CalcThickTarget
|
|
|
|
|
|
IF OCONV(RDSRec<RDS_CON_MIN_ORG$,1>,'MS21') NE LayerSpec<PRS_LAYER_CONC_MIN$> THEN ErrNum = -12
|
|
IF OCONV(RDSRec<RDS_CON_MAX_ORG$,1>,'MS21') NE LayerSpec<PRS_LAYER_CONC_MAX$> THEN ErrNum = -13
|
|
IF RDSRec<RDS_CON_UNITS_ORG$> NE LayerSpec<PRS_LAYER_CONC_UNITS$> THEN ErrNum = -14
|
|
IF OCONV(RDSConTarget,'MS21') NE LayerSpec<PRS_LAYER_CONC_TARGET$> THEN ErrNum = -15
|
|
|
|
IF OCONV(RDSRec<RDS_RES_MIN_ORG$>,'MD3') NE LayerSpec<PRS_LAYER_RES_MIN$> THEN ErrNum = -16
|
|
IF OCONV(RDSRec<RDS_RES_MAX_ORG$>,'MD3') NE LayerSpec<PRS_LAYER_RES_MAX$> THEN ErrNum = -17
|
|
IF RDSRec<RDS_RES_UNITS_ORG$> NE LayerSpec<PRS_LAYER_RES_UNITS$> THEN ErrNum = -18
|
|
IF OCONV(RDSResTarget,'MD3') NE LayerSpec<PRS_LAYER_RES_TARGET$> THEN ErrNum = -19
|
|
|
|
IF OCONV(RDSRec<RDS_THICK_MIN_ORG$>,'MD2') NE LayerSpec<PRS_LAYER_THICK_MIN$> THEN ErrNum = -110
|
|
IF OCONV(RDSRec<RDS_THICK_MAX_ORG$>,'MD2') NE LayerSpec<PRS_LAYER_THICK_MAX$> THEN ErrNum = -111
|
|
IF RDSRec<RDS_THICK_UNITS_ORG$> NE LayerSpec<PRS_LAYER_THICK_UNITS$> THEN ErrNum = -112
|
|
IF OCONV(RDSThickTarget,'MD2') NE LayerSpec<PRS_LAYER_THICK_TARGET$> THEN ErrNum = -113
|
|
|
|
RDSLayerInfo = RDSRec<RDS_LAYER_INFO$> ;* All Layers beyond the first
|
|
|
|
FOR I = 2 TO COUNT(LayerSpecs,@RM) + (LayerSpecs NE '')
|
|
LayerSpec = FIELD(LayerSpecs,@RM,I) ;* Take the Ith Layer
|
|
LayerSet = LayerSpec<1>
|
|
LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
|
|
thisLayerInfo = FIELD(RDSLayerInfo,CHAR(248),I-1,1) ;* L2 & 2 from the RDS
|
|
|
|
* Calculate RDS target using the same algorithm used in obj_Prod_Spec
|
|
|
|
RDSConMin = ICONV(thisLayerInfo<1,RLConMin$,1>,'MS')
|
|
RDSConMax = ICONV(thisLayerInfo<1,RLConMax$,1>,'MS')
|
|
|
|
GOSUB CalcConTarget
|
|
|
|
IF RDSConMin AND RDSConMax THEN
|
|
IF RDSConMin = RDSConMax THEN
|
|
RDSConTarget = RDSConMin
|
|
END ELSE
|
|
Delta = INT((RdsConMax-RDSConMin)/2)
|
|
RDSConTarget = OCONV(RDSConMin + Delta,'MS21')
|
|
END
|
|
END ELSE
|
|
RDSConTarget = ''
|
|
END
|
|
|
|
IF thisLayerInfo<1,RLRecipeNo$> NE RecipeNo THEN ErrNum = '-':I:1
|
|
|
|
IF thisLayerInfo<1,RLConMin$,1> NE LayerSpec<PRS_LAYER_CONC_MIN$> THEN ErrNum = '-':I:2
|
|
IF thisLayerInfo<1,RLConMax$,1> NE LayerSpec<PRS_LAYER_CONC_MAX$> THEN ErrNum = '-':I:3
|
|
IF thisLayerInfo<1,RLConUnits$> NE LayerSpec<PRS_LAYER_CONC_UNITS$> THEN ErrNum = '-':I:4
|
|
IF RDSConTarget NE LayerSpec<PRS_LAYER_CONC_TARGET$> THEN ErrNum = '-':I:5
|
|
|
|
IF OCONV(thisLayerInfo<1,RLResMin$>,'MD3') NE LayerSpec<PRS_LAYER_RES_MIN$> THEN ErrNum = '-':I:6
|
|
IF OCONV(thisLayerInfo<1,RLResMax$>,'MD3') NE LayerSpec<PRS_LAYER_RES_MAX$> THEN ErrNum = '-':I:7
|
|
IF thisLayerInfo<1,RLResUnits$> NE LayerSpec<PRS_LAYER_RES_UNITS$> THEN ErrNum = '-':I:8
|
|
IF OCONV(thisLayerInfo<1,RLResTarget$>,'MD3') NE LayerSpec<PRS_LAYER_RES_TARGET$> THEN ErrNum = '-':I:9
|
|
|
|
IF OCONV(thisLayerInfo<1,RLThickMin$>,'MD2') NE LayerSpec<PRS_LAYER_THICK_MIN$> THEN ErrNum = '-':I:10
|
|
IF OCONV(thisLayerInfo<1,RLThickMax$>,'MD2') NE LayerSpec<PRS_LAYER_THICK_MAX$> THEN ErrNum = '-':I:11
|
|
IF thisLayerInfo<1,RLThickUnits$> NE LayerSpec<PRS_LAYER_THICK_UNITS$> THEN ErrNum = '-':I:12
|
|
IF OCONV(thisLayerInfo<1,RLThickTarget$>,'MD2') NE LayerSpec<PRS_LAYER_THICK_TARGET$> THEN ErrNum = '-':I:13
|
|
|
|
NEXT I
|
|
|
|
SchedNo = RDSRec<RDS_SCHEDULE_NO$>
|
|
OrdNo = RDSRec<RDS_ORDER_NO$>
|
|
|
|
Result = ErrNum:@FM:'Sched No: ':SchedNo:@FM:' Order No: ':OrdNo
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
* Update:
|
|
* * * * * * *
|
|
*
|
|
* RDSNo = Parms[1,@RM]
|
|
*
|
|
* IF NOT(ASSIGNED(RDSNo)) THEN ErrorMsg = 'Unassigned Parm "RDSNo" passed to routine. (':Method:')'
|
|
*
|
|
* IF ErrorMsg NE '' THEN RETURN
|
|
*
|
|
* IF RDSNo = '' THEN ErrorMsg = 'Null Parameter "RDSNo" passed to routine. (':Method:')'
|
|
*
|
|
* IF ErrorMsg NE '' THEN RETURN
|
|
*
|
|
* RDSRec<RDS_ENTRY_ID$> = @USER4
|
|
* RDSRec<RDS_ENTRY_DATE$> = Date()
|
|
* RDSRec<RDS_ENTRY_TIME$> = Time()
|
|
* RDSRec<RDS_SCHEDULE_NO$> = SchedNo
|
|
* RDSRec<RDS_WO$> = WONo
|
|
*
|
|
* WO Run Order number is not stored in the RDS
|
|
*
|
|
* RDSRec<RDS_QUOTE_NO$> = QuoteNo
|
|
* RDSRec<RDS_ORDER_NO$> = OrderNo
|
|
* RDSRec<RDS_CUST_NO$> = CustNo
|
|
* RDSRec<RDS_PO$> = PONo
|
|
* RDSRec<RDS_PROD_SPEC_ID$> = PS_No
|
|
* RDSRec<RDS_STATUS$> = RDSStatus ;* Usually passed as 'C' - Received
|
|
* RDSRec<RDS_COMMIT_DATE_FINAL$> = SchedDt
|
|
* RDSRec<RDS_LOT_NUM$> = LotNo
|
|
* RDSRec<RDS_PART_NUM$> = PartNo
|
|
*
|
|
* IF CassNo = 1 THEN
|
|
* WOVStatus = 'O' ;* Open status (?)
|
|
* WOVNotes = ''
|
|
* WOVNo = obj_WO_Verify('Create',RDSNo:@RM:WOVStatus:@RM:WOVNotes) ;* Create a WO_Verify record on 1st run order
|
|
* RDSRec<RDS_WO_VERIFY_ID$> = WOVNo ;* Add pointer to RDS record
|
|
* END
|
|
*
|
|
* PSRec = XLATE('PROD_SPEC',PS_No,'','X')
|
|
*
|
|
* RDSRec<RDS_SPECIAL_INST$> = PSRec<PROD_SPEC_SPEC_INST$>
|
|
* RDSRec<RDS_SPEC_TYPE_ORIG$> = XLATE('PROD_SPEC',PS_No,'SPEC_TYPE','X')
|
|
*
|
|
* LayerSpecs = obj_Prod_Spec('GetLayerProp',PS_No:@RM:@RM:1) ;* Returns specs for all layers without output conversion
|
|
*
|
|
* LayerSpecs is @RM between layers, @FM between fields, LayerSet ID is in the first Field and needs to peeled off
|
|
* before the equates match up correctly
|
|
*
|
|
* Prod_Spec table has layer specs all in one field
|
|
* RDS has First layer stuff in individual fields and then has 2 and 3 shoved into Field 33 (Layer Info)
|
|
*
|
|
* LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer
|
|
* LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity
|
|
* LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
*
|
|
* RecipeNo = LayerSpec<PRS_LAYER_RECIPE$>
|
|
* RecipeRec = XLATE('RECIPE',RecipeNo,'','X') ;* This used in 2nd and 3rd layer stuff (in error it appears)
|
|
*
|
|
* RDSRec<RDS_RECIPE_NO$> = RecipeNo
|
|
* RDSRec<RDS_CON_MIN$> = LayerSpec<PRS_LAYER_CONC_MIN$>
|
|
* RDSRec<RDS_CON_MAX$> = LayerSpec<PRS_LAYER_CONC_MAX$>
|
|
* RDSRec<RDS_CON_UNITS$> = LayerSpec<PRS_LAYER_CONC_UNITS$>
|
|
* RDSRec<RDS_CON_TARGET$> = LayerSpec<PRS_LAYER_CONC_TARGET$>
|
|
*
|
|
* RDSRec<RDS_RES_MIN$> = LayerSpec<PRS_LAYER_RES_MIN$>
|
|
* RDSRec<RDS_RES_MAX$> = LayerSpec<PRS_LAYER_RES_MAX$>
|
|
* RDSRec<RDS_RES_UNITS$> = LayerSpec<PRS_LAYER_RES_UNITS$>
|
|
* RDSRec<RDS_RES_TARGET$> = LayerSpec<PRS_LAYER_RES_TARGET$>
|
|
*
|
|
* RDSRec<RDS_THICK_MIN$> = LayerSpec<PRS_LAYER_THICK_MIN$>
|
|
* RDSRec<RDS_THICK_MAX$> = LayerSpec<PRS_LAYER_THICK_MAX$>
|
|
* RDSRec<RDS_THICK_UNITS$> = LayerSpec<PRS_LAYER_THICK_UNITS$>
|
|
* RDSRec<RDS_THICK_TARGET$> = LayerSpec<PRS_LAYER_THICK_TARGET$>
|
|
*
|
|
* LayerInfo = ''
|
|
*
|
|
* FOR I = 2 TO COUNT(LayerSpecs,@RM) + (LayerSpecs NE '')
|
|
* LayerSpec = FIELD(LayerSpecs,@RM,I) ;* Take the Ith Layer
|
|
* LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
*
|
|
* thisLayerInfo = '' ;* Empty bucket to parse into
|
|
*
|
|
* thisLayerInfo<1,RLConMin$> = LayerSpec<PRS_LAYER_CONC_MIN$>
|
|
* thisLayerInfo<1,RLConMax$> = LayerSpec<PRS_LAYER_CONC_MAX$>
|
|
* thisLayerInfo<1,RLConUnits$> = LayerSpec<PRS_LAYER_CONC_UNITS$>
|
|
* thisLayerInfo<1,RLConTarget$> = LayerSpec<PRS_LAYER_CONC_TARGET$>
|
|
*
|
|
* thisLayerInfo<1,RLRecipeNo$> = RecipeNo ;* Copied from the original in the WRITE event of the Schedule window
|
|
* thisLayerInfo<1,RLThickRead$> = STR(@SVM,16)
|
|
* thisLayerInfo<1,RLSheetRhoRead$> = STR(@SVM,16)
|
|
*
|
|
* thisLayerInfo<1,RLResMin$> = LayerSpec<PRS_LAYER_RES_MIN$>
|
|
* thisLayerInfo<1,RLResMax$> = LayerSpec<PRS_LAYER_RES_MAX$>
|
|
* thisLayerInfo<1,RLResUnits$> = LayerSpec<PRS_LAYER_RES_UNITS$>
|
|
* thisLayerInfo<1,RLResTarget$> = LayerSpec<PRS_LAYER_RES_TARGET$>
|
|
*
|
|
* thisLayerInfo<1,RLThickMin$> = LayerSpec<PRS_LAYER_THICK_MIN$>
|
|
* thisLayerInfo<1,RLThickMax$> = LayerSpec<PRS_LAYER_THICK_MAX$>
|
|
* thisLayerInfo<1,RLThickUnits$> = LayerSpec<PRS_LAYER_THICK_UNITS$>
|
|
* thisLayerInfo<1,RLThickTarget$> = LayerSpec<PRS_LAYER_THICK_TARGET$>
|
|
*
|
|
* LayerInfo := thisLayerInfo:CHAR(248)
|
|
*
|
|
* NEXT I
|
|
*
|
|
* LayerInfo[-1,1] = '' ;* Strip trailing CHAR(248)
|
|
*
|
|
*
|
|
* RDSRec<RDS_LAYER_INFO$> = LayerInfo ;* End of the great Layer cluster function
|
|
*
|
|
* IF QXJFlag THEN
|
|
* RDSRec<RDS_QXJ_POST$> = 0 ;* And here a couple of minor cluster operations
|
|
* END
|
|
*
|
|
* IF CustNo = '621' AND CassNo = 1 THEN
|
|
* RDSRec<RDS_QXJ_POST$> = 0
|
|
* END
|
|
*
|
|
* obj_Tables('WriteRec','RDS':@RM:RDSKey:@RM:@RM:RDSRec)
|
|
*
|
|
* IF Get_Status(errCode) THEN
|
|
* Result = ''
|
|
* END ELSE
|
|
* Result = RDSKey
|
|
* END
|
|
*
|
|
*
|
|
*
|
|
* RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SchedWfrQty:
|
|
* * * * * * *
|
|
|
|
IF NOT(ASSIGNED(thisRDSNo)) THEN
|
|
thisRDSNo = Parms[1,@RM]
|
|
END
|
|
IF NOT(ASSIGNED(thisRDSRec)) THEN
|
|
thisRDSRec = Parms[COL2()+1,@RM]
|
|
END
|
|
|
|
IF thisRDSNo = '' THEN RETURN
|
|
IF thisRDSRec = '' THEN thisRDSRec = XLATE('RDS',thisRDSNo,'','X')
|
|
|
|
IF thisRDSRec = '' THEN RETURN
|
|
|
|
SchedNo = thisRDSRec<RDS_SCHEDULE_NO$>
|
|
SchedRec = XLATE('SCHEDULE',SchedNo,'','X')
|
|
|
|
LOCATE thisRDSNo IN SchedRec<SCHEDULE_RDS_IDS$> USING @VM SETTING Pos THEN
|
|
Result = SchedRec<SCHEDULE_WAFERS_IN$,Pos>
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
TestRejWfrQty:
|
|
* * * * * * *
|
|
|
|
IF NOT(ASSIGNED(thisRDSNo)) THEN
|
|
thisRDSNo = Parms[1,@RM]
|
|
END
|
|
IF NOT(ASSIGNED(thisRDSRec)) THEN
|
|
thisRDSRec = Parms[COL2()+1,@RM]
|
|
END
|
|
|
|
IF thisRDSNo = '' THEN RETURN
|
|
IF thisRDSRec = '' THEN thisRDSRec = XLATE('RDS',thisRDSNo,'','X')
|
|
|
|
IF thisRDSRec = '' THEN RETURN
|
|
|
|
Tmp = 0
|
|
Tmp += XLATE('RDS',thisRDSNo,'TOT_REJ','X')
|
|
|
|
TestKeys = XLATE('RDS_LAYER',thisRDSRec<RDS_RDS_LAYER_KEYS$>,3,'X')
|
|
|
|
ProdTestWfrs = obj_RDS_Test('ProdTestCount',TestKeys)
|
|
|
|
Tmp += ProdTestWfrs
|
|
|
|
Tmp += thisRDSRec<RDS_WAF_BACK_TO_INVENTORY$> ;* <97>
|
|
Tmp += thisRDSRec<RDS_RESEARCH_SRP_BILLABLE$> ;* <221>
|
|
|
|
Result = Tmp
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
MUSrcWfrQty:
|
|
* * * * * * *
|
|
|
|
IF NOT(ASSIGNED(thisRDSNo)) THEN
|
|
thisRDSNo = Parms[1,@RM]
|
|
END
|
|
IF NOT(ASSIGNED(thisRDSMakeupRec)) THEN
|
|
thisRDSMakeupRec = Parms[COL2()+1,@RM]
|
|
END
|
|
|
|
IF thisRDSNo = '' THEN RETURN
|
|
IF thisRDSMakeupRec = '' THEN thisRDSMakeupRec = XLATE('RDS_MAKEUP',thisRDSNo,'','X')
|
|
|
|
IF thisRDSMakeupRec NE '' THEN
|
|
Tmp = 0
|
|
FOR I = 1 TO COUNT(thisRDSMakeupRec<RDS_MAKEUP_SRC_SLOT$>,@VM) + (thisRDSMakeupRec<RDS_MAKEUP_SRC_SLOT$> NE '')
|
|
IF thisRDSMakeupRec<RDS_MAKEUP_SRC_SLOT$,I> NE '' THEN Tmp += 1
|
|
NEXT I
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
MUDestWfrQty:
|
|
* * * * * * *
|
|
|
|
IF NOT(ASSIGNED(thisRDSNo)) THEN
|
|
thisRDSNo = Parms[1,@RM]
|
|
END
|
|
IF NOT(ASSIGNED(thisRDSMakeupRec)) THEN
|
|
thisRDSMakeupRec = Parms[COL2()+1,@RM]
|
|
END
|
|
|
|
IF thisRDSNo = '' THEN RETURN
|
|
IF thisRDSMakeupRec = '' THEN thisRDSMakeupRec = XLATE('RDS_MAKEUP',thisRDSNo,'','X')
|
|
|
|
IF thisRDSMakeupRec NE '' THEN
|
|
Tmp = 0
|
|
FOR I = 1 TO COUNT(thisRDSMakeupRec<RDS_MAKEUP_DEST_SLOT$>,@VM) + (thisRDSMakeupRec<RDS_MAKEUP_DEST_SLOT$> NE '')
|
|
IF thisRDSMakeupRec<RDS_MAKEUP_DEST_SLOT$,I> NE '' THEN Tmp += 1
|
|
NEXT I
|
|
Result = Tmp
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
WafersOut:
|
|
* * * * * * *
|
|
|
|
IF NOT(ASSIGNED(RDSNo)) THEN RDSNo = Parms[1,@RM]
|
|
IF NOT(ASSIGNED(RDSRec)) THEN RDSRec = Parms[COL2()+1,@RM]
|
|
IF NOT(ASSIGNED(Filter)) THEN Filter = Parms[COL2()+1,@RM]
|
|
IF NOT(ASSIGNED(NoMU)) THEN NoMU = Parms[COL2()+1,@RM] ;* NoMU = No Makeup Wafer counts
|
|
|
|
IF RDSNo = '' THEN RETURN
|
|
IF RDSRec = '' THEN RDSRec = XLATE('RDS',RDSNo,'','X')
|
|
|
|
VerifyQty = RDSRec<RDS_VERIFY_QTY$>
|
|
WafersIn = RDSRec<RDS_WAFERS_IN$>
|
|
CassWfrQty = RDSRec<RDS_CASS_WAFER_QTY$>
|
|
NCRKeys = RDSRec<RDS_NCR_KEYS$>
|
|
|
|
If Not(Num(WafersIn)) then
|
|
// Log the WafersIn value
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = RDSNo
|
|
LogData<3> = WafersIn
|
|
Logging_Services('AppendLog', objWafersLog, LogData, @RM, @FM)
|
|
WafersIn = WafersIn<1, 1, 1>
|
|
end
|
|
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
MUWafersIn = XLATE('WO_MAT',WONo:'*':CassNo,'CURR_WFR_CNT_MU_ADDED','X')
|
|
MUWafersRemoved = XLATE('WO_MAT',WONo:'*':CassNo,'CURR_WFR_CNT_USED_MU','X')
|
|
CurrWfrCnt = XLATE('WO_MAT',WONo:'*':CassNo,'CURR_WFR_CNT','X') ;* Added 5/10/2011 JCH * * * * * * * * * * * * * *
|
|
|
|
IF NCRKeys NE '' THEN
|
|
* This happens when a box of wafers is bad upon opening in the cleanroom
|
|
* An NCR rejecting the entire cassette is generated and the box is returned to shipping/receiving
|
|
NCRStatuses = XLATE('NCR',NCRKeys,NCR_STATUS$,'X') ;* Added this section 09/17/2005 JCH - J.C. Henry & Co., Inc.
|
|
IF INDEX(NCRStatuses,'O',1) ELSE
|
|
* All NCR's are closed
|
|
RejectQty = XLATE('NCR',NCRKeys,'REJ_CNT','X')
|
|
* 11/17/22 - DJS/JRO - Updated the following line to check if CurrWfrCnt is equal to zero to prevent OI from
|
|
* erroneously returning zero. Consider refactoring WafersOut subroutine.
|
|
IF ( ( (SUM(RejectQty) = CassWfrQty) or (SUM(RejectQty) = WafersIn) ) and (CurrWfrCnt EQ 0) ) THEN
|
|
Result = 0
|
|
RETURN
|
|
end
|
|
END
|
|
END
|
|
|
|
TotRejects = SUM(XLATE('NCR',NCRKeys,'REJ_CNT','X'))
|
|
TestKeys = XLATE('RDS_LAYER',RDSRec<RDS_RDS_LAYER_KEYS$>,3,'X')
|
|
TWProd = obj_RDS_Test('ProdTestCount',TestKeys)
|
|
SRPBillable = RDSRec<RDS_RESEARCH_SRP_BILLABLE$>
|
|
|
|
IF NoMU THEN
|
|
Added = WafersIn
|
|
Removed = TotRejects + TWProd + SRPBillable
|
|
END ELSE
|
|
Added = WafersIn + MUWafersIn
|
|
Removed = TotRejects + TWProd + SRPBillable + MUWafersRemoved
|
|
END
|
|
|
|
IF Filter NE '' THEN
|
|
BEGIN CASE
|
|
CASE Filter = 'Q'
|
|
SignedOff = RDSRec<RDS_SUP_VER_SIG$> NE ''
|
|
CASE Filter = 'P'
|
|
SignedOff = RDSRec<RDS_POST_EPI_SIG$> NE ''
|
|
CASE 1
|
|
SignedOff = '' ;* This is an error
|
|
END CASE
|
|
END ELSE
|
|
SignedOff = (RDSRec<RDS_OPERATOR_OUT$> NE '')
|
|
END
|
|
|
|
IF (Removed <= Added) AND (Added NE 0) AND SignedOff THEN ;* Added SignedOff Flag for QA on 09/21/2005 JCH - J.C. Henry & Co., Inc.
|
|
Result = Added - Removed
|
|
IF Result NE CurrWfrCnt THEN Result = CurrWfrCnt
|
|
END ELSE
|
|
Result = ''
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
****************
|
|
YieldOutThruput:
|
|
****************
|
|
|
|
RDSNo = Parms[1,@RM]
|
|
RDSRec = Parms[COL2()+1,@RM]
|
|
|
|
YieldOut = 0
|
|
|
|
If (RDSNo NE '') then
|
|
If (RDSRec = '') then
|
|
RDSRec = XLATE('RDS',RDSNo,'','X')
|
|
end
|
|
// Number of wafers out = Number of wafers in
|
|
WafersOut = RDSRec<RDS_WAFERS_IN$>
|
|
|
|
// Calculate the total number of rejected wafers
|
|
CustScrap = Xlate('RDS', RDSNo, 'CUST_TOT_REJ', 'X')
|
|
IFXScrap = Xlate('RDS', RDSNo, 'LSL_TOT_REJ', 'X')
|
|
TotalRejects = CustScrap + IFXScrap
|
|
|
|
// Determine the number of production test wafers
|
|
TestKeys = XLATE('RDS_LAYER',RDSRec<RDS_RDS_LAYER_KEYS$>, 3, 'X')
|
|
TWProd = obj_RDS_Test('ProdTestCount', TestKeys)
|
|
|
|
YieldOut = WafersOut - TotalRejects - TWProd
|
|
end
|
|
|
|
Result = YieldOut
|
|
|
|
return
|
|
|
|
|
|
* * * * * * *
|
|
RemMUWafers:
|
|
* * * * * * *
|
|
|
|
RETURN
|
|
|
|
* * * * * * *
|
|
WafersPerHour:
|
|
* * * * * * *
|
|
|
|
RDSNos = Parms[1,@RM]
|
|
|
|
IF NOT(ASSIGNED(RDSNos)) THEN RDSNos = ''
|
|
IF RDSNos = '' THEN RETURN
|
|
|
|
HoursTotal = 0
|
|
WafersInTotal = 0
|
|
TargetTotal = 0
|
|
|
|
RDSCount = COUNT(RDSNos,@VM) + (RDSNos NE '')
|
|
FOR I = 1 TO RDSCount
|
|
|
|
RDSRec = XLATE('RDS',RDSNos<1,I>,'','X')
|
|
|
|
LoadDTM = ICONV(OCONV(RDSRec<RDS_DATE_IN$>,'D4/'):' ':OCONV(RDSRec<RDS_TIME_IN$>,'MTS'),'DT')
|
|
UnLoadDTM = ICONV(OCONV(RDSRec<RDS_DATE_OUT$>,'D4/'):' ':OCONV(RDSRec<RDS_TIME_OUT$>,'MTS'),'DT')
|
|
WafersIn = RDSRec<RDS_WAFERS_IN$>
|
|
|
|
If Not(Num(WafersIn)) then
|
|
// Log the WafersIn value
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM
|
|
LogData<2> = RDSNo
|
|
LogData<3> = WafersIn
|
|
Logging_Services('AppendLog', objWafersLog, LogData, @RM, @FM)
|
|
WafersIn = WafersIn<1, 1, 1>
|
|
end
|
|
|
|
IF UnloadDTM NE '' THEN
|
|
HoursTotal += (UnloadDTM - LoadDTM)*24
|
|
WafersInTotal += WafersIn
|
|
END
|
|
|
|
MinutesPerWfr = XLATE('PROD_SPEC',RDSRec<RDS_PROD_SPEC_ID$>,96,'X') ;* MD3 format
|
|
|
|
IF MinutesPerWfr = '' THEN MinutesPerWfr = ICONV('7.333','MD3') ;* Default per Todd to get us going with OEE
|
|
WfrsPerHour = ICONV(ICONV(60,'MD3')/MinutesPerWfr,'MD2') ;* Should be in MD2 format
|
|
|
|
TargetTotal += WfrsPerHour
|
|
|
|
NEXT I
|
|
|
|
IF HoursTotal = 0 THEN
|
|
Actual = ''
|
|
END ELSE
|
|
Actual = OCONV(ICONV(WafersInTotal/HoursTotal,'MD2'),'MD2') ;* Average Actual Wafers per Hour
|
|
END
|
|
|
|
IF RDSCount = 0 THEN
|
|
Target = ''
|
|
END ELSE
|
|
Target = OCONV(ICONV(TargetTotal/RDSCount,'MD0'),'MD2') ;* Average Target Wafers per Hour
|
|
END
|
|
|
|
Result = Actual:@RM:Target
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
AddShip:
|
|
* * * * * * *
|
|
|
|
ShipNo = Parms[1,@RM]
|
|
RdsNo = Parms[COL2()+1,@RM]
|
|
ShipDt = Parms[COL2()+1,@RM]
|
|
ShipTm = Parms[COL2()+1,@RM]
|
|
|
|
IF NOT(ASSIGNED(RdsNo)) THEN ErrorMsg = 'Unassigned Parm "RdsNo" passed to routine. (':Method:')'
|
|
IF NOT(ASSIGNED(ShipNo)) THEN ErrorMsg = 'Unassigned Parm "ShipNo" passed to routine. (':Method:')'
|
|
IF NOT(ASSIGNED(ShipDt)) THEN ErrorMsg = 'Unassigned Parm "ShipDt" passed to routine. (':Method:')'
|
|
IF NOT(ASSIGNED(ShipTm)) THEN ErrorMsg = 'Unassigned Parm "ShipTm" passed to routine. (':Method:')'
|
|
|
|
IF ErrorMsg NE '' THEN RETURN
|
|
|
|
IF RdsNo = '' THEN ErrorMsg = 'Null Parm "RdsNo" passed to routine. (':Method:')'
|
|
IF ShipNo = '' THEN ErrorMsg = 'Null Parm "ShipNo" passed to routine. (':Method:')'
|
|
IF ShipDt = '' THEN ErrorMsg = 'Null Parm "ShipDt" passed to routine. (':Method:')'
|
|
IF ShipTm = '' THEN ErrorMsg = 'Null Parm "ShipTm" passed to routine. (':Method:')'
|
|
|
|
IF ErrorMsg NE '' THEN RETURN
|
|
|
|
thisShipDt = ICONV(ShipDt,'D')
|
|
IF thisShipDt = '' THEN
|
|
ErrorMsg = 'Invalid ShipDt ':QUOTE(ShipDt):' parameter passed to routine. (':Method:')'
|
|
RETURN
|
|
END
|
|
|
|
thisShipTm = ICONV(ShipTm,'MT')
|
|
IF thisShipTm = '' THEN
|
|
ErrorMsg = 'Invalid ShipTm ':QUOTE(ShipTm):' parameter passed to routine. (':Method:')'
|
|
RETURN
|
|
END
|
|
|
|
otParms = 'RDS':@RM:RdsNo
|
|
RDSRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock
|
|
|
|
IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock
|
|
|
|
IF RDSRec<RDS_SHIP_NO$> = '' OR RDSRec<RDS_SHIP_NO$> = ShipNo THEN
|
|
RDSRec<RDS_SHIP_NO$> = ShipNo
|
|
RDSRec<RDS_SHIP_DATE$> = thisShipDt
|
|
RDSRec<RDS_SHIP_TIME$> = thisShipTm
|
|
RDSRec<RDS_STATUS$> = 'S'
|
|
|
|
otParms = FIELDSTORE(otParms,@RM,4,0,RDSRec)
|
|
obj_Tables('WriteRec',otParms)
|
|
|
|
END ELSE
|
|
obj_Tables('UnlockRec',otParms)
|
|
ErrorMsg = "RDS was already shipped on shipment" :QUOTE(RDSRec<RDS_SHIP_NO$>): ". (" :Method: ")"
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
RemShip:
|
|
* * * * * * *
|
|
|
|
ShipNo = Parms[1,@RM]
|
|
RdsNo = Parms[COL2()+1,@RM]
|
|
|
|
IF NOT(ASSIGNED(RdsNo)) THEN ErrorMsg = 'Unassigned Parm "RdsNo" passed to routine. (':Method:')'
|
|
IF NOT(ASSIGNED(ShipNo)) THEN ErrorMsg = 'Unassigned Parm "ShipNo" passed to routine. (':Method:')'
|
|
|
|
IF ErrorMsg NE '' THEN RETURN
|
|
|
|
IF RdsNo = '' THEN ErrorMsg = 'Null Parm "RdsNo" passed to routine. (':Method:')'
|
|
IF ShipNo = '' THEN ErrorMsg = 'Null Parm "ShipNo" passed to routine. (':Method:')'
|
|
|
|
IF ErrorMsg NE '' THEN RETURN
|
|
|
|
otParms = 'RDS':@RM:RdsNo
|
|
RDSRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock
|
|
|
|
IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock
|
|
|
|
IF RDSRec<RDS_SHIP_NO$> = ShipNo OR RDSRec<RDS_SHIP_NO$> = '' THEN
|
|
RDSRec<RDS_SHIP_NO$> = ''
|
|
RDSRec<RDS_SHIP_DATE$> = ''
|
|
RDSRec<RDS_SHIP_TIME$> = ''
|
|
RDSRec<RDS_STATUS$> = 'R'
|
|
|
|
otParms = FIELDSTORE(otParms,@RM,4,0,RDSRec)
|
|
obj_Tables('WriteRec',otParms)
|
|
|
|
END ELSE
|
|
obj_Tables('UnlockRec',otParms)
|
|
ErrorMsg = "Passed Ship No " :QUOTE(ShipNo): " doesn't match Ship No on RDS " :QUOTE(RdsNo): ". (" :Method: ")"
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
RefreshRDSSpec:
|
|
* * * * * * *
|
|
|
|
RdsNos = Parms[1,@RM]
|
|
|
|
IF RdsNos = '' THEN RETURN
|
|
|
|
RTParms = 'RDS'
|
|
LockedRDSNos = ''
|
|
|
|
FOR I = 1 TO COUNT(RdsNos,@VM) + (RdsNos NE '')
|
|
RdsNo = RdsNos<1,I>
|
|
RTParms = FieldStore(RTParms, @RM, 2, 1, RdsNo)
|
|
|
|
obj_Tables('LockRec',RTParms)
|
|
IF Get_Status(errCode) THEN
|
|
|
|
FOR N = 1 TO COUNT(LockedRDSNos,@VM) + (LockedRDSNos NE '')
|
|
RTParms = FieldStore(RTParms, @RM, 2, 1, LockedRDSNos<1,N>)
|
|
obj_Tables('UnlockRec',RTParms) ;* Unlock everything locked up to here
|
|
NEXT N
|
|
|
|
ErrorMsg = 'Unable to lock RDS ':QUOTE(RdsNo):' for update.'
|
|
obj_Tables('UnlockRec',OTParms)
|
|
RETURN
|
|
END ELSE
|
|
LockedRDSNos<1,-1> = RdsNo
|
|
END
|
|
NEXT I
|
|
|
|
|
|
RDSTableVar = FIELD(RTParms,@RM,3)
|
|
|
|
FOR N = 1 TO COUNT(LockedRDSNos,@VM) + (LockedRDSNos NE '')
|
|
LockedRDSNo = LockedRDSNos<1,N>
|
|
READ RDSRec FROM RDSTableVar,LockedRDSNo THEN
|
|
PS_No = RDSRec<RDS_PROD_SPEC_ID$>
|
|
|
|
PSRec = XLATE('PROD_SPEC',PS_No,'','X')
|
|
|
|
RDSRec<RDS_SPECIAL_INST$> = PSRec<PROD_SPEC_SPEC_INST$>
|
|
RDSRec<RDS_SPEC_TYPE_ORIG$> = XLATE('PROD_SPEC',PS_No,'SPEC_TYPE','X')
|
|
|
|
LayerSpecs = obj_Prod_Spec('GetLayerProp',PS_No:@RM:@RM:1) ;* Returns specs for all layers
|
|
|
|
* LayerSpecs is @RM between layers, @FM between fields, LayerSet ID is in the first Field and needs to peeled off
|
|
* before the equates match up correctly
|
|
|
|
* Prod_Spec table has layer specs all in one field
|
|
* RDS has First layer stuff in individual fields and then has 2 and 3 shoved into Field 33 (Layer Info)
|
|
|
|
LayerSpec = FIELD(LayerSpecs,@RM,1) ;* Take the first Layer
|
|
LayerSet = FIELD(LayerSpec,@FM,1) ;* Not used here but shown for clarity
|
|
LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
|
|
RecipeNo = LayerSpec<PRS_LAYER_RECIPE$>
|
|
RecipeRec = XLATE('RECIPE',RecipeNo,'','X') ;* This used in 2nd and 3rd layer stuff (in error it appears)
|
|
|
|
* IF RecipeNo NE RDSRec<RDS_RECIPE_NO$> THEN
|
|
* RDSRec<RDS_RECIPE_NO$> = RecipeNo
|
|
* END
|
|
|
|
RDSRec<RDS_CON_MIN_ORG$> = LayerSpec<PRS_LAYER_CONC_MIN$>
|
|
RDSRec<RDS_CON_MAX_ORG$> = LayerSpec<PRS_LAYER_CONC_MAX$>
|
|
RDSRec<RDS_CON_UNITS_ORG$> = LayerSpec<PRS_LAYER_CONC_UNITS$>
|
|
RDSRec<RDS_CON_TARGET_ORG$> = LayerSpec<PRS_LAYER_CONC_TARGET$>
|
|
|
|
RDSRec<RDS_RES_MIN_ORG$> = LayerSpec<PRS_LAYER_RES_MIN$>
|
|
RDSRec<RDS_RES_MAX_ORG$> = LayerSpec<PRS_LAYER_RES_MAX$>
|
|
RDSRec<RDS_RES_UNITS_ORG$> = LayerSpec<PRS_LAYER_RES_UNITS$>
|
|
RDSRec<RDS_RES_TARGET_ORG$> = LayerSpec<PRS_LAYER_RES_TARGET$>
|
|
|
|
RDSRec<RDS_THICK_MIN_ORG$> = LayerSpec<PRS_LAYER_THICK_MIN$>
|
|
RDSRec<RDS_THICK_MAX_ORG$> = LayerSpec<PRS_LAYER_THICK_MAX$>
|
|
RDSRec<RDS_THICK_UNITS_ORG$> = LayerSpec<PRS_LAYER_THICK_UNITS$>
|
|
RDSRec<RDS_THICK_TARGET_ORG$> = LayerSpec<PRS_LAYER_THICK_TARGET$>
|
|
|
|
LayerInfo = ''
|
|
|
|
FOR I = 2 TO COUNT(LayerSpecs,@RM) + (LayerSpecs NE '')
|
|
LayerSpec = FIELD(LayerSpecs,@RM,I) ;* Take the Ith Layer
|
|
LayerSpec = FIELD(LayerSpec,@FM,2,99) ;* LayerSpec without the LayerSet
|
|
|
|
thisLayerInfo = '' ;* Empty bucket to parse into
|
|
|
|
thisLayerInfo<1,RLConMin$> = LayerSpec<PRS_LAYER_CONC_MIN$>
|
|
thisLayerInfo<1,RLConMax$> = LayerSpec<PRS_LAYER_CONC_MAX$>
|
|
thisLayerInfo<1,RLConUnits$> = LayerSpec<PRS_LAYER_CONC_UNITS$>
|
|
thisLayerInfo<1,RLConTarget$> = LayerSpec<PRS_LAYER_CONC_TARGET$>
|
|
|
|
thisLayerInfo<1,RLRecipeNo$> = RecipeNo ;* Copied from the original in the WRITE event of the Schedule window
|
|
thisLayerInfo<1,RLThickRead$> = STR(@SVM,16)
|
|
thisLayerInfo<1,RLSheetRhoRead$> = STR(@SVM,16)
|
|
|
|
thisLayerInfo<1,RLResMin$> = LayerSpec<PRS_LAYER_RES_MIN$>
|
|
thisLayerInfo<1,RLResMax$> = LayerSpec<PRS_LAYER_RES_MAX$>
|
|
thisLayerInfo<1,RLResUnits$> = LayerSpec<PRS_LAYER_RES_UNITS$>
|
|
thisLayerInfo<1,RLResTarget$> = LayerSpec<PRS_LAYER_RES_TARGET$>
|
|
|
|
thisLayerInfo<1,RLThickMin$> = LayerSpec<PRS_LAYER_THICK_MIN$>
|
|
thisLayerInfo<1,RLThickMax$> = LayerSpec<PRS_LAYER_THICK_MAX$>
|
|
thisLayerInfo<1,RLThickUnits$> = LayerSpec<PRS_LAYER_THICK_UNITS$>
|
|
thisLayerInfo<1,RLThickTarget$> = LayerSpec<PRS_LAYER_THICK_TARGET$>
|
|
|
|
LayerInfo := thisLayerInfo:CHAR(248)
|
|
|
|
NEXT I
|
|
|
|
LayerInfo[-1,1] = '' ;* Strip trailing CHAR(248)
|
|
|
|
RDSRec<RDS_LAYER_INFO$> = LayerInfo ;* End of the great Layer cluster function
|
|
|
|
RTParms = FieldStore(RTParms, @RM, 2, 1, LockedRDSNo)
|
|
RTParms = FieldStore(RTParms, @RM, 4, 1, RDSRec)
|
|
obj_Tables('WriteRec',RTParms) ;* Write and unlock RDS records
|
|
END
|
|
NEXT N
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
WMInKeys:
|
|
* * * * * * *
|
|
|
|
InFlag = 1
|
|
OutFlag = 0
|
|
|
|
GOTO WMKeys
|
|
|
|
|
|
* * * * * * *
|
|
WMOutKeys:
|
|
* * * * * * *
|
|
|
|
OutFlag = 1
|
|
InFlag = 0
|
|
|
|
|
|
* * * * * * *
|
|
WMKeys:
|
|
* * * * * * *
|
|
|
|
RDSNo = Parms[1,@RM]
|
|
RDSRec = Parms[COL2()+1,@RM]
|
|
|
|
IF RDSNo = '' THEN RETURN
|
|
IF RDSRec = '' THEN RDSRec = XLATE('RDS',RDSNo,'','X')
|
|
|
|
IF InFlag THEN
|
|
CassNos = RDSRec<RDS_IN_CASS_NO$>
|
|
END ELSE
|
|
CassNos = RDSRec<RDS_OUT_CASS_NO$>
|
|
END
|
|
|
|
WOStepKey = RDSRec<RDS_WO_STEP_KEY$>
|
|
|
|
CassIDS = ''
|
|
|
|
FOR I = 1 TO COUNT(CassNos,@VM) + (CassNos NE '')
|
|
CassNo = CassNos<1,I>
|
|
IF CassNo NE '' THEn
|
|
LOCATE WOStepKey:'*':CassNo IN CassIDS BY 'AR' USING @VM SETTING Pos ELSE
|
|
CassIDS = INSERT(CassIDS,1,Pos,0,WOStepKey:'*':CassNo)
|
|
END
|
|
END
|
|
NEXT I
|
|
|
|
Result = CassIDS
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
SetSchedWfrQty:
|
|
* * * * * * *
|
|
|
|
RdsNo = Parms[1,@RM]
|
|
SchedWfrQty = Parms[COL2()+1,@RM]
|
|
|
|
IF RdsNo = '' THEN ErrorMsg = 'Null Parm "RdsNo" passed to routine. (':Method:')'
|
|
IF SchedWfrQty = '' THEN ErrorMsg = 'Null Parm "SchedWfrQty" passed to routine. (':Method:')'
|
|
|
|
IF ErrorMsg NE '' THEN RETURN
|
|
|
|
otParms = 'RDS':@RM:RdsNo
|
|
RDSRec = obj_Tables('ReadRec',otParms) ;* Reads and sets lock
|
|
|
|
IF Get_Status(errCode) THEN RETURN ;* Problems getting the lock
|
|
|
|
RDSRec<RDS_CASS_WAFER_QTY$> = SchedWfrQty
|
|
|
|
otParms = FIELDSTORE(otParms,@RM,4,0,RDSRec)
|
|
obj_Tables('WriteRec',otParms)
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
MU_ADE_Reads:
|
|
* * * * * * *
|
|
|
|
RDSNo = Parms[1,@RM]
|
|
RDSRec = Parms[COL2()+1,@RM]
|
|
|
|
IF RDSNo = '' THEN RETURN
|
|
IF RDSRec = '' THEN RDSRec = XLATE('RDS',RDSNo,'','X')
|
|
|
|
|
|
IF RDSRec = '' THEN RETURN
|
|
|
|
WONo = RDSRec<RDS_WO$>
|
|
CassNo = RDSRec<RDS_CASS_NO$>
|
|
|
|
MUCassIDs = obj_WO_Mat('GetMUCassIDs',WONo:'*':CassNo)
|
|
|
|
Result = XLATE('WO_MAT',MUCassIDs,'ADE_READ','X')
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * * *
|
|
MetPropFlag:
|
|
* * * * * * * *
|
|
|
|
RDSNo = Parms[1,@RM]
|
|
RDSRec = Parms[COL2()+1,@RM]
|
|
PropCd = Parms[COL2()+1,@RM]
|
|
|
|
IF RDSNo = '' THEN RETURN
|
|
IF PropCd = '' THEN RETURN
|
|
IF RDSRec = '' THEN RDSRec = XLATE('RDS',RDSNo,'','X')
|
|
|
|
IF RDSRec = '' THEN RETURN
|
|
|
|
WONo = RDSRec<RDS_WO$>
|
|
WOStepKey = RDSRec<RDS_WO_STEP_KEY$>
|
|
ReactNo = RDSRec<RDS_REACTOR$>
|
|
PSNo = RDSRec<RDS_PROD_SPEC_ID$>
|
|
|
|
WOStepNo = FIELD(WOStepKey,'*',2)
|
|
|
|
ReactRDSNos = XLATE('WO_REACT',WONo:'*':WOStepNo:'*':ReactNo,WO_REACT_RDS_NO$,'X')
|
|
|
|
LOCATE RDSNo IN ReactRDSNos USING @VM SETTING Pos THEN
|
|
Result = obj_PRS_Prop('GetIntervalFlag',PSNo:@RM:PropCd:@RM:Pos)
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
* P r i v a t e M e t h o d s *
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
* * * * * * *
|
|
CalcConTarget:
|
|
* * * * * * *
|
|
|
|
IF RDSConMin AND RDSConMax THEN
|
|
IF RDSConMin = RDSConMax THEN
|
|
RDSConTarget = RDSConMin
|
|
END ELSE
|
|
Delta = INT((RdsConMax-RDSConMin)/2)
|
|
RDSConTarget = RDSConMin + Delta
|
|
END
|
|
END ELSE
|
|
RDSConTarget = ''
|
|
END
|
|
|
|
RETURN
|
|
|
|
|
|
* * * * * * *
|
|
CalcResTarget:
|
|
* * * * * * *
|
|
|
|
IF RDSResMin AND RDSResMax THEN
|
|
IF RDSResMin = RDSResMax THEN
|
|
RDSResTarget = RDSResMin
|
|
END ELSE
|
|
Delta = INT((RdsResMax-RDSResMin)/2)
|
|
RDSResTarget = RDSResMin + Delta
|
|
END
|
|
END ELSE
|
|
RDSResTarget = ''
|
|
END
|
|
|
|
RETURN
|
|
|
|
* * * * * * *
|
|
CalcThickTarget:
|
|
* * * * * * *
|
|
|
|
IF RDSThickMin AND RDSThickMax THEN
|
|
IF RDSThickMin = RDSThickMax THEN
|
|
RDSThickTarget = RDSThickMin
|
|
END ELSE
|
|
Delta = INT((RdsThickMax-RDSThickMin)/2)
|
|
RDSThickTarget = RDSThickMin + Delta
|
|
END
|
|
END ELSE
|
|
RDSThickTarget = ''
|
|
END
|
|
RETURN
|
|
|
|
|