Sas 连接引用的宏变量

Sas 连接引用的宏变量,sas,concatenation,sas-macro,Sas,Concatenation,Sas Macro,我只是想连接两个引用的宏变量,但似乎没有一个简单的方法 假设我们有: %LET VAR1="This is not the greatest song in the world"; %LET VAR2="this is just a tribute."; %LET TRIBUTE=%SYSFUNC(CATX(%STR( ),&VAR1,&VAR2)); %PUT &TRIBUTE; 我实际上想要: "This is not the greatest song in

我只是想连接两个引用的宏变量,但似乎没有一个简单的方法

假设我们有:

%LET VAR1="This is not the greatest song in the world";
%LET VAR2="this is just a tribute.";

%LET TRIBUTE=%SYSFUNC(CATX(%STR( ),&VAR1,&VAR2));
%PUT &TRIBUTE;
我实际上想要:

  "This is not the greatest song in the world this is just a tribute."
但上述代码实际上会产生:

"This is not the greatest song in the world"  "this is just a tribute."
因此,我尝试在
&VAR1
%VAR2
周围放置
%QUOTE()
%BQUOTE
等,希望能解开引号,但我得到了相同的结果

唯一适合我的是:

 %LET TRIBUTE="%SUBSTR(&VAR1.,2,%LENGTH(&VAR1.)-2) %SUBSTR(&VAR2.,2,%LENGTH(&VAR2.)-2)"; 
但这很难看,而且很快就会变得冗长。
难道没有更好的办法吗

您可以使用COMPRESS来完成此操作

%LET VAR1="This is not the greatest song in the world";
%LET VAR2="this is just a tribute.";


%let VAR3=%sysfunc(compress(&VAR1,%str(%")));
%put &=var1 &=var3;
删除引号有点棘手,但它是有效的

也可以在FCMP函数或函数样式宏中执行此操作;这里有一个例子

%macro unquote_string(string=);
%sysfunc(compress(&string.,%str(%'%")))
%mend unquote_string;

%let VAR3="%unquote_string(string=&var1.) %unquote_string(string=&var2.)";
%put &=var3.;
注意:不应使用CAT函数连接宏变量。它们只是文本,因此一个接一个地键入会自动连接它们


但是,对于“是否有更好的方法”的问题,真正的答案是不要将引号存储在宏变量中。大多数情况下,您应该使用引号存储宏变量,并在需要时在引号中使用它。SAS宏不把引号视为任何特殊的东西—它们只是字符串中的一个字符—因此它们没有处理这一问题的特定工具。

我将解释Joe的“真实答案”,即—不要在宏变量中存储引号。宏语言中的单引号和双引号与任何其他字符没有区别。你应该做的是推迟引用,直到你真正需要它们。这将产生更干净、更灵活、更易于阅读和无bug的代码

代码:

注意,我已经删除了引号,为了连接字符串,我只是一个接一个地列出它们:

%LET VAR1=This is not the greatest song in the world;
%LET VAR2=this is just a tribute.;
%LET TRIBUTE=&VAR1 &VAR2;
示例1

在第一个示例中,我们使用的是
%put
语句,因此打印所需字符串不需要引号-因此,我省略了引号:

%PUT &TRIBUTE;
输出:

This is not the greatest song in the world this is just a tribute.
This is not the greatest song in the world this is just a tribute.
示例2

报价是必需的,因为我们现在处于数据阶段:

data _null_;
  put "&TRIBUTE";
run;
输出:

This is not the greatest song in the world this is just a tribute.
This is not the greatest song in the world this is just a tribute.

请注意,这两个示例都假设您实际上不想在屏幕上打印引号。

有两件事。。。首先-我不知道
&=
语法-谢谢!其次,您可以将var3赋值简化为
%let var3=“%unquote_string(string=&var1&var2.)”。您完全可以通过这种方式简化它。不过,我更喜欢上面的内容,因为它更清楚地表明了您要从中删除引号,这有点类似于宏引用时
%UNQUOTE
的工作方式。(我认为如果这些是宏引用的MVAR,您必须调用它两次)。事实上,现在我想起来了,这是一个关于何时创建FCMP函数或宏函数的坏例子,因为您只是包装对现有函数的调用。。。。也可以直接调用函数。将其称为宏的原因是它不太混乱,并且您可以更容易地立即知道它在做什么(如果您正确地命名了函数/宏)<代码>%SYSFUNC(COMPRESS(&string.,%STR(%%“))
更长,需要一点心理处理才能了解它在做什么,而
%UNQUOTE\u string(&string.)
很明显它在做什么。这是真的。
%SYSFUNC()
就是这么一口。我通常倾向于更多的自我记录代码的方法。所以我会做一些事情,比如定义一个var
%let chars_to_remove=%STR(%“%”)
将%sysfunc调用简化为更可读的:
%let unquoted_string=%sysfunc(COMPRESS(&string.,&chars_to_remove))通常我会像你说的那样避免在宏变量中加引号。但是,我有两个通用宏,它们需要的参数可能包含逗号,也可能不包含逗号。如果不加引号,这可能会导致位置参数错误,因此作为一项规则,每当我编写这些宏时,为了安全起见,我都要求引用这些参数。但是,我可能想在宏或其他什么的主体中连接,这就是我的问题所在。处理逗号以避免您描述的问题的正确方法是使用
%bquote()
宏函数包装值。@Pane确实,引号字符不应用于此目的。