• Print  |
  • Feedback  |

Knowledge Base


TS-605

Sending Electronic Mail within the SAS System under OS/390

THE EMAIL DEVICE TYPE IS SUPPORTED IN VERSION 8 (TS M0).

The SAS System enables you send electronic mail (e-mail) by way of a DATA step, SAS procedure, or SCL. Specifically, you can:

  • use the logic of the DATA step or SCL to subset e-mail distribution based on a large data set of e-mail addresses.

  • send e-mail automatically upon completion of a SAS program that you submitted for batch processing.

  • direct output through e-mail that is based on the results of processing.


E-mail System Interface

The SAS System sends all e-mail over a socket to an SMTP server.

Note:   You or your system administrator may have to specify the EMAILHOST SAS system option to identify the host that runs the SMTP server on your network. The EMAILHOST option defaults to localhost.


Syntax of the FILENAME Statement for E-mail

FILENAME fileref EMAIL 'address' <e-mail-options>;

The FILENAME statement for the EMAIL device-type accepts the following options:

fileref
is a name temporarily assigned to an external file or to an aggregate storage location that identifies it to the SAS System.

'address'
is the e-mail address of the recipient. Alternatively, you may specify recipient address arguments to the TO= option or by way of a !EM_TO! directive.

e-mail-options
are:

TO=to-address
specifies the primary recipients of the e-mail. If an address contains special characters or more than one word, enclose the entire address in single or double quotes. To specify more than one address, enclose the list of addresses in parentheses and each address in single or double quotes. Separate addresses with a space.

Examples:

to='joe@somplace.org'

to=("joe@smplc.org" "jane@diffplc.org")

Specifying the TO= option overrides the 'address' option.

CC=cc-address
identifies the recipients to receive a copy of the e-mail. If an address contains special characters or more than one word, enclose the entire address in single or double quotes. To specify more than one address, enclose the list of addresses in parentheses. Separate addresses with a space.

Example:

cc='joe@somplace.org'

cc=('joe@smplc.org' 'jane@diffplc.org')

SUBJECT='subject'
specifies the subject of the message. If the subject text contains special characters or more than one word, enclose the text in single or double quotes.

Examples:

subject=Sales

subject='June Report'

Any subject that is not enclosed in quotes is converted to upper case.

ATTACH='file-specification'
specifies the name of one or more files to attach to the message. Enclose the file name in double quotes. To attach more than one file, or a file and other attachment options, enclose the list of file-specifications in parentheses and separate each file-specification with a space. In addition, you may specify a content-type and an extension for each attachment by using the content-type and extension options for each attachment file-specification.
c[ontent_]t[ype]='content/type'
specifies the MIME content type that should be associated with this attachment. The default content type is text/plain. Content_type may be specified as:
  • Content_type
  • content-type
  • type
  • ct
ext[ension]='extension'
specifies the filename extension on the file that is attached. This extension will be used by the recipient's e-mail system for selecting the appropriate utility to use for displaying the attachment. The default attachment extension is "txt".
Examples:

attach="user.misc.pds(member)" content_type='text/html' extension='html'

attach=("user.misc.jcl(sasjcl)" extension='doc' "userid.sas.output" content_type='image/gif' extension='gif')

TYPE='content-type'
specifies the content type of the main message body.

Examples:

type='text/plain'

type='text/html'

type='image/gif'

The value for TYPE must be enclosed in single or double quotes.


Using the DATA Step or SCL to Send E-mail

In general, a DATA step or SCL code that sends e-mail has these components:

  • a FILENAME statement with the EMAIL device-type keyword

  • options specified on the FILENAME or FILE statements indicating the e-mail recipients, subject, and any attached files

  • PUT statements that contain the body of the message

  • PUT statements that contain special e-mail directives (of the form !EM_directive!) that can override the e-mail attributes (TO, CC, SUBJECT, TYPE, ATTACH) or perform actions (such as SEND, ABORT, and start a NEWMSG).

Options that you specify in the FILE statement override any corresponding options that you specified in the FILENAME statement.

In your DATA step, after using the FILE statement to define your e-mail fileref as the output destination, use PUT statements to define the body of the message.

You can also use PUT statements to specify e-mail directives that change the attributes of your electronic message or perform actions with it. Specify only one directive in each PUT statement; each PUT statement can contain only the text associated with the directive it specifies. Use quotes as necessary to construct the arguments of the PUT statement. However, the final string written by the PUT statement does not need to be enclosed in quotes.

These directives can change the attributes of a message:

!EM_TO! addresses
replaces the current primary recipient addresses with addresses.

Examples:

PUT "!EM_TO!" "joe@somplace.org";

user="joe@somplace.org";
put '!EM_TO!' user;
To specify more than one address, enclose the list of addresses in parentheses and each address in single or double quotes, and separate each address with a space.

Examples:

PUT "!EM_TO!" ('joe@smplc.org' 'jane@diffplc.org');


list=('joe@smplc.org' 'jane@diffplc.org');
put '!EM_TO!' list;

!EM_CC! addresses
replaces the current copied recipient addresses with addresses.

Examples:

PUT "!EM_CC!" "joe@somplace.org";


user="joe@somplace.org";
put '!EM_CC!' user;
To specify more than one address, enclose the list of addresses in parentheses and each address in single or double quotes and separate addresses with a space.

Examples:

PUT "!EM_CC!" ('joe@smplc.org' 'jane@diffplc.org');


list=('joe@smplc.org' 'jane@diffplc.org');
put '!EM_CC!' list;

!EM_SUBJECT! subject
replaces the current subject of the message with subject.

!EM_CONTENTTYPE! content-type
replaces the current content-type of the message with content-type.

!EM_ATTACH! file-specification
replaces the current list of attachments with file-specification. Enclose the file name in double quotes. To attach more than one file or a file with additional attachment options, enclose the list of file specifications or options in parentheses and separate each file-specification with a space. In addition, you may specify a content-type and an extension for each attachment by using the content_type and extension options for each attachment file-specification.

c[ontent_]t[ype]='content/type'
specifies the MIME content type that should be associated with this attachment. The default content type is text/plain.
ext[ension]='extension'
specifies the filename extension on the recipient's file that is attached. This extension will be used by the recipient's e-mail system for selecting the appropriate utility to use for displaying the attachment. The default attachment extension is "txt".
Examples of valid file attachment specifications are:

put '!EM_ATTACH!' "user.misc.pds(member)" content_type='text/html' extension='html'

put '!EM_ATTACH!' ("user.misc.jcl(sasjcl)" extension='doc', "userid.sas.output" content_type='image/gif' extension='gif')

mycfg='"user.misc.jcl(sasjcl)"';
syscfg="user.sas.output" content_type='image/gif' !em_gif='gif';
put '!EM_ATTACH!' "'("mycfg","syscfg")'";

These directives perform actions:

!EM_SEND!
sends the message with the current attributes. By default, the message is automatically sent at the end of the DATA step. If you use this directive, the SAS System sends the message when it encounters the directive, and again at the end of the DATA step.

!EM_ABORT!
aborts the current message. You can use this directive to stop the SAS System from automatically sending the message at the end of the DATA step.

!EM_NEWMSG!
clears all attributes of the current message, including TO, CC, SUBJECT, TYPE, ATTACH, and the message body.


Example: Sending E-mail from the DATA Step

Suppose that you want to share a copy of your SASV8 CONFIG file with your co-worker Jim, whose userid is JBrown. You could send it by submitting the following DATA step:

filename mymail email 'JBrown@ajax.com'
         subject='My SASV8 CONFIG file'
         attach="jbrown.tso.config(sasv8)"

data _null_;
  file mymail;
  put 'Jim,';
  put 'This is my SASV8 CONFIG file.';
  put 'I think you might like the new options I added.';
  run;

The following example sends a message and two attached files to multiple recipients. It specifies the e-mail options in the FILE statement instead of in the FILENAME statement:

filename outbox email 'ron@acme.com';

data _null_;
  file outbox
     to=('ron@acme.com' 'lisa@acme.com')
     /* Overrides value in */
     /* filename statement */

     cc=('margaret@yourcomp.com'
         'lenny@laverne.abc.com')
     subject='My SAS output'
     attach=("my.sas.output" "my.sas.code")
     ;
  put 'Folks,';
  put 'Attached is my output from the
      SAS program I ran last night.';
  put 'It worked great!';
run;

You can use conditional logic in the DATA step to send multiple messages and to control which recipients receive which message. For example, suppose you want to send customized reports to members of two different departments. Here is a DATA step example:

filename reports email 'Jim@corp.com';

data _null_;
  file reports;
  infile cards eof=lastobs;
  length name dept $ 21;
  input name dept;
  put '!EM_TO!' name;
   /* Assign the TO attribute      */

  put '!EM_SUBJECT! Report for ' dept;
   /* Assign the SUBJECT attribute */

  put name ',';
  put 'Here is the latest report for ' dept '.';
  if dept='marketing' then
    put '!EM_ATTACH!' "userid.market.report";
  else
    /* ATTACH the appropriate report */

    put '!EM_ATTACH!' "userid.devlpmnt.report";
  put '!EM_SEND!';
    /* Send the message */

  put '!EM_NEWMSG!';
    /* Clear the message attributes */

  return;
lastobs: put '!EM_ABORT!';
    /* Abort the message before the */
    /*   RUN statement causes it to */
    /*   be sent again.             */

  datalines;
Susan          marketing
Jim            marketing
Rita           development
Herb           development
;
run;

The resulting e-mail message and its attachments are dependent on the department to which the recipient belongs.

Note:   You must use the !EM_NEWMSG! directive to clear the message attributes between recipients. The !EM_ABORT! directive prevents the message from being automatically sent at the end of the DATA step.


Sending Procedure Output as E-mail

E-mail can be used to send procedure output. ODS HTML procedure output must be sent with the RECORD_SEPARATOR (RS) option set to NONE. For OS/390, ODS produces an HTML stream with embedded record-separator characters, by default. When the RS option is set to NONE, ODS writes one line of HTML at a time to the file. Be sure that the files' record length is large enough to accommodate the longest HTML line.

The following section contains examples that illustrate how to send ODS HTML and graph output in the body of an e-mail message and also as attachments to e-mail.


Examples: Sending Procedure Output via E-mail

The following example shows how to use ODS to send HTML output in e-mail:

     filename outbox email
        to='susan@mvs'
        type='text/html'
        subject='Temperature conversions'
        ;

     data temperatures;
        do centigrade = -40 to 100 by 10;
           fahrenheit = centigrade*9/5+32;
           output;
        end;
     run;

     ods html
        body=outbox /* Mail it! */
        rs=none;

     title 'Centigrade to Fahrenheit conversion table';
     proc print;
     id  centigrade;
     var fahrenheit;
     run;

     ods html close;

The following example shows how to create and send a GIF image in an e-mail message:

     filename gsasfile email
        to='Jim@acme.com'
        type='image/gif'
        subject="SAS/GRAPH output."
        ;

     goptions dev=gif gsfname=gsasfile;

     proc gtestit pic=1; run;

The following example shows how to create ODS HTML and send it as attachments to an e-mail message:

 /* ------------------------- */
 /* allocate PDSE to contain the HTML output */
 /* ---------------------------------------- */
filename odsout '.mvsmail1.pdse' disp=(new,catlg,delete)
                dsorg=po dsntype=library;

 /* ------------------------------------ */
 /* stop sending output to OUTPUT window */
 /* ------------------------------------ */
ods listing close;

 /* ----------------------------------------------------- */
 /* Assign frame, contents and body files.                */
 /* Specify the URLs to have the .html extension.         */
 /* Specify the PATH to be the PDSE.                      */
 /* Specify RS=NONE to write one line of HTML per record. */
 /* This is necessary when e-mailing the HTML output.    */
 /* ----------------------------------------------------- */
ods html frame='shoes1f'
    contents='shoes1c' (url='shoes1c.html')
    body='shoes1b'     (url='shoes1b.html')
    path=odsout
    rs=none;

data newshoes;
   set sashelp.shoes;
   where Region in ('Canada' 'Central America/Caribbean'
                    'South America' 'United States');
run;

 /* ----------------------------------------- */
 /* sort the data set and generate the report */
 /* ----------------------------------------- */
proc sort data=newshoes;
   by Region Subsidiary Product;
run;

options nobyline;
title1 'Sales for Regions #byval(Region)';
proc report data=newshoes nowindows;
  by Region;
  column Region Product Subsidiary Sales;
  define Region / noprint group;
  define Product    / display group;
  define Subsidiary / display group;
  define Sales   / display sum format=dollar8.;
  compute after Region;
          Product='Total';
  endcomp;
  break after Region    / summarize style=rowheader;
run;

 /* ------------------------------------------------------ */
 /* Close the HTML destination and open the listing output */
 /* ------------------------------------------------------ */
ods html close;
ods listing;

 /* ----------------- */
 /* E-mail the report */
 /* ----------------- */
filename email email 'fred@bedrock.com'
     subject="Shoe report 1"
     type="text/plain"
attach=(".mvsmail1.pdse(shoes1f)" content_type='text/html' extension='html'
        ".mvsmail1.pdse(shoes1c)" content_type='text/html' extension='html'
        ".mvsmail1.pdse(shoes1b)" content_type='text/html' extension='html') ;
data _null_;
   file email;
   put 'Here is the latest Shoe sales report';
run;

The following example shows how to create ODS HTML and GIF files and send them as e-mail attachments:

 /* ------------------------------------------------ */
 /* Define the UNIX System Services HFS directory to */
 /* contain the graphics and HTML output.            */
 /* ------------------------------------------------ */
filename odsout '/u/myhome/public_html';

 /* ------------------------------------------------ */
 /* stops sending output to GRAPH and OUTPUT windows */
 /* ------------------------------------------------ */
ods listing close;

 /* ---------------------------- */
 /* set the graphics environment */
 /* ---------------------------- */
goptions reset=global gunit=pct
         colors=(black blue green red)
         hsize=8.42 in vsize=6.31 in ftitle=zapfb
         ftext=swiss htitle=4 htext=2.5
         device=gif transparency noborder;

 /* --------------------------------- */
 /* add the HTML variable to NEWSHOES */
 /* --------------------------------- */
data newshoes;
   set sashelp.shoes;
   where Region in ('Canada' 'Central America/Caribbean'
                    'South America' 'United States');
   length regdrill $40;

if Region='Canada' then
   regdrill='HREF="shoes1_regsales.html#IDX1"';

else if Region='Central America/Caribbean' then
   regdrill='HREF="shoes1_regsales.html#IDX2"';

else if Region='South America' then
   regdrill='HREF="shoes1_regsales.html#IDX3"';

else if Region='United States' then
   regdrill='HREF="shoes1_regsales.html#IDX4"';

run;

 /* ------------------------------------------------------*/
 /* Assign the destination for the ODS graphics output    */
 /* and ODS HTML files.                                   */
 /* Specify RS=NONE to write one line of HTML per record. */
 /* This is necessary when e-mailing the HTML output.     */
 /* ----------------------------------------------------- */
ods html path=odsout
         body='shoe_report.html'
         rs=none
         nogtitle;

 /* ----------------------------------- */
 /* define title and footnote for chart */
 /* ----------------------------------- */
title1 'Total Sales for the Americas';
footnote1 h=3 j=l 'click on bars' j=r 'REPORT3D ';

 /* ----------------------------------- */
 /* assign a pattern color for all bars */
 /* ----------------------------------- */
pattern color=cyan;

 /* --------------------------- */
 /* define axis characteristics */
 /* --------------------------- */
axis1 order=(0 to 7000000 by 1000000)
      minor=(number=1)
      label=none;
axis2 label=none offset=(4,4)
      value=('Canada' 'C. Amr./Car.'
             'S. America' 'USA');

 /* --------------------------- */
 /* generate vertical bar chart */
 /* --------------------------- */
proc gchart data=newshoes;
   vbar3d Region / discrete
                 width=6
                 sumvar=sales
                 html=regdrill
                 coutline=black
                 cframe=blue
                 maxis=axis2
                 raxis=axis1
                 name='shoes1 ';
run;
quit;

 /* ----------------------------------------------------- */
 /* Open the HTML destination for the PROC PRINT output.  */
 /* Specify RS=NONE to write one line of HTML per record. */
 /* This is necessary when e-mailing the HTML output.     */
 /* ----------------------------------------------------- */
ods html body='shoes1_regsales.html'
         rs=none
         path=odsout;

 /* ----------------------------------------- */
 /* sort data set NEWSHOES in order by region */
 /* ----------------------------------------- */
proc sort data=newshoes;
   by Region Subsidiary Product;
run;
quit;

 /* -------------------------------------------- */
 /* print a report of shoe sales for each Region */
 /* -------------------------------------------- */
goptions reset=footnote;
option nobyline;
title 'Sales Report for #byval(Region)';
proc report data=newshoes nowindows;
  by Region;
  column Region Subsidiary Product Sales;
  define Region    / noprint group;
  define Subsidiary    / display group;
  define Product / display group;
  define Sales   / display sum format=dollar12.;
  compute after Region;
          Subsidiary='Total';
  endcomp;
  break after Region / summarize style=rowheader page;
run;

 /* ------------------------------------------------------ */
 /* Close the HTML destination and open the listing output */
 /* ------------------------------------------------------ */
ods html close;
ods listing;

 /* ---------------- */
 /* Email the report */
 /* -----------------*/
filename email email 'barney@bedrock.com'
     subject="Shoe report 2"
     type="text/plain"
attach=("./public_html/shoe_report.html" content_type='text/html'
        "./public_html/shoes1_regsales.html" content_type='text/html'
        "./public_html/shoes1.gif" content_type='image/gif') ;
data _null_;
   file email;
   put 'Here is the latest Shoe sales report';
run;

Example: Sending E-mail By Using SCL Code

The following example is the SCL code that underlies a frame entry design for e-mail. The frame entry includes these text entry fields:

mailto the userid of the e-mail recipient
copyto the userid of the e-mail recipient of the e-mail copy (CC)
attach the name of the file to attach
subject the subject of the e-mail message
line1 the text of the e-mail message

The frame entry also contains a pushbutton named SEND that causes this SCL code (marked by the send: label) to execute.

send:

   /* set up a fileref */

   rc = filename('mailit','userid','email');

   /* if the fileref was successfully set up
      open the file to write to */

   if rc = 0 then do;
      fid = fopen('mailit','o');
      if fid > 0 then do;

         /* fput statements are used to
            implement writing the
            mail and the components such as
            subject, who to mail to, etc. */


         fputrc1  = fput(fid,line1);
         rc = fwrite(fid);

         fputrc2  = fput(fid,'!EM_TO! '||mailto);
         rc = fwrite(fid);
         fputrc3  = fput(fid,'!EM_CC! '||copyto);
         rc = fwrite(fid);

         fputrc4  = fput(fid,'!EM_ATTACH! '||attach);
         rc = fwrite(fid);
         fputrc5  = fput(fid,'!EM_SUBJECT! '||subject);
         rc = fwrite(fid);

         closerc  = fclose(fid);
      end;
   end;
return;

cancel:
   call execcmd('end');
return;