Using the ODS statement to add layers in your ODS sandwich

The ODS statement controls most aspects of how SAS creates your output results. You use it to specify the destination type (HTML, PDF, RTF, EXCEL or something else), as well as the details of those destinations: file paths, appearance styles, graphics behaviors, and more. The most common use pattern is the "ODS sandwich." In this pattern, you open the destination with the ODS statement, then include all of the code that generates the substance of the output, and then use an ODS CLOSE statement to finish it off. Here's a classic example:

ods html file="c:\project\myout.html" /* top slice of bread */
style=journal gpath="c:\project";
proc means data=sashelp.class; /* the "meat" */
run;

proc sgplot data=sashelp.class;
histogram weight;
run;
ods html close; /* bottom slice */

But did you know that you can insert more ODS statements to adjust ODS behavior midstream? These allow you to use a variety of ODS behaviors within a single result. You can create your own "Dagwood sandwich" version of SAS output! For cultural reference:

Dagwood sandwich: A Dagwood is a tall, multi-layered sandwich made with a variety of meats, cheeses, and condiments. It was named after Dagwood Bumstead, a central character in the comic strip Blondie, who is frequently illustrated making enormous sandwiches. Source: Wikipedia

Here's an example program that changes graph style and title behavior within a single ODS output file. You should be able to try this code in any SAS programming environment.

ods _all_ close;
%let outdir = %sysfunc(getoption(WORK));
ods graphics / width=400 height=400;

ods html(id=dagwood) file="&outdir./myout.html"
style=journal gtitle
gpath="&outdir.";

title "Example ODS Dagwood sandwich";
proc means data=sashelp.class;
run;
ods layout gridded columns=2;
ods region;
ods html(id=dagwood) style=statdoc ;
proc sgplot data=sashelp.class;
title "This title is part of the graph image, Style=STATDOC";
histogram weight;
run;
ods region;
ods html(id=dagwood) style=raven nogtitle;
title "This title is in the HTML, Style=RAVEN";
proc sgplot data=sashelp.class;
histogram height;
run;
ods layout end;

ods html(id=dagwood) close;

Here's the result, plus some important items to note about this technique.

It's a good practice to distinguish each ODS destination with an ID= value. This allows you to reference the intended ODS stream with no ambiguity. After all, you can have multiple ODS destinations open at once, even multiple destinations of the same type. In my example, I used ID=dagwood to make it obvious which destination the statement applies to.

You can use this technique to modify only those directives that can change "mid-file" to apply to different parts of the output. You can't modify those items that apply to the entire file, such as PATH, ENCODING, STYLESHEET and many more. These can be set just once when you create the file; setting multiple different values wouldn't make sense.

You can use this technique within those applications that generate ODS statements for you, such as SAS Enterprise Guide. For example, to modify the default SAS Enterprise Guide HTML output "midstream", add a statement like:

ods html(id=eghtml) /*... plus your options, like STYLE=*/ ;
ods html(eghtml) /* this shorthand works too */ ;

In SAS Studio or SAS OnDemand for Academics, try this:

ods html5(id=web) /*... plus your options, like STYLE=*/ ;
ods html5(web) /* this shorthand works too */ ;

Example: an ODS Graphics style sampler

Here's one more example that puts it all together. Have you ever wanted an easy way to check the appearance of the dozens of different built-in ODS styles? Here's a SAS macro program that you can run in SAS Enterprise Guide (with the HTML result on) that generates a "sampler" of graphs that show variations in fonts, colors, and symbols across the different styles.

This example uses ODS LAYOUT (production in SAS 9.4) to create a gridded layout of example plots. If you want to try this in SAS Studio or in SAS OnDemand for Academics, you can adjust one line in the program (as noted in the code comments).

/* Run within SAS Enterprise Guide */
/* with the HTML result option turned ON */
%macro styleSampler;
title;
proc sql noprint;
select style into :style1-:style99
from sashelp.vstyle
where libname="SASHELP" and memname="TMPLMST";

ods layout gridded columns=4;
ods graphics / width=300 height=300;
%do index=1 %to &sqlobs;
ods region;
ods html(eghtml) gtitle style=&&style&index.;
/* In SAS Studio, use this instead: */
/* ods html5(web) gtitle style=&&style&index.; */
title "Style=&&style&index.";
proc sgplot data=sashelp.class;
scatter x=Height y=Weight /group=Sex;
reg x=Age y=Weight / x2axis;
run;
%end;
ods layout end;
%mend;

%styleSampler;

See also

Take control of ODS results in SAS Enterprise Guide
Best way to suppress ODS output in SAS
Advanced ODS Graphics techniques: a new free book