BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Espresso
Obsidian | Level 7

 

Greetings,

 

As a new user, I want to create a running log of messages I create for the user (administrative team members). The SAS log is a maze, the users can't read anything more complicated that this " Table Blah, observation 327 variable blah, value unexpected." That's all they can understand.

 

<rant>In other languages, I just append a message to a variable, anywhere in the program. If at the end the variable is not empty, I output to a log. With SAS feels like an act of Congress as a newbie, if in a data step, this does't work, if in a macro, that doesn't work, if in a proc sql, that's not defined. I am just not experienced enough yet, I'm the problem.</rant>

 

In SAS, since tables are everything, I'm thinking of appending a message as a new observation to an error table, then add it to the output.

 

Lets assume I declare a data set at the beginning of the program called work.errors, and lets assume it has two variables "type" and "msg". which would allow me to output a two column table at the end like this:

 

WARN Table Blah, observation 327 variable blah, value unexpected |

Note Table Blah, observation 500 value is outdated. |

 

Now, regardless of where I am in ANY data step, do statement, if statement: how can I push these ad hoc custumized "type" and "Msg" values to the work.errors data set through the program?

 

Then all I need is to Proc Print the table at the end (That is, if the table has any observations which I'm trying to research how to do that.)

 

I appreciate your time.

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

This approach is likely to be clunky in SAS.  For the most part, the DATA step must name any output data sets on the DATA statement.  You could do something like:

 

data errors ;
  length type $10 msg $200 ;
  call missing(type,msg) ;
  stop ;
run ;


data want   (drop=type msg) 
     error1 (keep=type msg)
  ;
  set sashelp.class ;
  *main processing ... ;
  output want ;

  if age<12 then do ;
     type="WARN" ;
     msg=cats("Young student:",name,"Age=",age) ;
     output error1 ;
  end ;
  if age>15 then do ;
     type="NOTE" ;
     msg=cats("Old student:",name,"Age=",age) ;
     output error1 ;
  end ;
run ;

proc append base=errors data=error1 ;
run ;

But that seems ugly.  The data step isn't designed to let you just  dynamically append to any arbitrary data set that exists.  Part of the reason is that the data step is compiled, and then executed.  When the step compiles, it must name all of the data sets it will be writing, and set up the output buffers, etc.  Then when it executes, it reads the data and can conditionally write records to different output data sets.  But during execution time, you can't suddenly decide to write to a new data set that wasn't named when the step compiled.

 

There are probably better approaches.  For example, if you want a file of messages, you can use PUT statements to write to a file, e.g.:

 

filename errlog "c:\junk\myerrorlog.txt" ;

data want;
  set sashelp.class ;

  *main processing ... ;

  *write to errorlog;

  file errlog mod ;

  if age<12 then do ;
     put "Warning: young student" name= age= ;
  end ;
  if age>15 then do ;
     put "Note: old student" name= age= ;
  end ;
run ;

You could also just write error messages to the main SAS log (same step as above, but without the FILE statement).  Then at the end of your program you could read in the log (because it's a text file), and parse out all the user-written error messages.  You'll find lots of log scanning papers over at lexjansen.com.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

View solution in original post

5 REPLIES 5
Anthony45
Fluorite | Level 6

SAS allows you to write user generated messages to the log, which may be a simpler way to achieve your goal. I'd look into the "putlog" type of statements. More info here and here. These statements allow you to send information to external text files as well. Creating an entire dataset seems like an unnecessarily complicated solution to your problem.

Quentin
Super User

This approach is likely to be clunky in SAS.  For the most part, the DATA step must name any output data sets on the DATA statement.  You could do something like:

 

data errors ;
  length type $10 msg $200 ;
  call missing(type,msg) ;
  stop ;
run ;


data want   (drop=type msg) 
     error1 (keep=type msg)
  ;
  set sashelp.class ;
  *main processing ... ;
  output want ;

  if age<12 then do ;
     type="WARN" ;
     msg=cats("Young student:",name,"Age=",age) ;
     output error1 ;
  end ;
  if age>15 then do ;
     type="NOTE" ;
     msg=cats("Old student:",name,"Age=",age) ;
     output error1 ;
  end ;
run ;

proc append base=errors data=error1 ;
run ;

But that seems ugly.  The data step isn't designed to let you just  dynamically append to any arbitrary data set that exists.  Part of the reason is that the data step is compiled, and then executed.  When the step compiles, it must name all of the data sets it will be writing, and set up the output buffers, etc.  Then when it executes, it reads the data and can conditionally write records to different output data sets.  But during execution time, you can't suddenly decide to write to a new data set that wasn't named when the step compiled.

 

There are probably better approaches.  For example, if you want a file of messages, you can use PUT statements to write to a file, e.g.:

 

filename errlog "c:\junk\myerrorlog.txt" ;

data want;
  set sashelp.class ;

  *main processing ... ;

  *write to errorlog;

  file errlog mod ;

  if age<12 then do ;
     put "Warning: young student" name= age= ;
  end ;
  if age>15 then do ;
     put "Note: old student" name= age= ;
  end ;
run ;

You could also just write error messages to the main SAS log (same step as above, but without the FILE statement).  Then at the end of your program you could read in the log (because it's a text file), and parse out all the user-written error messages.  You'll find lots of log scanning papers over at lexjansen.com.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Espresso
Obsidian | Level 7
This worked great, thanks. I could format the output with a delimiter, allowing me to then read the log into a dataset, which I will then output as a table. Thanks!
SASKiwi
PROC Star

With all due respect to your issue, SAS logs, in my experience, at least provide enough information so you can zero in on the likely cause of a problem pretty quickly. A lot of languages can be so cryptic in their logs that troubleshooting is pretty much guesswork.

 

Logs can be a lot easier to deal with if you start with the obvious. For example are there any ERROR or WARNING messages? You should start by checking for these looking at your own error checking. It's as simple as searching through the log for the words ERROR and WARNING.

 

You should also look at ways to customise the SAS log with existing SAS options as covered in this link: https://documentation.sas.com/?docsetId=lrcon&docsetTarget=n03qoiyzzrrl4in1pfvbqgj7jan8.htm&docsetVe...

 

A good example of this is the MSGLEVEL option.

 

 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 4656 views
  • 3 likes
  • 5 in conversation