在宏内使用数据集名称内的变量时出现 SAS 语法错误 22 和 200
SAS syntax error 22 and 200 when using variable inside dataset name inside macro
我正在尝试使用宏中的循环对 SAS 中的多个数据集进行排序,使用数字列表,其中一些数字在数据集名称中具有前导零(例如,在示例代码中,列表 01,02
),此代码还将指导我想构建的其他一些循环。
我使用 SAS 指南循环遍历非顺序值列表,使用宏 DO 循环代码作为起点:http://support.sas.com/kb/26/155.html。
data dir1201;
input compid directorid X;
format ;
datalines;
01 12 11
02 15 5
;
run;
data dir1202;
input compid directorid X;
format ;
datalines;
01 12 1
03 18 8
;
run;
%macro loops1(values);
/* Count the number of values in the string */
%let count=%sysfunc(countw(&values));
/* Loop through the total number of values */
%do i = 1 %to &count;
%let value=%qscan(&values,&i,%str(,));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
by directorid compid;
run;
%end;
%mend;
options mprint mlogic;
%loops1(%str(01,02))
我假设非顺序列表需要 str
,但这在我想保留前导零时也很有用;
我看到宏变量似乎在日志中包含了 01 或 02,但随后我收到错误 22 和 200。以下是使用此示例代码的日志错误片段:
339 %macro loops1(values);
340 /* Count the number of values in the string */
341 %let count=%sysfunc(countw(&values));
342 /* Loop through the total number of values */
343 %do i = 1 %to &count;
344 %let value=%qscan(&values,&i,%str(,));
345 proc sort data=dir12&value out=dir12sorted&value nodupkey;
346 by directorid compid;
347 run;
348 %end;
349 %mend;
350 options mprint mlogic;
351 %loops1(%str(01,02))
MLOGIC(LOOPS1): Beginning execution.
MLOGIC(LOOPS1): Parameter VALUES has value 0102
MLOGIC(LOOPS1): %LET (variable name is COUNT)
MLOGIC(LOOPS1): %DO loop beginning; index variable I; start value is 1; stop value is 2; by
value is 1.
MLOGIC(LOOPS1): %LET (variable name is VALUE)
NOTE: Line generated by the macro variable "VALUE".
1 dir1201
--
22
--
200
ERROR: File WORK.DIR12.DATA does not exist.
我不明白为什么显示 dir1201
,但是错误是引用数据集 work.dir12
(忽略 01
)
宏引号使解析器误以为宏引号表示新标记的开始。您可以添加 %unquote()
以删除宏引号。
proc sort data=%unquote(dir12&value) out=%unquote(dir12sorted&value) nodupkey;
或者只是不添加开头的宏引号。
%let value=%scan(&values,&i,%str(,));
如果您将宏设计为采用 space 分隔值而不是逗号分隔值,那么使用宏会容易得多。那么也不需要在调用中添加宏引用。
%macro loops1(values);
%local i value ;
%do i = 1 %to %sysfunc(countw(&values,%str( )));
%let value=%scan(&values,&i,%str( ));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
by directorid compid;
run;
%end;
%mend loops1;
%loops1(values=01 02)
宏声明选项 /PARMBUFF
用于使自动宏变量 SYSPBUFF
可用于扫描作为参数传递的任意数量的逗号分隔值。
%macro loops1/parmbuff;
%local index token;
%do index = 1 %to %length(&syspbuff);
%let token=%scan(&syspbuff,&index);
%if %Length(&token) = 0 %then %goto leave1;
proc sort data=dir12&token out=dir12sorted&token nodupkey;
by directorid compid;
run;
%end;
%leave1:
%mend;
options mprint nomlogic;
%loops1(01,02)
因为你在日期上循环,我认为这样的事情可能对长期 运行 更有帮助:
%macro date_loop(start, end);
%let start=%sysfunc(inputn(&start, anydtdte9.));
%let end=%sysfunc(inputn(&end, anydtdte9.));
%let dif=%sysfunc(intck(month, &start, &end));
%do i=0 %to &dif;
%let date=%sysfunc(intnx(month, &start, &i, b), yymmdd4.);
%put &date;
%end;
%mend date_loop;
%date_loop(01Jan2012, 01Jan2015);
这是对 SAS 文档(宏附录,示例 11)中版本的略微修改。
我正在尝试使用宏中的循环对 SAS 中的多个数据集进行排序,使用数字列表,其中一些数字在数据集名称中具有前导零(例如,在示例代码中,列表 01,02
),此代码还将指导我想构建的其他一些循环。
我使用 SAS 指南循环遍历非顺序值列表,使用宏 DO 循环代码作为起点:http://support.sas.com/kb/26/155.html。
data dir1201;
input compid directorid X;
format ;
datalines;
01 12 11
02 15 5
;
run;
data dir1202;
input compid directorid X;
format ;
datalines;
01 12 1
03 18 8
;
run;
%macro loops1(values);
/* Count the number of values in the string */
%let count=%sysfunc(countw(&values));
/* Loop through the total number of values */
%do i = 1 %to &count;
%let value=%qscan(&values,&i,%str(,));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
by directorid compid;
run;
%end;
%mend;
options mprint mlogic;
%loops1(%str(01,02))
我假设非顺序列表需要 str
,但这在我想保留前导零时也很有用;
我看到宏变量似乎在日志中包含了 01 或 02,但随后我收到错误 22 和 200。以下是使用此示例代码的日志错误片段:
339 %macro loops1(values);
340 /* Count the number of values in the string */
341 %let count=%sysfunc(countw(&values));
342 /* Loop through the total number of values */
343 %do i = 1 %to &count;
344 %let value=%qscan(&values,&i,%str(,));
345 proc sort data=dir12&value out=dir12sorted&value nodupkey;
346 by directorid compid;
347 run;
348 %end;
349 %mend;
350 options mprint mlogic;
351 %loops1(%str(01,02))
MLOGIC(LOOPS1): Beginning execution.
MLOGIC(LOOPS1): Parameter VALUES has value 0102
MLOGIC(LOOPS1): %LET (variable name is COUNT)
MLOGIC(LOOPS1): %DO loop beginning; index variable I; start value is 1; stop value is 2; by
value is 1.
MLOGIC(LOOPS1): %LET (variable name is VALUE)
NOTE: Line generated by the macro variable "VALUE".
1 dir1201
--
22
--
200
ERROR: File WORK.DIR12.DATA does not exist.
我不明白为什么显示 dir1201
,但是错误是引用数据集 work.dir12
(忽略 01
)
宏引号使解析器误以为宏引号表示新标记的开始。您可以添加 %unquote()
以删除宏引号。
proc sort data=%unquote(dir12&value) out=%unquote(dir12sorted&value) nodupkey;
或者只是不添加开头的宏引号。
%let value=%scan(&values,&i,%str(,));
如果您将宏设计为采用 space 分隔值而不是逗号分隔值,那么使用宏会容易得多。那么也不需要在调用中添加宏引用。
%macro loops1(values);
%local i value ;
%do i = 1 %to %sysfunc(countw(&values,%str( )));
%let value=%scan(&values,&i,%str( ));
proc sort data=dir12&value out=dir12sorted&value nodupkey;
by directorid compid;
run;
%end;
%mend loops1;
%loops1(values=01 02)
宏声明选项 /PARMBUFF
用于使自动宏变量 SYSPBUFF
可用于扫描作为参数传递的任意数量的逗号分隔值。
%macro loops1/parmbuff;
%local index token;
%do index = 1 %to %length(&syspbuff);
%let token=%scan(&syspbuff,&index);
%if %Length(&token) = 0 %then %goto leave1;
proc sort data=dir12&token out=dir12sorted&token nodupkey;
by directorid compid;
run;
%end;
%leave1:
%mend;
options mprint nomlogic;
%loops1(01,02)
因为你在日期上循环,我认为这样的事情可能对长期 运行 更有帮助:
%macro date_loop(start, end);
%let start=%sysfunc(inputn(&start, anydtdte9.));
%let end=%sysfunc(inputn(&end, anydtdte9.));
%let dif=%sysfunc(intck(month, &start, &end));
%do i=0 %to &dif;
%let date=%sysfunc(intnx(month, &start, &i, b), yymmdd4.);
%put &date;
%end;
%mend date_loop;
%date_loop(01Jan2012, 01Jan2015);
这是对 SAS 文档(宏附录,示例 11)中版本的略微修改。