Sometimes you are writing a program that needs to find out whether a particular SAS product (like SAS/ETS, SAS/QC, or SAS/OR) is licensed. I was reminded of this fact when I wrote last week's blog post about how to create a map with PROC SGPLOT. Although the SGPLOT procedure is included with Base SAS, the data set that I used (MAPS.US) is only available at sites that have licensed SAS/GRAPH software.
If you just want to find out what products are licensed at your site, but you don't need this information as part of a program, you can use the SETINIT procedure:
proc setinit; run; |
Product expiration dates: ---Base SAS Software 26OCT2016 ---SAS/STAT 26OCT2016 ---SAS/GRAPH 26OCT2016 ---SAS/ETS 26OCT2016 ---SAS/IML 26OCT2016 |
The SAS log contains all the licensed products. However, this information is hard to use in a program, which is necessary if you are writing a program that you intend to distribute to many sites. (Perhaps you intend to post it on the SAS/IML File Exchange>)
You can use the SYSPROD function to determine at run time whether a SAS product is licensed. For example, the following SAS/IML program tests whether the SAS/GRAPH product is installed. If not, it aborts the program and prints an error message. If so, it reads the MAPS.USCity data and performs a computation:
proc iml; if sysprod("graph") ^= 1 then ABORT "SAS/GRAPH is not licensed at this site"; else do; use maps.USCity; read all var {City StateCode Pop}; close maps.USCity; City = strip(City); idx = Pop[<:>]; /* find index of city with largest population */ print (City[idx])[L="Largest City"] (StateCode[idx])[L="State"] (Pop[idx])[L="Population" F=COMMA10.]; idx = Pop[>:<]; /* find index of city with smallest population */ print (City[idx])[L="Smallest City"] StateCode[idx])[L="State"] (Pop[idx])[L="Population" F=COMMA10.]; end; quit; |
The output of the program is shown. The program uses the index maximum operator to discover that New York City has the largest population in the data set. Similarly, the index minimum operator is used to return one of the 17 "ghost towns" in the data set.
You can use the SYSPROD function in the DATA step and in SAS/IML. For SAS macro programs, you can use the %SYSPROD macro function. The documentation for %SYSPROD has an example program that tests whether SAS/GRAPH is installed.
By the way, for this example you could use the LIBREF function to check whether the MAPS libref exists. However, the SYSPROD function makes it clear that you are checking for the existing of a product, not the existence of a libref.
For a fun exercise, print out the complete set of ghost towns (WHERE POP=0) in the MAPS.USCity data set. Which states have the most ghost towns?
7 Comments
Rick,
The documentation has this for the SYSPROD function:
"Requirement Product-name must be the correct official name of the product or solution."
Where do we find a list of these official names? Clearly from your example they are not what PROC SETINIT reports. The naming of SAS products has long puzzled me.
A related question: Now that versions of many products are decoupled from the base version number (&SYSVER), how do we programmatically discover the installed version, say, of SAS/STAT?
Greate question. Some product names are listed in the documentation for the %SYSPROD function.
For product versions, they always go out with a corresponding SAS release, so %put SYSVLONG; gives what you need. To link up the SAS release with the numbering scheme for the analytics products, see my blog post
Have you tried to run the following:
PROC PRODUCT_STATUS;
RUN;
I believe it gives version of the products in the log, so maybe this could be read.
I think there is also an option on this proc called MAKE_MACROS but I can't see an easy way to relate the macro name SYSPRODSTAT3 to a product name.
Very useful info in this blog post for SAS programmers - thanks!
Rick,
is there a simple way to determine which SAS products are necessary to run a given SAS code?
I don't think so. You can either grep for "proc " in the sas file and look up any procedures that are unfamiliar to you, or you can run the code and see if you get any "PROC not found" errors.