open-insight/LSL2/STPROC/WO_MAT_QA_ACTIONS.txt

608 lines
33 KiB
Plaintext

Function WO_MAT_QA_Actions(Action, CalcColName, FSList, Handle, Name, FMC, Record, Status, OrigRecord, Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)
/***********************************************************************************************************************
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
permission from Infineon.
Name : WO_MAT_QA_Actions
Description : Handles calculated columns and MFS calls for the current table.
Notes : This function uses @ID, @RECORD, and @DICT to make sure {ColumnName} references work correctly.
If called from outside of a calculated column these will need to be set and restored.
Parameters :
Action [in] -- Name of the action to be taken
CalcColName [in] -- Name of the calculated column that needs to be processed. Normally this should only be
populated when the CalcField action is being used.
FSList [in] -- The list of MFSs and the BFS name for the current file or volume. This is an @SVM
delimited array, with the current MFS name as the first value in the array, and the BFS
name as the last value. Normally set by a calling MFS.
Handle [in] -- The file handle of the file or media map being accessed. Note, this does contain the
entire handle structure that the Basic+ Open statement would provide. Normally set by a
calling MFS.
Name [in] -- The name (key) of the record or file being accessed. Normally set by a calling MFS.
FMC [in] -- Various functions. Normally set by a calling MFS.
Record [in] -- The entire record (for record-oriented functions) or a newly-created handle (for
"get handle" functions). Normally set by a calling MFS.
Status [in/out] -- Indicator of the success or failure of an action. Normally set by the calling MFS but
for some actions can be set by the action handler to indicate failure.
OrigRecord [in] -- Original content of the record being processed by the current action. This is
automatically being assigned by the WRITE_RECORD and DELETE_RECORD actions within
BASE_MFS.
Param1-10 [in/out] -- Additional request parameter holders
ActionFlow [out] -- Used to control the action chain (see the ACTION_SETUP insert for more information.)
Can also be used to return a special value, such as the results of the CalcField
method.
History : (Date, Initials, Notes)
10/22/18 djs Original programmer.
***********************************************************************************************************************/
#pragma precomp SRP_PreCompiler
$insert LOGICAL
$insert FILE.SYSTEM.EQUATES
$insert ACTION_SETUP
$insert RDS_TEST_EQUATES
$insert RDS_EQUATES
$insert WO_LOG_EQUATES
$insert WM_OUT_EQUATES
$insert WM_IN_EQUATES
$insert WO_MAT_EQUATES
$insert WO_MAT_QA_EQUATES
$insert PRS_STAGE_EQUATES
$insert TOOL_CLASS_EQUATES
Declare function Database_Services, obj_NCR, obj_SAP, Qa_Services, SRP_Trim, Environment_Services, Logging_Services
Declare subroutine Error_Services, Database_Services, obj_NCR, obj_SAP, Post_Metrology_Manual_Data_Entry_Log
Declare subroutine Logging_Services, obj_Notes
Equ CRLF$ to \0D0A\
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\WO_MAT_QA'
LogDate = Oconv(Date(), 'D4/')
LogTime = Oconv(Time(), 'MTS')
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' WO_MAT_QA Log.csv'
Headers = 'Logging DTM' : @FM : 'User' : @FM : 'Key ID' : @FM : 'Call Stack' : @FM : 'Record'
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\FQABlocked'
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' FQA Log.csv'
Headers = 'Logging DTM' : @FM : 'RDS Key ID' : @FM : 'Table' : @FM : 'Key' : @FM : 'Notes'
FQAobjLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, Comma$, Headers, '', False$, False$)
If KeyID then GoSub Initialize_System_Variables
Begin Case
Case Action _EQC 'CalcField' ; GoSub Calc_Field
Case Action _EQC 'READ_RECORD_PRE' ; GoSub READ_RECORD_PRE
Case Action _EQC 'READ_RECORD' ; GoSub READ_RECORD
Case Action _EQC 'READONLY_RECORD_PRE' ; GoSub READONLY_RECORD_PRE
Case Action _EQC 'READONLY_RECORD' ; GoSub READONLY_RECORD
Case Action _EQC 'WRITE_RECORD_PRE' ; GoSub WRITE_RECORD_PRE
Case Action _EQC 'WRITE_RECORD' ; GoSub WRITE_RECORD
Case Action _EQC 'DELETE_RECORD_PRE' ; GoSub DELETE_RECORD_PRE
Case Action _EQC 'DELETE_RECORD' ; GoSub DELETE_RECORD
Case Otherwise$ ; Status = 'Invalid Action'
End Case
If KeyID then GoSub Restore_System_Variables
If Assigned(ActionFlow) else ActionFlow = ACTION_CONTINUE$
Return ActionFlow
// ----- Calculated Columns --------------------------------------------------------------------------------------------
//
// The typical structure of a calculated column will look like this:
//
// Declare function TableName_Actions
//
// A = {COL1} ; * Reference as many data columns in this way to ensure the dictionary dependency is generated.
//
// @ANS = TableName_Actions('CalcField', 'CalcColName')
//
// ---------------------------------------------------------------------------------------------------------------------
Calc_Field:
// Make sure the ActionFlow return variable is cleared in case nothing is calculated.
ActionFlow = ''
return
// ----- MFS calls -----------------------------------------------------------------------------------------------------
READ_RECORD_PRE:
// In order to stop a record from being read in this action these lines of code must be used:
//
// OrigFileError = 100 : @FM : KeyID
// Status = 0
// Record = ''
// ActionFlow = ACTION_STOP$
return
READ_RECORD:
// In order to stop a record from being read in this action these lines of code must be used:
//
// OrigFileError = 100 : @FM : KeyID
// Status = 0
// Record = ''
return
READONLY_RECORD_PRE:
// In order to stop a record from being read in this action these lines of code must be used:
//
// OrigFileError = 100 : @FM : KeyID
// Status = 0
// Record = ''
// ActionFlow = ACTION_STOP$
return
READONLY_RECORD:
// In order to stop a record from being read in this action these lines of code must be used:
//
// OrigFileError = 100 : @FM : KeyID
// Status = 0
// Record = ''
return
WRITE_RECORD_PRE:
WorkOrderNo = Field(Name, '*', 1, 1)
CassNo = Field(Name, '*', 2, 1)
WOMatKey = WorkOrderNo : '*' : CassNo
FinalQA = False$
WorkOrderRow = Database_Services('ReadDataRow', 'WO_LOG', WorkOrderNo)
ReactType = WorkOrderRow<WO_LOG_REACT_TYPE$>
// Check to see if the Final QA signature is in place.
If ReactType EQ 'EPP' then
WMOutKey = WorkOrderNo : '*1*' : CassNo
WMOutRow = Database_Services('ReadDataRow', 'WM_OUT', WMOutKey)
If WMOutRow<WM_OUT_SUP_VER_SIG$> NE '' then
FinalQA = True$
end
end else
RDSNo = Xlate('WO_MAT', WOMatKey, 'RDS_NO', 'X')
RDSRow = Database_Services('ReadDataRow', 'RDS', RDSNo)
If RDSRow<RDS_SUP_VER_SIG$> NE '' then
FinalQA = True$
end
end
Begin Case
Case Record EQ ''
// Unscheduled record write attempt. Block the write and log the event.
ErrorMessage = 'Empty WO_MAT_QA profile. Unscheduled record write attempt!'
Error_Services('Add', 'FS104: ':ErrorMessage)
OrigFileError = 104 : @FM : ErrorMessage
Stack = RetStack()
Swap @FM with ' || ' in Stack
RecordSnapshot = Record
Swap @FM with CRLF$ in RecordSnapshot
Swap @VM with ' @VM ' in RecordSnapshot
Swap @SVM with ' @SVM ' in RecordSnapshot
Swap @TM with ' @TM ' in RecordSnapshot
Swap @STM with ' @STM ' in RecordSnapshot
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = @User4
LogData<3> = Name
LogData<4> = Stack
LogData<5> = CRLF$:RecordSnapshot:CRLF$
LogData<6> = 'FS104: ':ErrorMessage
// Sending a null message will send the LogData instead
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, '', '', '')
// Send an internal OI message to OI admins
Recipients = Xlate('SEC_GROUPS', 'OI_ADMIN', 'USER', 'X')
SentFrom = 'SYSTEM'
Subject = 'Unscheduled WO_MAT_QA record write attempt.'
Message = ErrorMessage
AttachWindow = ''
AttachKey = ''
SendToGroup = ''
Parms = Recipients:@RM:SentFrom:@RM:Subject:@RM:Message:@RM:AttachWindow:@RM:AttachKey:@RM:SendToGroup
obj_Notes('Create',Parms)
Status = 0
Record = ''
ActionFlow = ACTION_STOP$
Case FinalQA EQ True$
// User is attempting to modify this row. Set the FS104 error and log the event.
OrigFileError = 104 : @FM : 'FQA has already been signed. WO_MAT_QA record cannot be updated!'
LogData = ''
LogData<1> = LoggingDTM
LogData<2> = @User4
LogData<3> = WOMatKey
LogData<4> = 'WO_MAT_QA'
LogData<5> = Name
LogData<6> = 'FS104:FQA has already been signed. WO_MAT_QA record cannot be updated!'
Logging_Services('AppendLog', FQAobjLog, LogData, @RM, @FM)
Status = 0
Record = ''
ActionFlow = ACTION_STOP$
Error_Services('Add', 'FS104:FQA has already been signed. WO_MAT_QA record cannot be updated!')
Case Otherwise$
// Validate metrology data
// Current values in record
OrigDataPoints = OrigRecord<WO_MAT_QA_DATA_POINTS$>
OrigProfiles = OrigRecord<WO_MAT_QA_PROFILE$>
OrigResult = OrigRecord<WO_MAT_QA_RESULT$>
OrigSigs = OrigRecord<WO_MAT_QA_SIG$>
OrigSpecMin = OrigRecord<WO_MAT_QA_MIN$>
OrigSpecMax = OrigRecord<WO_MAT_QA_MAX$>
// New values to be saved
DataPoints = Record<WO_MAT_QA_DATA_POINTS$>
Profiles = Record<WO_MAT_QA_PROFILE$> ; // THICK_ONLY, CRES
Sigs = Record<WO_MAT_QA_SIG$>
SigDTMS = Record<WO_MAT_QA_SIG_DTM$>
Result = Record<WO_MAT_QA_RESULT$> ; // Average of Data Points
MinResult = Record<WO_MAT_QA_MIN_RESULT$> ; // Min of Data Points
MaxResult = Record<WO_MAT_QA_MAX_RESULT$> ; // Max of Data Points
RangePctResult = Record<WO_MAT_QA_RANGE_PCT_RESULT$> ; // Range % of Data Points
EdgeMeanResult = Record<WO_MAT_QA_EDGE_MEAN_RESULT$> ; // Edge Mean Delta of Data Points
SpecMin = Record<WO_MAT_QA_MIN$>
SpecMax = Record<WO_MAT_QA_MAX$>
SpecPhaseMin = Record<WO_MAT_QA_PHASE_MIN$>
OutOfSpec = Record<WO_MAT_QA_OUT_OF_SPEC$>
FailReasons = Record<WO_MAT_QA_FAIL_REASON$>
ScanRecipes = Record<WO_MAT_QA_RECIPE$>
Stages = Record<WO_MAT_QA_STAGE$>
PSN = {PS_NO}
RawThicknessData = ''
RawHgCVData = ''
RawPhaseData = ''
// Only enter validation code below if relevant data has changed.
If ( (OrigDataPoints NE DataPoints) or (OrigProfiles NE Profiles) or (OrigResult NE Result) |
or (OrigSigs NE Sigs) or (OrigSpecMin NE SpecMin) or (OrigSpecMax NE SpecMax) ) then
Profile = ''
For each Profile in Profiles using @VM setting ProfileIndex
Stage = Stages<1, ProfileIndex>
PRSStageKey = PSN:'*':Stage
PRSStageRec = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey)
SpecRecipes = PRSStageRec<PRS_STAGE_MET_RECIPE$>
SpecProfiles = PRSStageRec<PRS_STAGE_MET_TEST$>
Begin Case
Case ( (Profile EQ '1THICK_ONLY') and (Stage EQ 'UNLOAD') )
FailReason = ''
ThickOutOfSpec = False$
ToolClassID = Record<WO_MAT_QA_TOOL_CLASS$, ProfileIndex>
ToolClassRec = Database_Services('ReadDataRow', 'TOOL_CLASS', ToolClassID)
RecipePattern = Record<WO_MAT_QA_RECIPE_PATTERN$, ProfileIndex>
RequiredDataPoints = ''
Locate RecipePattern in ToolClassRec<TOOL_CLASS_PATTERN$> setting rPos then
RequiredDataPoints = ToolClassRec<TOOL_CLASS_PATTERN_SIZE$, rPos>
end
ScanProfile = Profile
ScanProfile[1,1] = ''
Locate ScanProfile in SpecProfiles using @VM setting vPos then
SpecRecipe = SpecRecipes<1, vPos>
ScanRecipe = ScanRecipes<1, ProfileIndex>
If ScanRecipe NE SpecRecipe then
ThickOutOfSpec = True$
FailReason = 'Scanned THICK_ONLY UNLOAD recipe, ':ScanRecipe:', does not match spec ' |
: 'recipe, ':SpecRecipe:'.'
end
end
SaveList = ''
ThickSig = Sigs<1, ProfileIndex>
ThickSigDTM = SigDTMS<1, ProfileIndex>
ThickSpecMin = SpecMin<1, ProfileIndex>
ThickSpecMax = SpecMax<1, ProfileIndex>
ThicknessData = DataPoints<1, ProfileIndex>
ResAvg = Result<1, ProfileIndex>
ThicknessDataCount = 0
For each DataPoint in ThicknessData using @SVM setting ThickIndex
Until DataPoint EQ ''
Begin Case
Case ThickIndex GT 10
Null
Case (DataPoint EQ '')
ThickOutOfSpec = True$
FailReason = 'Thickness data point ':ThickIndex:' is missing.'
Case (DataPoint GT ThickSpecMax) OR (DataPoint LT ThickSpecMin)
ThickOutOfSpec = True$
FailReason = 'Thickness data point ':ThickIndex:' is out of bounds.'
End Case
SaveList<1, 1, ThickIndex> = DataPoint
RawThicknessData<1, ThickIndex> = DataPoint
ThicknessDataCount += 1
Next DataPoint
DataPoints<1, ProfileIndex> = SaveList
If ThicknessDataCount LT RequiredDataPoints then
ThickOutOfSpec = True$
FailReason = 'Number of data points is less than the required amount of ' : RequiredDataPoints : '!'
end
If RawThicknessData NE '' then
Response = QA_Services('CalculateThickData', RawThicknessData)
ThickAvg = Response<1,1>
ThickMin = Response<1,2>
ThickMax = Response<1,3>
Result<1, ProfileIndex> = ThickAvg
MinResult<1, ProfileIndex> = ThickMin
MaxResult<1, ProfileIndex> = ThickMax
end else
// Lead/Supervisor/Engineer is overriding the typical workflow and is
// entering the Thickness average only.
ThickAvg = ResAvg
Begin Case
Case (ThickAvg EQ '')
ThickOutOfSpec = True$
FailReason = 'Thickness average is missing.'
Case (ThickAvg GT ThickSpecMax) OR (ThickAvg LT ThickSpecMin)
ThickOutOfSpec = True$
FailReason = 'Thickness average is out of bounds.'
End Case
end
If ThickOutOfSpec EQ False$ then
// Final failure check. Only check if a previous failure reason has not been set as to not
// ovewrite the previous failure reason.
If (ThickSig EQ '') or (ThickSigDTM EQ '') then
ThickOutOfSpec = True$
FailReason = 'THICK_ONLY UNLOAD product measurement test has not been signed.'
end
end
OutOfSpec<1, ProfileIndex> = ThickOutOfSpec
FailReasons<1, ProfileIndex> = FailReason
Case ( (Profile EQ '1CRES') and (Stage EQ 'UNLOAD') )
CresOutOfSpec = False$
FailReason = ''
ToolClassID = Record<WO_MAT_QA_TOOL_CLASS$, ProfileIndex>
ToolClassRec = Database_Services('ReadDataRow', 'TOOL_CLASS', ToolClassID)
RecipePattern = Record<WO_MAT_QA_RECIPE_PATTERN$, ProfileIndex>
RequiredDataPoints = ''
Locate RecipePattern in ToolClassRec<TOOL_CLASS_PATTERN$> setting rPos then
RequiredDataPoints = ToolClassRec<TOOL_CLASS_PATTERN_SIZE$, rPos>
end
ScanProfile = Profile
ScanProfile[1,1] = ''
Locate ScanProfile in SpecProfiles using @VM setting vPos then
SpecRecipe = SpecRecipes<1, vPos>
ScanRecipe = ScanRecipes<1, ProfileIndex>
If ScanRecipe NE SpecRecipe then
CresOutOfSpec = True$
FailReason = 'Scanned CRES UNLOAD recipe, ':ScanRecipe:', does not match spec ' |
: 'recipe, ':SpecRecipe:'.'
end
end
SaveList = ''
CriticalPoints = '1,2,5,6,9'
CRESSig = Sigs<1, ProfileIndex>
CRESSigDTM = SigDTMS<1, ProfileIndex>
HgCVSpecMin = SpecMin<1, ProfileIndex>
HgCVSpecMax = SpecMax<1, ProfileIndex>
ThisPhaseMin = SpecPhaseMin<1, ProfileIndex>
HgCVData = DataPoints<1, ProfileIndex>
// Adding Result Average here in the case that a lead manually only enters the averages.
ResAvg = Result<1, ProfileIndex>
If ThisPhaseMin EQ '' then
// Spec Phase Min was not added when the record initially created, so add it here.
PSN = Xlate('RDS', RDSNo, 'PROD_SPEC_ID', 'X')
If PSN NE '' then
PRSStageKey = PSN:'*UNLOAD'
PRSStageRec = Database_Services('ReadDataRow', 'PRS_STAGE', PRSStageKey)
MetProps = PRSStageRec<PRS_STAGE_MET_PROP$>
Locate 'CRES' in MetProps using @VM setting PropPos then
SpecPhaseMinCol = PRSStageRec<PRS_STAGE_MET_PHASE_MIN$>
ThisPhaseMin = SpecPhaseMinCol<1, PropPos>
SpecPhaseMin<1, ProfileIndex> = ThisPhaseMin
Record<WO_MAT_QA_PHASE_MIN$> = SpecPhaseMin
end
end
end
ResDataCount = 0
For each DataPoint in HgCVData using @SVM setting CresIndex
Until DataPoint EQ ''
HgCVDataPoint = DataPoint[1, 'F':@TM]
PhaseDataPoint = DataPoint[-1, 'B':@TM]
CriticalPoint = Index(CriticalPoints, CresIndex, 1)
Begin Case
Case (HgCVDataPoint EQ '') and CriticalPoint
CresOutOfSpec = True$
FailReason = 'HgCV data point: ':CresIndex:' is missing data.'
Case (PhaseDataPoint EQ '') and CriticalPoint
CresOutOfSpec = True$
FailReason = 'Phase data point: ':CresIndex:' is missing data.'
Case (HgCVDataPoint GT HgCVSpecMax) OR (HgCVDataPoint LT HgCVSpecMin) and CriticalPoint
CresOutOfSpec = True$
FailReason = 'HgCV data point: ':CresIndex:' is out of bounds.'
Case (PhaseDataPoint LT ThisPhaseMin) and CriticalPoint
CresOutOfSpec = True$
FailReason = 'Phase data point: ':CresIndex:' is out of bounds.'
End Case
RawHgCVData<1, CresIndex> = HgCVDataPoint
RawPhaseData<1, CresIndex> = PhaseDataPoint
ResDataCount += 1
Next DataPoint
If ResDataCount LT RequiredDataPoints then
CresOutOfSpec = True$
FailReason = 'Number of data points is less than the required amount of ' : RequiredDataPoints : '!'
end
If (RawHgCVData NE '') AND (RawPhaseData NE '') then
Response = QA_Services('CalculateHgCVData', RawHgCVData)
HgCVAvg = Response<1,1>
HgCVMin = Response<1,2>
HgCVMax = Response<1,3>
HgCVEdgeMean = Response<1,4>
HgCVRangePct = Response<1,5>
Response = QA_Services('CalculateHgCVData', RawPhaseData)
PhaseAvg = Response<1,1>
PhaseMin = Response<1,2>
PhaseMax = Response<1,3>
PhaseEdgeMean = Response<1,4>
PhaseRangePct = Response<1,5>
DataPoints<1, ProfileIndex> = HgCVData
Result<1, ProfileIndex> = HgCVAvg : @SVM : PhaseAvg
MinResult<1, ProfileIndex> = HgCVMin : @SVM : PhaseMin
MaxResult<1, ProfileIndex> = HgCVMax : @SVM : PhaseMax
EdgeMeanResult<1, ProfileIndex> = HgCVEdgeMean : @SVM : PhaseEdgeMean
RangePctResult<1, ProfileIndex> = HgCVRangePct : @SVM : PhaseRangePct
end else
// Lead/Supervisor/Engineer is overriding the typical workflow and is
// entering the HgCV average and Phase average only.
HgCVAvg = ResAvg<1, 1, 1>
PhaseAvg = ResAvg<1, 1, 2>
Begin Case
Case (HgCVAvg EQ '')
CresOutOfSpec = True$
FailReason = 'HgCV average is missing.'
Case (PhaseAvg EQ '')
CresOutOfSpec = True$
FailReason = 'Phase average is missing.'
Case (HgCVAvg GT HgCVSpecMax) OR (HgCVAvg LT HgCVSpecMin)
CresOutOfSpec = True$
FailReason = 'HgCV is out of bounds.'
Case (PhaseAvg LT ThisPhaseMin)
CresOutOfSpec = True$
FailReason = 'Phase is out of bounds.'
End Case
end
If CresOutOfSpec EQ False$ then
// Final failure check. Only check if a previous failure reason has not been set as to not
// overwrite the previous failure reason.
If (CRESSig EQ '') or (CRESSigDTM EQ '') then
CresOutofSpec = True$
FailReason = 'CRES UNLOAD product measurement test has not been signed.'
end
end
OutOfSpec<1, ProfileIndex> = CresOutOfSpec
FailReasons<1, ProfileIndex> = FailReason
OrigHgCVAvg = OrigRecord<WO_MAT_QA_RESULT$, ProfileIndex, 1>
If HgCVAvg NE OrigHgCVAvg then
Post_Metrology_Manual_Data_Entry_Log(@USER4, 'HgCRes', RDSNo : ' / ' : WorkOrderNo : '*' : CassNo)
end
Case ( (Profile EQ '1LW_RHO') and (Stage EQ 'UNLOAD') )
ThisOutOfSpec = False$
FailReason = ''
ThisSig = Sigs<1, ProfileIndex>
ThisSigDTM = SigDTMS<1, ProfileIndex>
ThisSpecMin = SpecMin<1, ProfileIndex>
ThisSpecMax = SpecMax<1, ProfileIndex>
ThisResult = Result<1, ProfileIndex>
ThisSpecTest = SpecProfiles<1, ProfileIndex>
If ( (ThisResult LT ThisSpecMin) or (ThisResult GT ThisSpecMax) ) then
ThisOutOfSpec = True$
FailReason = 'RHO is out of bounds.'
end
If ThisOutOfSpec EQ False$ then
If (ThisSig EQ '') or (ThisSigDTM EQ '') then
ThisOutOfSpec = True$
FailReason = Stage:' ':ThisSpecTest:' product measurement test has not been signed.'
end
end
OutOfSpec<1, ProfileIndex> = ThisOutOfSpec
FailReasons<1, ProfileIndex> = FailReason
Case Otherwise$
// This profile & stage do not currently have any specific validation code associated with them.
// Ensure 'out of spec' flag and 'fail reason' field for this profile are clear.
OutOfSpec<1, ProfileIndex> = False$
FailReasons<1, ProfileIndex> = ''
End Case
Next Profile
Record<WO_MAT_QA_DATA_POINTS$> = DataPoints
Record<WO_MAT_QA_RESULT$> = Result
Record<WO_MAT_QA_MIN_RESULT$> = MinResult
Record<WO_MAT_QA_MAX_RESULT$> = MaxResult
Record<WO_MAT_QA_EDGE_MEAN_RESULT$> = EdgeMeanResult
Record<WO_MAT_QA_RANGE_PCT_RESULT$> = RangePctResult
Record<WO_MAT_QA_OUT_OF_SPEC$> = OutOfSpec
Record<WO_MAT_QA_FAIL_REASON$> = FailReasons
SaveRecord = Record
end
End Case
return
WRITE_RECORD:
return
DELETE_RECORD_PRE:
return
DELETE_RECORD:
return
// ----- Internal Methods ----------------------------------------------------------------------------------------------
Initialize_System_Variables:
// Save these for restoration later
SaveDict = @DICT
SaveID = @ID
SaveRecord = @RECORD
OrigFileError = @FILE.ERROR
// Now make sure @DICT, ID, and @RECORD are populated
CurrentDictName = ''
If @DICT then
DictHandle = @DICT<1, 2>
Locate DictHandle in @TABLES(5) Using @FM Setting fPos then
CurrentDictName = Field(@TABLES(0), @FM, fPos, 1)
end
end
If CurrentDictName NE DictName then
Open DictName to @DICT else Status = 'Unable to initialize @DICT'
end
@ID = KeyID
If Record else
// Record might not have been passed in. Read the record from the database table just to make sure.
@FILE.ERROR = ''
Open TableName to hTable then
FullFSList = hTable[1, 'F' : @VM]
BFS = FullFSList[-1, 'B' : @SVM]
LastHandle = hTable[-1, 'B' : \0D\]
FileHandle = \0D\ : LastHandle[1, @VM]
Call @BFS(READO.RECORD, BFS, FileHandle, KeyID, FMC, Record, ReadOStatus)
end
end
@RECORD = Record
return
Restore_System_Variables:
Transfer SaveDict to @DICT
Transfer SaveID to @ID
Transfer SaveRecord to @RECORD
@FILE.ERROR = OrigFileError
return