I did mention some possible topics in one of my emails but here are some ideas:
- Using references
- dt = Open()... and so on instead of Current Data Table()
- Finding references to reports / in report layer in robust manner
- Managing namespace/scopes
- Initializing variables
- Finding programming style
- write globals in UPPERCASE
- Utilizing expressions
- Try-Catch
- Logging
- Show,Write,Print, custom logger
- Utilizing Stack
- Variables in buttons / windows
- Especially when returning from function
- Context Box(), window:
- Button - Paths
- Packaging scripts
- Instead of having massive JMP created script, separate parts from those into more robust scripts
- Best practices
- Avoid Clear/Delete Symbols/Globals
- Don't leave Clear Log in scripts
- Locking variables / namespaces
- Paths
- Convert File Path
- Default Directory
- $PATH_VARIABLES
- Referencing columns
- Column(dt, "colname") vs dt:colname vs :colname, vs dt:"colname"n (and AsColumn) and so on...
- Floating point math
- Look before you leap vs Easier to ask forgiveness than permission when writing code
- Missing / Empty values
- Is Empty(), Is Missing(), If, IfMZ, N Items() > 0
- Checking for open tables, open reports, already open custom windows,...
- << Bring Window to front
- Throw() in .jsl vs jmpaddin
- Custom modal window function
- Improving (and utilizing) JMP created scripts
- Adding references/variables
- Shortening JMP created scripts
- Avoiding Dispatch
- How user preferences can affect these (usually causing very big problems)
- Understanding and utilizing data structures
- For example no need to store everything in different variable names (especially not when using Eval Parse)
- Use Lists/Associative Arrays
- If talking about UI, could references when they are needed
Posts partially related (might look extremely messy due to "new" JMP community pages)
THX, Here I can share some of mine but most of what I doo is already mentioned above:
- Try(close(dt_ref,nosave)); dt_ref = Open(...) --> cleans up a table and doesn't produce an error wen the script is run for the first time. The problem is, that you can rename the table but JSL will still close it since the dt reference switches too.
- Use always tab to identify bigger loops and functions so you don't get lost in the code and search for a missing );
- Consider re-naming columns after a tabulate step if you see the possibility for multi language use. This can break an other users code but your's work fine.
- Try to dynamically work with reference in platform to avoid user inputs.
You could do this:
dt << Process screening(Process Variables({:Column 4, :Column 6, :Column 7}));
But you can also use this:
dt = current data table();
col_names = dt << get column names();
spec_list = {};
for(k=1,k<=nitems(col_names),k++,
if(!isempty(column(dt,k) << Get Property("Speclimits")),insertinto(spec_list,col_names[k]);););
dt << Process screening(Process Variables(eval(spec_list)));
altering a column name will then not break the code and the question about missing spec limits will not be triggered. -
I will most likely go with something like attached (I definitely won't have enough time to go through all of them, but that shouldn't be a problem). Might have ended up with something like "tips for JSL" but it took enough time to even create that.
Tank you Jarmo, some thoughts on the script:
line 103: I use this only when the loop is very short with only on line to execute. this keeps the code a bit more tide up.
line 109: with short names you may run into the problem to override a JMP function with a variable like mean = (x1 + x2 ) / 2; better to write m_production_speed or mean_production_speed.
line 149: I made the habit if comment an if loop right after the coma for code folding:
If you write the code like this:
if(1,//average of x
mean_x = mean(x);
);
and you fold the code, it will look like this:

It saves me a line above the for loop or if statement.
line 198: "Let’s initialize the matrix, because if it is created in advance, filling it will be faster". that took me 1 minute with copilot, I cant imagen to debug a code with 200 comments *g*.
line 212: I would mention that you can use log and workflow as a reference and then alter the code to your programming stile. This is specially the case when I ask non-programming user to make a workflow of what they want to achieve with the script I should program for them. So I have a good understanding on what the want and have most of the function already coded.
line 391: This can speed up the script when you iterate trough a table wile having a graph builder open so it doesn't update the graph with each change.
Names Default To Here( 1 );
try(close(dt,nosave));
dt = new table("test");
dt << New Column( "Y",
Numeric,
"Continuous",
Format( "Best", 12 ),
<<SET initial="" data="https://community.jmp.com/"></SET>line 414: In addition to this I would add: always add a table reference when you give a fixed name when using functions like << Subset and so on) this is very helpful when the generating name already exists and JMP automatically adds the " 2" at the end. Without a reference you may accidently working on the wrong table.
line 74: this is something I will steal for my scripts 
line757: this also can sometime slow down for loops to a crawl. but is useful when dealing with SQL statements since sending a request can overtake the rest of the script and cause an error because it may take some time to get the data but it works fine when execute the code line by line.
line 780: maybe referencing to the JSL cook book? JSL Cookbook - JMP User Community
line 787: Just be aware that this will also break when a report reference name contains a variable.
This is what happened here: Re: fitting truncated data to a continuous distribution - JMP User Community
the detection limits is added with censored data in the title and can change depending on the data set.
THX a lot for the script.
Regards
Mauro
line 787
This is exactly the reason why almost always use XPath with helpKey attribute if it is available (I doesn't care about the outlinebox title). There are too many ways of (trying) to build robust references, that I could spend ~20minutes with examples on that.
For example with the detection limits I would use either the helpKey OR wild cards (if I knew that the outline box name can change...)
Names Default To Here(1);
dt = open("$SAMPLE_DATA/Big Class.jmp");
Column(dt, "height") << Set Property("Detection Limits", {60, 100});
dist = dt << Distribution(
Stack(1),
Continuous Distribution(
Column(:height),
Horizontal Layout(1),
Vertical(0),
Process Capability(0),
Fit Normal
)
);
obs = Report(dist) << XPath("//OutlineBox[@helpKey='FitDistributions']");
show(obs << get title);
// Or
ob = Report(dist)[OutlineBox("Fitted Normal Distribution?")];
show(ob << get title);
// Or
obs2 = Report(dist) << XPath("//OutlineBox[contains(text(), 'Fitted Normal Distribution')]");
show(ob << get title);
</CODE></P>
<P>I also added few things based on your comments. Thanks!<CODE class=" language-jsl">