幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗你好,
我創建了一個腳本來透過分析 M 個因素對 N 個指標的單獨統計影響來匯總資料表。
總結表顯示了 N 個指標(行)和 M 個因素(列)的矩陣,具體影響為:平均值漂移、Cpk 退化或兩者兼而有之。
我想添加一個功能來使用列公式繪製每個選定行的分佈。
我受到這篇文章的啟發:
將單元格(在 JMP 表中)連結到腳本?
問題是,我的腳本在具有固定選定行(本例中為 [5])的新腳本視窗中運行良好,但當我將腳本包含在 :Graph 列公式中時會失敗。我不明白為什麼…
你能幫我調試一下嗎?
附2個表:帶有原始資料的datatable_test.jmp,帶有列公式的Summary.jmp。這個想法是單擊要在“圖形”列中繪製的單元格。
當前錯誤顯示::“行 [ ] 處非法引用(遞歸)”

當我在兩個表都打開的情況下運行以下腳本時,它按預期工作(見下文)。但是直接從表運行時腳本會失敗(單擊圖形列中的單元格)。

預先非常感謝,
- 傳教士
// this script works from a Script window
// All features related to the column formula are commented
// here the row selected is row 5 : rn1 = [5]
Names Default To Here( 1 );
dt = Data Table( "datatable_test" );
dt2 = Data Table( "Summary" );
//If( Selected( Row State() ),
Eval(
Parse(
rn1 = [5]/*dt2 << get selected rows*/;
rn = rn1[1];
Factors = dt2 << get column names( "string" );
show(rn1, rn);
Eval(
Eval Expr(
For( i = N Items( Factors ), i >= 1, i--,
CurrCol = Column( dt2, Factors[i] );
If(Char( CurrCol[ rn ] ) == "Ok" | Factors[i] == "Metric"| Factors[i] == "Graph",
Remove From( Factors, i, 1 )
);
)
)
);
FactorA = "X( :" || Char( Factors[1] ) || ", Position( 1 ))";
FactorB = "X(1)";
For( j = 2, j <= N Items( Factors ), j++,
FactorA = Char( FactorA ) || ",X( :" || Char( Factors[j] ) ||
", Position( 1 ))";
FactorB = Char( FactorB ) || ",X( " || Char( j ) || " ) ";
);
Show( dt2:Metric[rn], FactorA, FactorB );
Key = dt2:Metric[rn];
Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(
Y( ^Key^ ), ^FactorA^),
Elements( Box Plot( Y, Legend( 18 ), ^FactorB^ ) ),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -0.485125992718803 ), Max( 5.53364268893602 ), Inc( 1 ),
Minor Ticks( 0 )}
)
)
) "
);
)
//)
);自動化和腳本編寫回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗使用列公式執行此操作是否有特定原因?例如,自訂一個帶有表格框和按鈕的視窗將更容易建立和管理。或者也許在匯總表上使用行狀態處理程序(儘管如果可能的話我會避免這樣做)。
回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗嗨,賈莫,
沒有具體原因,我只是這樣創建了我的原始腳本,使用資料表產生摘要。
我沒有想到這一點:打開一個表格框並添加按鈕似乎是一個好主意,我可以考慮到這一點來修改我的未來版本。
但同時,您認為讓列公式發揮作用值得嗎?那麼我可以在下一個版本之前更快地獲得一個工作版本嗎?恐怕更改結構以產生表格框而不是資料表會花費我一些時間,因為我對顯示/表格框還不是很熟悉。
我想要包含在列公式中的腳本片段可以單獨運行,但在列公式中運行時會失敗。我一定做錯了什麼,但不確定是什麼...
回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗編輯:
我實際上發現將表格轉換為顯示框很容易:
nw = New Window("Report",
dt << Get As Report()
);下面產生的報告

當單擊行時,我沒想到公式會在報告中起作用(並且它不會...)。
但現在我不確定您建議如何繼續您的建議。
(同樣,我還不熟悉顯示框操作)
先致謝
回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗編輯2:
根據 Jarmo 和這篇文章的建議,我終於使腳本可以工作:
JSL 幫助:取得報表和表格框
現在,當我單擊報告中的一行時,它會根據所選行運行腳本,這正是我所需要的:)

下面的腳本,它需要打開我在第一條訊息中加入的 2 個表
謝謝
- 傳教士
Names Default To Here( 1 );
dt7 = Data Table("Summary");
dt = Data Table("datatable_test");
dt7 << clear select;
dt7 << Clear Column Selection();
RptWin = New Window( "Data Table as report",
Outline Box("Data Table as Report",
dt7_Rpt = dt7 << Get as Report();
)
);
tb = dt7_Rpt[Table Box( 1 )];
tb << Set Heading Column Borders( 1 );
tb << Set Selectable Rows( 1 );
tb << Set Row Change Function(
Function( {this},
{SelRows},
SelRows = this << Get Selected Rows;
If(
N Items( SelRows ) > 1, Throw( "Too many items selected!\!rOnly one selection possible." ),
N Items( SelRows ) == 1,
SelRows = this << Get Selected Rows;
);
dt7 << Clear Select;
rn = dt7 << Select rows( SelRows ) << get selected rows;
show (rn[1], dt7:Metric[rn]);
Factors = dt7 << get column names( "string" );
Eval(
Eval Expr(
For( i = N Items( Factors ), i >= 1, i--,
CurrCol = Column( dt7, Factors[i] );
If(Char( CurrCol[ rn[1] ] ) == "Ok" | Factors[i] == "Metric"| Factors[i] == "Graph",
Remove From( Factors, i, 1 )
);
)
)
);
show (Factors);
Try(FactorA = "X( :" || Char( Factors[1] ) || ", Position( 1 ))");
FactorB = "X(1)";
For( j = 2, j <= N Items( Factors ), j++,
Try(FactorA = Char( FactorA ) || ",X( :" || Char( Factors[j] ) || ", Position( 1 ))");
FactorB = Char( FactorB ) || ",X( " || Char( j ) || " ) ";
);
Show( dt7:Metric[rn], FactorA, FactorB );
Key = dt7:Metric[rn];
If (Factors != {},
Eval(Parse(Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(Y( ^Key^ ), ^FactorA^),
Elements(
Box Plot( Y, Legend( 18 ), ^FactorB^ ),
Caption Box(X, Y, Legend(20), Summary Statistic( \!"N\!" ),Location( \!"Graph per factor\!" ))),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -0.485125992718803 ), Max( 5.53364268893602 ), Inc( 1 ),
Minor Ticks( 0 )}
)
)
) "
))),
Eval(Parse(Eval Insert(
" dt << Graph Builder(
Size( 534, 464 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Variables(Y( ^Key^ )),
Elements(
Box Plot( Y, Legend( 18 )),
Caption Box(Y, Legend(20), Summary Statistic( \!"N\!" ))),
SendToReport(
Dispatch(
{},
ScaleBox,
{Min( -7.06199976676385 ), Max( 26.8097086791615 ), Inc( 5 ),
Minor Ticks( 0 )}
)
)
) "
)))
)
));回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗我想要做的另一項改進是擺脫 Eval(Parse()) (它通常使腳本更易於調試,並且您不會養成壞習慣)。但這需要一些努力和不同的技術,所以你可以慢慢進行。
我還可以在大約 12 小時內查看,以便您了解自己可以做什麼。
回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗同意。我會更進一步並替換Eval Insert() 。
關於Eval(Parse()) - 你可以跳過它:

Parse 需要一個字串作為參數。
將計算一個表達式,並解析結果字串並將其作為表達式傳回。
Parse(Print(1);"a"||"b")
所以,
Parse(Print(1);Eval Insert(Graph Builder());"a")
將列印 1,建立圖形並返回 a 作為表達式。如果您只對中心部分感興趣,可以跳過Parse 。
用Eval()包裝Parse(Eval Insert())仍會對其進行評估。
另一方面, Eval(Eval Expr())只需要計算內部的Expr()即可。
如果沒有Expr() ,您可以將其從程式碼中刪除而不會造成任何損害。
一般來說,我建議發布一個基於幫助/範例資料資料夾中的資料集的程式碼。
然後程式碼可以立即執行,無需透過網路下載檔案。
額外的好處:使程式碼適應不同的輸入通常有助於理解問題。
通常,當我有正確的程式碼來發布問題時 - 問題就消失了:)

回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗這看起來確實很複雜(確實如此),但這就是我最有可能解決這個問題的方法(這不是唯一的方法,您還可以利用 << 添加變數/<< 新增元素)
Names Default To Here(1);
dt_summary = Open("$DOWNLOADS/Summary.jmp");
dt = Open("$DOWNLOADS/datatable_test.jmp");
dt << New Column("Ones", Numeric, Nominal, Set Each Value(1));
dt_summary << clear select;
dt_summary << Clear Column Selection();
possible_factors = dt_summary << get column names("string");
Remove From(possible_factors, Contains(possible_factors, "Metric"));
Remove From(possible_factors, Contains(possible_factors, "Graph"));
create_report = function({sel_row}, {Default Local},
valid_factor_idx = Loc(dt_summary[sel_row, possible_factors], "Ok");
valid_factors = possible_factors[valid_factor_idx];
key = dt_summary[sel_row, "Metric"];
If(N Items(valid_factors) == 0,
valid_factors = {"Ones"};
);
variables_expr = Expr(Variables());
bp_expr = Expr(Box Plot(Y, Legend(18)));
dt = dt; // JMP being JMP
For Each({valid_factor, idx}, valid_factors,
x_expr = EvalExpr(X(Expr(Name Expr(AsColumn(dt, valid_factor))), Position(1)));
Insert Into(variables_expr, Name Expr(x_expr));
Insert Into(bp_expr, Eval Expr(X(Expr(idx))));
);
y_expr = EvalExpr(Y(Expr(Name Expr(AsColumn(dt, key)))));
Insert Into(variables_expr, Name Expr(y_expr));
gb_expr = Substitute(
Expr(dt << Graph Builder(
Size(534, 464),
Show Control Panel(0),
Show Legend(0),
_variables_,
Elements(
_boxplot_,
Caption Box(X, Y, Legend(20), Summary Statistic("N"), Location("Graph per factor"))
),
SendToReport(
Dispatch({}, ScaleBox, {Min(-7.06199976676385), Max(26.8097086791615), Inc(5), Minor Ticks(0)})
)
)),
Expr(_variables_), Name Expr(variables_expr),
Expr(_boxplot_), Name Expr(bp_expr)
);
gb = Eval(gb_expr);
return();
);
nw = New Window("Data Table as report",
Outline Box("Data Table as Report",
summary_report = dt_summary << Get as Report();
)
);
report_tb = summary_report[Table Box(1)];
report_tb << Set Heading Column Borders(1);
report_tb << Set Selectable Rows(1);
report_tb << Set Row Change Function(Function({this},
selrows = this << Get Selected Rows;
If(N Items(selrows) > 1,
Throw("Too many items selected!\!rOnly one selection possible.")
);
create_report(selrows[1]);
));
Write();
在這工作之後,我可能會開始考慮使用者體驗:
- 也許我應該使用一個按鈕,按下該按鈕即可為選定的行建立報告?
- 我可以讓使用者選擇多行嗎?
- 在這種情況下,我應該將所有報告建立到同一視窗嗎?
- 如果已經創建了圖表,我需要重新建立它嗎?
- 當使用者關閉視窗時,我是否也應該關閉資料表?
- ..
看更多...Names Default To Here(1);
dt_summary = Open("$DOWNLOADS/Summary.jmp");
dt = Open("$DOWNLOADS/datatable_test.jmp");
dt << New Column("Ones", Numeric, Nominal, Set Each Value(1));
dt_summary << clear select;
dt_summary << Clear Column Selection();
possible_factors = dt_summary << get column names("string");
Remove From(possible_factors, Contains(possible_factors, "Metric"));
Remove From(possible_factors, Contains(possible_factors, "Graph"));
create_report = function({sel_row}, {Default Local},
valid_factor_idx = Loc(dt_summary[sel_row, possible_factors], "Ok");
valid_factors = possible_factors[valid_factor_idx];
key = dt_summary[sel_row, "Metric"];
If(N Items(valid_factors) == 0,
valid_factors = {"Ones"};
);
variables_expr = Expr(Variables());
bp_expr = Expr(Box Plot(Y, Legend(18)));
dt = dt; // JMP being JMP
For Each({valid_factor, idx}, valid_factors,
x_expr = EvalExpr(X(Expr(Name Expr(AsColumn(dt, valid_factor))), Position(1)));
Insert Into(variables_expr, Name Expr(x_expr));
Insert Into(bp_expr, Eval Expr(X(Expr(idx))));
);
y_expr = EvalExpr(Y(Expr(Name Expr(AsColumn(dt, key)))));
Insert Into(variables_expr, Name Expr(y_expr));
gb_expr = Substitute(
Expr(dt << Graph Builder(
Size(534, 464),
Show Control Panel(0),
Show Legend(0),
_variables_,
Elements(
_boxplot_,
Caption Box(X, Y, Legend(20), Summary Statistic("N"), Location("Graph per factor"))
),
SendToReport(
Dispatch({}, ScaleBox, {Min(-7.06199976676385), Max(26.8097086791615), Inc(5), Minor Ticks(0)})
)
)),
Expr(_variables_), Name Expr(variables_expr),
Expr(_boxplot_), Name Expr(bp_expr)
);
return(gb_expr);
);
nw = New Window("Data Table as report",
H List Box(
Outline Box("Data Table as Report",
summary_report = dt_summary << Get as Report();
),
Outline Box("Actions",
Button Box("Create Reports",
sel_rows = report_tb << Get Selected Rows;
lub_collector = Lineup Box(N Col(2));
For Each({selrow}, sel_rows,
lub_collector << Append(create_report(selrow));
);
nw_graphs = New Window("Graphs",
lub_collector
);
wait(0);
),
Button Box("Close Window", summary_report << close window);
)
)
);
report_tb = summary_report[Table Box(1)];
report_tb << Set Heading Column Borders(1);
report_tb << Set Selectable Rows(1);
I will edit and add images here if JMP Community ever lets me do it...
Edit: Images


回覆:幫助,我的腳本在腳本視窗中運行正常,但在列公式中運行時失敗非常感謝 Jarmo 和 Hogi。
我回覆得很晚,很抱歉我沒有回复,過去幾個月我不得不把注意力集中在其他優先事項上,但現在我可以回來做這件事了!
我會對此進行反思並嘗試您的建議。
最好的,
-牧師