Compile subroutine Material_Track(RptColumns, LocationFilter) /*********************************************************************************************************************** Name : Report_Services Description : Handler program for all Report 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) 10/30/20 djs Original programmer. ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $Insert LOGICAL $Insert OIPRINT_EQUATES $Insert SCHED_DET_EQUATES $Insert WO_LOG_EQUATES $Insert APPCOLORS $Insert MSG_EQUATES $Insert SCHEDULE_EQU $Insert LOCATION_EQUATES $Insert RLIST_EQUATES Declare subroutine Utility, ErrMsg, Set_Status, Set_Printer, RList, SRP_Stopwatch, Btree.Extract, Error_Services, V119 Declare function Set_Printer, Get_Printer, Msg, Get_Status, Printer_Select, obj_Install, Dialog_Box, obj_Location Declare function Schedule_Services, Error_Services, Location_Services, SRP_Array, Signature_Services Declare function Epi_Part_Services, SRP_Math Equ TAB$ TO \09\ GetMaterialTrackReport: // All Possible Report Columns AllRptColumns = '' AllRptColumns<1, 1> = 'React No' AllRptColumns<1, 2> = 'React Type' AllRptColumns<1, 3> = 'WO No' AllRptColumns<1, 4> = 'SAP Prod No' AllRptColumns<1, 5> = 'Sub Part No' AllRptColumns<1, 6> = 'Epi Part No' AllRptColumns<1, 7> = 'WO Qty' AllRptColumns<1, 8> = 'RX Qty' AllRptColumns<1, 9> = 'UnRel Qty' AllRptColumns<1, 10> = 'Kit Location' AllRptColumns<1, 11> = 'Kit Qty' AllRptColumns<1, 12> = '+/-' AllRptColumns<1, 13> = 'Kit RO' AllRptColumns<1, 14> = 'PTI RO' AllRptColumns<1, 15> = 'Load' AllRptColumns<1, 16> = 'Comments' If Index(RptColumns, 'Comments', 1) then AllColFmt = '' AllColFmt<1, 1> = '+^720' AllColFmt<1, 2> = '+<720' AllColFmt<1, 3> = '+^1000' AllColFmt<1, 4> = '+^1100' AllColFmt<1, 5> = '+^1300' AllColFmt<1, 6> = '+^1200' AllColFmt<1, 7> = '+>720' AllColFmt<1, 8> = '+>720' AllColFmt<1, 9> = '+>720' AllColFmt<1, 10> = '+^1260' AllColFmt<1, 11> = '+^720' AllColFmt<1, 12> = '+^500' AllColFmt<1, 13> = '+^1300' AllColFmt<1, 14> = '+^1300' AllColFmt<1, 15> = '+^700' AllColFmt<1, 16> = '+^1300' end else AllColFmt = '' AllColFmt<1, 1> = '+^720' AllColFmt<1, 2> = '+<720' AllColFmt<1, 3> = '+^1000' AllColFmt<1, 4> = '+^1100' AllColFmt<1, 5> = '+^1300' AllColFmt<1, 6> = '+^1200' AllColFmt<1, 7> = '+>720' AllColFmt<1, 8> = '+>720' AllColFmt<1, 9> = '+>720' AllColFmt<1, 10> = '+^1260' AllColFmt<1, 11> = '+^720' AllColFmt<1, 12> = '+^500' AllColFmt<1, 13> = '+^1800' AllColFmt<1, 14> = '+^1800' AllColFmt<1, 15> = '+^1100' AllColFmt<1, 16> = '' end ErrorTitle = 'Error in subroutine Material_Track' ErrCode = '' ErrorMsg = '' OPEN 'SCHED_DET' TO SchedDetTable then OPEN 'DICT.SCHED_DET' TO @DICT then Today = OCONV(Date(),'D4/') EndDate = OCONV(Date()+13,'D4/') ReactList = '' WOList = '' SchedDetKeys = '' PrevReactNo = '' PrevWO = '' SelectSent = 'SELECT SCHED_DET WITH SCHED_DT GE ':QUOTE(Today):' BY REACT_NO' RList(SelectSent,TARGET_ACTIVELIST$,'','','') IF Get_Status(errCode) THEN ErrMsg(errCode) RETURN END Done = 0 @ID = '' LOOP PrevSchedDetKey = @ID READNEXT @ID ELSE Done = 1 UNTIL Done ReactNo = @ID[1,'*'] SchedDt = @ID[COL2()+1,'*'] SeqNo = @ID[COL2()+1,'*'] READ SchedDetRec FROM SchedDetTable,@ID THEN WONo = SchedDetRec LOCATE ReactNo IN ReactList BY 'AR' USING @FM SETTING Pos ELSE ReactList = INSERT(ReactList,Pos,0,0,ReactNo) END PrevReactNo = Field(PrevSchedDetKey, '*', 1) PrevSchedDt = Field(PrevSchedDetKey, '*', 2) LOCATE WONo IN WOList USING @VM SETTING WPos ELSE WOList = INSERT(WOList,Pos,-1,0,WONo) // Patch added on 10/24/18 to resolve scheduling conflicts on the same day for // the material track report. - djs If (PrevReactNo EQ ReactNo) and (PrevSchedDt EQ SchedDt) then PrevSeqNo = Field(PrevSchedDetKey, '*', 3) NumWO = DCount(WOList, @VM) PrevWONo = WOList SchedEvents = Schedule_Services('GetScheduleEventSummary', ReactNo, WONo, SchedDt, SeqNo, True$) StartDt = IConv(SchedEvents, 'D') PrevSchedEvents = Schedule_Services('GetScheduleEventSummary', ReactNo, PrevWONo, PrevSchedDt, PrevSeqNo, True$) PrevStartDt = IConv(PrevSchedEvents, 'D') If StartDt GT PrevStartDt then // This is the common case SchedDetKeys = INSERT(SchedDetKeys,-1,0,0,@ID) end else // Scheduling irregularity - Insert this key in the second to last position. NumKeys = DCount(SchedDetKeys, @FM) InsertPos = NumKeys SchedDetKeys = INSERT(SchedDetKeys,InsertPos,0,0,@ID) end end else SchedDetKeys = INSERT(SchedDetKeys,-1,0,0,@ID) end END END REPEAT CALL Make.List(0,SchedDetKeys,SchedDetTable,@DICT) Header = "'D'":@VM:obj_Install('Get_Prop','CompTitle'):' Material Tracking by Reactor':@VM:"Page 'P'" MinDemand = 0 Set_Status(0) * Start of printing process FileName = 'C:\Users\StieberD\Desktop\Material_Demand.pdf' Title = 'Printing Material Demand' TopMargin = 1.0 BottomMargin = 0.75 LeftMargin = 0.25 RightMargin = 0.25 Margins = LeftMargin:@FM:TopMargin:@FM:RightMargin:@FM:BottomMargin PageSetup = '1' ;* LandScape PrintSetup = '2' ;* Preview Normal PrintSetup<1,2> = '0' ;* All buttons PrintSetup<1,5> = '1' ;* Page Range PrintSetup<1,6> = 7 ;* full mouse and keyboard support PrintPath = '' stat = Set_Printer('INIT',FileName,Title,Margins,PageSetup,PrintSetup,PrintPath) IF stat < 0 THEN ErrorMsg = 'Stat = ' : Stat : ', PrintPath = ' : PrintPath GOTO OIPrintErr end DateRange = 'Effective ':OCONV(Date(),'D4') Header<-1> = "'T'" Header<-1> = '' ;* Blank line following heading font = 'Arial' font<2> = '10' font<4> = '0' ;* Bold stat = Set_Printer('FONTHEADFOOT',font) ; IF stat < 0 THEN GOTO OIPrintErr stat = Set_Printer('HEADER',Header) ; IF stat < 0 THEN GOTO OIPrintErr Footer = " 'D' 'T'":@VM:@VM:"Page: 'P'" stat = Set_Printer('FOOTER',Footer) ; IF stat < 0 THEN GOTO OIPrintErr @RECCOUNT = 0 FirstPass = 1 LastRecord = 0 FirstLine = 1 fontSpacing = 100 * Make Column Heading ColHead = '' ColFmt = '' For each Column in RptColumns using @VM setting rcPos Locate Column in AllRptColumns using @VM setting dataPos then ColHead<0, -1> = Column ColFmt<0, -1> = AllColFmt<0, dataPos> end Next Column * Zero Accumulators For Each Break Prev.ReactNo = '' Last.ReactNo.Break = 1 GoTo ReadRecord end else ErrorMsg = 'Unable to open "SCHED_DET" table.' ErrMsg(ErrorTitle:@SVM:ErrorMsg) end end else ErrorMsg = 'Unable to open "SCHED_DET" table.' ErrMsg(ErrorTitle:@SVM:ErrorMsg) end return //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ReadRecord: * Zero Break Flags To False ReactNo.Break=0 READNEXT @ID, Which.Value ELSE LastRecord = 1 ReactNo.Break = 1 ReactNo = Prev.ReactNo END S.ATID = @ID IF FirstPass AND LastRecord THEN GOTO Bail END IF LastRecord THEN GOTO BREAKS READO @RECORD FROM SchedDetTable,@ID ELSE GOTO ReadRecord END @RECCOUNT += 1 * Calculate Value(s) For Column(s) S.ATID = {@ID} I.ATID = S.ATID S.ReactNo = {REACT_NO} I.ReactNo = S.ReactNo S.WoNo = {WO_NO} I.WoNo = S.WoNo S.SubPartNo = XLATE('WO_LOG',S.WoNo,'ORD_SUB_PART_NO','X') I.SubPartNo = S.SubPartNo S.EpiPartNo = XLATE('WO_LOG',S.WoNo,WO_LOG_EPI_PART_NO$,'X') I.EpiPartNo = S.EpiPartNo S.WO_Qty = {WO_QTY} I.WO_Qty = S.WO_Qty S.WO_RX_Qty = {WO_RX_QTY} I.WO_RX_Qty = S.WO_RX_Qty S.WO_UnRel_QTY = {WO_UNREL_QTY} I.WO_UnRel_QTY = S.WO_UnRel_QTY S.Sched_DT = {SCHED_DT} I.Sched_DT = S.Sched_DT S.REACT_TYPE = {REACTOR_TYPE} S.ProdOrdNo = {PROD_ORD_NO} Locate 'SR*KTR]' in LocationFilter using @VM setting vPos then KitData = Location_Services('GetLocationCassInfo', S.WONo, 'SR*KTR]') SWAP CRLF$ WITH @VM IN KitData end else KitData = '' end S.KitLocation = KitData<1> I.KitLocation = S.KitLocation S.KitQty = OCONV(SUM(KitData<2>) * 25,'MD0,Z') I.KitQty = S.KitQty S.KitCassCnt = COUNT(KitData<3>,',') + (KitData<3> NE '') I.KitCassCnt = S.KitCassCnt KitCassList = KitData<3> Locate '1K*PTI' in LocationFilter using @VM setting vPos then PTIData = Location_Services('GetLocationCassInfo', S.WONo, '1K*PTI') SWAP CRLF$ WITH @VM IN PTIData end else PTIData = '' end PTICassList = PTIData<3> CRLocs = '' CRLocs<0, -1> = 'CR*BE' CRLocs<0, -1> = 'CR*BO' CRLocs<0, -1> = 'CR*TUN' CRLocs<0, -1> = 'CR*EPR' CRLocs<0, -1> = 'CR*FE' CRLocs<0, -1> = 'CR*FEH' CRLocs<0, -1> = 'CR*FO' CRLocs<0, -1> = 'CR*FOH' LoadedData = '' LocQueryList = '' For each Loc in CRLocs using @VM setting crPos Locate Loc in LocationFilter using @VM setting vPos then LocQueryList<0, -1> = Loc end Next Loc LoadedCassList = '' ReactType = Xlate('WO_LOG', S.WONo, 'REACT_TYPE', 'X') If ReactType NE 'EPP' then If LocQueryList NE '' then LoadedData = Location_Services('GetLocationCassInfo', S.WONo, LocQueryList) Swap CRLF$ with @VM in LoadedData CassList = LoadedData<3> For each CassNo in CassList using ',' If ( (S.WONo NE '') and (CassNo NE '') ) then WOMatKey = S.WONo:'*':CassNo UnloadSigComp = Signature_Services('CheckSignature', WOMatKey, 'UNLOAD') If UnloadSigComp then // Add this cassette to the PTI list instead of the Load list PTICassList<0, -1> = CassNo end else LoadedCassList<0, -1> = CassNo end end Next CassNo end end * TEST FOR CONTROL BREAK(S) IF (S.ReactNo NE Prev.ReactNo) OR ReactNo.Break THEN ReactNo = Prev.ReactNo Prev.ReactNo = S.ReactNo ReactNo.Break += 1 END IF FirstPass THEN FirstPass=0 GOTO DETAIL END BREAKS: * Print Break Total(s) And Accumulate Total(s) IF ReactNo.Break THEN stat = Set_Printer('TEXT') * Perform Last Record Output If Done IF LastRecord THEN colData = '' GOTO Bail END DETAIL: * Do Conversion If Any IF S.REACTNO NE "" THEN S.REACTNO = OCONV(S.REACTNO,"MD0,") IF S.WONO NE "" THEN S.WONO = OCONV(S.WONO,"MD0") IF S.WO_QTY NE "" THEN S.WO_QTY = OCONV(S.WO_QTY,"MD0,") IF S.WO_RX_QTY NE "" THEN S.WO_RX_QTY = OCONV(S.WO_RX_QTY,"MD0,") IF S.WO_UNREL_QTY NE "" THEN S.WO_UNREL_QTY = OCONV(S.WO_UNREL_QTY,"MD0,") IF S.SCHED_DT NE "" THEN S.SCHED_DT = OCONV(S.SCHED_DT,"D4/") * PRINT DETAIL LINE COLDATA = '' RowNumber = 0 /* ascending sort */ Convert @VM to ',' in KitCassList Convert @VM to ',' in PTICassList Convert @VM to ',' in LoadedCassList KitCassList = SRP_Array('SortSimpleList', KitCassList, 'AscendingNumbers', ',') PTICassList = SRP_Array('SortSimpleList', PTICassList, 'AscendingNumbers', ',') LoadedCassList = SRP_Array('SortSimpleList', LoadedCassList, 'AscendingNumbers', ',') Convert ',' to @VM in KitCassList Convert ',' to @VM in PTICassList Convert ',' to @VM in LoadedCassList NumKitCass = DCount(KitCassList, @VM) If NumKitCass GT 4 then For CassIndex = 4 to NumKitCass Step 4 CassNo = KitCassList<0, CassIndex> CassNo := CRLF$ KitCassList<0, CassIndex> = CassNo Next CassIndex end NumPTICass = DCount(PTICassList, @VM) If NumPTICass GT 4 then For CassIndex = 4 to NumPTICass Step 4 CassNo = PTICassList<0, CassIndex> CassNo := CRLF$ PTICassList<0, CassIndex> = CassNo Next CassIndex end NumLoadedCass = DCount(LoadedCassList, @VM) If NumLoadedCass GT 2 then For CassIndex = 2 to NumLoadedCass Step 2 CassNo = LoadedCassList<0, CassIndex> CassNo := CRLF$ LoadedCassList<0, CassIndex> = CassNo Next CassIndex end Convert @VM to ',' in KitCassList Convert @VM to ',' in PTICassList Convert @VM to ',' in LoadedCassList CassNeeded = '' EpiPartNo = Xlate('WO_LOG', S.WONo, 'EPI_PART_NO', 'X') If EpiPartNo NE '' then WPDAdjusted = Epi_Part_Services('GetAdjustedWafersPerDayScheduler', EpiPartNo, S.React_Type) If WPDAdjusted NE '' then CPDAdjusted = SRP_Math('CEILING', (WPDAdjusted/25) ) CassInCR = DCount(KittCassList, ',') + DCount(PTICassList, ',') + DCount(LoadedCassList, ',') CassNeeded = CassInCR - CPDAdjusted end end Swap '.1' with '' in S.ProdOrdNo AllReportData = '' AllReportData<1> = S.ReactNo AllReportData<2> = S.React_Type AllReportData<3> = S.WONo AllReportData<4> = S.ProdOrdNo AllReportData<5> = S.SubPartNo AllReportData<6> = S.EpiPartNo AllReportData<7> = S.WO_Qty AllReportData<8> = S.WO_RX_Qty AllReportData<9> = S.WO_UnRel_Qty AllReportData<10> = S.KitLocation AllReportData<11> = S.KitQty AllReportData<12> = CassNeeded AllReportData<13> = KitCassList AllReportData<14> = PTICassList AllReportData<15> = LoadedCassList AllReportData<16> = '' If ( (KitCassList NE '') or (PTICassList NE '') or (LoadedCassList NE '') ) then RowNumber += 1 For each RptColumn in RptColumns using @VM setting rcPos Locate RptColumn in AllRptColumns using @VM setting dataPos then COLDATA = AllReportData end Next RptColumn If COLDATA NE '' then GoSub PrintTable END GOTO ReadRecord Bail: stat = Set_Printer('TERM',1) RETURN OIPrintErr: ErrMsg(ErrorTitle:@SVM:ErrorMsg) ErrMsg(ErrorTitle:@SVM:'Set_Printer returned errorcode ':stat) stat = Set_Printer('TERM',1) RETURN PrintTable: PageHeight = Get_Printer('PAGESIZE')<2> PrintableHeight = PageHeight - TopMargin - BottomMargin PrinterHeight = Get_Printer('POS')<2> stat = Set_Printer('CALCTABLE',ColFmt:@FM:ColData) TableSize = Get_Printer('CALCTABLE') TableHeight = TableSize<2> fontSpacing = 120 IF ( TableHeight + PrinterHeight >= PrintableHeight ) OR FirstLine THEN IF NOT(FirstLine) THEN stat = Set_Printer('PAGEBREAK') END FirstLine = 0 font<2> = 10 font<4> = 1 ;* Bold stat = Set_Printer('FONT',font,'100') stat = Set_Printer('ADDTABLE',colFmt,colHead,'',LTGREY$,'',0,TB_ALL) font<4> = 0 stat = Set_Printer('FONT',font,fontSpacing) stat = Set_Printer('ADDTABLE',colFmt,'',colData,LTGREY$,'',0,7) END ELSE font<2> = 10 font<4> = 0 stat = Set_Printer('FONT',font,fontSpacing) stat = Set_Printer('ADDTABLE',colFmt,'',colData,LTGREY$,'',1,TB_ALL) END RETURN