Monday, December 4, 2017

Announcing the Launch of My Book of SAS Programming Hacks!


SAS Programming Professionals,

I am pleased to announce the publication of the print edition of my book:

Did You Know That?  Essential Hacks for Clever SAS Programmers!
https://tinyurl.com/y83aleb4

This book was previously published as an Amazon Kindle e-book.  But, I received a lot of requests for a print edition, so here it is.  And just in time for the holiday gift-giving season, too!

Best of luck in all of your SAS endeavors!

(aka Michael A. Raithel)




Monday, November 27, 2017

Hack 7.1 Avoiding File Lock Problems



SAS Programming Professionals,

Did you know that you can avoid those occasional, sporadic, annoying file lock wait errors on SAS for Windows by using a simple LIBNAME option?

Occasionally on SAS for Windows, the Microsoft DFS replication process unintentionally causes a lock on SAS data sets.  SAS does not wait for the lock to be released on the SAS data set and displays an error in the SAS log.  For Example:

libname timing "r:\path" ;

Proc sort data = timing.studyfil; 
by fncl_ast_id; 
run;

…could possibly produce the following error:

ERROR: A lock is not available for TIMING.STUDYFIL.DATA.

This happens because locks from third party software applications are not automatically checked by SAS’s internal FILELOCKWAIT facility. This particular error has occasionally been observed when the path to the SAS data library goes to a network drive, not to a C-drive.

To avoid this problem, use the libname option FILELOCKWAIT as follows:

libname timing "r:\path" filelockwait=10;


Note that filelockwait=  is in seconds and in most cases 10 seconds is enough. Also, don’t fret if you have never experienced this issue.  It is relatively rare and has not affected most SAS programmers.  But, now you are sufficiently armed in case you do encounter 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, October 30, 2017

Hack 6.5 Jazzing Up Reports Using ODS Style Templates



SAS Programming Professionals,

The Output Delivery System (ODS) utilizes style templates (sometimes called “style definitions”) to render output.  Style templates describe the font face, size, color, and other attributes that are to be used when a report is rendered.  SAS currently has 58 individual style templates available for your use; and more are sure to be added moving forward.  If you do not specify a style template in your SAS program, ODS uses the aptly named Default style template.  Most of the time, Default is satisfactory.  However, there are some very nice alternatives!

You can get a listing of all of the style templates available to you by submitting the following:

proc template;

list styles;

run;

The output looks, in part, like this:

       Obs    Path                         Type
       -----------------------------------------
       1     Styles                       Dir
       2     Styles.Analysis              Style
       3     Styles.Astronomy             Style
       4     Styles.Banker                Style
       5     Styles.BarrettsBlue          Style
       6     Styles.Beige                 Style
       .     ...                            ...

…where the style templates are Analysis, Astronomy, Banker, etc.

To see the effect of changing the style template, first copy the following code into a SAS session, run it, and look at the resulting RTF file:

options nodate nonumber;

ods Listing close;
ods RTF  file="c:\temp\Class_Report.rtf”;

    proc print data=sashelp.class  noobs n;
      title1 "Report of Class Weight/Height Study";
    run;

ods RTF close;
ods Listing;

Not bad.  No surprises there, right?

Now, run this code that has the Astronomy style template specified:

options nodate nonumber;

ods Listing close;
ods RTF  file="c:\temp\Class_Report.rtf" style=astronomy;

    proc print data=sashelp.class  noobs n;
      title1 "Report of Class Weight/Height Study";
    run;

ods RTF close;
ods Listing;

Very nice departure from the default, isn’t it?  Well, you have 56 more styles (…because one style is the Default; which you previously used) to try, so I am sure that you will find one that is just perfect for your team and your client!

It’s nice to see a bit of color in your reports, isn’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

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