Tuesday, October 17, 2017

Hack 6.4 Inserting the SAS Date and Time into an RTF Document



SAS Programming Professionals,

Did you know that you can insert the standard SAS date and time into a new RTF document in place of the default RTF specification that inserts the printing date and time?

This is a bit hard to visualize, but stick with me; it’s worth it! 

If you were to submit the follow simple program at 8:00am this morning:

ods rtf file="rtfdate2.rtf";

proc print data=sashelp.class;
run;

ods rtf close;

…you would create an RTF document that would have the date/time embedded as a header in the upper right hand side.  If you were to open that file at 11:00am this morning, the header would read:

11:00 Monday, December 12, 2015  1

…even thought it was actually created at 8:00am this morning.  If you were to print the document at 11:30 this morning, the header on the printed page would read:

11:30 Monday, December 12, 2015  1

…even though it was actually created at 8:00am this morning and you opened the file at 11:00am this morning. 

Now, what’s wrong with this picture?  Well, nothing if you want the RTF default header date/time in effect.  However, if you want to document the date/time this document was actually created, then code the SASDATE option in the ODS statement.  Here is an example using the same program as before:

ods rtf file="sasdate.rtf" sasdate;

proc print data=sashelp.class;
run;

ods rtf close ;

If you were to submit that at 8:00am this morning, then whenever you open it up, you will see the following header:

8:00 Monday, December 12, 2015  1

Similarly, whenever you print the document, that will be the header in the hard copy.  This will happen each and every time that you open the file and that you print the file.

So, the SASDATE option on the ODS FILE= statement “freezes” the date/time the RTF document was created.  Nine times out of ten, that is exactly the behavior that I want!  And you?

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, October 2, 2017

Hack 6.3 Customizing Footnotes For More Professional Looking Reports



SAS Programming Professionals,

Did you know that you can make your reports look more professional by customizing the footnotes?

Sometimes, too much information at the top of a report can make it look a bit cluttered.  SAS-generated reports often have the date and time they were created, as well as the page number, on the upper right-hand side of their pages.  They also tend to have several lines of titles describing the general content of the report.

Wouldn’t it be cleaner to put the report’s creation date and page numbers on the bottom?  And, wouldn’t it be nice to show your clients which relative page they are viewing by having “page x of y” as the page specification?  If the answer to both of these questions is “Yes”, then take a look at this example:

ods pdf file="c:\temp\car_report.pdf";
ods escapchar="^";

options nodate nonumber;

proc print noobs data=sashelp.cars;

      var make model msrp;

title "Important Cars Report";

footnote1 j=l '^{thispage} of ^{lastpage}' j=r "Report Date: 

%sysfunc(date(),worddate.)";

run;

ods pdf close;

We start off with an ODS statement that specifies a new PDF document that will house our report.  The second ODS statement specifies the ESCAPECHAR—a symbol telling ODS that what follows is an instruction, not something to be printed.  The OPTIONS statement directs SAS to not write the date/time and page number at the top of the report.  Less clutter!

The important action takes place in the FOOTNOTE statement:

·        j=l tells SAS to left justify the following section of the footnote.


·        ‘^{thispage} of ^{lastpage}’ – the THISPAGE function inserts the current page number; the LASTPAGE function inserts the last page number.

·        j=r specifies for the following section of the footnote  to be right justified.

·        "Report Date:  %sysfunc(date(),worddate.)" – surfaces the current date and formats that date using the WORDDATE format.

Copy the example, above into a SAS Display Manager Session and give it a test drive.  Nice report, eh?  Note the cleaner look at the top and the more professional look at the bottom.  Maybe you can use this technique to improve the look of some of your own projects’ reports!

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, September 25, 2017

Hack 6.2 Printing in Portrait and Landscape Mode in the Same Document



SAS Programming Professionals,

Did you know that you can change the orientation of printed SAS reports between portrait and landscape?

This can be done by specifying either PORTRAIT (the default) or LANDSCAPE as the value of the ORIENTATION option.

Here is an example of creating a report in a PDF file with the ORIENTATION option specified as landscape and then as portrait:

ods _all_ close;
ods noresults;
title2 'Switching PDF orientation on the fly';
ods pdf notoc  file="%sysfunc(pathname(WORK))\ChangeOrientation.pdf";

title3 'Females in Landscape';
options orientation=landscape;

proc print  data=sashelp.class;
where sex = 'F';
run;

title3 'Males in Portrait';
options orientation=portrait;

proc print  data=sashelp.class;
where sex = 'M';
run;

ods pdf close;

The first OPTIONS statement specifies to print in landscape mode, so the first report created in the PDF has that orientation.  The second OPTIONS statement specifies portrait mode, so the second report is printed with the portrait orientation.  Don’t forget that the ORIENTATION option is a system option, and the value you change it to is in effect for the duration of your SAS program… unless, of course, you change it back again.

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, July 31, 2017

Hack 6.1 Adding Color to Report Titles with the ODS ESCAPECHAR Statement




SAS Programming Professionals,

Did you know that you can improve the look of your SAS-generated reports by adding a little color to the titles?

You can use the Output Delivery System (ODS) ESCAPECHAR statement and inline formatting to add and change colors within your report titles.  Here is an example:

ods escapechar = "^";

ods pdf file="example2.pdf";

title1 "^S={color=blue}Though this title started off blue ^S={color=red}it changed to red";
title2 "^S={color=green}This title was green ^S={}before changing to black";

proc print data=sashelp.class;
run;

ods _all_ close;

We start off with the ODS ESCAPECHAR statement, which defines a special character that will be used to signal to SAS that we want to perform inline formatting.  In our case, whenever SAS sees “^” in a title statement, it knows that ODS inline statements follow.  Thereafter, we put “^” to work in two TITLE statements; each time specifying the color for the following text.  If you copy the example above into a SAS Display Manager session and execute it, you will note the changes in the colors in the title lines.  Really makes you think about how you may be able to spruce-up those tired old reports, doesn’t it?

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers


Monday, July 10, 2017

Hack 5.5 Using Macros to Comment Out Sections of SAS Programs



SAS Programming Professionals,

Did you know that you can use SAS macros as a handy way to comment out code in a program?

You can do this by enclosing portions in a SAS macro and not calling that macro.  Here is an example:

options msglevel=I;

%MACRO HIDEIT;

libname audit "H:\My Documents\My SAS Programs\Audit Trails\Data";

proc copy in=sashelp out=audit;
      select orsales;
run;

data audit.orsales;

seqno = _n_;

set  audit.orsales;

run;

%MEND HIDEIT;

data audit.orsales2;
set  audit.orsales;
stop;
run;

proc datasets library=audit nolist;
      audit orsales2;
      initiate;
      log admin_image=yes
      before_image=yes
      data_image=no
      error_image=yes;
run;
quit;

In this example, we wish to not execute (to hide) the LIBNAME statement, PROC COPY, and the DATA step as we test the latter sections of our program.  So, after they are first executed, we enclose them in the HIDEIT macro.  Thereafter, when we run this program, the aforementioned SAS constructs do not execute.  Once we are done testing the program, we can either comment out the %MACRO and %MEND statements or delete them entirely.  Pretty clever, eh?

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, June 26, 2017

Hack 5.4 Using A SAS Utility Macro that Creates CSV Files




SAS Programming Professionals,

Did you know that you can easily create a CSV file using a simple SAS utility macro?

The %DS2CSV utility macro allows you to create a CSV file from any SAS data set.  Here is an example:

%DS2CSV(data=sashelp.class,
 runmode=B,
csvfile=c:\temp\class.csv,
var=name age sex height,
where=sex="F");

…where:

·        data= specifies the SAS data set to be CSV-i-tized

·        runmode= use “B” to specify that you are running the macro in a non-SAS/IntrNet environment

·        csvfile= the full path name of the CSV file you want to create

·        var= optional parameter to use to list a subset of variables to output to the CSV file, otherwise all variables are written to the file

·        where= optional parameter to use if you want to subset the observations output to the CSV file

The code, above, produces the following SAS log entry:

1    %DS2CSV(data=sashelp.class, runmode=B, csvfile=c:\temp\class.csv, var=name age sex height, where=sex="F");
NOTE: CSV file successfully generated for SASHELP.CLASS.

…and produces this CSV file:

"Name","Age","Sex","Height"
"Alice","13","F","56.5"
"Barbara","13","F","65.3"
"Carol","14","F","62.8"
"Jane","12","F","59.8"
"Janet","15","F","62.5"
"Joyce","11","F","51.3"
"Judy","14","F","64.3"
"Louise","12","F","56.3"
"Mary","15","F","66.5"

Note that only the variables we specified were copied to the CSV file.  And, our subsetting the observations was also successful.

Of course, the CSV file looks a lot better if you open it using Excel:

Name
Age
Sex
Height
Alice
13
F
56.5
Barbara
13
F
65.3
Carol
14
F
62.8
Jane
12
F
59.8
Janet
15
F
62.5
Joyce
11
F
51.3
Judy
14
F
64.3
Louise
12
F
56.3
Mary
15
F
66.5

But, you already knew that, didn’t you?

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers

Monday, June 12, 2017

Hack 5.3 Saving the Source Code of Compiled Macros




SAS Programming Professionals,

Did you know that you can save the source code for compiled macros in the same macro catalog entry as the compiled code for later use?

The SOURCE option of the %MACRO statement directs SAS to save the macro source statements along with the compiled macro code in the macro catalog entry.  Thereafter, you can use the %COPY macro statement to print the macro’s source code to the SAS log, or have it written to a file.  Here is an example:

libname maclib "c:\temp";

options mstored sasmstore=maclib;

%MACRO BIGMAC / store source;

proc print data=sashelp.class;
    var name age;
run;

%MEND BIGMAC;


%COPY BIGMAC / source out='c:\temp\bigmac.sas';

We begin this example by allocating a directory to house the macro catalog via a LIBNAME statement.  The two options specified in the OPTIONS statement declare that all stored macros are to be stored in the macro catalog (which SAS will name SASMACR)  in the previously allocated directory.

Next, we create the %BIGMAC macro.  The STORE option directs SAS to store the compiled macro in a catalog entry.  The SOURCE option tells SAS to store the source code for the macro—everything between %MACRO and the final semicolon on the %MEND statement—in the same catalog entry.

We suddenly realize that we need to create a separate SAS program from the BIGMAC macro catalog entry.  So, we use the %COPY macro statement and the SOURCE option, and create the BIGMAC.SAS program file.  If we had not specified the OUT= option, SAS would have simply written the macro source code to the log.

The ability to store macro SOURCE code in the macro catalog entry was introduced in version 9 of SAS.  It obviates the old tried-and-true method of storing the source code of compiled macros in separate directories.  Though many of us have done that for years and have it down-pat, there is always the possibility that the macro catalog and the source code directory could somehow lose sight of one another.  Having the source code living in the same Dwelling Unit as the compiled macro provides an extra layer of integrity to the clever SAS macros that you write!

Best of luck in all your SAS endeavors!


---MMMMIIIIKKKKEEEE
(aka Michael A. Raithel)
Author of the new cult classic for computer programmers:  It Only Hurts When I Hit <ENTER>
Print edition:  http://tinyurl.com/z8bzx2e 
Kindle edition: http://tinyurl.com/zypgqa7 

The hack above is an excerpt from the book:  Did You Know That?  Essential Hacks for Clever SAS Programmers