我想将宏源代码的内容存储到变量中,以便稍后对它进行一些正则表达式。
说我有以下宏功能:
%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
答案 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;