%复制到宏变量

时间:2018-04-24 09:14:58

标签: sas sas-macro

我想将宏源代码的内容存储到变量中,以便稍后对它进行一些正则表达式。

说我有以下宏功能:

%MACRO sleep
/*--------------------------------------
pauses for the desired amount of seconds
---------------------------------------*/ 
(sec
) / STORE SOURCE DES='pauses for the desired amount of seconds';
/* EXAMPLE:
%sleep(3);
*/
DATA _NULL_;
vVar1=SLEEP(%eval(&sec*1000));
RUN;
%mend;

我可以使用以下方式在日志中显示代码:

%copy sleep /source;

但我希望能够写下:

%let sleep_source = %get_source(sleep);

我的最终目标是能够提取示例(或测试)并执行以下操作:

%run_examples(sleep)
%run_tests(sleep)    # if I define tests in the function's body

3 个答案:

答案 0 :(得分:2)

使用OUTFILE=宏的%COPY选项。我的测试显示OUTFILE不喜欢成为SOURCE目录条目,因此本示例使用WORK libref文件夹中的外部文件。注意:%COPY会覆盖现有的OUTFILE。

libname mymacros 'c:\temp';
option mstored sasmstore=mymacros;

%MACRO sleep
/*--------------------------------------
pauses for the desired amount of seconds
---------------------------------------*/ 
(
  sec /* number of seconds to sleep */
) 
/ STORE SOURCE DES='pauses for the desired amount of seconds';
/* EXAMPLE:
%sleep(3);
*/
DATA _NULL_;
vVar1=SLEEP(%eval(&sec*1000));
RUN;
%mend;

filename extract "%sysfunc(pathname(work))\source-code.sas";

%copy sleep / outfile=extract source;

data _null_;
  infile extract;
  input;
  put _infile_;

  * do regex tests on the macros source code lines ;
  * ... ;
run;

%SLEEP:您可能并不总是希望宏创建具有步边界的代码。您可以转而%sysfunc(sleep(%eval(&sec)*1000))

答案 1 :(得分:1)

为什么不直接使用自动调用宏?然后,您可以创建一个指向您用于自动调用宏的路径的fileref。因此,很容易从包含它的实际文本文件中读取源代码。

filename mymacros '/path';
options sasautos=(mymacros);

data _null_;
  infile mymacros('sleep.sas');
  ...
run;

答案 2 :(得分:0)

我重写了理查德的答案,将其包装成一个宏并从中获取一个宏变量。

我并不完全满意,因为它会创建全局变量src_code和几个_temp_outi,而我无法使用我想要的语法,但它可以完成这项工作。< / p>

%macro get_source(mac, line_sep = \n);
%global src_code;
filename extract "%sysfunc(pathname(work))\temp-source-code.sas";
%copy &mac / outfile=extract source;

data _null_;
  infile extract;
  input;
  call symput('_temp_out'||strip(_n_), _infile_);
  call symput('last_n', _n_);
run;

%let src_code = %superq(_temp_out1);
%do i = 2 %to &last_n;
  %let curr_var = _temp_out&i;
  %let src_code = &src_code&line_sep.%superq(&curr_var);
%end;
%mend;

让我们测试一下:

%get_source(sleep) /* creates a src_code global variable containing the source code */   
%put %superq(src_code);

将打印到日志:

%MACRO sleep\n/*--------------------------------------\npauses for the desired amount of 
seconds\n---------------------------------------*/ \n(sec\n) / STORE SOURCE;\n/* EXAMPLE:\n%sleep(3);\n*/\nDATA 
_NULL_;\nvVar1=SLEEP(%eval(&sec*1000));\nRUN;\n%mend;