Subscribe Bookmark RSS Feed

Can JMP do macros similar to SAS?


Community Trekker


Jul 24, 2014

Currently where I work we have SAS 9.2 Foundation with QC package, and we have 4 templates, or macro programs, that will run with each of our products.  Which we have 40+ products.  The problem is, we are the only branch in the company using SAS for our reports and it has been desired for use to do them in JMP.  A typical SAS marco for what we currently have is

%macro Import(Filepath=) the excel file(s), usually two worksheets from one workbook.  One for the data and one for specification limits

%macro USLtest(test=)

%macro LSLtest(test=)

%macro BothSLtest(test=)

ods rtf startpage=now columns=1;

data resultsdata;

set resultsdata;


format tablevalue 8.;


/* timeline */

data phases (keep=lot_count _Lot_ _PHASE_);

length _PHASE_ $7;

set resultsdata;

if mfg_date <= &startdate then _PHASE_='Prior';

else if mfg_date >= &startdate then _PHASE_='Current';


data limits (rename=(underscore=_VAR_));

set limitsdata;

where translate(strip(_VAR_),'____',' ()/')="&test";

underscore=translate(strip(_VAR_),'____',' ()/');

drop _VAR_;


data vref (keep=newvar _REF_ _REFLAB_ _CVREF_ rename=(newvar=_VAR_));

set limits;

where _VAR_="&test";


do i=1 to 2;

if i=1 then do;






if i=2 then do;







drop _VAR_;


/* run chart */

proc shewhart data=resultsdata;

irchart &test*lot_count='*' / nochart nochart2 vref=vref /*outtable=data1*/ outhistory=data1;


data data2;

merge data1 phases;

by lot_count;



data charts;

merge data2 limits;

by _VAR_;

call symput('lsl',strip(_LSL_));

call symput('usl',strip(_USL_));

call symput('var',strip(_VAR_));

call symput('units',strip(Units));


/* Individual Measrements Chart */

proc shewhart history=data2;

irchart &test*lot_count='*'  / outlabel=(lot_count) /* remove range chart */ nochart2  vref=vref /* Capability index based on subgroup data */ ciindices /* Spec LImits */ lsl=&lsl usl=&usl

/* Reads timelines */ readphases=all /* Identifies Phases at top of chart */ phaselegend vreflabpos=2 zerostd tests=1 to 4 testlabel1=' ' testlabel2=' ' clipfactor=2 totpanels=1;

inset stddev cpklcl='Cpk 95% Lower' cpk='Cpk' cpkucl='Cpk 95% Upper';

label &var="&var (&units)";


/* Histogram */

ods select histogram;

proc capability data=charts noprint;

spec lsl=&lsl usl=&usl;

var &var;

histogram &var / normal;

inset n='N'

pctlss='% < LSL' pctgtr='% > USL' cpklcl='Ppk 95% Lower' cpk='Ppk' cpkucl='Ppk 95% Upper' /

                                 cfill  = ywh

                                 format = 6.2;

                                 label &var="&var (&units)";


data resultsdata;

set resultsdata;


format tablevalue 8.;


ods rtf columns=4;

proc report data=resultsdata nowindows;

column lot_count _lot_ &test;

define lot_count / 'Count' display style(column)=[cellwidth=.5in];

define _lot_ / display;

define mfg_date / display;

define &test / display;


%macro USLtestwithsubgroups(test=)

%macro LSLtestwithsubgroups(test=)

%macro BothSLtestwithsubgroups(test=)


%macro Outputfilemacro(filepath=) inside of this macro is summarized by a general order of  (ODS graphics on, ods rtf startpage, call the test macros such as %BothSLtest(test='pH'), ods graphics off, rtf close)

I call anywhere from 8-20 different test macros inside of the outputfilemacro, each displaying 2-4 charts per test depending on which test macro is used.

at the end of my program I have just a hand full of things to change.

%Import(filepath=file location)

%Outputfilemacro(filepath=file loaction, product information for titles and such)

An example of Macros that I run in the outputfilemacro would be:

%mend outputfilemacro

ods graphic options with outfilepath destination

%BothSLChart (startdate='01Apr2013'd, test=pH)

%BothSLMeansChart (startdate='01Apr2013'd, test=Extractable_Volume, firstvar=C1, lastvar=C5, samplesize=5, startlotcount=42)

%USLChart (startdate='01Apr2013'd, test=Water_Content)

%BothSLChart (startdate='01Apr2013'd, test=Assay__Alprostadil_)

%USLChart (startdate='01Apr2013'd, test=PGA1)

%USLChart (startdate='01Apr2013'd, test=PGB1)

%USLChart (startdate='01Apr2013'd, test=keto_PGE1)

%USLChart (startdate='01Apr2013'd, test=iso_PGE1)

%USLChart (startdate='01Apr2013'd, test=Total_Impurities)

%BothSLMeansChart (startdate='01Apr2013'd, test=Content_Uniformity, firstvar=CU1, lastvar=CU10, samplesize=10, startlotcount=42)

%USLChart (startdate='01Apr2013'd, test=AV)

%BothSLChart (startdate='01Apr2013'd, test=Assay__NaCl_)

ods closing statements

%mend outputfilemacro

%Outputfilemacro (filepath=2014\2014_Productname\SAS\code, productnumber=code, productname=name, startdate='12Jun2013'd, enddate='11Jun2014'd)

Highlight that macro, click submit, SAS does the rest.

Test is the variable name from my data set that is being tested and charted against specification limits.  I have control charts with Capability estimates tested against the spec limits.

The charts display spec limits specific to each test, current and prior time phases depending on the dates I select, and capability indexes in the top left corner of the charts.  Each time I run this for a different product, all I do is change the filepath name, copy and paste which test macros I want to run, and set the test= value in each of the SLChart macros that I desire to have.  I can output all the charts I need about about 5-10 minutes for each product and product strength that I have.  This particular program for a strength of a product will produce 26 or so charts with data printout specific to the test following the chart.

Question is, can I do something similar as this in JMP 10?  If so, how do macros work in JMP?

I have a slight understanding of JMP JSL, but am brand new to it.  Just trying to figure out how to make things as automated in JMP as they are in our SAS macros.

Message was edited by: Jeff Ollis




Apr 26, 2012


I'm not exactly sure what your output might look like, but the JSL to open a file and then make some control charts is fairly simple.  Use JMP to open your excel file, and the JMP table will have a "source" script in the table box that you can use to open the table again. Then use JMP to make the control charts, format them to match your criteria, then save the script to the data table. 

Then to automate opening a table and running your control charts, just combine the Open statement from the Source script, and the Control Chart script in a new script window (separate the two instructions with a semi colon). There you have it, a automated report, with virtually no coding on your part.

Here are two simple examples:

//example 1

dt = Open( "$SAMPLE_DATA/Tablet" );

dt << Control Chart(

  Chart Col( :Blend Time, Individual Measurement ),

  Chart Col( :Blend Speed, Individual Measurement ),

  Chart Col( :Force, Individual Measurement ),

  Chart Col( :Mill Time, Individual Measurement ),

  Chart Col( :Coating Viscosity, Individual Measurement ),

  Chart Col( :Inlet Temp, Individual Measurement )


//example 2, slightly more complex

group1 = Expr(

  Control Chart(

  Sample Label( :Coating Supplier ),

  Chart Col( :Coating Viscosity, XBar, R ),

  Chart Col( :Inlet Temp, XBar, R )



group2 = Expr(

  control chart(

  Chart Col( :Blend Time, Individual Measurement ),

  Chart Col( :Blend Speed, Individual Measurement )



win = New Window( "Control Chart Example",

  H List Box(

  "Vertical list box",

  Panel Box( "First Group of Control Charts", group1 ),

  Panel Box( "Second Group of Control Charts", group2 )




Community Trekker


Jul 24, 2014

I updated my message is to help clear up exactly what is in my macros.

Thank you,


Super User


Jun 23, 2011

You can also simply call your SAS programs from a JSL program.  You can build a nice front end using JSL.




Oct 1, 2013

Hey, Jolly,

One thing other responders didn't cover, and maybe you know this, is that JMP's equivalent of a "macro" is a JSL Function.  A SAS Macro is a piece of SAS code that is encapsulated and can have parameters passed to it.  JSL Functions can encapsulate JMP scripts and allow parameters to be passed in.  So if your goal is to encapsulate some JMP functionality and have it be callable, possibly with parameters, consider JSL Functions.






Jun 23, 2011


I think the JSL equivalent of SAS macros would be JSL expressions. I say this because a SAS macro doesn't really pass arguments as much as it creates a text program where values have been substituted into the text for the macro variables. This is very similar to using Substitute() or Substitute Into() functions in JSL for expressions.

You can read here to get started with expressions and expression handling functions in JSL: Lists and Expressions.

That being said, JSL functions will also probably work in most of the same type situations that SAS macros do.


Michael Crotty
Sr Statistical Writer
JMP Development