BookmarkSubscribeRSS Feed
DavidRice
Fluorite | Level 6

I'm trying to do something similar to another post, but the accepted answer didn't meet my requirements.

 

We're working on a SAS macro to produce control chart data tables using PROC SHEWHART.  We need to capture exceptions/errors, take appropriate action, and then continue with subsequent data steps/procedures.  In the example I've included below, we're simply changing from a p-Chart to a c-Chart when something causes the p-Chart to fail.  This specific example is where the denominator value is larger than the numerator; that is one known failure mode, but we don't know what other p-Charts rules could be violated.  Pre-testing for a specific failure mode, or failure modes, is not a desirable solution.

 

As expected, an exception, caught while the SYNTAXCHECK option is set, causes SAS to enter the special syntax check mode, and subsequent procedure calls within the macro fail due to empty data sets.

 

I have a workaround where I temporarily set the NOSYNTAXCHECK system option immediately before the error-prone procedure call, and then set SYNTAXCHECK immediately following the exception handling code.  In our environment we are supposed to keep the SYNTAXCHECK option active for the duration of the SAS session, so this is also an undesirable solution.

 

Is it possible to recover from "syntax check mode" after an error has occured with the SYNTAXCHECK system option set?

 

I would rather include a few lines of "reset" code within my exception-handling block and continue on.  I have set the OBS and REPLACE system options in my exception-handling block, but that doesn't appear to completely reverse the syntax check mode changes to the environment.

 

options mprint mprintnest mlogic mlogicnest symbolgen spool syntaxcheck;
options msglevel=i notes source serror fullstimer errorcheck=normal;

%put NOTE: obs option : %sysfunc(getoption(obs,keyword));
%put NOTE: replace option : %sysfunc(getoption(replace));
%put NOTE: syntaxcheck option : %sysfunc(getoption(syntaxcheck));

data WORK.shewhart_data;
  input interval_month mmddyy10. numerator denominator;
  datalines;
07/01/2018 5 11
08/01/2018 14 9
09/01/2018 12 24
10/01/2018 19 27
11/01/2018 15 13
12/01/2018 20 34
01/01/2019 25 15
02/01/2019 22 31
03/01/2019 34 28
;

%macro test_shewhart(
  in_data=,
  out_data=
);
  proc shewhart data=&in_data;
    pchart numerator*interval_month
      / subgroupn=denominator sigmas=3 nochart outtable=&out_data;
  run;

  %if &syserr ne 0 %then
    %do;
      options obs=max replace; run; quit;

      %put NOTE: obs option : %sysfunc(getoption(obs,keyword));
      %put NOTE: replace option : %sysfunc(getoption(replace));
      %put NOTE: syntaxcheck option : %sysfunc(getoption(syntaxcheck));

      proc shewhart data=&in_data;
        cchart numerator*interval_month
          / sigmas=3 nochart outtable=&out_data;
      run;
    %end;

%mend test_shewhart;

%test_shewhart(
  in_data = WORK.shewhart_data,
  out_data = WORK.chart_data
)

I've also attached the log with this code run from a brand new SAS session.

 

Thanks,
David

3 REPLIES 3
Tom
Super User Tom
Super User

Doesn't look like you are resetting the SYNTAXCHECK option in your code that sets the OBS option.

Or the ERRORCHECK option that it looks like EG (or what ever front end you are using) submitted in front of your code.

Patrick
Opal | Level 21

@DavidRice 

Please note that SYNTAXCHECK is for batch while for running in a Windowing mode (EG, SAS Studio, PC SAS) the option is DMSSYNCHK.

As for your code: Possibly also reset macro variable &SYSCC to zero to continue processing. That's what worked for me in the past.

 

The option statement is a global statement. You don't need a RUN;QUIT; after it.

 

 

Actually: I'd be storing the value of &SYSCC in another macro var before your TRY block, set &syscc to zero in your CATCH logic but then reset it back to the saved value after the CATCH logic using the max value of the current &SYSCC value (=the max from the value you've saved away and the value you've got out of the CATCH block). 

I'm not sure what value &syserr will have if you've got already and error before your try/catch and you're already entering the TRY block in syntaxcheckmode. So eventually use &SYSCC instead of &SYSERR to decide if you'll enter the CATCH block at all.

ChrisNZ
Tourmaline | Level 20

In most production environments, a non-nil value for syserr is unacceptable.

Since your production environment seems to have strict rules in place, I would expect this to be true as well?

In this case, the typical production program would:

- Not alter error-checking options 

- Pick the most appropriate plot type depending on the data

- Fail if something unexpected (i.e. not catered for in the code) happens.
  This failure is desirable as it highlights an unexpected event that should be looked into.

  For example if there is no data, one wants to know about this abnormal event, 

  or the program could be ready for this and display a "No data" report.

 

Sorry, not much help about your specific question, just to bring a bit of (maybe irrelevant) context.

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
  • 3 replies
  • 2738 views
  • 0 likes
  • 4 in conversation