cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
rcookie
Level III

How to close the correct tables with "On close" when running the same script multiple times?

Hello,

 

I have an add-in outputting a graph with several tables hidden in the background.

Upon closing the window I use the "On Close" function to close related data tables, like this: 

 New window() << On close(
			Close(TableA, nosave);
			Close(TableB, nosave);
		) ; 

 

The problem is if I run the script twice, TableA of the first run will be overwritten during the second script execution.

I have tried going around the problem by using a Unique ID created at each script launch, like this:

 

NewWindow() << On Close(
	For(i = NItems(GetWindowList() << Get Window Title()), i > 0, i--,
		win = GetWindow((GetWindowList() << Get Window Title())[i]);
		If(Contains(win << get window title, Eval(uniqueID)) != 0,
			win << closewindow()
		);
	)
)

Unfortunately the same problem remains, UniqueID is overwritten.

 

 

Is there a way to reference the tables correctly so that closing the window will close the correct tables?

Thank you in advance for your help!

2 ACCEPTED SOLUTIONS

Accepted Solutions
jthi
Super User

Re: How to close the correct tables with "On close" when running the same script multiple times?

Evaluate the tables to your On Close

Eval(EvalExpr(
	New Window() << On close(
		Try(Close(Expr(TableA), nosave));
		Try(Close(Expr(TableB), nosave));
	)
));
-Jarmo

View solution in original post

Craige_Hales
Super User

Re: How to close the correct tables with "On close" when running the same script multiple times?

How it works: In your original example,

 New window() << On close(
			Close(TableA, nosave);
			Close(TableB, nosave);
		) ; 

TableA and TableB are variables holding pointers to the tables. If there multiple instances, the variables point to the last instance that was assigned.

In @jthi  example,

Eval(EvalExpr(
	New Window() << On close(
		Try(Close(Expr(TableA), nosave));
		Try(Close(Expr(TableB), nosave));
	)
));

your script is being preprocessed by the Eval(EvalExpr( ... Expr(...) ) ) code to replace the variable with its value. This makes the script no longer dependent on the variable's current variable because the call to close() now uses a constant value (obtained from the variable much earlier.)

How to read it: EvalExpr(...) looks through its argument for Expr(...) and evaluates them, leaving the evaluated result in place of Expr(). When EvalExpr is done, it returns an expression which still needs to be evaluated to make the OnClose(...) method run.

It is important to position the Expr(...) markers at the right place; the part that needs to be cast into stone is just the variable's value. If you use Expr(close(tableA,nosave)), for example, the close() function would run too soon.

Craige

View solution in original post

5 REPLIES 5
jthi
Super User

Re: How to close the correct tables with "On close" when running the same script multiple times?

Evaluate the tables to your On Close

Eval(EvalExpr(
	New Window() << On close(
		Try(Close(Expr(TableA), nosave));
		Try(Close(Expr(TableB), nosave));
	)
));
-Jarmo
rcookie
Level III

Re: How to close the correct tables with "On close" when running the same script multiple times?

Amazing, thanks a lot!

Craige_Hales
Super User

Re: How to close the correct tables with "On close" when running the same script multiple times?

How it works: In your original example,

 New window() << On close(
			Close(TableA, nosave);
			Close(TableB, nosave);
		) ; 

TableA and TableB are variables holding pointers to the tables. If there multiple instances, the variables point to the last instance that was assigned.

In @jthi  example,

Eval(EvalExpr(
	New Window() << On close(
		Try(Close(Expr(TableA), nosave));
		Try(Close(Expr(TableB), nosave));
	)
));

your script is being preprocessed by the Eval(EvalExpr( ... Expr(...) ) ) code to replace the variable with its value. This makes the script no longer dependent on the variable's current variable because the call to close() now uses a constant value (obtained from the variable much earlier.)

How to read it: EvalExpr(...) looks through its argument for Expr(...) and evaluates them, leaving the evaluated result in place of Expr(). When EvalExpr is done, it returns an expression which still needs to be evaluated to make the OnClose(...) method run.

It is important to position the Expr(...) markers at the right place; the part that needs to be cast into stone is just the variable's value. If you use Expr(close(tableA,nosave)), for example, the close() function would run too soon.

Craige
rcookie
Level III

Re: How to close the correct tables with "On close" when running the same script multiple times?

Thank you Craige for the explanations, very helpful! I have generalized this and am happy that the correct tables are closed upon closing the window.

I still have a problem that is probably somehow related: on these windows I set menu scripts in order to allow drill-down, now they call the correct arguments thanks to the Eval(EvalExpr(...Expr(...))) code. Nevertheless I define variables inside these scripts for data manipulation purpose and I don't know how to avoid them being overwritten: is there a way to declare these variables as local to this script ?

Example:

Eval(
	EvalExpr(
		NewWindow("Example", Outline = OutlineBox("Add-ins", Tabs = TabBox())) <<
		On close(
			Try(Close(Expr(TableA), nosave));
			Try(Close(Expr(TableB), nosave));
		)
	)
);

Outline << Set Menu Script(
	{"Script1", Eval(EvalExpr(Add_in_table = Expr(TableA) << Subset(Selected Rows))) ; 
	
	// some code
	
	TableD = Add_in_table << Summary(...) ; 
	
	Eval(
		EvalExpr(
			NewWindow(Graph builder()) << OnClose(
				Try(Close(Expr(Add_in_table), nosave));
				Try(Close(Expr(TableD), nosave));
			)
		)
	)}
);

Thank you

jthi
Super User

Re: How to close the correct tables with "On close" when running the same script multiple times?

Names Default To Here(1); at the start of script or maybe using window scope (or box). Scripting Guide has some information regarding namespaces and scopes

You can move to different pages from left side menu

jthi_0-1708101078634.png

or top right arrows

jthi_1-1708101086555.png

 

-Jarmo