为什么 %str(%inner_macro()) 中的 %str 不起作用?
Why does the %str in `%str(%inner_macro())` not work?
%str 应该将字符串作为一个参数传递给 sas 宏,即使它包含逗号,但如果 %str 的参数本身是宏的结果,那显然不起作用?我得到 ERROR: More positional parameters found than defined.
例子
这就是错误的意思
15 %macro outer_macro(left, right);
16 %put NOTE: outer_macro: left is &left;
17 %put NOTE: outer_macro: right is &right;
18 %mend;
19 %outer_macro(left, right);
NOTE: outer_macro: left is left
NOTE: outer_macro: right is right
20 %outer_macro(left, midle, right);
ERROR: More positional parameters found than defined.
正常情况下%str
是这样解决的
21 %outer_macro(left, %str(midle, right));
NOTE: outer_macro: left is left
NOTE: outer_macro: right is midle, right
可以用内部宏构造宏的参数
23 %macro blank_macro(left, right);
24 %put NOTE: blank_macro: left is &left;
25 %put NOTE: blank_macro: right is &right;
26 &left. &right.
27 %mend;
28 %outer_macro(links, %blank_macro(midden, rechts));
NOTE: blank_macro: left is midden
NOTE: blank_macro: right is rechts
NOTE: outer_macro: left is links
NOTE: outer_macro: right is midden rechts
但是如果内部宏插入一个逗号,你会得到原来的错误
30 %macro comma_macro(left, right);
31 %put NOTE: comma_macro: left is &left;
32 %put NOTE: comma_macro: right is &right;
33 &left., &right.
34 %mend;
35 %outer_macro(left, %comma_macro(midle, right));
NOTE: comma_macro: left is midle
NOTE: comma_macro: right is right
ERROR: More positional parameters found than defined.
我希望 %str
能够解决这个问题,但事实并非如此。为什么?
36 %outer_macro(left, %str(%comma_macro(midle, right)));
NOTE: comma_macro: left is midle, right
NOTE: comma_macro: right is
ERROR: More positional parameters found than defined.
上下文
供您参考:我需要这个,因为我写了一个宏来列出一些我应该从数据库查询的字段,我需要通过另一个宏将我的 sql 传递给数据库。
%run_SQL(select key, %list_fields(some_arguments), from something);
引用 %COMMA_MACRO
的输出
33 %macro comma_macro(left, right);
34 %put NOTE: comma_macro: left is &left;
35 %put NOTE: comma_macro: right is &right;
36 %nrbquote(&left., &right.)
37 %mend;
38 %macro outer_macro(left, right);
39 %put NOTE: outer_macro: left is &left;
40 %put NOTE: outer_macro: right is &right;
41 %mend;
42 %outer_macro(left, %comma_macro(midle, right));
NOTE: comma_macro: left is midle
NOTE: comma_macro: right is right
NOTE: outer_macro: left is left
NOTE: outer_macro: right is midle, right
您遇到的问题是 %str
在宏 编译 期间屏蔽字符,而不是在宏 执行 期间屏蔽字符。因此,宏调用会正确编译,执行 %comma_macro
,但是一旦执行,就不再引用这些值(因为 %str
已经完成了它的工作)。它不会在 秒 时间内屏蔽值。
您的 %comma_macro
调用也是错误的事实进一步证明了这一点。它掩盖了 ,
,然后导致 %comma_macro
认为 midle,right
是第一个参数(与您在宏括号内使用 %str
相同)。
请注意,SAS 在 the %str documentation 中特别提到这种做法是危险的:
Do not use %STR to enclose other macro functions or macro invocations that have a list of parameter values.
Because %STR masks parentheses without a match, the macro processor does not recognize the arguments of a function or the parameter values of a macro invocation.
%quote
与 %str
相同,只是 masks characters during resolution:
%QUOTE and %NRQUOTE mask the same items as %STR and %NRSTR, respectively. However, %STR and %NRSTR mask constant text instead of a resolved value. And, %STR and %NRSTR work when a macro compiles, while %QUOTE and %NRQUOTE work when a macro executes.
在您的示例中,将 %str
替换为 %quote
会非常有效。然而,我认为 %bquote
可能是首选,因为它为不匹配的引号提供了额外的保护。我一直认为 %bquote
中的 b
代表 better
,并且从未见过使用 %quote
的理由。
The %BQUOTE and %NRBQUOTE functions mask a character string or resolved value of a text expression during execution of a macro or macro language statement.
这听起来像是你对我做的。您不需要使用 %NRBQUOTE
,除非结果中可能包含 & %
个字符。
宏引用时间线的table:
Quoting Type | Occurs At | Mask details
%str | Compilation | Unmatched Quotations/Parens with %
%nrstr | Compilation | Same as %str plus & %
%quote | Execution | Same as %str
%nrquote | Execution | Same as %quote plus & %
%bquote | Execution | Unmatched quotes/parens automatically
%nrbquote | Execution | Same as %bquote plus & %
%superq | Execution | Only variable and without &, same list as %nbrquote
(continuned) | Does not attempt to resolve anything inside of variable
%str 应该将字符串作为一个参数传递给 sas 宏,即使它包含逗号,但如果 %str 的参数本身是宏的结果,那显然不起作用?我得到 ERROR: More positional parameters found than defined.
例子
这就是错误的意思
15 %macro outer_macro(left, right);
16 %put NOTE: outer_macro: left is &left;
17 %put NOTE: outer_macro: right is &right;
18 %mend;
19 %outer_macro(left, right);
NOTE: outer_macro: left is left
NOTE: outer_macro: right is right
20 %outer_macro(left, midle, right);
ERROR: More positional parameters found than defined.
正常情况下%str
是这样解决的
21 %outer_macro(left, %str(midle, right));
NOTE: outer_macro: left is left
NOTE: outer_macro: right is midle, right
可以用内部宏构造宏的参数
23 %macro blank_macro(left, right);
24 %put NOTE: blank_macro: left is &left;
25 %put NOTE: blank_macro: right is &right;
26 &left. &right.
27 %mend;
28 %outer_macro(links, %blank_macro(midden, rechts));
NOTE: blank_macro: left is midden
NOTE: blank_macro: right is rechts
NOTE: outer_macro: left is links
NOTE: outer_macro: right is midden rechts
但是如果内部宏插入一个逗号,你会得到原来的错误
30 %macro comma_macro(left, right);
31 %put NOTE: comma_macro: left is &left;
32 %put NOTE: comma_macro: right is &right;
33 &left., &right.
34 %mend;
35 %outer_macro(left, %comma_macro(midle, right));
NOTE: comma_macro: left is midle
NOTE: comma_macro: right is right
ERROR: More positional parameters found than defined.
我希望 %str
能够解决这个问题,但事实并非如此。为什么?
36 %outer_macro(left, %str(%comma_macro(midle, right)));
NOTE: comma_macro: left is midle, right
NOTE: comma_macro: right is
ERROR: More positional parameters found than defined.
上下文
供您参考:我需要这个,因为我写了一个宏来列出一些我应该从数据库查询的字段,我需要通过另一个宏将我的 sql 传递给数据库。
%run_SQL(select key, %list_fields(some_arguments), from something);
引用 %COMMA_MACRO
的输出33 %macro comma_macro(left, right);
34 %put NOTE: comma_macro: left is &left;
35 %put NOTE: comma_macro: right is &right;
36 %nrbquote(&left., &right.)
37 %mend;
38 %macro outer_macro(left, right);
39 %put NOTE: outer_macro: left is &left;
40 %put NOTE: outer_macro: right is &right;
41 %mend;
42 %outer_macro(left, %comma_macro(midle, right));
NOTE: comma_macro: left is midle
NOTE: comma_macro: right is right
NOTE: outer_macro: left is left
NOTE: outer_macro: right is midle, right
您遇到的问题是 %str
在宏 编译 期间屏蔽字符,而不是在宏 执行 期间屏蔽字符。因此,宏调用会正确编译,执行 %comma_macro
,但是一旦执行,就不再引用这些值(因为 %str
已经完成了它的工作)。它不会在 秒 时间内屏蔽值。
您的 %comma_macro
调用也是错误的事实进一步证明了这一点。它掩盖了 ,
,然后导致 %comma_macro
认为 midle,right
是第一个参数(与您在宏括号内使用 %str
相同)。
请注意,SAS 在 the %str documentation 中特别提到这种做法是危险的:
Do not use %STR to enclose other macro functions or macro invocations that have a list of parameter values. Because %STR masks parentheses without a match, the macro processor does not recognize the arguments of a function or the parameter values of a macro invocation.
%quote
与 %str
相同,只是 masks characters during resolution:
%QUOTE and %NRQUOTE mask the same items as %STR and %NRSTR, respectively. However, %STR and %NRSTR mask constant text instead of a resolved value. And, %STR and %NRSTR work when a macro compiles, while %QUOTE and %NRQUOTE work when a macro executes.
在您的示例中,将 %str
替换为 %quote
会非常有效。然而,我认为 %bquote
可能是首选,因为它为不匹配的引号提供了额外的保护。我一直认为 %bquote
中的 b
代表 better
,并且从未见过使用 %quote
的理由。
The %BQUOTE and %NRBQUOTE functions mask a character string or resolved value of a text expression during execution of a macro or macro language statement.
这听起来像是你对我做的。您不需要使用 %NRBQUOTE
,除非结果中可能包含 & %
个字符。
宏引用时间线的table:
Quoting Type | Occurs At | Mask details
%str | Compilation | Unmatched Quotations/Parens with %
%nrstr | Compilation | Same as %str plus & %
%quote | Execution | Same as %str
%nrquote | Execution | Same as %quote plus & %
%bquote | Execution | Unmatched quotes/parens automatically
%nrbquote | Execution | Same as %bquote plus & %
%superq | Execution | Only variable and without &, same list as %nbrquote
(continuned) | Does not attempt to resolve anything inside of variable