【发布时间】:2015-08-05 23:05:12
【问题描述】:
所以,我想要一个包含其他宏的宏。
代码如下:`
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;
我的代码(仅取决于 &sus)/
%END;
%MEND;
%CICLO_PF_SUS_CSRANK;
%end;
%mend;
%ciclo_first;`
我认为主要的问题在于这部分:
%put lsus&ref=&lsus&ref;
%put nrsus&ref=&nrsus&ref;
关于那个的错误是:
在 %EVAL 函数或 %IF 条件中找到一个字符操作数 其中需要数字操作数。条件是: &nrsus&参考
我怎样才能改变它才能工作?我知道依赖两个的东西是没有意义的,比如&nrsus&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;
我想获取work.5pct_&ref 的“recetor”列上的元素。
对于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 工作正常,只要我用 id 替换 &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;
[更新 10.08.2015]
好的,只需阅读建议的答案并进行处理。
我有一个列表,其中包含 100 个客户的标识(数字),让我们调用每个客户:ref。那是在 WORK.AMOSTRACHU 上。
我编写了以下代码并且它有效,并将帮助我向您解释我想要什么:
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;
将显示前 3 个案例的输出(共 100 个,work.amostrachu 中的起始列表),它是 SAS 中的结果部分:
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
所以,我有数据 work.e5pct_id&ref 的“recetor”列的“值”以及每个 ref 有多少个值。 (我已经向您展示了前 3 个裁判的结果,但我有 100 个)。
现在,第一个宏:
%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;
我对 & 和 && 的所有疑问都在这里。
所以,有了数据:我有我的第一个 ref,其“recetor”列的结果是
Recetor
507
723
955
-page break-
3
所以,我想为每个值运行该代码。首先是“507”,然后是“723”,然后是“955”,我想对所有裁判都这样做。
因此,当宏完成运行我的这 3 的代码时,我希望宏跳到第二个参考,然后运行我的代码以获取第二个参考的“recetor”列的值:380,500,675,977 和 984。
我使用了这个代码:
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;
因为每个 ref 都有不同的值,并且它们的数量可能不同,就像我向您展示的那样。所以,这要告诉宏运行它nre&ref 次以及列表中的所有值listae&ref。
错误如下:
错误:在 %EVAL 函数或 %IF 中找到字符操作数 需要数字操作数的条件。条件是: nre&ref 错误:%DO T 循环的 %TO 值无效。错误:宏 CICLO_M_PF_REF 将停止执行。
【问题讨论】:
-
您通常不会嵌套宏。我很难跟上,你能提供示例数据和预期输出吗?
-
首先我有一个包含 100 个客户的列表。我想在他们身上运行 %MACRO CICLO_PF_SUS&ref。然后,在这个宏(100 个表)的输出上,我用一些查询运行另一个宏。这两个宏在“大宏”之外可以正常工作。
-
同意 Reeza。嵌套宏定义是个坏主意。嵌套宏调用很好。要解决您的错误消息,请尝试 &&nrsus&ref 和 &&lsus&ref。
-
您有
%do ... ;语句错过了%end;和%macro ... ;语句错过了%mend;。如果你解决了这个问题并正确缩进你的代码,如果你仍然有错误,我会看看。 -
Dirk Horsten,实际上它们并没有丢失,我只是忘记粘贴宏的结尾部分。我会更新这个问题,试图更好地解释我想要什么,并欢迎关于如何解决这个问题的新想法。