获取宏变量列表中的第 i 个单词

Get the ith word in a macro variable list

%let TableList = TableA TableH TableB TableG;

&TableList 中的单词由 ' ' 分隔。

我如何检索特定的单词来执行以下操作?

我不知道 tablelist 中的单词数,想从列表中获取第 n 个单词。

给定 i = 4,

data &&table&i.; /* &&table&i. will resolve to TableG */
set have;
[..];
run;

简短的回答是使用 %scan 函数:

%put %scan(&tablelist,4,%str( ));

第三个参数指定 %scan 应仅将空格计为分隔符。否则,它也会默认将以下所有字符视为分隔符:

. < ( + & ! $ * ) ; ^ - / , % |

鉴于您拥有的列表,您可以使用 %do 循环将宏变量添加到列表中:

/* initialise a counter macro variable */
%let k = 1;

/* iterate through tablelist until a value is not found */
%do %until (%scan(&tablelist,&k,%str( )) = );
  %let table&k = %scan(&tablelist,&k,%str( )); 
  %let k = &k + 1;
%end;

%let i = 4;
%put &&table&i;

N.B。此代码仅适用于宏定义(即由 %macro%mend 语句分隔的代码块。

我会使用与@mjsqu 相同的 %sysfunc(scan) 技巧来回答您剩下的问题 - 获取最后一个词,因为您不知道列表中的词数,这是最简单的方法我能想到的是像下面这样使用 array

%let all=word1 word2 word3 word4 word5;

%macro test;
data _NULL_;
array x[*] &all.;
Num=dim(x);
call symput("Num_of_words",num);
run;
%mend;
%test;

现在你知道了总字数,所以也可以找出最后一个字了。

如果您这样做是为了从列表中快速选择一个词,您应该只制作一个宏,而不是尝试设置宏变量。与单行宏相比,要完成所有这些业务需要做太多额外的工作来制作各种宏变量。

%let tableList=TableA TableB TableC TableD;

%macro selectTable(k=);
  %scan(&tablelist,&k)
%mend selectTable;

data %selectTable(k=4);
  set sashelp.class;
run;