所以,我想要一个内部有其他宏的宏。
这是代码:`
proc sql NOPRINT ;
select id into :l_id separated by ' ' from work.AMOSTRACHU;
select count(*) into :nr_reg separated by ' ' from tdata.work.AMOSTRACHU;
quit;
* check;
%put l_id=&l_id nr_reg=&nr_reg;
%macro ciclo_first();
%do n=1 %to &nr_reg;
%let ref=%scan(&l_id,&n);
%put ref=&ref;
proc sql;
select recetor into : lsus&ref separated by ' ' from tdata.5pct_&ref;
select count(*) into :nrsus&ref separated by ' ' from tdata.5pct_&ref;
quit;
%put lsus&ref=&lsus&ref;
%put nrsus&ref=&nrsus&ref;
%MACRO CICLO_PF_SUSref();
%do n=1 %to &nrsus&ref %by 1;
%let sus=%scan(&lsus&ref,&n);
%put sus=&sus;
%LET I = %EVAL(14);
%DO %WHILE (&I<=24);
*my code (depends on &i and &sus)* (works fine alone)
%LET I = %EVAL(&I+1);
%END;
%END;
%MEND;
%CICLO_PF_SUSref;
%MACRO CICLO_PF_SUS_CSRANK();
%do n=1 %to &nrsus&refm %by 1;
%let sus=%scan(&lsus&ref,&n);
%put sus=&sus;
%CICLO_PF_SUSPEITOSrefmsisdn;
%CICLO_PF_SUS_CSRANK;
我的代码(仅取决于&amp; sus) /
%END;
%MEND;
%CICLO_PF_SUS_CSRANK;
%end;
%mend;
%ciclo_first;`
我认为主要问题在于这一部分:
%put lsus&ref=&lsus&ref;
%put nrsus&ref=&nrsus&ref;
关于这个的错误是:
在%EVAL函数或%IF条件中找到了字符操作数 其中需要数字操作数。条件是: &安培; nrsus&安培; REF
我怎样才能改变这个以便工作?据我所知,依赖于两个东西并不是很有意义,例如&amp; nrsus&amp; ref。
此处出现第一个警告和错误:
ref=15
WARNING: Apparent symbolic reference LSUS not resolved.
lsus15=&lsus15 WARNING: Apparent symbolic
reference NRSUS not resolved.
nrsus15=&nrsus15 ERROR: Expected semicolon not
found. The macro will not be compiled.
我该如何解决这个问题?没有想法,为了避免这次运行100次,使这个宏起作用真的很有用。
更新[06.08.2015]
我有一个包含100个数字的表,就在
中'work.amostrachu'。
我创建了宏ciclo_first
,以便为此列表运行其他2个宏。因为,如果我用我想要的数字手动替换&ref
它可以正常工作。
我们假设'work.amostrachu'有:
ID 1 2 3(...)直到n = 100
然后,用这部分:
proc sql;
select recetor into : lsus&ref separated by ' ' from work.5pct_&ref;
select count(*) into :nrsus&ref separated by ' ' from work.5pct_&ref;
quit;
我想获取 对于 然后, 然后,前一个宏的输出将是这一个的输入: 如果我只是用id替换 所以,我想要的东西允许我为我在开头得到的列表运行这两个宏( [更新10.08.2015] 好的,只需阅读建议的答案并进行处理。 我有一个列表,带有100个客户的标识(数字),让我们调用每个客户端:ref。这是在WORK.AMOSTRACHU。 我想了下面的代码并且它有效,并且会帮助我解释你想要的东西: 将显示前3个案例的输出(100个,work.amostrachu中的开始列表),这是SAS的结果部分: 所以,我有数据work.e5pct_id&amp; ref的列'recetor'的'值'以及每个ref有多少值。 (我已经向你展示了前3个参考的结果,但我已经为100了。) 现在,第一个宏: 我对&amp; amp;和&amp;&amp;在这附近。 所以,对于数据:我有我的第一个参考,其中'recetor'列的结果是 所以,我想为每个值运行该代码。首先是“507”,然后是“723”,然后是“955”,我想为所有裁判做到这一点。 因此,当宏完成运行我的代码3时,我希望宏跳转到第二个引用然后运行我的代码以获取第二个引用的列'recetor'的值:380,500,675,977和984。 我使用了这段代码: 因为每个裁判都有不同的值,而且它们的数量可能不同,就像我给你看的那样。所以,这要告诉宏运行它 错误如下: 错误:在%EVAL函数或%IF中找到了字符操作数
条件,其中需要数字操作数。条件是:
nre&amp; ref错误:%DO T循环的%TO值无效。错误:宏CICLO_M_PF_REF将停止执行。work.5pct_&ref
列ID=1
,我会获得lsus1
,例如,3个数字(124,564,859)%MACRO CICLO_PF_SUSref();
将输入这3个数字(可能是4或5或其他)。
(在这里,我可能会错误地称呼我想要的元素列表来自'work.5pct_&ref
)。%MACRO CICLO_PF_SUS_CSRANK
。
这就是全部。 %MACRO CICLO_PF_SUSref()
,%MACRO CICLO_PF_SUS_CSRANK
和&ref
就可以了。这就是为什么我试图创建一个宏来运行这两个宏的初始列表。如果你有最好的想法,我会很感激。%MACRO CICLO_PF_SUSref()
和`%MACRO CICLO_PF_SUS_CSRANK): proc sql NOPRINT ;
select id into :l_id separated by ' ' from work.AMOSTRACHU;
select count(*) into :nr_reg separated by ' ' from tdata.work.AMOSTRACHU;
quit;
proc sql NOPRINT ;
select id into :l_id separated by ' ' from work.AMOSTRACHU;
select count(*) into :nr_reg separated by ' ' from work.AMOSTRACHU;
quit;
* check;
%put l_id=&l_id nr_reg=&nr_reg;
%macro lista_ent();
%do n=1 %to &nr_reg;
%put n=&n;
%let ref=%scan(&l_id,&n);
%put ref=&ref;
proc sql;
select recetor into :listae&ref SEPARATED BY ' ' from work.e5pct_id&ref;
select count(*) into :nre&ref separated by ' ' from work.e5pct_id&ref;
quit;
%end;
%mend;
%lista_ent;
Recetor
507
723
955
-page break-
3
-page break-
380
500
675
977
984
-page break-
5
-page break-
200
225
351
488
698
781
927
-page break-
7
%MACRO CICLO_M_PF_ref();
%local me n i;
%do n=1 %to nre&ref %by 1;
%let me=%scan(listae&ref,&n);
%put me=&me;
%LET I = %EVAL(14);
%DO %WHILE (&I<=24);
proc sql;
create table work.smthng_&I as
select * from
work.wtv&I
WHERE A=&me OR B=&me;RUN;
PROC APPEND
DATA=work.smthng_&I
BASE=work.pf_&me
FORCE;
RUN;
%LET I = %EVAL(&I+1);
%END;
%END;
%MEND;
%CICLO_M_PF_ref;
Recetor
507
723
955
-page break-
3
proc sql;
select recetor into :listae&ref SEPARATED BY ' ' from work.e5pct_id&ref;
select count(*) into :nre&ref separated by ' ' from work.e5pct_id&ref;
quit;
nre&ref
次以及列表listae&ref
中的所有值。
答案 0 :(得分:0)
我无法完全遵循您想要的输出和宏,但这里有一些我注意到的事情。
我想你想要这样的东西:
%macro def1(param1);
...
%mend;
%macro def2(param2);
...
%mend;
%macro execute();
%do i=1 to 100;
%def1(param1);
%def2(param2);
%end;
%mend;
这似乎有点尴尬,所以如果你能用你的数据来解释你的过程,那么整体可能会有更好的方法。
答案 1 :(得分:0)
我发现您可以解决许多问题,但如果没有测试数据则很难评估。
您的实际嵌套宏没有多大意义。引入的这个变量是什么?它似乎是一个常数。
为什么不将它们编码为外部宏的一部分?如果仅在一个地方调用它们,则不需要使它们成为单独的宏。
首先定义子程序宏。
%MACRO CICLO_PF_SUSref(ref_list);
* CICLO_PF_SUSref ;
%local n sus;
%do n=1 %to %sysfunc(countw(&ref_list,%str( )));
%let sus=%scan(&ref_list,&n);
%put NOTE: &sysmacroname N=&n SUS=&sus;
%end;
%MEND CICLO_PF_SUSref;
%MACRO CICLO_PF_SUS_CSRANK(ref_list);
* CICLO_PF_SUS_CSRANK ;
%local n sus ;
%do n=1 %to %sysfunc(countw(&ref_list,%str( )));
%let sus=%scan(&ref_list,&n);
%put NOTE: &sysmacroname N=&n SUS=&sus;
%put NOTE: Call macro named: CICLO_PF_SUSPEITOSrefmsisdn;
%end;
%MEND CICLO_PF_SUS_CSRANK;
然后你的主宏。
%macro ciclo_first(id_list);
* Start ciclo_first ;
%local n id ;
%do n=1 %to %sysfunc(countw(&id_list,%str( )));
%let id=%scan(&id_list,&n);
proc sql noprint;
select recetor into : lsus&id separated by ' ' from pct_&id;
%let nrsus&id = &sqlobs ;
quit;
%put NOTE: Current ID=&id ;
%put NOTE: &&nrsus&id records read from PCT_&ID ;
%put NOTE: Value List LSUS&id = &&LSUS&id ;
%CICLO_PF_SUSref(&&lsus&id);
%CICLO_PF_SUS_CSRANK(&&lsus&id);
%end;
* End ciclo_first ;
%mend ciclo_first;
然后设置一些数据并调用主宏。
* Setup test data ;
data AMOSTRACHU;
do id=1 to 2; output; end;
run;
data PCT_1 ;
do recetor='A','B';
output;
end;
run;
data PCT_2 ;
do recetor='C','D';
output;
end;
run;
options mprint;
%ciclo_first(1 2);