sas 宏中的错误处理
Error Handling in a sas macro
我正在编写一个简单的宏来计算 table 的所有列中的不同值。
我需要包含一个错误处理程序,它显示错误信息并继续执行宏,如果在第一个列中找到某些列但在第二个列中找不到 table.
例如,
可以说,我写了一个宏来计算任何数据集和
中col1、col2、col3的不同值
table1 有列 (col1, col2, col3)
但,
table2 有列 (col2, col3) - 因此会出现一个错误,即 col1 在 table2 中不存在。我需要一种方法来处理这个错误。
喜欢 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 数据集中是否有任何观察结果。 %nobs 有很多不同的版本,here is a selection.
如果您决定让 SAS 结束而无需 运行ning 任何更多代码,下面显示了一个很好的宏。如果 运行 以批处理模式运行,它将退出 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 中的错误处理是一件非常混乱的事情,虽然这为您提供了一些统计信息,但我确信此列表绝不是全面的。我建议只尝试上面列出的几种不同方法,然后选择最适合您的方法...
我正在编写一个简单的宏来计算 table 的所有列中的不同值。 我需要包含一个错误处理程序,它显示错误信息并继续执行宏,如果在第一个列中找到某些列但在第二个列中找不到 table.
例如, 可以说,我写了一个宏来计算任何数据集和
中col1、col2、col3的不同值table1 有列 (col1, col2, col3) 但, table2 有列 (col2, col3) - 因此会出现一个错误,即 col1 在 table2 中不存在。我需要一种方法来处理这个错误。
喜欢 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 数据集中是否有任何观察结果。 %nobs 有很多不同的版本,here is a selection.
如果您决定让 SAS 结束而无需 运行ning 任何更多代码,下面显示了一个很好的宏。如果 运行 以批处理模式运行,它将退出 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 中的错误处理是一件非常混乱的事情,虽然这为您提供了一些统计信息,但我确信此列表绝不是全面的。我建议只尝试上面列出的几种不同方法,然后选择最适合您的方法...