Problem Solvers

8月 172021
 

What happens if you need to edit graph output files from SAS in a different application (for example, Microsoft Word)? It is not recommended that you edit your SAS graph output outside of SAS, but if you must do so, this article discusses the graphics output options that you need to use.

Understanding the EMF graph output types

To create graphics output that is editable, you need to create your graphics output as EMF (Enhanced Metafile Format) graph output. The EMF graph format is a vector-based graphics format. Formats such as PNG, GIF, JPEG, and TIFF are bitmap image formats and, typically, bitmap image formats cannot be edited.

You can either create a stand-alone EMF graph output file or embed your EMF graph output inside an RTF document by using the ODS RTF destination. The EMF graph format is the default graph format when you want to create graphics output with the ODS RTF destination.

By design, the default EMF graph output that SAS creates is in an EMF Plus (EMF+) format. However, this type of EMF graph output is not editable. To create an EMF graph output that you can edit, you must create your EMF graphics output in a format known as EMF Dual format. This format combines EMF Plus output and traditional EMF graph output in a single graph file.

Creating EMF Dual graph output with the SAS/GRAPH® procedures

If you are using a SAS/GRAPH procedure (such as GPLOT or GCHART), you can create EMF Dual graph output by specifying the DEVICE=EMFDUAL option in the GOPTIONS statement:

goptions device=emfdual;

When you use the EMFDUAL device driver to write a stand-alone EMF graph file to disk, use code similar to the following:

ods _all_ close; 
ods listing; 
filename grafout "\file-path\file-name.emf"; 
goptions device=emfdual gsfname=grafout;
/* Your SAS/GRAPH procedure code goes here */

When you use the EMFDUAL device driver to write an RTF document to disk, use code similar to the following:

goptions device=emfdual;
ods _all_ close; 
ods rtf file="\file-path\file-name.rtf"; 
/* Your SAS/GRAPH procedure code goes here */
ods rtf close; 
ods listing;

Creating EMF Dual graph output with ODS Graphics and the SAS SG procedures

If you are using ODS Graphics or the SAS statistical graphics (SG) procedures (such as SGPLOT), you can create EMF Dual graph output by adding the following REGISTRY procedure code to the top of your existing code:

%let workdir=%trim(%sysfunc(pathname(work)));
data _null_;
   file "&workdir./emf94.sasxreg";
   put '[CORE\PRINTING\PRINTERS\EMF\ADVANCED]';
   put '"Description"="Enhanced Metafile Format"';
   put '"Metafile Type"="DUAL"';
run;
proc registry import="&workdir./emf94.sasxreg";
run;

Then, specify the OUTPUTFMT=EMF option in the ODS GRAPHICS statement before the procedure step. Here is an example:

ods graphics / outputfmt=emf;

Understanding issues that might occur

The EMF format does not support data skins or transparency. Therefore, if your SAS code creates graphics output using data skins or transparency, keep in mind that the graph output is created as an image and the following note is written to the log:

NOTE: The graph in the RTF destination will be rendered as an image due to the use of transparency and data skin.

To create editable vector-based graphics output, you need to modify your code to not use data skins or transparency.

Also, graphs that use dashed lines cannot be edited outside of SAS. In this case, you need to modify your SAS code or the ODS style so that the graph is created with solid lines instead of dashed lines.

Conclusion

Instead of editing a graph outside of SAS, it is recommended that you modify your graph by using statements and options in the SAS code itself. If you need assistance about how to do that, contact SAS Technical Support.

See also:

How to create EMF graph output files that can be edited outside of your SAS® program was published on SAS Users.

8月 172021
 

What happens if you need to edit graph output files from SAS in a different application (for example, Microsoft Word)? It is not recommended that you edit your SAS graph output outside of SAS, but if you must do so, this article discusses the graphics output options that you need to use.

Understanding the EMF graph output types

To create graphics output that is editable, you need to create your graphics output as EMF (Enhanced Metafile Format) graph output. The EMF graph format is a vector-based graphics format. Formats such as PNG, GIF, JPEG, and TIFF are bitmap image formats and, typically, bitmap image formats cannot be edited.

You can either create a stand-alone EMF graph output file or embed your EMF graph output inside an RTF document by using the ODS RTF destination. The EMF graph format is the default graph format when you want to create graphics output with the ODS RTF destination.

By design, the default EMF graph output that SAS creates is in an EMF Plus (EMF+) format. However, this type of EMF graph output is not editable. To create an EMF graph output that you can edit, you must create your EMF graphics output in a format known as EMF Dual format. This format combines EMF Plus output and traditional EMF graph output in a single graph file.

Creating EMF Dual graph output with the SAS/GRAPH® procedures

If you are using a SAS/GRAPH procedure (such as GPLOT or GCHART), you can create EMF Dual graph output by specifying the DEVICE=EMFDUAL option in the GOPTIONS statement:

goptions device=emfdual;

When you use the EMFDUAL device driver to write a stand-alone EMF graph file to disk, use code similar to the following:

ods _all_ close; 
ods listing; 
filename grafout "\file-path\file-name.emf"; 
goptions device=emfdual gsfname=grafout;
/* Your SAS/GRAPH procedure code goes here */

When you use the EMFDUAL device driver to write an RTF document to disk, use code similar to the following:

goptions device=emfdual;
ods _all_ close; 
ods rtf file="\file-path\file-name.rtf"; 
/* Your SAS/GRAPH procedure code goes here */
ods rtf close; 
ods listing;

Creating EMF Dual graph output with ODS Graphics and the SAS SG procedures

If you are using ODS Graphics or the SAS statistical graphics (SG) procedures (such as SGPLOT), you can create EMF Dual graph output by adding the following REGISTRY procedure code to the top of your existing code:

%let workdir=%trim(%sysfunc(pathname(work)));
data _null_;
   file "&workdir./emf94.sasxreg";
   put '[CORE\PRINTING\PRINTERS\EMF\ADVANCED]';
   put '"Description"="Enhanced Metafile Format"';
   put '"Metafile Type"="DUAL"';
run;
proc registry import="&workdir./emf94.sasxreg";
run;

Then, specify the OUTPUTFMT=EMF option in the ODS GRAPHICS statement before the procedure step. Here is an example:

ods graphics / outputfmt=emf;

Understanding issues that might occur

The EMF format does not support data skins or transparency. Therefore, if your SAS code creates graphics output using data skins or transparency, keep in mind that the graph output is created as an image and the following note is written to the log:

NOTE: The graph in the RTF destination will be rendered as an image due to the use of transparency and data skin.

To create editable vector-based graphics output, you need to modify your code to not use data skins or transparency.

Also, graphs that use dashed lines cannot be edited outside of SAS. In this case, you need to modify your SAS code or the ODS style so that the graph is created with solid lines instead of dashed lines.

Conclusion

Instead of editing a graph outside of SAS, it is recommended that you modify your graph by using statements and options in the SAS code itself. If you need assistance about how to do that, contact SAS Technical Support.

See also:

How to create EMF graph output files that can be edited outside of your SAS® program was published on SAS Users.

7月 242021
 

Are you thinking about migrating your environment over to SAS Viya but don’t know if your current architecture will be supported? Luckily, with the help of the SAS 9 Content Assessment Tool, we can help to alleviate some of those worries.

If you look at our documentation on the SAS 9 Content Assessment Tool, you’ll see that there is a fairly large amount of information to parse through. However, each section is designed to cover a different application within the SAS 9 Content Assessment Tool to help assist in your transition. Before diving in and running all the applications, first ask yourself a few questions:

  • What is your goal with using the SAS 9 Content Assessment Tool?
  • Are you simply wanting to count (inventory) what is in your environment?
  • Do you want a more detailed explanation (profile) about the items that exist in your deployment?
  • Are you wanting to know if your current SAS code will transition (code check) correctly to SAS Viya?

These are all important questions to consider before choosing which application to run and for what purpose. In this guide, I will show you an average use case for running the SAS 9 Content Assessment Tool and how we will check if our environment is Viya-ready.

Download and unpack the tool

Before we can access SAS Content Assessment, we will first need to download and unpack the tool itself. The latest download available at the time of this article is version 2021.1.2 and can be downloaded from the SAS 9 Content Assessment 2021.1.3 support site.

We will be downloading the Linux version for our purposes:

You will then want to unpack the tar file using the Linux command below:

tar zxvf /SAS9ContentAssessment/SAS9ContentAssessment.2021.1.2.lax.tgz

The resulting unpacked files should produce the “assessment” and “migration” files:

Now that we have successfully unpacked the Content Assessment tool, we can proceed to modifying the setenv.yaml and metaparms.sas files for configuration.

Set up the configuration

We’ll start by specifying specific configuration information necessary to run the Content Assessment tool successfully. Let’s modify the setenv.yaml file first:

We are required to set explicit values for each key-value pair that is denoted with an asterisk. However, both the SAS_CATALOGSDIR and ENTERPRISE_GUIDE_PROJECTSDIR only need values specified if you intend to gather this content. This means, for this example, we will be setting values for:

  • SAS_HOME
  • ASSESSMENT_CONFIGDIR

We have modified the file in our text editor of choice Notepad++:

*We do not have any SAS Enterprise Guide projects to gather for this particular example so we will leave this field blank.

*Same for this one

Once you have set these values, you can Save and Close the file and proceed to editing metaparms.sas.

In this file, specific values must be defined. These values are written in italics:

  • METADATAHOSTNAME
  • METADATAUSERPASSWORD

In this case, we will be specifying additional values to help distinguish which host machines we are running the Content Assessment Tool on:

Once you have set these values, you can Save and Close the file.

Task #1: Inventory Content

Now that we have filled in the required values for the configuration files, we can begin with running the applications within SAS Content Assessment Tool. We will first begin with running Inventory Content. In summary, Inventory Content performs the following:

  • It determines what licensed products are installed.
  • It examines the SAS Deployment Registry for various actions and items.
  • It enumerates all file system content.
  • It enumerates SAS metadata, such as:
    • SAS metadata objects contained in SAS folders
    • SAS server and SAS application server contexts
    • ACTs and ACEs

We will go ahead and run Inventory Content by navigating to our unpacked tool directory:

Then we will run the script:

[sas@trcv037 assessment]$ ./inventoryContent

Running the script should show multiple check like that below:

Now that Inventory Content has completed, it should have products 3 different datasets:

  • all_objects.sas7bdat
  • deploymentinfo.sas7bdat
  • licenseinfo.sas7bdat

We can confirm this by navigating to the path for inventory as defined in the setenv.yaml file: ASSESSMENT_DATAMARTDIR/inventory/METADATALABEL.

We have completed the Inventory Content task.

Task #2: Profile Content

Running the Profile Content application will allow us profile SAS objects and SAS content. To run the Profile Content application, you will need to navigate to the unpacked tool directory and issue the command:


./profileContent

The process will look similar to:

Note: If you are running a version of SAS earlier than 9.4 M3, you will need to run the Relationship Loader by adding the command option --load-relationships

This will produce multiple SAS datasets in the output defined for ASSESSMENT_DATAMARTDIR/profile/METADATALABEL.

We have now completed the Profile Content task.

Task #3: Code Check

The goal of the Code Check application is to check SAS code for SAS Viya incompatibilities. During the process Code Check performs the following actions:

  • It classifies any file in the starting directory and any subdirectories that have an extension of .SAS as SAS code. It adds it to the list of files to be scanned.
  • It searches the files for keywords that have been identified as not compatible in SAS Viya.
  • It searches the files for hardcoded paths in statements such as LIBNAME, INFILE, FILENAME, %INC, and %INCLUDE. These occurrences might not cause errors, but they are gathered so that they can be validated.

When executing the codeCheck command, you will have a few options available to you. You can use the --scan-tag option to distinguish separate runs from Code Checks across different directories.

Then there’s the --source-location which is required to target the directory in which you scan for code.

Finally, there’s the --sources-file option if you have several directories you would like to scan all at once.

In our instance, we will simply point to one directory to gather our code and distinguish this run with a unique scan tag. We’ll run the following command:



./codeCheck --scan-tag exampleGather --source-location /home/sas/My_SAS_Files

You can see that we are targeting the directory: /home/sas/My_SAS_Files. This directory contains 5 example programs that we would like to check:

After executing the command, you should see the following generated from the script:

And two datasets created for each scan tag in the Code Check datamart:

  • scan-tag_elements.sas7bdat
  • scan-tag_issues.sas7bdat

We have now completed our run of the Code Check application.

Task #4: Publish Assessed Content

Now that we have finished running Inventory, Profile, and Code Check, we can now choose to Publish and Merge our content so that we can view the results in a more readable format. If Inventory, Profile or Code Check has been run on more than one machine, we would need to aggregate all the resulting datasets to one location and run publishAssessedContent on that directory. However, in our instance, we have only generated the results on one machine so this is not necessary.

When running the publishAssessedContent command, you will need to specify which datamart type you are targeting. For example, for Code Check, we would specify the Code Check datamart type:


./publishAssessedContent --datamart-type codecheck

The datamart-type value would change for Inventory and Profile.

When executing the publishAssessedContent command, the result looks like this:

You can see that Publish found the resulting datasets generated from Code Check and merged and published them to the respective datamart.

If we go to that datamart location we can see that some additional datasets were generated:

  • codechk_elements.sas7bdat
  • codechk_issues.sas7bdat
  • codechk_keywords.sas7bdat
  • elements_aggregated.sas7bdat

Once you have the datasets generated in this manner, you can choose to import these by following the steps in our Importing the Data Mart documentation.

You can also choose to encrypt your result using the --encryption option. You can specify either:

--encrypt-aes

--encrypt-sas

When using this method, an assessment-key.sas file is created in the location the tool was unpacked.

If you are coordinating with your SAS success team to plan a road map to SAS Viya, you will likely be requested to provide these datamarts. To do so, you will need to run the --create-uploads option with the original command. For example:


$ ./SAS9ContentAssessment/assessment/publishAssessedContent --create-uploads

--datamart-type profile --encrypt-aes

The result is three upload files that are created:

OURCustomer_profile_abcdef03470.tgz

OURCustomer_profile_abcdef03470_assessment-key.sas

OURCustomer_profile_abcdef03470_reports.tgz

These will be delivered to your SAS success team by following the steps in our documentation.

Related Resources

READ MORE | THE SAS 9 CONTENT ASSESSMENT TOOL
WATCH ON YOUTUBE | SAS 9 CONTENT ASSESSMENT DEMO
READ MORE | SYSTEM EVALUATION TOOL HELPS WITH SAS 9.4 UPGRADE-IN-PLACE PLANNING

How to use the SAS® 9 Content Assessment Tool was published on SAS Users.

6月 212021
 

Even with the all the new and powerful tools that are available with the release of SAS® Viya® and SAS® Cloud Analytic Services (CAS), the DATA step remains the same programming powerhouse that it has always been. However, there are some considerations that you need to be aware of when you run a DATA step on CAS tables. This post provides a brief overview of some of these considerations, which include these topics:

  • Running the DATA step in your SAS® session versus running it in CAS
  • Using elements within the DATA step that are not available when you run the step in in CAS
  • Using the CASDATALIMIT system option and the DATALIMIT data-set option to prevent a size-limit error

Running the DATA step on the SAS® client versus running it in CAS

This question is one of the most common questions asked of SAS Technical Support:  "Is it always faster to run my DATA step in CAS?" The answer is no. CAS is designed to be used with big data. In general, the larger the table, the better the performance when you use CAS. CAS obtains this increased performance by running the code in multiple threads on multiple workers. When you execute a DATA step in CAS, the code and data are distributed across the different workers and threads. This strategy enables the code to run in parallel and to achieve better performance.

However, there is a cost that is associated with running code in parallel. A certain amount of overhead is required to distribute the code and data to multiple threads on multiple workers. The overhead that is required can result in your DATA step running slower in CAS than it does in SAS. The following basic example illustrates this concept.

The two code examples below contain a DATA step that creates a 5000-row sample data set and CAS table, respectively. The data is read into the DATA step for processing. In this case, the processing involves a simple multiplication of values.

I ran these steps successively.  As you can see in the output below, the DATA step runs faster in SAS than it does in CAS.

Now, let’s try an example that uses a much larger data source. This example is exactly the same as the previous example. However, it uses a table that contains 10 million rows.

A table that contains  ten million rows and 5 variables is not really considered big data, but a table of that size does show that CAS is faster when the data is larger. Just imagine what CAS can do with input tables that contain 100 million rows and 50 variables!

Using DATA step language elements that are not available in CAS

To take advantage of the faster processing times using CAS, you must run the DATA step directly in CAS. There are certain criteria that must be met in order for the DATA step to run on the CAS server. First, the input and output tables must be CAS tables. If one of your tables is a SAS data set, then the step runs in SAS. Second, all language elements that you use in the DATA step must be available in CAS. Most language elements from the DATA step are available in CAS. However, a number of DATA step elements are not available in CAS. Most elements are there, but a handful are not. For details, see Language Element Support in SAS® Cloud Analytic Services 3.5: DATA Step Programming.

What happens if my DATA step uses a CAS table for input and is creating a CAS table, but my code contains an unsupported language element? If you attempt to use an unsupported language element in your DATA step, the code and data are sent back to the SAS client to be processed. Once the processing is done, the data is moved back to the CAS server. All of this action takes place in the background.   Moving the data back and forth creates some performance issues in that you lose the ability to run your DATA step in parallel. In certain situations, you cannot avoid this issue. In these cases, there are a couple of methods that can help you determine whether your DATA step is running in CAS or in SAS, as explained in this section.

There is an unmistakable sign that your DATA step is running in CAS. The following note is always generated by a DATA step that is running in CAS.

NOTE: Running DATA step in Cloud Analytic Services.

If you do not see this note in the notes that are generated by your DATA step, then that step did not run in CAS. You can also use the MSGLEVEL= system option to help determine whether your DATA step ran in CAS. Setting this option provides more detail in the log about where the DATA step is running.

Here is an example. The RANUNI function is not supported in CAS, and it causes the step to run on the SAS client.

90   data casuser.b;
91      set casuser.a;
92      random=ranuni(1000);
93   run;
NOTE: There were 100 observations read from the data set CASUSER.A.
NOTE: The data set CASUSER.B has 100 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.32 seconds
      cpu time            0.09 seconds

The note indicating that this step ran in CAS is absent in the output above, but it does not say specifically where the step ran.

If you add the MSGLEVEL= system option in your code, as shown below, a note is added in the output that explains where the DATA step ran.

89   options msglevel=I;
90   data casuser.b;
91      set casuser.a;
92      random=ranuni(1000);
93   run;
NOTE: Could not execute DATA step code in Cloud Analytic Services. Running DATA step in the SAS client.
NOTE: There were 100 observations read from the data set CASUSER.A.
NOTE: The data set CASUSER.B has 100 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.29 seconds
      cpu time            0.09 seconds

Unfortunately, the MSGLEVEL= system option does not tell you the nature of the problem. To resolve that issue, you can use the SESSREF= system option in the DATA statement. This option associates the DATA step with a CAS session. In addition, if the step does not run in CAS, the option generates an error and explains which language element causes the issue. Here is an example.

90   data casuser.b / sessref=casauto;
91      set casuser.a;
92      random=ranuni(1000);
93   run;
NOTE: Running DATA step in Cloud Analytic Services.
ERROR: The function RANUNI is unknown, or cannot be accessed.
ERROR: The action stopped due to errors.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: DATA statement used (Total process time):
      real time           0.15 seconds
      cpu time            0.01 seconds

In this output, you can see why the step failed to execute—the RANUNI function is not available in CAS.

In case you are wondering, the RAND function is an improved version of RANUNI, and RAND is available in CAS.

Using the CASDATALIMIT= system option and the DATALIMIT= data set option to override the default table size that can be moved to SAS

Both of these options perform the same task. They specify the number of bytes of data from a single CAS table that can be transferred from the CAS server to SAS. These options are important when these conditions are true:

  • You are run a DATA step that is uses a CAS table as input and that creates a CAS table as output.
  • The DATA step contains a language element that prevents the step from running in CAS.

In some programming tasks, the code must use a language element that is not available in CAS. In this case, the code and data are sent back to the SAS client. It is important to know that there is a limit for the size of the table that can be moved to the SAS client. The default limit for this is 100 MB. When a table is larger than the limit, the following error is generated by the DATA step:

ERROR: The maximum allowed bytes (nnnn) of data have been fetched from Cloud Analytic Services. Use the DATALIMIT option to increase the maximum value.

You can prevent this error by setting the CASDATALIMIT= system option in an OPTIONS statement or the DATALIMIT= option in a DATA statement. That is, the values for these options override the default limit of 100 MB. Here are examples of each option in their respective statements:

options casdatalimit=20g;
data casuser.test(datalimit=20g);

Summary

The DATA step continues to be a programming powerhouse in CAS. However, you must consider certain caveats when you execute the DATA step in CAS. The size of your data and the language elements that you use in your code are two of the most important considerations when you write a DATA step that is uses a CAS table to create a new CAS table. Our online documentation provides the most complete discussion about these topics. For details, see SAS® Cloud Analytic Services 3.5: DATA Step Programming.

See also:

 

Important caveats to consider when you run a DATA step on CAS tables was published on SAS Users.

6月 112021
 

Have you ever wondered where you can find information about known issues with SAS® Customer Intelligence 360? Well, look no further! You can find the issues on the SAS Customer Intelligence 360 Status page. This page is your "one-stop shop" (comprehensive source) for locating the current issues that are being addressed in major releases.

Get notified of known issues

SAS Technical Support recommends that you subscribe to the SAS Customer Intelligence 360 status notifications (either via email or by using the related RSS feed). These notifications alert you about software updates, fixes that address a current issue, operational updates, and planned maintenance.

For information about how to subscribe, see the SAS Communities board post CI360: How to Subscribe to Status Notifications.

The Status page contains the most recent information about issues. It also contains a history in case you need to search for a past issue. These resources enable you to search quickly for known issues or open JIRA tickets that you have in order to determine whether a fix has been implemented.

Find JIRA ticket info

When you open a SAS Technical Support ticket for an issue, Technical Support opens a JIRA ticket to address the issue. If a JIRA ticket is available, Technical Support staff can provide you with the ticket number. You can search for this number on the SAS Customer Intelligence Status page to determine whether an issue has been addressed.

In addition, you can find major-release (YY.MM) information in the What's New in SAS® Customer Intelligence 360 customer documentation.

Finding known issues with SAS® Customer Intelligence 360 was published on SAS Users.

4月 212021
 
A customer recently contacted SAS Technical Support and wanted to know how he could generate a report that displays just the column headings for a data set (or table) that does not contain any records. Rather than just omitting the missing data, he wanted to provide his customers with a visual way to see where data was missing.

This blog demonstrates how to create a report that provides only the column headings for data that is missing. The blog also explains how to create, select, and exclude output objects as well as how to generate reports with the SAS® Output Delivery System (ODS). These concepts are relevant to the task of generating a report with the column headings for a data set that contains no (0) observations.

The first section below provides some basic information that you need to understand about ODS. Specifically, it discusses ODS destinations along with the concept of output objects and how they work in ODS.

The second section explains tools that enable you to achieve the desired output for the report:

  • how to use the ODS SELECT statement to specify certain objects that you want to send to the destination for the report.
  • how to use a SAS® macro and dictionary tables to display column headings when no output object is generated

The last section provides a code example that unites all of these concepts. The end result is a report that contains only column headings from the WORK.CLASS data set and information from the Moments output object in the SASHELP.CLASS data set.

Understanding the SAS® Output Delivery System

The SAS Output Delivery System has many destinations that you can use to generate files in various formats. Some of these destinations generate files in third-party formats such as XLSX (Excel), DOCX (Word), PPTX (PowerPoint), and HTML (HTML, HTML5). Other types of destinations are available, too. Examples include ODS Package, which generates Archive (or ZIP) files, and ODS Document, which generates binary objects from SAS DATA steps or procedures.

The foundation for the output delivery system is an output object, which is generated when a SAS® procedure or DATA step is executed. The output object is generated when you combine text and numbers with a template definition.

SAS® Output Delivery System

DATA steps generate only one output object, whereas procedures can generate one or more output objects.

Using ODS statements to select or exclude output objects

To see the contents of an output object, you can use the ODS TRACE statement to generate trace records. A trace record displays the object name, the template location, and the label.

The following example generates trace records for the SASHELP.CLASS data set:

ods trace on;
univariate data=sashelp.class;
run;

The output from this code is shown below:

ODS TRACE output

Once you discover an object's name, you can choose to select or exclude it from the output by using either the ODS SELECT statement or the ODS EXCLUDE statement.

For example, using the previous code example, you can use the ODS SELECT statement to choose a specific output object.

ods trace on;
ods select moments;
proc univariate data=sashelp.class;
run;

In this example, The ODS SELECT statement selects just the Moments object and sends it to any open ODS destinations so that the object's data can be printed in a report. No other objects are sent to the destination.

The ODS TRACE statement generates the following output in the trace log since only the Moments object is specified.

Moments object

Generating a report with column headings for a data set with 0 records and with information from a selected output object

The information in the previous section is helpful for data sets that contain records. But it is not helpful if you want to generate a report that shows column headings from a data set that does not have any records.

When a table has no records, it does not generate an output object. Because no object is generated, ODS cannot display headings.

However, you can use another strategy with ODS to display headings from a data set with no records. You can use dictionary tables to obtain the name of the column headings for a table that has no records. Dictionary tables are created automatically by SAS® to store information related to SAS libraries, SAS system options, SAS catalog, and so on. These tables enable you to query information about a data set (column names, titles, and so on).

To accomplish the task at hand, you can use a dictionary table and a SAS macro with ODS. The macro is used to verify whether you are processing a zero-observation data set:

  1. If the data set that is passed is not a zero-observation data set, the macro passes and executes the procedure.
  2. If the data set that is passed is a zero-observation table, the SQL procedure is used with the DICTIONARY.COLUMNS table to query only the column names in the table. Then, the column names are transposed with the TRANSPOSE procedure, and they are displayed with the REPORT procedure.

Note: The column headings are arranged vertically. You need to transpose them so that they are displayed horizontally in the report that is generated by the ODS destination.

Creating the report with SAS® Output Delivery System, a SAS® macro, and dictionary tables

The following example illustrates the strategy that is described in the last section:

/* Sample table with 0 observations */
data work.class;
set sashelp.class;
stop;
run;
ods excel file="sample.xlsx" options(embedded_titles="yes");
 
%macro test(libref=,dsn=);
%let rc=%sysfunc(open(&libref..&dsn,i));
%let nobs=%sysfunc(attrn(&rc,NOBS));
%let close=%sysfunc(CLOSE(&rc));
%if &nobs ne 0 and %sysfunc(Exist(&libref..&dsn)) %then %do;
 
title "Report for Company XYZ";
ods select moments;
proc univariate data=&libref..&dsn;
run;
 
%end;
%else %do;
 
proc sql noprint;
create table temp as
select name from dictionary.columns
where libname=%upcase("&libref") and memname=%upcase("&dsn");
run;
quit;
proc transpose data=temp out=temp1(drop=_label_ _name_);
id name;
var name;
run;
proc report noheader style(column)=header[just=center] nowd;
title "No data for data set &libref..&dsn";
run;
%end;
%mend;
%test(libref=work,dsn=class)
%test(libref=sashelp,dsn=class)
 
ods excel close;

As you can see below, the report that is generated shows the column headings for the empty WORK.CLASS data set as well as the data from the Moments object from the SASHELP.CLASS data set.

No data for data set work.class

Report for Company XYZ

Learn More

Creating a report that displays only the column headings for a data set containing 0 records was published on SAS Users.

3月 132021
 

As a programmer, you might be accustomed to how SAS® stores date, time, and datetime values as 8-byte floating-point numeric values. A SAS date is the number of days since January 1, 1960; a SAS time is the number of seconds since midnight; and a SAS datetime is the number of seconds since midnight, January 1, 1960. Are you aware that date and time values are handled differently if you are programming in DS2? Because DS2 can process databases, it has access to ANSI data types, which have greater precision. The ANSI data types that are relevant for processing dates and times include DOUBLE, TIME, DATE, and TIMESTAMP. However, these data types are not comparable to SAS date and time values, so they are not automatically converted.

Dates and times in DS2

Declaring DS2 DATE, TIME, and TIMESTAMP constants requires a specific structure. The syntax is shown here:

  • DATE 'yyyy-mm-dd'
  • TIME 'hh:mm:ss[.fraction]'
  • TIMESTAMP 'yyyy-mm-dd hh:mm:ss[.fraction]'

Here is an example:

proc ds2;
data _null_;
method run();
dcl date ds2dt;
dcl time ds2tm;
dcl timestamp ds2dtm;
ds2dt = date '2017-01-31';
ds2tm = time '20:44:59';
ds2dtm = timestamp '2017-02-07 07:00:00.7569';
put ds2dt=;
put ds2tm=;
put ds2dtm=;
end;
enddata;
run;
quit;

Results:

ds2dt=2017-01-31
ds2tm=20:44:59
ds2dtm=2017-02-07 07:00:00.756900000

Using functions to help with conversion

When date, time, or timestamp values are read into DS2 from a database, they are processed in their native data types. Variables in a SAS data set that are formatted with a date, time, or datetime format and read into DS2 must be converted to the equivalent ANSI DATE, TIME, or TIMESTAMP data types. To successfully process ANSI values in DS2 using SAS interval functions, such as INTCK or INTNX, you must first explicitly convert them to the appropriate SAS double-precision numeric value. The following functions can assist with the conversion between ANSI and SAS:

  • TO_DOUBLE—converts any ANSI date, time, or timestamp value to the appropriate SAS numeric date, time, or datetime value
  • TO_DATE—converts an unformatted SAS date to an ANSI date
  • TO_TIME—converts an unformatted SAS time to an ANSI time
  • TO_TIMESTAMP—converts an unformatted SAS datetime to an ANSI timestamp

Example 1: Convert an unformatted SAS date, time, or datetime value in DS2

You can convert unformatted SAS date, time, or datetime values in DS2 by using the TO_DATE, TO_TIME, and TO_TIMESTAMP functions. The HAVING FORMAT option in the DECLARE (DCL) statement assigns a format to the new variables.

data dates;
sas_time=time();
sas_date=today();
sas_datetime=datetime();
run;
 
proc ds2;
data _null_;
dcl date ds2dt having format YYMMDD10.;
dcl time ds2tm having format TIME18.5;
dcl timestamp ds2dtm having format DATETIME28.5;
method run();
set dates;
ds2dt=to_date(sas_date);
ds2tm=to_time(sas_time);
ds2dtm=to_timestamp(sas_datetime);
put 'SAS: ' sas_date sas_time sas_datetime;
put 'ANSI: ' ds2dt ds2tm ds2dtm;
end;
enddata;
run;
quit;

Results:

SAS: 22326 30565.0650000572 1928996965.065
ANSI: 2021-02-15 8:29:25.06500 15FEB2021:08:29:25.06500

Example 2: Convert a formatted SAS date, time, or datetime value in DS2

If you have applied formats to the SAS variables, you must first convert the variables by using the TO_DOUBLE function. If you do not do this conversion in advance and then try to use a SAS function, such as INTNX, you see messages like the following in the log:

ERROR: Compilation error.
ERROR: Line 402: Invalid conversion for date or time type.
WARNING: Implicit conversion of time(4) type to double type. Statement 402.
WARNING: Implicit conversion of int type to double type. Statement 402.

Here is the syntax that you can use for conversion:

data dates;
sas_time=time();
sas_date=today();
sas_datetime=datetime();
format sas_time time. sas_date mmddyy10. sas_datetime datetime.;
run;
 
proc ds2;
data _null_;
dcl double SAS_Date_New having format mmddyy10.;
dcl double SAS_Time_New having format time.;
dcl double SAS_Datetime_New having format datetime.;
method run();
set work.dates;
SAS_Date_New=INTNX('week',to_double(sas_date),26);
SAS_Time_New=INTNX('hour',to_double(sas_time),3);
SAS_Datetime_New=INTNX('dtweek',to_double(sas_datetime),2);
put SAS_Date_New=;
put SAS_Time_New=;
put SAS_Datetime_New=;
end;
enddata;
run;
quit;

Results:

SAS_Date_New=08/15/2021
SAS_Time_New=11:00:00
SAS_Datetime_New=15AUG21:00:00:00

Example 3: Convert an ANSI date, time, or timestamp value to a SAS date in DS2

If you want to convert an ANSI value into a SAS value, use the TO_DOUBLE function. In the example below, the TO_DOUBLE function converts the ANSI timestamp value to a SAS datetime. After you have a SAS datetime, you can then use the SAS functions DATEPART and TIMEPART to extract the date and time values.

proc ds2;
data _null_;
method run();
dcl timestamp ds2dtm;
dcl double sas_date having format mmddyy10.;
dcl double sas_time having format time8.2;
dcl double sas_datetime having format datetime18.2;
ds2dtm = timestamp '2020-02-01 01:23:45.7569';
sas_datetime=to_double(ds2dtm);
sas_date=datepart(sas_datetime);
sas_time=timepart(sas_datetime);
put ds2dtm=;
put sas_date=;
put sas_time=;
put sas_datetime= ;
end;
enddata;
run;
quit;

Results:

ds2dtm=2020-02-01 01:23:45.756900000
sas_date=02/01/2020
sas_time= 1:23:46
sas_datetime=01FEB20:01:23:45.7

Working with both ANSI and SAS date, time, and datetime values in a DS2 program is easily managed with the TO_DOUBLE, TO_DATE, TO_TIME, and TO_DATETIME functions. These functions make the conversion between ANSI and SAS values seamless and efficient.

Thank you for reading and thanks to Mark Jordan for his expertise and help in reviewing this blog before publication.

Additional references

Tips for working with date, time, and datetime values in DS2 was published on SAS Users.

1月 072021
 

This is the last of three posts on our hot-fix process, aimed at helping you better manage your SAS®9 environment through tips and best practices. The first two installments are linked here:

Having a good understanding of the hot-fix process can help you keep your SAS environment running smoothly. This last installment aims to help you get on a schedule with your hot-fix installations and provides an example spreadsheet (available for download on GitHub) to manage hot fixes.

Schedule hot fixes

As an administrator, sometimes applying outstanding hot fixes can be a daunting task. However, the longer you wait, the worse your situation becomes—with a potentially unstable environment and a growing backlog of hot fixes to apply. With a little careful planning, the task can become routine and everyone involved will be much happier. The next sections outline a strategy for getting on a quarterly schedule.

Run the SASHFADD tool

The first step of getting on a quarterly schedule to apply hot fixes is to run the SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool. For information about running this tool and analyzing the report it generates, see the first two installments in this blog series, The SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool and Understanding the SAS Hot Fix Analysis, Download and Deployment Tool Report.

Once you review the SASHFADD report, you will have a better understanding of what resources will be needed to apply the outstanding hot fixes. You also need to decide which philosophy of installing hot fixes you want to follow. For more information, see Which hot fixes should I apply?

Coordinate with IT

The second step is to coordinate the process with your IT department. Before you take the system offline to apply hot fixes, IT typically wants to do the following:

  • Perform a full system backup.
  • Check for scheduled jobs and make necessary adjustments.
  • Decide the best time to stop SAS services.
  • Evaluate how long the system will need to be offline.

After the first session of applying your hot-fix backlog, all these tasks can run on a regular (preferably at least quarterly) schedule that won't require as much analysis time from IT.

Communicate with end users

Before you implement the plan that you and the IT department devised, you need to communicate with your end users. Let them know ahead of time (maybe by a week) when the outage will occur, what they need to do to prepare for it, and how long it will take. It's a best practice to perform the update outside of regular business hours.

Reap the benefits

When you follow a quarterly schedule of applying hot fixes, there are many benefits:

  • The administrator is more experienced from installing hot fixes regularly, so the process goes more smoothly and takes less time.
  • The IT department has an established process in place for backing up the system and taking it offline for the maintenance.
  • End users know what to expect and are not surprised by the outage.
  • The system runs better and is protected from vulnerabilities due to the regular schedule of updates.
  • There is less downtime because there are fewer hot fixes to install with each update.

Manage hot fixes

Applying hot fixes can often be a complicated process with multiple steps before and after you install them. So, a key aspect of successfully applying hot fixes is ensuring that you follow all the steps that are included in the SASHFADD report. A great tool for managing this complexity is a spreadsheet!

Download one I created and customize it:

SANDY'S SPREADSHEET | DOWNLOAD IT NOW

This tool allows you to see and then check off (through highlighting, color coding, or notes) each of the steps to get the best results.

Administrators will have different approaches to their spreadsheets. Mine, linked above, is the result of much trial and error. Here are the items that I keep track of in my spreadsheet:

  • Hot-fix number
  • Hot-fix dependencies
  • Pre-installation steps
  • Post-installation steps
  • Special notes

Another benefit of the spreadsheet is that you can group steps together so that you can do them all at once. Here are some examples of when you can group steps to save time:

  • When performing the Rebuild Web Applications step, you can select the SAS® Marketing Automation, SAS® Marketing Optimization, and/or SAS® Deployment Manager web applications to be rebuilt in one iteration.
  • When performing the Deploy Web Applications step, you can select the SAS® Marketing Automation, SAS® Marketing Optimization, and/or SAS® Deployment Manager web applications to be rebuilt in one iteration.

Helpful resources

See the following links for the detailed and thorough documentation:

I hope that this blog series has been helpful to you! Have a terrific day!

READ PART ONE | The SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool READ PART TWO | Understanding the SAS Hot Fix Analysis, Download and Deployment Tool Report

How to schedule and manage your SAS hot fixes was published on SAS Users.

12月 082020
 

This is the second of three posts on our hot-fix process, aimed at helping you better manage your SAS®9 environment through tips and best practices. The first, an overview of the SASHFADD tool, is linked here and at the end of this post.

Having a good understanding of the hot-fix process can help you keep your SAS environment running smoothly. This second installment aims to help you understand hot-fix dependencies by giving you a sneak peek into the report generated by the SASHFADD tool.

SASHFADD tool report

Here's what the SASHFADD tool report looks like:

The citation key for items in the report is listed at the bottom of the page. This blog takes you through an example report for the SAS middle tier to show you how the citation key (shown below) works. For full details about the items in the citation key, see the SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool Usage Guide.

My report, SAS Middle Tier 9.4_M6 for Windows for x64, shown in the display below contains the following:

  • [1] for Issues Addressed
  • [A] for Alert
  • [C] for Container
  • [D] for Documentation
  • [S] for Security

What do the citations mean to you? Well, you need to click the citations to get a bigger picture of what this hot fix contains. Let's examine each citation in my example report in detail.

Citation key example

When you click the [1] for Issue(s) Addressed, it takes you to a page that lists all the SAS Notes that are being addressed in the fix:

If you scroll to the bottom of that section, it shows you whether there are other hot-fix dependencies or requirements that you need to meet before installing this hot fix. In this example, it shows that you must also install Hot Fix E3I012.

In the list of SAS Notes, any alert SAS Notes are labeled with ALERT. This report includes an [A], and you can see the alert SAS Note marked in the list. This citation is helpful if you want to update your system only for critical issues. If that is your preference, there is a SASHFADD script that will automatically download only the alert hot fixes and any corresponding dependency hot fixes.

The [C] in the report shows that it is a container hot fix. This citation is not clickable; it is there to indicate that you should refer to the documentation for a list of hot fixes in the container. When you click the [D], you see any relevant installation instructions. This page also lists the "member" hot fixes of the D8T013 "container" hot fix:

This page includes important notes along with installation instructions, and sometimes also includes pre-installation and/or post-installation instructions.

In this example, the post-installation instructions refer to a security update, which corresponds with the [S] from the report. Security updates might require additional steps. For example, some security updates require that you reapply them after you install the latest hot fixes. The security update will have its own instructions, so be sure to carefully read and follow all the steps.

Remember that the SASHFADD tool that generates this report can keep you from missing essential dependencies and instructions!

SASHFADD tool tips

Here are a couple of tips about using the SASHFADD tool.

Recommendation: If you ran the SASHFADD report a while ago, it is a good idea to run the SASHFADD report again before you apply your hot fixes so that you have the most up-to-date information. As you can see, when I ran the SASHFADD tool today, E3I012 is on the list as a dependency, not E3I011.

Reminder: If you run the SASHFADD tool manually, make sure that you get the updated SAS9X_HFADD_data.xml file before generating the updated report. Otherwise, you are running the same report you had before. This XML file is available on page 16 in the SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool Usage Guide:

SAS Note versus SASHFADD report for checking dependencies

Sometimes, people access hot fixes via a SAS Note rather than through a SASHFADD report. If you install the hot fix via a SAS Note such as SAS Note 66740, be sure to complete these steps:

  1. Click the Hot Fix tab and click the appropriate link for your release.
  2. Go to the bottom of the hot-fix page and check whether there are any dependent hot fixes.
  3. (This step applies to both methods for checking dependencies – via a SAS Note or via a SASHFADD report.) Before you install the dependent hot fixes, check whether they are already installed by looking at the View Registry report. You should also make sure that the version matches. In this example, you can see that the version matches but that Hot Fix E3I012 is not installed:

The SASHFADD report already listed the above dependent hot fix, so it would be part of my install if I used the SASHFADD report as my guide:

Tip: It is worth noting that when I click the link for E3I011, it shows that E31011 was replaced with E3I012:

 

The biggest takeaway message that I would like you to get from this blog is this: If you do not install the dependent hot fixes and/or follow the instructions such as the post-installation steps, you will encounter issues that will cause more downtime. This is something that I know we all want to avoid! If you run the SASHFADD tool, it automatically downloads all dependent hot fixes that you are eligible for, which eliminates the need for you to review the list of dependencies from any download page.

Helpful resources

See the following links for the detailed and thorough documentation:

Coming soon: third and final post in the series

The third blog in the series is about getting on a schedule with your hot-fix updates.

Thank you and have a wonderful day!

READ PART ONE | The SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool

Understanding the SAS Hot Fix Analysis, Download and Deployment Tool Report was published on SAS Users.

11月 252020
 

Helping customers is my passion. Having a good understanding of the hot-fix process can help you keep your SAS environment running smoothly. To help you better manage your environment, I am writing a series of blog posts with best practices and tips to successfully administer SAS hot fixes for SAS®9 environments. This first entry in the series focuses on the SAS Hot Fix Analysis, Download and Deployment Tool.

Importance of installing hot fixes

During my time helping SAS customers, I have seen many sites that did not apply hot fixes correctly or at all, which in turn caused them unnecessary downtime on their production environment(s). These issues could have been avoided if they had kept up-to-date with the hot fixes that were available. I've also seen many cases where the dependencies for hot fixes were not considered or the post-installation steps were not performed, again causing unnecessary downtime. Hopefully, some of the tips in this blog series will help SAS administrators realize just how important hot fixes are.

Benefits of the SASHFADD Tool

The focus of this post is the SAS Hot Fix Analysis, Download and Deployment Tool, commonly known as SASHFADD. This is the tool that SAS recommends for you to always use in SAS® 9.3 and SAS® 9.4 environments when applying hot fixes. Why? There are many reasons!

  • It creates a report that shows the products that are installed in your environment that have outstanding hot fixes. The report goes into detail about dependencies that you need to address before installing hot fixes. My next post provides a detailed analysis of an example report.
  • After you run the SASHFADD.exe file, it creates a DOWNLOAD<name> directory with some additional scripts that allow you to automatically download all your hot fixes into the DEPLOY<name> directory, so that you do not have to manually download each file. If you want to download only the alert hot fixes, there is a script available in the DOWNLOAD<name> directory to do that as well.
  • After you install SASFHADD, you need to run it periodically to check for hot fixes. One of the posts in this series provides more information about scheduling SASHFADD runs.
  • Overall, it provides a great picture of what is needed to keep your environment running in top shape.

Note: There are certain items that SASHFADD does not support. For details, see SAS Note 527, "SAS® hot fixes and patches that are not supported by the SAS Hot Fix Analysis, Download and Deployment Tool."

The SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool Usage Guide clearly describes the steps to install and use SASHFADD. If you haven't already installed this tool, you should do it right away! Always remember that if you run into an issue, this guide has a wonderful troubleshooting section.

Workaround if you are not the server administrator

This section primarily applies to consultants who are working onsite with the SAS administrator. If you are in a situation in which you do not have administrator access to the server or there are proxy issues, you can run SASHFADD on a different system. Doing this allows you to create the report on another system that you can use to plan your hot-fix implementation.

Here are the steps that you should follow on a Microsoft Windows system.

On the system where you plan to run the SASHFADD tool:

1. Download and execute the SASHFADD tool following the instructions in the Usage Guide.

2. Go to page 16 of the Usage Guide and click the appropriate HFADD_data.xml file to get the most recent list of hot fixes. Once it opens the file, save it in the SASHFADD

On the server that you want to apply the hot fixes to:

3. Go to the deploymntreg folder in SASHome.

4. Double-click the sas.tools.viewregistry.jar file. This action creates a create the Deployment Registry and accompanying txt file in the deploymntreg folder:

5. Copy the DeploymentRegistgry.txt file.

On the system where you plan to run the SASHFADD tool:

6. Paste the DeploymentRegistgry.txt file in the SASHFADD

7. In the SASHFADD folder, run the SASHFADD.exe file and provide a name for the tier that you are running it on. In the display below, the file is being run on the metadata tier:

Note that you must run the file on each tier. This action creates the report in a folder whose name corresponds to the name of the tier that you ran the EXE file on. You can then share this report (or multiple reports) with the SAS administrator who will be installing the hot fixes:

Helpful resources

See the following links for the detailed and thorough documentation:

Coming soon

The second post in the series is to help you understand dependencies covered in the SASHFADD report.

Thank you and have an awesome day!

 

The SAS Hot Fix Analysis, Download and Deployment (SASHFADD) Tool was published on SAS Users.