简体   繁体   English

在宏变量名称SAS中解析包含%eval的宏

[英]Resolving macro containing %eval in macro variable name, SAS

this is a toy example in order to help with a larger problem I have. 这是一个玩具示例,以帮助解决我遇到的更大问题。 It essentially involves using a %eval() macro when referencing a bigger macro variable name. 它主要涉及在引用更大的宏变量名时使用%eval()宏。

I have created a macro variable x_2, which uses the values of the loop, '&it', the variable is created successfully as can be seen by the final output, however I can only put it to the log without evaluating &it+1, which I will need to do when using a loop bigger than size 1. 我创建了一个宏变量x_2,它使用循环的值'&it',变量被成功创建,如最终输出所示,但是我只能将它放到日志中而不评估&it + 1,使用大于1的循环时我需要做。

It seems to resolve x_ first, giving a warning, before then evaluating x_2 as a whole and giving the output. 它似乎首先解决x_,发出警告,然后再评估x_2作为一个整体并给出输出。

I realise this is just a problem about how to reference macros correctly, but I cannot find any examples where it uses an evaluation as part of a macro variable name. 我意识到这只是一个关于如何正确引用宏的问题,但我找不到任何使用评估作为宏变量名称的一部分的示例。

Thanks. 谢谢。

%macro testing;

%DO it = 1 %TO 1; 

data dataset;
    s=100;
    t=99;
run;

data _null_;
    set dataset;
    if s = 100 then do;
        call symput("x_%eval(&it+1)",t);
    end;
run;

%put "&x_%eval(&it+1)";

%put &x_2;

%END;

%mend testing;

%testing;

LOG OUTPUT 日志输出

MLOGIC(TESTING):  %PUT "&x_%eval(&it+1)"

WARNING: Apparent symbolic reference X_ not resolved.

SYMBOLGEN:  Macro variable IT resolves to 1

SYMBOLGEN:  Macro variable X_2 resolves to           99

"          99"

MLOGIC(TESTING):  %PUT &x_2

SYMBOLGEN:  Macro variable X_2 resolves to           99

99

MLOGIC(TESTING):  %DO loop index variable IT is now 2; loop will not iterate again.

MLOGIC(TESTING):  Ending execution.

Indeed, SAS does the variable substitution before calling the %eval function The easiest solution is to call %eval in an earlier statement 实际上,SAS在调用%eval函数之前执行变量替换最简单的解决方案是在之前的语句中调用%eval

%let xNr = %eval(&it+1);
%put "&&x_&xNr";

The double ampersand serves to delay the evaluation of x_&xNr until &xNr is evaluated to 2 and not have the warning that x_ is undefined. 双&符号用于延迟x_&xNr计算,直到&xNr被计算为2并且没有x_未定义的警告。

SYMBOLGEN:  Macro variable IT resolves to 1
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable XNR resolves to 2
SYMBOLGEN:  Macro variable X_2 resolves to           99
"          99"

It is much easier to build the macro variable name into another variable and then expand the value. 将宏变量名称构建到另一个变量然后展开值要容易得多。

%let t2=found;
%let mvar=t%eval(1+1);
%put &&&mvar;

Agree with Dirk's answer. 同意Dirk的回答。 But as a thought exercise, it is possible to achieve the desired result with ugly use of quoting functions: 但作为一个思考练习,可以通过丑陋的引用函数来实现所需的结果:

%let x_2=99;
%let it=1;
%put %unquote(%nrstr(&x_)%eval(&it+1));

So %nrstr hides the & until after the %eval has done its work (I think. :) 所以%nrstr隐藏了&%直到%eval完成它的工作后(我想。:)

Update: 更新:

@Shenglin added a similar answer in a comment that I like better than my approach above: @Shenglin在评论中添加了一个类似的答案,我比上面的方法更喜欢:

%put %superq(x_%eval(&it+1));

This works because %superq() is unusual in taking a macro variable name as a parameter (no leading &), not a macro variable reference. 这是因为%superq()在将宏变量名称作为参数(无前导&)而不是宏变量引用时不常见。 So you can use %EVAL to generate part of the name of the macro variable. 因此,您可以使用%EVAL生成宏变量名称的一部分。 You could %unquote() if wanted, but it should not be necesssary. 如果需要,你可以%unquote(),但它不应该是必需的。

你能试试"&&x_%eval(&it+1)"吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM