2015-08-16 113 views
0

我有一个关于解决SAS中宏变量的问题。我有以下代码,这是一个更大块的简化版本。出于实际原因,我无法更改代码的结构。解决SAS中的宏变量问题

%let a = x1 x2 x3; 
%let b = y1 y2 y3; 
%let c = a b; 


%macro test (input); 
    %local i; 
    %let string_c = %str(&input); 
    %do i=1 %to 2; 
     %put &%qscan(&string_c, &i); /* ? */ 
    %end; 
%mend test; 

%test(&c); 

在步骤?以上,我想解决A和B作为宏观变量和有系统打印出

x1 x2 x3 

然后

y1 y2 y3 

然而,上面的代码不reslove A和B作为宏观变量和系统打印出来

&a 
&b 

我想知道是否有解决这个问题的办法。

非常感谢!

回答

1

试试这个:

%let a = x1 x2 x3; 
%let b = y1 y2 y3; 
%let c = a b; 

%macro test (input); 
    %local i; 
    %let string_c =%str(&input); 
    %do i=1 %to 2; 
     %put %unquote(&&%qscan(&string_c, &i)); 
    %end; 
%mend test; 

%test(&c); 
+1

有趣的答案。你可以添加一些解释为什么这会起作用,特别是为什么%unquote()在这里很有用,即使你用%str()和%qscan()删除了引用。例如,它有助于这个简单的测试案例: %macro x; x%修补; %let x = 1; %put%unquote(&&%x); – Quentin

+0

谢谢Shenglin。它的工作原理!后续问题类似于Quentin的原因:) – frostman

+0

没有%unquote,SAS将a/b解释为文本加上&,而不是宏变量&a/&b,使用%unquote,强制将&和a/b粘合在一起并恢复值的正常标记。 –

0

该&触发器是解析一个名称,但您已经跟随另一个宏触发%而不是名称。所以它什么都不做。将名称分配给宏变量然后对其进行评估会更容易。

%macro test(list); 
    %local i varname value; 
    %do i=1 %to %sysfunc(countw(&list,%str())); 
    %let varname=%scan(&list,&i,%str()); 
    %let value=&&&varname ; 
    %put The value of "&varname" is "&value" ; 
    %end; 
%mend test; 
%let a=One ; 
%let b=Two ; 
%test(a b); 

导致:

The value of "a" is "One" 
The value of "b" is "Two" 
+0

谢谢你,汤姆。我的问题是,我必须保持代码的结构,以实用但不合理的理由:)。因此,我必须解决循环中的宏变量a和b。 – frostman

+0

那么这与我发布的例子有什么不同呢?它解决了宏变量A和B.如果您首先将列表中的名称解析为新的宏变量,然后使用&& mvar语法来解析MVAR中命名的变量的值,那么它就更容易管理。 – Tom

+0

谢谢,汤姆。是的,我同意,如果我们在宏中实际定义“a”和“b”,而不是从一开始就更容易管理。然而,由于现有的政策,我必须在一开始就定义a和b,所以我的手完全紧盯在我正在编写的代码中......万岁官僚主义:) – frostman