SAS宏变量引号

SAS宏变量引号,sas,sas-macro,Sas,Sas Macro,我有一个宏变量 %let data =london paris; 实数变量是由sql语句生成的,并且会发生变化。我想要什么 要做的是创建一个新的宏变量datalist,如下所示: ('london' , 'paris') 我将在where statt中使用它(old是一个包含城市变量的表): 我试图用以下丑陋的方式创建此变量: %let data =london paris; %let datalist = (%str(%')%sysfunc(tranwrd(&data,%str(

我有一个宏变量

%let data =london paris;
实数变量是由sql语句生成的,并且会发生变化。我想要什么 要做的是创建一个新的宏变量datalist,如下所示:

('london' , 'paris')
我将在where statt中使用它(old是一个包含城市变量的表):

我试图用以下丑陋的方式创建此变量:

%let data =london paris;
%let datalist =  (%str(%')%sysfunc(tranwrd(&data,%str( ),%str(%' ,    %')))%str(%')); 
%put &datalist;
但当我运行此代码时,我收到以下错误消息:

10   %let data =london paris;
11   %let datalist =  (%str(%')%sysfunc(tranwrd(&data,%str( ),%str(%' , %')))%str(%'));
NOTE: Line generated by the macro function "SYSFUNC".
1    london' , 'paris
           -----
           49
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
             release.  Inserting white space between a quoted string and the succeeding
             identifier is recommended.
12   %put &datalist;
NOTE: Line generated by the macro variable "DATALIST".
1     ('london' , 'paris')
              -----
              49
('london' , 'paris')
NOTE 49-169: The meaning of an identifier after a quoted string might change in a future SAS
             release.  Inserting white space between a quoted string and the succeeding
             identifier is recommended.
真正奇怪的是,如果我在%unqote中输入,我可以使用这个变量:

data new;
   set old;
   where city in %unquote(&datalist);
run;
但我仍然有这个错误消息。是否有更好的方法将数组变量从更改为:

巴黎-伦敦->(“巴黎”、“伦敦”)

解决方案 昆汀提出的简单解决方案实际上解决了我的问题

where findw("&datalist",trim(city)) ;

但昆廷提出的宏也可以找到,但由于我的变量中没有空格(不是数据集中的城市,而是sas列名),这个简单的解决方案就足够了。

你的
%str
需要取消引用。我不会使用
翻译
或类似工具;相反,将其设置为宏并在单词上循环

%let data =Jane Alfred;

%macro quote_data(var=);

  %do i = 1 %to %sysfunc(countw(&var.));  %unquote(%str(%')%scan(&var.,&i.)%str(%'))
  %end;

%mend quote_data;

%let dataquote = %quote_data(var=&data.);
%put &=dataquote.;

proc sql;
select * from sashelp.class 
where name in (&dataquote.);
quit;

您需要将
%unquote
放在我做的地方或以后(例如在
%let
中或使用它时)。

您的
%str
需要取消引用,例如。我不会使用
翻译
或类似工具;相反,将其设置为宏并在单词上循环

%let data =Jane Alfred;

%macro quote_data(var=);

  %do i = 1 %to %sysfunc(countw(&var.));  %unquote(%str(%')%scan(&var.,&i.)%str(%'))
  %end;

%mend quote_data;

%let dataquote = %quote_data(var=&data.);
%put &=dataquote.;

proc sql;
select * from sashelp.class 
where name in (&dataquote.);
quit;

您需要将
%unquote
放在我之前或之后的位置(例如在
%let
中或使用它时)。

我非常喜欢Richard DeVenezia的%seplist实用程序宏:。我在我的个人库中对其进行了修改,以生成最后一条语句
%unquote(&emit)
,而不是
&emit
。 有了它,您可以编写以下代码:

where city IN (%seplist(&datalist,nest=Q)) ;
nest=Q
在列表中的每个项目周围添加单引号

也就是说,另一种选择是使用FINDW,这样您就不需要对每个项目进行报价,即:

where findw("&datalist",trim(city)) ;

我非常喜欢Richard DeVenezia的%seplist实用程序宏:。我在我的个人库中对其进行了修改,以生成最后一条语句
%unquote(&emit)
,而不是
&emit
。 有了它,您可以编写以下代码:

where city IN (%seplist(&datalist,nest=Q)) ;
nest=Q
在列表中的每个项目周围添加单引号

也就是说,另一种选择是使用FINDW,这样您就不需要对每个项目进行报价,即:

where findw("&datalist",trim(city)) ;

基于
TRANWRD()
函数使用此方法的最大问题是,需要确保空格分隔的列表在单词之间只有一个空格。但是,由于您是使用procsql生成它的,所以应该不会有问题。如果手动输入,则添加对
COMPBL()
的调用以清除源字符串

可以使用宏引用创建字符串,然后删除宏引用

%let data =london paris;
%let qlist=%qsysfunc(tranwrd(&data,%str( ),%bquote(',')));
%let qlist=(%unquote(%bquote('&qlist')));
或者可以使用双引号生成字符串,然后将双引号反转为单引号

%let data =london paris;
%let qlist=("%sysfunc(tranwrd(&data,%str( ),%bquote(",")))");
%let qlist=%sysfunc(translate(&qlist,'"',"'"));
当然,如果您没有将空格分隔的版本用于其他任何内容,那么只需直接在procsql中生成带引号的版本。您可以稍后添加
()

select quote(trim(city),"'") into :data separated by ',' ...
...
where city in (&data)
...

基于
TRANWRD()
函数使用此方法的最大问题是,需要确保空格分隔的列表在单词之间只有一个空格。但是,由于您是使用procsql生成它的,所以应该不会有问题。如果手动输入,则添加对
COMPBL()
的调用以清除源字符串

可以使用宏引用创建字符串,然后删除宏引用

%let data =london paris;
%let qlist=%qsysfunc(tranwrd(&data,%str( ),%bquote(',')));
%let qlist=(%unquote(%bquote('&qlist')));
或者可以使用双引号生成字符串,然后将双引号反转为单引号

%let data =london paris;
%let qlist=("%sysfunc(tranwrd(&data,%str( ),%bquote(",")))");
%let qlist=%sysfunc(translate(&qlist,'"',"'"));
当然,如果您没有将空格分隔的版本用于其他任何内容,那么只需直接在procsql中生成带引号的版本。您可以稍后添加
()

select quote(trim(city),"'") into :data separated by ',' ...
...
where city in (&data)
...

如果可以备份多个步骤,则可以在SQL中添加QUOTE()并用分隔符分隔,以便首先以这种方式创建宏变量。这是一个选项吗?
QUOTE
真的会这样做吗,或者它会使用
”(我假设这最终会进入一个passthrough SQL查询),也就是说,如果我对
QUOTE
的理解正确,当然可以使用
cats(“”,cityname,“”)
。您尝试过使用
%qsfunc()
?或者任何宏引用都会导致问题。Joe。这看起来不错。我会尝试一下,但需要阅读更多有关宏引用的内容,以了解整个问题。如果您可以备份几个步骤,可以添加引号()并在SQL中用分隔符分隔,以便首先以这种方式创建宏变量。这是一个选项吗?
QUOTE
实际会这样做吗,还是使用
?(我假设这是最终进入passthrough SQL查询的内容)也就是说,如果我对
quote
的理解正确,当然可以使用
cats(“”,cityname“”)
。您是否尝试使用
%Qsysfunc()
?或者任何宏引用都会导致问题。Joe。这看起来不错。我会尝试一下,但需要阅读更多关于宏引用的内容,以便理解整个问题。这个宏看起来非常有用。我会尽快试一试。我经常有这个问题。我有一个用proc sql和into生成的变量列表,但是需要一个SAS数组来与in一起使用。这个宏看起来非常有用。我会尽快试一试。我经常有这个问题。我有一个用proc-sql和into生成的变量列表,但需要一个SAS数组用于in。