/*Report by Exception using IR Control Charts Reporting by exception may be just a little counterintuitive for checking control charts? A key concept of control chart review is that a person actually looks at each chart. This however gets a little tedious with the daunting task of frequently reviewing hundreds of process variables that typically contain few special cause events. For reviewing many control charts at once it may be beneficial to only present charts with control chart test alarms. In addition we typically review ranges of 25 to 250 data points where only the most recently added data is interesting. Test alarms early in the reporting period are just noise have typically been addressed in earlier reports and no longer need attention. This script is design to simplify this reporting task. Two sets of control charts are generated. The first contains control charts for all the variables. The second only contains reports with the specified test alarms for the specified reporting period. The reporting period can be either a range of rows, or it can be for a certain number of measurements from the end of the table. *The data for this script must be sorted sequentially by measurement order. *This script is designed for IR control charts only. If you give it labels that are not unique, an Xbar and R chart dialog will launch. (no error control for this) *The Ys (process variables) must be numeric continuous data. *The Label must be unique for each row. *Test 1 to 4 are implemented as options (feel free to add more) In the column dialog, specify continuous numeric columns for control charts. Select the control chart alarm 1 to 4 (test 1 is on by default). Enter either the beginning and ending row of the range you want alarms from or the number of days from the end of the last row. Click OK or Cancel. Byron Wingerd (JMP) Sept 4, 2015*/ Names Default To Here( 1 ); Clear Symbols(); //example table for testing //dt = Open( "$SAMPLE_DATA/Semiconductor Capability.jmp" ); dt = Current Data Table(); dtn = N Rows( dt ); nt = New Table( "Alarms" ); nt << New Column( "Message", character ); nt << New Column( "Test", Character ); nt << New Column( "Metric", Character ); nt << New Column( "Row", Numeric ); Current Data Table( dt ); ///////////////////////////////////////// ycol = Expr( chart col() ); rowcol = Expr( Sample Label() ); cc = Expr( Control Chart( KSigma( 3 ), Chart Type( Individual Measurement ) )); dtn = N Rows( dt ); r = Column Dialog( col_ID = ColList( "Sample Lable", Max Col( 1 ), DataType( "Numeric" ) ), col_Ys = ColList( "Metric (Y)", mincol( 1 ), DataType( "Numeric" ), modelingtype( "continuous" ) ), HList( "Total Rows: " || Char( N Rows( dt ) ) ), HList( "Reporting Period Start ", rpstart = EditNumber( N Rows( dt ) ), " Reporting Period End ", rpend = EditNumber( N Rows( dt ) ) ), HList( "Or, Set end Reporting Period" ), HList( "Reporting Period ", rplen = EditNumber( 0 ), " 0=Use interval above" ), vList( "Set Alarms for Report", t1 = Check Box( "Test 1", (1) ), t2 = Check Box( "Test 2" ), t3 = Check Box( "Test 3" ), t4 = Check Box( "Test 4" ) ) ); at1 = Expr( test1() ); at2 = Expr( test2() ); at3 = Expr( test3() ); at4 = Expr( test4() ); Insert Into( at1, Eval( r[6] ) ); Insert Into( at2, Eval( r[7] ) ); Insert Into( at3, Eval( r[8] ) ); Insert Into( at4, Eval( r[9] ) ); atest = {}; Insert Into( atest, Name Expr( at1 ) ); Insert Into( atest, Name Expr( at2 ) ); Insert Into( atest, Name Expr( at3 ) ); Insert Into( atest, Name Expr( at4 ) ); col_ID = Eval( r[1] ); If( N Items( col_id ) == 1, Insert Into( rowcol, Name Expr( col_ID[1] ) ); Insert Into( cc, Name Expr( rowcol ) ); ); yyy = Eval( r[2] ); For( i = 1, i <= N Items( yyy ), i++, ycol = Expr( chart col() ); Insert Into( yCol, yyy[i] ); Insert Into( cc, Name Expr( ycol ) ); Show( Name Expr( yCol ) ); ); Show( cc ); //////////////////////////////////////// Current Data Table( dt ); Show( Current Data Table() ); alarm = Expr( alarm script( nt << Add Rows( 1 ); msg = "Out of Control for test " || Char( qc_test ) || " in column " || Char( qc_col ) || " in sample " || Char( qc_sample ); Column( nt, "Message" )[N Row( nt )] = msg; Column( nt, "Test" )[N Row( nt )] = Char( qc_test ); Column( nt, "Metric" )[N Row( nt )] = Char( qc_col ); Column( nt, "Row" )[N Row( nt )] = (qc_sample); ) ); eval(substitute(expr(obj=_p),expr(_p),Insert( nameexpr(cc), Name Expr( alarm ) ))); eval( substitute( expr(obj<<_l),expr(_l),atest ) ); //------------------------------------------ rpstart = Eval( r[3] ); rpend = Eval( r[4] ); rplen = Eval( r[5] ); nt:Row << Data Type( Numeric, 2 ); nt << Run Formulas(); rprange = Expr( nt << select where( :Row < (dtn - rplen) ); nt << delete rows; ntrowmax = dtn; ntrowmin = dtn - rplen; ); rpends = Expr( nt << select where( :Row < rpstart ); nt << delete rows; nt << select where( :Row > rpend ); nt << delete rows; ntrowmax = rpstart; ntrowmin = rpend; ); If( rplen == 0, rpends, rprange ); nt << run formulas(); If( N Rows( nt ) == 0,//---------------the big nt if Show( "no alarms" ), Summarize( nt, rerun = by( :Metric ) ); Eval List( rerun ); rycol = Expr( chart col() ); rr = Expr( Control Chart( KSigma( 3 ), Chart Type( Individual Measurement ) )); /// If( N Items( col_id ) == 1, Insert Into( rr, Name Expr( rowcol ) ) ); For( i = 1, i <= N Items( rerun ), i++, rycol = Expr( chart col() ); Insert Into( ryCol, rerun[i] ); Insert Into( rr, Name Expr( rycol ) ); Show( Name Expr( ryCol ) ); ); /// eval(substitute(expr(objr=_r),expr(_r),Insert( nameexpr(rr), Name Expr( alarm ) ))); eval( substitute( expr(objr<<_l),expr(_l),atest ) ); );///////////end of big nt if Report( obj)[Outline Box( 1 )] << set title( "All Control Charts" ); Report( objr)[Outline Box( 1 )] << set title( "Control Charts with Alarms Between " || Char( ntrowmin ) || " and " || Char( ntrowmax ) ); done = Expr( //not used, for clean up after testing Close All( reports ); Close( nt, no save ); Close( dt, no save ); ); Show Symbols(); /* done; close all( data tables) show symbols();