Problem Solvers

6月 102022
 

There are several alternatives to writing to a Microsoft Word file when you use the SAS® Output Delivery System (ODS). The RTF, TAGSETS.RTF and TAGSETS.RTF_SAMPLE destinations create an RTF formatted file. The WORD destination, which is still considered preproduction, creates a DOCX formatted file. The destinations provide many of the same functions, although some features are unique to each one. The destination that you choose might vary depending on your desired final output.

Both the Tagsets and the Word destination enable you to specify suboptions using the OPTIONS option. These suboptions are described in the documentation. For the Tagsets destinations, you can also see a list of the available suboptions and their values in the log by using the DOC='HELP' suboption as follows:

Ods tagsets.rtf file='test.rtf'
 options(doc='help');

What is common across destinations

There are some often-used features that are common across all ODS destinations that write to Microsoft Word. All ODS statements support the following options:

  • SASDATE – This option uses the date and time that the SAS session started if the DATE system option is turned on. Otherwise, the date and time listed are when the file is created. This is the default setting for the Tagsets destinations.
  • COLUMNS= – This option allows for multi-column output.
  • None of the destinations support the Report Writing Interface or the ODS LAYOUT ABSOLUTE option.
  • All destinations can create a table of contents, although the options for this task vary. To show the Table of Contents once the file is created, right-click in the page and select Update Field:
    • Ods rtf file='file.rtf' contents toc_data;
    • Ods tagsets.rtf file='file.rtf' options(contents='yes' toc_data='on');
    • Ods word file='file.docx' options(contents='yes' toc_data='on);
    • The TOC_LEVEL='n' suboption in the Tagsets and Word destinations controls the level of expansion of the table of contents.

Unique features, strengths and limitations for each destination

ODS RTF

The RTF destination was introduced in SAS® 8.1. The style template inherits from Styles.Printer. By default, title and footnote text is placed in the header and footer sections of the document. The BODYTITLE option in the ODS statement places the title and footnote text in the body of the document. The KEEPN option controls where tables are split on the page and the NOTRKEEP option controls whether table rows can be split by a page break.

A significant limitation of the RTF destination is that paging can be difficult because there is no vertical measurement. SAS allows Word to determine paging. In addition, the RTF destination does not support the UNIFORM option.

Here is an example:

ods _all_ close;
ods rtf file='paging_rtf.rtf' ;
 
proc print data=sashelp.cars(obs=15) noobs;
title 'Shows paging difficulties where columns wrap on the same page';
run;
 
ods _all_ close;

Shows paging difficulties where columns wrap on the same page

ODS Tagsets.RTF

The Tagsets.RTF destination was introduced in SAS® 9.2, partly to provide more control over paging. The style template inherits from Styles.Printer. Bodytitle is the default behavior, which means that the title and footnote text is placed in the body of the document. This destination supports the UNIFORM option. Another useful option is TABLEROWS=n, which specifies the number of rows in each table before ODS inserts a page break. Suboptions that are often used include the following:

  • CONTINUE_TAG= controls whether the “(Continued)” text is displayed at the end of a page when a table crosses a page boundary.
  • VSPACE= controls vertical space in the document.
  • WATERMARK= adds a diagonal text string as an argument.

Here is an example:

ods tagsets.rtf file='watermark_vspace_tagsets_rtf.rtf'
 options(doc='help' watermark="Draft" vspace='off') ;
 
proc print data=sashelp.class noobs;
title 'Shows watermark and no space between title and table';
run;
 
ods _all_ close;

Shows watermark and no space between title and table

ODS Tagsets.RTF_Sample

The Tagsets.RTF_Sample destination was also introduced in SAS 9.2. The style template inherits from Styles.Printer. The main distinction between this tagset and Tagsets.RTF is that this tagset places the title and footnote text in the header and footer of the Word document. This behavior makes it similar to the RTF destination without the BODYTITLE option. It includes the same suboptions listed in the ODS Tagsets.RTF section.

Here is an example:

ods tagsets.rtf_sample file='title_header_tagsets_rtf_sample.rtf'
 options(doc='help');
 
proc print data=sashelp.class noobs;
title 'Shows title in Header section of document';
run;
 
ods _all_ close;

Shows title in Header section of document

ODS WORD

The ODS WORD destination is still considered preproduction in the current release of SAS. It produces Microsoft Word output that is compatible with Microsoft Office 2010 and later. The style template inherits from Styles.Word and uses the SCHEME statement in the TEMPLATE procedure to define its style.

Some strengths of the ODS WORD destination are that it creates a native DOCX file and the file size can be smaller than that of a file created by the RTF destinations. The following file created with ODS WORD is 12 KB. The same file that is created with ODS RTF is 22 KB. There are several suboptions that help control where text splits on a page, including KEEP_LINES and KEEP_NEXT. The ODS WORD destination also supports accessibility and SVG output.

The ODS WORD destination currently does not support watermarks.

Here is an example:

ods word file='word_output.docx' sasdate;
 
proc print data=sashelp.class noobs;
title 'ODS WORD output';
run;
 
ods _all_ close;
ods listing;

ODS WORD output

Conclusion

Multiple ODS destinations can create a Microsoft Word file. Any method that you choose can create presentation-quality output for Microsoft Word. Thank you for reading and please check out the documentation links below.

Learn more

A comparison of the ODS destinations for writing to Microsoft Word was published on SAS Users.

4月 182022
 

SASPy and the SAS kernel for Jupyter Notebook enable you to connect to SAS® 9.4 and the SAS® Viya® compute server from your client machine. You can then interact with SAS and SAS Viya via Python. If you are not familiar with SASPy and the SAS kernel, this article provides an introduction.

Installing SASPy

SASPy is a client application. You install SASPy on the same client where Python is installed. If SAS is installed on a server, you do not need to install SASPy on the server (because it needs to be installed only on the client).

Since most users install Python, SASPy, and the SAS kernel on a Microsoft Windows client, this article assumes that your client is a Windows client too. But your client could also be a Linux or UNIX environment.

In most situations, installing SASPy on your client machine is as simple as issuing a Python PIP command on your client. For example, if your client is a Windows client, issue this command from a DOS prompt or DOS command line:

pip install saspy

To verify that SASPy is properly installed, submit the following client command:

pip show saspy

The information that is displayed by the pip show saspy command also tells you which version of SASPy is installed and the client directory in which SASPy is installed.

Installing the SAS kernel

The SAS kernel is also a client application. You install the SAS kernel on the same client where Python and SASPy are installed. Note that while the use of SASPy does not require the SAS kernel, the SAS kernel does require SASPy to be installed. Also, in order to use the SAS kernel, you must first be able to use SASPy to connect successfully to SAS or SAS Viya.

In most situations, installing the SAS kernel on your client machine is as simple as issuing a Python PIP command. For example, if your client is a Windows client, issue this command from a DOS prompt or DOS command line:

pip install sas_kernel

To verify that the SAS kernel is properly installed, submit the following client command:

pip show sas_kernel

The information that is displayed by the pip show sas_kernel command also tells you which version of the SAS kernel is installed and the client directory in which the SAS kernel is installed.

Python and Java dependencies

SASPy and the SAS kernel require Python 3.4 or higher.

Also, most configurations that use SAS 9.4 require that Java be installed on your client. To check to see whether you have Java on your client, issue the following command:

java -version

Common operating environments

This article discusses several commonly used operating environments that use SASPy and the SAS kernel:

  • A local SAS session that is running on Windows, where both SAS and SASPy are installed on the same local Windows client machine
  • A remote SAS session that is running on a Windows server
  • A remote SAS session that is running on a Linux server
  • A SAS Programming Runtime Environment (SPRE) compute server that is running as part of a SAS Viya installation

Connecting to a local SAS session that is running on Windows

A common scenario is to use SASPy with a local installation of SAS on Windows. In this case, use the WINLOCAL definition in your sascfg.py configuration file. The configuration file resides in your SASPy installation directory. To determine the exact name of that directory, issue the following command on your client machine:

pip show saspy

To use the WINLOCAL definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['winlocal']

To connect to a local Windows installation of SAS, submit the following Python statements:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="winlocal")

Connecting to a remote SAS session that is running on a Windows server

Another common scenario is to use SASPy on your client machine to connect to SAS 9.4, which is running on a separate Windows server. In this case, use the WINIOMWIN definition in your sascfg.py configuration file.

To use the WINIOMWIN definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['winiomwin']

Then, farther down in your sascfg.py file, find the following default definition:

winiomwin  = {'java'    : 'java',
            'iomhost'   : 'windows.iom.host',
            'iomport'   : 8591,
            }

Modify the value for IOMHOST in this definition by specifying the host name of the SAS IOM server that is running on Windows.

Then, to connect to SAS 9.4 on your Windows server, submit the following Python statements from your client:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="winiomwin")

Connecting to a remote SAS session that is running on a Linux server

You might use SASPy on your client machine to connect to SAS 9.4, which is running on a Linux server. In this case, use the WINIOMLINUX definition in your sascfg.py configuration file.

To use the WINIOMLINUX definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['winiomlinux']

Then, farther down in your sascfg.py file, find the following default definition:

winiomlinux = {'java'   : 'java',
            'iomhost'   : 'linux.iom.host',
            'iomport'   : 8591,
            }

Modify the value for IOMHOST in this definition by specifying the host name of the SAS IOM server that is running on Linux.

Then, to connect to SAS 9.4 on your Linux server, submit the following Python statements from your client:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="winiomlinux")

Connecting to a SPRE server that is running as part of SAS Viya

SASPy cannot connect directly to a SAS® Cloud Analytic Services (CAS) server that is running as part of SAS Viya. However, SASPy can connect to the SPRE server that is running as part of SAS Viya. (The SPRE server is also referred to as the compute server in SAS Viya.) In this case, use the HTTPVIYA definition in your sascfg.py configuration file.

To use the HTTPVIYA definition, find the following line in your sascfg.py file:

SAS_config_names=['default']

Modify the line to match the following:

SAS_config_names=['httpviya']

Then, farther down in your sascfg.py file, find the following default definition:

httpviya = {'ip'      : 'name.of.your.spre.server',
            'ssl'     : False,  # this will use port 80
            'context' : 'Data Mining compute context',
            'authkey' : 'viya_user-pw',
            'options' : ["fullstimer", "memsize=1G"]
            }

Modify the IP value in this definition by specifying the name of the SPRE server for your installation of SAS Viya.

Then, to connect to the SPRE server, submit the following Python statements from your client:

import saspy
import pandas as pd
sas = saspy.SASsession(cfgname="httpviya")

Using SASPy

After you connect successfully to SAS or the SPRE server, you can then submit Python statements via your client to interact with SAS. For example, you can display the first five rows (observations) in SASHELP.CLASS by submitting the following statements:

cars = sas.sasdata("cars","sashelp")
cars.head()

You can display summary statistics for SASHELP.CLASS with the following code:

cars = sas.sasdata("cars","sashelp")
cars.describe()

Using the SAS kernel for Jupyter Notebook

The SAS kernel enables you to use the Jupyter Notebook interface to execute SAS code and view results inline.

As previously noted, the SAS kernel requires SASPy to be installed. You also must be able to connect successfully to SAS or SAS Viya via SASPy. After you do so, after bringing up Jupyter Notebook, in the upper right-hand corner of your notebook, choose New > SAS.

After that, you can then submit regular SAS statements via Jupyter Notebook. Here is an example:

proc print data=sashelp.class;
run;

Additional resources and documentation

For additional information about using SASPy and the SAS kernel, see these resources:

Getting started using SASPy® and the SAS® kernel for Jupyter Notebook was published on SAS Users.

2月 152022
 

Where does SAS Studio store files, and how do you access them? The answer: it depends.

For an illustration, submit the following code in SAS Studio:

%put &sysscpl;

%put &syshostname;

%put &sysvlong;

The values that are returned in your log window show which operating system is being used to run SAS, the name of the server that is running Base SAS®, and the version of SAS that is running on that server.

If you are running the single-user edition of SAS® Studio, then SAS®9 is installed on your Microsoft Windows PC locally and you are running SAS Studio on your own personal machine. With this edition of SAS Studio, you can access files on your system and from any mapped drive that uses the Universal Naming Convention (UNC) standard.

However, if you are running an edition of SAS Studio other than the single-user edition, then the files that you create and the files that you have access to are stored on the server where SAS is running.

The server where SAS is running does not have access to the machine from which you are submitting code via the SAS Studio URL in a web browser. In SAS® Studio 3.x, which runs on SAS®9, the Server Files and Folders pane helps you visualize the locations that are accessible to your user ID on the server.

Use the following macro variable to determine where your Home directory is on the server that is running SAS:

%put &userdir;

Your user ID should have Read and Write access to that directory on the file system. Your SAS administration team should have shared best practices for where to store your files on the server and how you can access those files if needed on your local machine. In general, the quickest way to access a file is to right-click it and select Download File, as shown here:

Accessing files in SAS® Studio on SAS® Viya®

On SAS Viya, the file system might not be available to you. If that is the case, your files must be stored in the SAS Content folder. If you are not familiar with the  SAS Content folder in SAS Viya, it is important to understand that the folder does not exist via a physical path on the file system. When you store files in the SAS Content folder tree, you can use the FILESRVC file access method to access them with code. See the examples in 

This blog contains useful information about making files available to the SAS Content folder:

The following SAS Communities blog posts describe how your SAS administrator can make the file system available for you, depending on your version of SAS Viya:

If the file system has been made available for you, then this macro variable contains your default Home directory:

%put &_USERHOME ;

Your SAS server is displayed in the Explorer pane after the Folder Shortcuts entry. As shown below, a myfile.txt file is stored in the Home directory on the file system. Right-click it and select Download file to download it to your local machine:

In the above example, the SAS server is named “NFS mount” and the Home directory is named “Home.” However, the names will be specific to your environment.

Moving files from your local machine to SAS® Studio

To do the reverse and make files from your local machine available to the SAS server where SAS Studio is running, right-click the desired destination folder in the Explorer pane and select Upload files:

Figure 4

I hope that this information helps demystify where your files are stored when you use SAS Studio!

LEARN MORE | SAS TUTORIALS ON YOUTUBE

Where are the files that you have access to through SAS® Studio? was published on SAS Users.

12月 112021
 

SAS Studio is a very common interface to use to work with SAS® Cloud Analytic Services (CAS) data. The Libraries tree in SAS Studio displays SAS libraries (librefs) that contain your SAS data sets. To view CAS data in the Libraries tree, you need to associate a libref with the CAS library (or caslib) that contains your CAS tables.

This article discusses how you can define librefs to be associated with caslibs. The terms “libref” and “caslib” might be new to you, so here is a quick explanation of these terms.

  • A SAS library reference, or libref, is a shortcut name that points to a storage location on the server where your SAS files are stored.
  • A CAS library name, or caslib, is a shortcut name that references an in-memory space that holds your CAS tables.

The LIBNAME statement enables you to create these types of shortcut names.

What you see in the Libraries tree

The Libraries tree in SAS Studio displays the defined librefs where you can select and view your data sets. In the following image, the Libraries tree displays the default libraries:




Any user-defined libraries would appear in this list as well. Note: No caslibs are displayed in this list.

To view caslibs in the Libraries tree, you need to associate a libref with each caslib.

Use the CASLIB _ALL_ ASSIGN; statement to associate all caslibs

After you establish a CAS session (by using the CAS statement), you can associate a libref with each of the defined caslibs by running the following statement:

caslib _all_ assign;

After you submit this code, you can see in the log that a libref was created for each caslib, and the name of the caslib is used as the name of the libref.

After you define a libref for each caslib, the Libraries tree is then updated to include these new librefs, as shown in the following image. The librefs that are associated with caslibs are identified by a cloud and snowflake icon that is next to the caslib name:



You can also use the following SAS Studio snippet to create a libref for each caslib:
SAS Snippets ► SAS Viya Cloud Analytic Services ► Generate SAS librefs for caslibs

Use the LIBNAME statement and CAS engine to associate specific caslibs

The CASLIB _ALL_ ASSIGN; statement defines a libref for each of your caslibs. However, if you do not want to include all caslibs in the Libraries tree, you can define librefs for only the caslibs that you want to include.

To do that, use the LIBNAME statement with the CAS engine to define a libref that is associated with a specific caslib. The following statement shows the syntax to define the libref:

libname libref cas caslib=caslib;

Here, libref is the name that you choose for the SAS libref, and caslib is the name of the assigned caslib that you want to associate with the libref.

When you use the CASLIB _ALL_ ASSIGN; statement, the caslib name is used for the libref name. But the libref name does not have to be the same as the caslib name.

For example, the following statement creates a libref named MYCAS that is associated with the CASUSER caslib:

libname MYCAS cas caslib=CASUSER;

Ensure that the caslib is already defined before you associate it with a libref.

If you are not sure whether a caslib is defined, the following code generates a list of the available defined caslibs. The list is generated on the Results tab in SAS Studio:

proc cas;
table.caslibInfo;
quit;

Note that you can also use the CASLIB _ALL_ LIST; statement to view the list of caslibs in the SAS Studio log.

Whether you use the table.caslibInfo action or the CASLIB _ALL_ LIST; statement is a matter of preference for where you want to view the results.

Additional options are supported for the LIBNAME statement and can be found in the CAS LIBNAME engine documentation.

Troubleshooting

Some librefs are not shown

What if you followed the above instructions and see some, but not all, of the librefs for your caslibs in the Libraries tree?

The rules for caslib names are not the same as the rules for librefs, so not all caslib names can be used as libref names.

For example, when you use the CASLIB _ALL_ ASSIGN; statement, you might see a note like the following written to the log:

NOTE: CASLIB SystemData for session CASAUTO will not be mapped to SAS Library SystemData. The CASLIB name is not valid for use as a libref.

This note is produced because the LIBNAME statement attempted to define a libref named SystemData to be associated with the caslib SystemData. However, a libref name is limited to eight characters, so SystemData could not be used as a libref name.

The name that is used for a SAS libref must conform to the rules for a SAS name.

If a caslib name is longer than eight characters, you can use the LIBNAME statement with the CAS engine to associate your caslib with a libref that meets the requirements for a SAS name.

For example, to define a libref for the SystemData caslib, you can use a shorter libref name, such as SYSDATA:

libname sysdata cas caslib=SystemData;

In the following image, the Libraries tree now includes the SYSDATA libref, which enables you to view the CAS tables that are stored in the SystemData caslib.



Another issue that you might encounter is that the name of the caslib is defined as a SAS name literal, such as containing character spaces in the caslib name, and you cannot associate a libref with that caslib. The CAS LIBNAME engine does not support a SAS name literal for a caslib name.

When you want to specify a name for a caslib, keep these SAS name rules in mind.

CAS tables are not shown

What if you defined librefs for each of the caslibs that you want to view in the Libraries tree, but some CAS tables are not displayed for a caslib?

If the name of a CAS table does not comply with the VALIDMEMNAME rules, then the table is not displayed in SAS Studio. SAS Note 63538 provides more information about this issue.

Librefs are not assigned automatically

What if you want to be able to see your caslibs in the Libraries tree in SAS Studio every time that you sign in? For this preference, you can edit your autoexec file in SAS Studio and include the statements to automatically define the librefs for your caslibs.

Follow these steps:

  1. Select Options ► Autoexec file.
  2. In the file, enter each of the statements that you want to run every time that you sign in. Here are examples:
cas;
caslib _all_ assign;

You can also include the LIBNAME statements for your caslibs as well as any other SAS statements that you want to run each time you sign in to SAS Studio.

  1. Click Run to submit the statements.
  2. Open the Log tab to verify that your statements ran without error.
  3. Click Save.

With each subsequent sign-in for SAS Studio, the statements from your autoexec file are run automatically, and you then can view the librefs for your CAS tables in the Libraries tree.

Conclusion

CAS libraries enable you to access your CAS data. By defining the librefs for those caslibs in SAS Studio, you can have more interactive access to the CAS data.

Learn more

How to view CAS tables in SAS® Studio was published on SAS Users.

12月 112021
 

SAS Studio is a very common interface to use to work with SAS® Cloud Analytic Services (CAS) data. The Libraries tree in SAS Studio displays SAS libraries (librefs) that contain your SAS data sets. To view CAS data in the Libraries tree, you need to associate a libref with the CAS library (or caslib) that contains your CAS tables.

This article discusses how you can define librefs to be associated with caslibs. The terms “libref” and “caslib” might be new to you, so here is a quick explanation of these terms.

  • A SAS library reference, or libref, is a shortcut name that points to a storage location on the server where your SAS files are stored.
  • A CAS library name, or caslib, is a shortcut name that references an in-memory space that holds your CAS tables.

The LIBNAME statement enables you to create these types of shortcut names.

What you see in the Libraries tree

The Libraries tree in SAS Studio displays the defined librefs where you can select and view your data sets. In the following image, the Libraries tree displays the default libraries:




Any user-defined libraries would appear in this list as well. Note: No caslibs are displayed in this list.

To view caslibs in the Libraries tree, you need to associate a libref with each caslib.

Use the CASLIB _ALL_ ASSIGN; statement to associate all caslibs

After you establish a CAS session (by using the CAS statement), you can associate a libref with each of the defined caslibs by running the following statement:

caslib _all_ assign;

After you submit this code, you can see in the log that a libref was created for each caslib, and the name of the caslib is used as the name of the libref.

After you define a libref for each caslib, the Libraries tree is then updated to include these new librefs, as shown in the following image. The librefs that are associated with caslibs are identified by a cloud and snowflake icon that is next to the caslib name:



You can also use the following SAS Studio snippet to create a libref for each caslib:
SAS Snippets ► SAS Viya Cloud Analytic Services ► Generate SAS librefs for caslibs

Use the LIBNAME statement and CAS engine to associate specific caslibs

The CASLIB _ALL_ ASSIGN; statement defines a libref for each of your caslibs. However, if you do not want to include all caslibs in the Libraries tree, you can define librefs for only the caslibs that you want to include.

To do that, use the LIBNAME statement with the CAS engine to define a libref that is associated with a specific caslib. The following statement shows the syntax to define the libref:

libname libref cas caslib=caslib;

Here, libref is the name that you choose for the SAS libref, and caslib is the name of the assigned caslib that you want to associate with the libref.

When you use the CASLIB _ALL_ ASSIGN; statement, the caslib name is used for the libref name. But the libref name does not have to be the same as the caslib name.

For example, the following statement creates a libref named MYCAS that is associated with the CASUSER caslib:

libname MYCAS cas caslib=CASUSER;

Ensure that the caslib is already defined before you associate it with a libref.

If you are not sure whether a caslib is defined, the following code generates a list of the available defined caslibs. The list is generated on the Results tab in SAS Studio:

proc cas;
table.caslibInfo;
quit;

Note that you can also use the CASLIB _ALL_ LIST; statement to view the list of caslibs in the SAS Studio log.

Whether you use the table.caslibInfo action or the CASLIB _ALL_ LIST; statement is a matter of preference for where you want to view the results.

Additional options are supported for the LIBNAME statement and can be found in the CAS LIBNAME engine documentation.

Troubleshooting

Some librefs are not shown

What if you followed the above instructions and see some, but not all, of the librefs for your caslibs in the Libraries tree?

The rules for caslib names are not the same as the rules for librefs, so not all caslib names can be used as libref names.

For example, when you use the CASLIB _ALL_ ASSIGN; statement, you might see a note like the following written to the log:

NOTE: CASLIB SystemData for session CASAUTO will not be mapped to SAS Library SystemData. The CASLIB name is not valid for use as a libref.

This note is produced because the LIBNAME statement attempted to define a libref named SystemData to be associated with the caslib SystemData. However, a libref name is limited to eight characters, so SystemData could not be used as a libref name.

The name that is used for a SAS libref must conform to the rules for a SAS name.

If a caslib name is longer than eight characters, you can use the LIBNAME statement with the CAS engine to associate your caslib with a libref that meets the requirements for a SAS name.

For example, to define a libref for the SystemData caslib, you can use a shorter libref name, such as SYSDATA:

libname sysdata cas caslib=SystemData;

In the following image, the Libraries tree now includes the SYSDATA libref, which enables you to view the CAS tables that are stored in the SystemData caslib.



Another issue that you might encounter is that the name of the caslib is defined as a SAS name literal, such as containing character spaces in the caslib name, and you cannot associate a libref with that caslib. The CAS LIBNAME engine does not support a SAS name literal for a caslib name.

When you want to specify a name for a caslib, keep these SAS name rules in mind.

CAS tables are not shown

What if you defined librefs for each of the caslibs that you want to view in the Libraries tree, but some CAS tables are not displayed for a caslib?

If the name of a CAS table does not comply with the VALIDMEMNAME rules, then the table is not displayed in SAS Studio. SAS Note 63538 provides more information about this issue.

Librefs are not assigned automatically

What if you want to be able to see your caslibs in the Libraries tree in SAS Studio every time that you sign in? For this preference, you can edit your autoexec file in SAS Studio and include the statements to automatically define the librefs for your caslibs.

Follow these steps:

  1. Select Options ► Autoexec file.
  2. In the file, enter each of the statements that you want to run every time that you sign in. Here are examples:
cas;
caslib _all_ assign;

You can also include the LIBNAME statements for your caslibs as well as any other SAS statements that you want to run each time you sign in to SAS Studio.

  1. Click Run to submit the statements.
  2. Open the Log tab to verify that your statements ran without error.
  3. Click Save.

With each subsequent sign-in for SAS Studio, the statements from your autoexec file are run automatically, and you then can view the librefs for your CAS tables in the Libraries tree.

Conclusion

CAS libraries enable you to access your CAS data. By defining the librefs for those caslibs in SAS Studio, you can have more interactive access to the CAS data.

Learn more

How to view CAS tables in SAS® Studio was published on SAS Users.

10月 202021
 
As defined in the SAS® 9.4 Stored Processes: Developer's Guide, Third Edition, a stored process "is a SAS program that is stored on a server and defined in metadata, and which can be executed as requested by client applications." One of the benefits of using stored processes is that client applications always have the latest version of the code. In addition, stored processes provide enhanced security and application integrity.

Have you ever submitted a stored process, and instead of the expected output, you saw errors or no output at all? Depending on how you submit the stored process, various logs are available to assist you with debugging.

This article provides guidance for understanding which situations call for which logs, where to find each log, and what you should look for in each log. The article uses two clients as examples: SAS® Enterprise Guide® and the SAS® 9.4 Stored Process Web Application.

The article is divided into two sections:

  • Frequently Used Logs
  • Infrequently Used Logs

Frequently Used Logs

The logs that are described in this section are the most prevalent logs that you request when a stored process does not execute properly or when there seems to be a problem with the stored-process server.

SAS® Object Spawner log

What

The SAS Object Spawner log records anytime that the spawner tries to start or stop a stored-process server, a workspace server, or a pooled workspace server. It also records when a request is redirected to a running stored-process server or a pooled workspace server or to a SAS® Grid Manager server.

The syntax for this log's name is ObjectSpawner_yyyy-mm-dd_machine-name_process-ID.log.

Where

The default locations for the object-spawner log are as follows:

  • Microsoft Windows operating environments: SAS-configuration-directory\Lev1\ObjectSpawner\Logs
  • UNIX operating environments: SAS-configuration-directory/Lev1/ObjectSpawner/Logs

If the logs are not in the directories that are listed above, you can check the logconfig.xml file that resides in the SAS-configuration-directory\Lev1\ObjectSpawner\ directory. That file contains a parameter called FileNamePattern that determines the location of the object-spawner log, as shown in this example:

<param name="FileNamePattern" value="/sas/config/Lev1/ObjectSpawner/Logs/ObjectSpawner_%d_%S{hostname}_%S{pid}.log"/>

Why

Here are some reasons why you should check the object-spawner log:

  1. Performance problems occur within stored processes.
  2. Servers do not start or servers stop working. The stored process server, the workspace server, and the pooled workspace server are all started by the object spawner.
  3. Running a stored process returns no results and no errors.
  4. Users do not have permission to start the server or do not have ReadMetadata permission on their application server context (for example, the SASApp application server).
  5. The connecting user has to wait longer than the availability time-out of 60 seconds, and the stored process fails.
  6. A server is not available on which to run a stored process.

The following error is an example of one that you might find in this log:

The launch of the server process failed due to a problem with the processing of the SAS logging facility configuration file (LOGCONFIGLOC).

This error might occur because the file that is specified for the -LOGCONFIGLOC option cannot be processed. The option either is invalid or it cannot be accessed.

For more examples of errors that you might see in the object-spawner log, see the section Object Spawner Messages in "Appendix 1: Object Spawner and SAS OLAP Server Messages" in the SAS® 9.4 Intelligence Platform: Application Server Administration Guide.

You can also enable more detailed logging within the object-spawner log by following the steps in Enable More Detailed Logging for SAS Object Spawner Troubleshooting in "Chapter 10, Administering Logging for SAS Servers" of the SAS® 9.4 Intelligence Platform: System Administration Guide, Fourth Edition.

Example and possible cause

Let’s look at an example of how the object-spawner log can be helpful.

Suppose that the stored-process server fails to validate. Within the object-spawner log, you might see an error like the following:

Error authenticating user domain\sassrv in function LogonUser. Error 1326 (The user name or password is incorrect. ).
 
The credentials specified for the SASApp – Stored Process Server (A5WN99NR.AZ000007) server definition failed to authenticate. Therefore this server definition will not be included.

With this type of error, you might have an invalid sassrv password. You can check the password by trying to log on to the server directly with the sassrv user ID. If the logon is successful, open SAS® Management Console and verify that the password is correct in the metadata, as follows:

  1. In SAS® Management Console, select User Manager.
  2. Locate the SAS General Servers group. Then, right-click and select Properties.
  3. Click the Accounts tab.
  4. Select the sassrv user ID. Then click Edit.
  5. Update the password to what was successful on the operating system.
  6. Restart the object spawner.
  7. Check the logs again to verify that the error is resolved.

Object-spawner console log

What

The object-spawner console log, available only on UNIX platforms, does not actually contain information about the object spawner. Instead, this log contains STDERR and STDOUT messages about the applications that are launched by the object spawner. The syntax for this log's name ObjectSpawner_console_machine-name.log.

Where

Under UNIX, the default location for the object-spawner console log is SAS-configuration-directory/Lev1/ObjectSpawner/Logs.

Why

Here are some reasons why you should check this log:

  • SAS modules are missing. The program tries to run SAS modules that are not present in your environment.
  • Possible memory issues occur.
  • Storage or space issues occur.
  • Possible encoding issues occur.
  • Library permission issues occur.

The following error is an example of one that you might find in the object-spawner console log:

ERROR: Could not find extension: (sasgis)

This error can occur when someone or some component runs code that either checks for the existence of certain SAS modules or that contains references to certain SAS modules that are not present in your environment. Because these modules do not exist, errors are written to the log. This behavior is expected, and it is not indicative of any larger issue. So, you can ignore these messages.

Example and possible cause

Let’s look at an example of how the object-spawner console log can be helpful.

Suppose that your program generates a segmentation violation, but there is no indication as to why that happens. Within the object-spawner console log, you might see an error like the following:

ERROR: No space left on device

This type of error is an indication that you might be running out of disk space. Try adding more space, point to a network drive, or use smaller files.

SAS® Stored Process Server log

You need to enable verbose logging to see every stored process that runs through the server. For more details about verbose logging, see SAS Note 34114, "Creating a detailed SAS® Stored Process Server log by default."

What

The syntax for the SAS Stored Process Server log name is SASApp_STPServer_yyyy-mm-dd_machine-name_process-ID.log.

Where

The default locations for the stored-process server log are as follows:

  • Windows: SAS-configuration-directory\Lev1\SASApp\StoredProcessServer\Logs
  • UNIX: SAS-configuration-directory/Lev1/SASApp/StoredProcessServer/Logs

Why

Here are the reasons that you might need to check this log:

  • Performance problems occur.
  • You do not receive any results. That is, the stored process runs, but it does not return an error, a warning, or the expected results.

Here is an example of an error that you might see in the log:

ERROR: A lock is not available for library.dataset.data
ERROR: Lock held by process 26834

This error indicates that the data set that is shown in the error cannot be locked for processing because the lock is held by another process. Further investigation of the stored-process server log that contains process ID 26834 shows the DATA step that is also reading from the same data set, which causes the lock.

Here is another error that you might see in this log:

ERROR: No logical assign for filename _WEBOUT.

Possible causes

The two main reasons for this error are as follows:

  • The %STPBEGIN and %STPEND macros are enabled.
  • The item Package is selected under the Result capabilities section (via Execution Options ► Result capabilities in either SAS Management Console or SAS Enterprise Guide)

The object-spawner console log is often needed in conjunction with the object-spawner log so that you can evaluate the communication between them.

SAS® Stored Process web-application log

What

The SAS Stored Process web-application log resides on the middle-tier machine, and the syntax for the log's name is SASStoredProcess9.4.log. (Note: The 9.4 in SASStoredProcess9.4.log will change with new releases.)

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\Logs\SASServer1_1
  • UNIX: SAS-configuration-directory/Lev1/Web/Logs/SASServer1_1

Why

Here are some scenarios for which you might want to check this log:

  • HTTP errors are displayed in the browser when you submit the stored process from the SAS Stored Process Web Application.
  • Pages in the stored-process web application (for example, the welcome page, index page, or custom input form) do not load or they take a long time to load.
  • A dynamic prompt cannot load.

Examples

The following error occurs when dynamic prompts from a data set and the SAS General Servers user group are denied ReadMetadata permission in SAS Management Console for that specific stored process:

2021-07-30 15:01:43,494 [tomcat-http--10] WARN [sasdemo] com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider - Cannot resolve data type
2021-07-30 15:01:43,505 [tomcat-http--10] ERROR [sasdemo] com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider - Unable to find physical table
com.sas.storage.exception.ServerConnectionException: Unable to find physical table
	at com.sas.prompts.valueprovider.dynamic.DataProviderUtil.getLibrary(DataProviderUtil.java:163)
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.setConnection(PromptColumnValueProvider.java:815)
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.getValuesAsList(PromptColumnValueProvider.java:647)
	at com.sas.prompts.valueprovider.dynamic.workspace.PromptColumnValueProvider.getValues(PromptColumnValueProvider.java:633)

The following pop-up message occurs because the SAS General Servers user group or the sasdemo user ID are denied permission to the data set that is needed for the prompts for a stored process.

Unable to execute query: SQL passthru expression contained these errors: ERROR: File MYLIB.MYCLASS.DATA does not exist

When you run a stored process from the SAS Stored Process Web Application, it is often helpful to add debugging options to the end of the URL by using the reserved macro variable _DEBUG. The following example URL demonstrates how to use the TRACE and LOG options to obtain pertinent information in the log that is produced in the browser.

http://your.web.server:8080/SASStoredProcess/do?_program=/STP_Examples/test1&_debug=trace,log

For a complete list of _DEBUG= values, see List of Valid Debugging Keywords in "Chapter 7: Building a Web Application with SAS® Stored Processes" in the SAS® 9.4 Stored Processes: Developer's Guide, Third Edition.

Workspace-server log

What

You must request logging for the workspace-server log because it is not one that is enabled, by default. The syntax for the log's name is SASApp_WorkspaceServer_yyyy-mm-dd_machine-name_process-ID.log.

Where

As mentioned earlier, you must request logging for this log, as follows:

  • Windows: In the sasv9_usermods.cfg file that resides in SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\ directory, add the following command to turn on logging:
    -logconfigloc SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\logconfig.trace.xml"

    This setting generates the log file in SAS-configuration-directory\Lev1\SASApp\WorkspaceServer\Logs.

  • UNIX: In the sasv9_usermods.cfg file that resides in SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/logconfig.trace.xml"
    to /Lev1/SASApp/WorkspaceServer/
    directory, add the following command to turn on logging:

    -LOGCONFIGLOC SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/logconfig.trace.xml"

    This setting generates the log file that resides in SAS-configuration-directory/Lev1/SASApp/WorkspaceServer/Logs.

Why

If you run the stored process from the SAS Stored Process Web Application with the server set to the workspace server, you need to consult this log for any errors or warnings. Running the stored process from SAS Enterprise Guide produces a log directly in the application. You need to consult the workspace server log in either of these circumstances:

  • when Default server is selected as the server type in the stored-process properties
  • when you submit the stored process from SAS Enterprise Guide

Pooled workspace-server Log

What

The syntax for the pooled workspace-server log's name is SASApp_PooledWSServer_yyyy-mm-dd_machine-name_process-ID.log.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\ Lev1\SASApp\PooledWorkspaceServer\Logs
  • UNIX: SAS-configuration-directory/Lev1/SASApp/PooledWorkspaceServer/Logs

Why

The pooled workspace server loads dynamic prompt values in the SAS Stored Process web application. So, you need this log if a dynamic prompt does not load.

SAS® Metadata Server Log

What

The syntax for the SAS Metadata Server log' name is SASMeta_MetadataServer_yyyy-mm-dd_machine-name_process-ID.log

Where

The default locations for the metadata-server log are as follows:

  • Windows: SAS-configuration-directory\Lev1\SASMeta\MetadataServer\Logs
  • UNIX: SAS-configuration-directory/Lev1/SASMeta/MetadataServer/Logs

Why

This log is helpful for issues with the LIBNAME META engine and metadata permissions.

The following error is written to the metadata-server log when no metadata identity is associated with the user name and password.

ERROR [00000779] 28:billyw - User Folders cannot be created or retrieved if connected user ID is not a person identity. Must be connected as a person identity or valid person name must be passed in request.

The following messages might also be written to this log when you try to open SAS Management Console and when the user billyw requires log on as a batch job user rights at the operating system level.

20100122:13.00.36.82: 00002410:NOTE:    User tbanks probably does not have the right to log on as a batch job.
20100122:13.00.36.82: 00002410:ERROR:   Error authenticating user tbanks in function LogonUser.  Error 1385 (Logon failure: the user has not been granted the requested logon type at this computer. ).
20100122:13.00.36.82: 00002410:ERROR:   Access denied.

Infrequently Used Logs

Windows Event Viewer log

The Windows Event Viewer contains several logs that are used less frequently than the aforementioned logs. This fact in no way diminishes their effectiveness when you are troubleshooting stored-process issues. SAS Technical Support will request these logs from you for an issue if it is necessary.

Although the event viewer contains several logs, SAS Technical Support reviews only the application log, the system log, and the security log for errors that are related to start-up and other failures in the SAS Stored Process Server (or any SAS server).

If the sassrv user ID cannot write to the Logs directory, you receive a message in this log.

If a server is stopped or started, those behaviors register in these logs. Hopefully, this review of the various logs that are related to debugging stored-process issues will assist your troubleshooting efforts.

ERROR_yyyy-mm-dd-time.log

What

This web-server log is useful when you have catastrophic failures in loading or running a stored process in a SAS web application. The syntax for this log's name is ERROR_yyyy-mm-dd-time.log.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebServer\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebServer/logs

Why

Here are some reasons why you should check this log:

  • Java errors are returned in the browser when you try to load or run a stored process using the SAS Stored Process Web Application.
  • Connection errors occur between the web server and the tc Server.

Here is an example of an error that you might find in this log:

[error] (OS 10061)No connection could be made because the target machine actively refused it.  : proxy: HTTP: attempt to connect to 192.168.x.xxx:8080 (machine-name) failed

This error might occur when your servers are down or when they are restarting and are not active yet.

Example and possible cause

Let’s look at an example of how the ERROR_yyyy-mm-dd-time log can be helpful.

Suppose that you try to run a stored process through the SAS Stored Process Web Application and you cannot load any SAS 9.4 web applications after you enter your user ID and password. If you check this log, you might see errors like the following:

No connection could be made because the target machine actively refused it. : proxy: HTTP: attempt to connect to 192.168.x.xxx:8080 (machine-name) failed
 
ap_proxy_connect_backend disabling worker for (machine-name)

The secondary middle-tier node is in a clustered environment, but it configured incorrectly. For a circumvention, see SAS Note 55904, "You cannot access any SAS® 9.4 web applications when the secondary middle-tier node is in a clustered environment."

Localhost_access_log..yyyy-mm-dd.txt

What

This log shows the sequence and query strings of URLs that are submitted through the SAS Web Application Server (for all web applications that use this application server). This log lists activity sequentially and includes HTTP status codes for each URL. The syntax for this log's name is Localhost_access_log..yyyy-mm-dd.txt.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebAppServer\SASServer1_1\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebAppServer/SASServer1_1/logs

Why

Here are some reasons why you should check this log:

  • A page cannot load or the URL is invalid.
  • Performance problems occur.
  • You need a good way to trace the stored-process activity after you click the Run button in web applications only.

Here is an example of a message that you might see in this log:

"POST /SASLogon/v1/tickets HTTP/1.1" 404 796

Example and possible cause

Let’s look at an example of how this log can be helpful. Suppose that you cannot log on to the SAS Stored Process Web Application. If you check this log, you might see a message like the following:

GET /SASStoredProcess/j_spring_cas_security_check?ticket=ST-9994-zpD2sFdBmayXEuoj4cya-cas HTTP/1.1" 401 802

In this example, you can see that the issue is a 401 HTTP return code.

If the servers have just been restarted, try waiting a little longer for them to start up. If that is not the issue, the server might be down. The best approach is to stop and then restart the servers. Because of dependencies, it is important to start the servers in the correct order. You can find the correct order in Overview of Server Operation, in "Chapter 6: Operating Your Servers" of the SAS® Intelligence Platform: System Administration Guide, Fourth Edition.

Access_yyyy-mm-dd-time.log

What

This log shows the sequence and query strings of URLs that are submitted through the SAS Web Server. The syntax for the name of this log is access_yyyy-mm-dd-time.log.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebServer\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebServer/logs

Why

Here are some reasons why you would check this log:

  • A connection error occurs when you submit a stored process.
  • Java errors occur in the browser.
  • When you evaluate a performance problem, timestamps in the log confirm when the web server received the request and what was in the request.
  • The output that is produced by the stored process does not match the expected output based on the prompt selections that are available when you submit the stored process.

Here is an example of a message that you might see in this log:

"GET /SASTheme_default/themes/ThemeXMLFiles.config HTTP/1.1" 503 299

This error might occur because the servers are down or are in the process of restarting and are not active yet.

Example and possible cause

Let’s look at an example of how the access_yyyy-mm-dd-time log can be helpful.

Suppose that you are trying to run a stored process through the SAS web application and you receive a connection error. If you check this log, you might see a message like the following:

"GET /SASLogon/proxy?pgt=TGT-6-aGakal9b2VGBg3dnNTbbwiVALOWqBSem9E3cVWehDD35vegmxI-cas&targetService=http%3A%2F%2FLazySecurityContext HTTP/1.1" 502 407

The message above shows a 502 HTTP return code. This error indicates that the server, while acting as a gateway or proxy, received an invalid response from the upstream server. If the servers were just restarted, try waiting a little longer for them to start back up. If that is not the issue, then a server might be down. The best approach is to stop and restart the servers. Because of dependencies, it is important to start the servers in the correct order. You can find the correct order in Overview of Server Operation, in "Chapter 6: Operating Your Servers" of the SAS® Intelligence Platform: System Administration Guide, Fourth Edition.

Server.log

What

This log is helpful if a stored-process web application generates an HTPP, browser, or generic error in the browser when it loads a page or results that are returned from a stored process.

Where

The default locations for this log are as follows:

  • Windows: SAS-configuration-directory\Lev1\Web\WebAppServer\SASServer1_1\logs
  • UNIX: SAS-configuration-directory/Lev1/Web/WebAppServer/SASServer1_1/logs

Why

Here are some reasons why you would check this log:

  • The SAS Stored Processes web application is not working.
  • Requests time out.
  • A configuration change is made to one of the web applications (for example, an increase to the time-out for the stored-process web application).
  • A generic error is displayed in the SAS Stored Processes web application when you run a stored process.

Here is an example of a message that you might find in this log:

java.io.IOException: Cannot bind to URL

One possible reason for this type of error is network issues at the site where the stored process is run.

Example and possible cause

Let’s look at an example of how the server.log file can be helpful.

Suppose that you want to run a stored process through the SAS Web Application and you receive a generic error that says The system is experiencing problems. Please contact your system administrator. If you check this log, you might see a message like the following:

ERROR (ContainerBackgroundProcessor[StandardEngine[Catalina]]) [org.apache.catalina.core.ContainerBase] Unexpected death of background thread ContainerBackgroundProcessor[StandardEngine[Catalina]]
java.lang.OutOfMemoryError: Java heap space

There is insufficient memory available to process the request. As a possible workaround, you need to modify the setenv.bat file that resides on Windows in SAS-configuration-directory\Lev1\Web\Webappserver\Sasserver1_1\bin\ or the setenv.sh in SAS-configuration-directory/Lev1/Web/WebAppServer/Sasserver1_1/bin/ on UNIX. You need to edit the JVM_OPTS value by changing the -Xmx4096m -Xms1024m parameter to the following:

-Xmx8092m -Xms8092m

Making this change requires the restart of the SAS Web Application Server if only the webappserver script is updated.

Conclusion

Hopefully, this review of logs that are related to debugging stored-process issues will assist your troubleshooting efforts. When you request help from SAS Technical Support, these are some of the logs that you will be asked to send so that Technical Support can better determine the cause of your problem.

Learn more

Debugging a stored-process problem 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.

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.