sas宏中的错误处理

时间:2015-10-29 10:49:06

标签: error-handling sas sas-macro proc-sql

我正在编写一个简单的宏来计算表的所有列中的不同值。 我需要包含一个错误处理程序,它显示错误信息,并且如果在第一个表中找到某个列而在第二个表中找不到某个列,则继续执行宏。

例如, 比方说,我写了一个宏来计算任何数据集 col1,col2,col3 的不同值,以及

table1有列(col1,col2,col3) 但, table2有列(col2,col3) - 因此会有一个错误,即table2中不存在col1。我需要一种方法来处理这个错误。

1 个答案:

答案 0 :(得分:3)

爱SAS,但我讨厌错误处理(因为它几乎不存在,几乎总是需要使用宏代码完成...哎呀)。

您最好的选择是在执行代码之前检查任何条件,如果不满足任何要求,那么您的一些选择是:

  • 在步骤运行之前使用描述性消息中止。我发现%abort cancel语句是在批处理和交互式会话中停止代码的最好方法。
  • 使用%if %then语句跳过失败的步骤。
  • 让代码优雅地解决问题并继续(如果可能的话)。这可以通过有条件地运行通常不属于常规作业流程的附加代码来完成。
  • 让它运行然后重置错误条件(即将&syserr设置为零)?我从来没有真正玩过这个选项,所以我不能100%确定它是如何工作的,即使它是可行的。

在你的情况下,我想你的代码看起来像:

data have1;
  set sashelp.class;
run;

data have2;
  set sashelp.class(drop=age);
run;

/* GET A LIST OF COLUMNS IN EACH TABLE */
proc sql noprint;
  create table column_list as
  select memname, name
  from dictionary.columns
  where libname = 'WORK'
   and memname in ('HAVE1','HAVE2')
  order by name
  ;
quit;

/* CREATE A DATASET CONTAINING COLUMNS THAT ONLY EXISTS IN ONE OF THE TWO TABLES */
/* YOUR LOGIC MAY DIFFER */
data diff_columns;
  set column_list;
  by name;
  if first.name and last.name then do;
    output;
  end;
run;

%macro error_handling;
  %if %nobs(iDs=diff_columns) %then %do;  
    %put ERROR: TABLES CONTAINED DIFFERENT COLUMNS.;
    /* CHOOSE HOW YOU WANT TO HANDLE IT HERE */
  %end;
%mend;
%error_handling;

一些事情......我使用了一个名为%nobs()的宏来帮助我确定diff_columns数据集中是否有任何obersvations。有许多不同版本的%nobs,here is a selection

如果您决定在没有运行任何代码的情况下让SAS结束,那么下面显示了一个很好的宏。如果以批处理模式运行,它将退出SAS,但如果您以交互方式运行,它将只取消剩余的提交代码而不离开SAS:

%macro stop_sas;
  %if "&sysenv" eq "FORE" %then %do;
    %abort cancel;
  %end;
  %else %do;
    endsas;
  %end;
%mend;

如果您想在遇到任何错误时阻止SAS混乱日志,请考虑使用%runquit宏。看起来像这样,使用说明can be found here

%macro runquit;
  ; run; quit;
  %if &syserr %then %abort cancel;
%mend;

SAS中的错误处理是一个相当混乱的业务,虽然这给你一个统计数据,但我确定这个列表并不全面。我建议您尝试一些我上面列出的不同方法,然后选择最适合您的方法......