我有一段连接到远程服务器的代码,将一些变量传递给它,然后在服务器上查询数据然后对其进行操作。这段代码完全按照我的预期运行,生成我需要的数据。
但是,我需要在宏循环中运行代码。这就是全部崩溃的地方。我不确定是什么问题,但我怀疑它是某种可变范围问题。我试图在网上做这个研究,但无法搞清楚。
问题出现在data xtemp2
块中。当我尝试运行它时,我收到以下错误:
WARNING: Apparent symbolic reference INTERVAL_SECONDS not resolved.
ERROR 22-322: Syntax error, expecting one of the following: a name,
a quoted string, a numeric constant, a datetime constant,
a missing value, INPUT, PUT.
和
WARNING: Apparent symbolic reference START_TIME not resolved.
ERROR 22-322: Syntax error, expecting one of the following: a name,
a quoted string, a numeric constant, a datetime constant,
a missing value, INPUT, PUT.
另请注意,我有时会因rtime
,iprice
,oprice
和itime
而遇到类似错误。再一次,当我自己运行它时,这段代码非常有效。将它放入带循环的宏中似乎会产生这些问题,这让我觉得我没有正确地初始化这些变量。我非常感谢您提供的任何见解和提示。
%macro getthedata(nrows,ystart,yend); *nrows is the number of rows in the text file;
%do i=1 %to &nrows;
%do m=&ystart %to ¥d;
(...)
signon username=_prompt_;
%syslput VAR1 = &var1;
%syslput M = &m;
rsubmit;
libname abc'/data/sasdata'; *Thisis where the datasets are located;
%let start_time = '9:30:00't; * starting time;
%let interval_seconds =15*60; * interval is 15*60 seconds, 15min;
data all2009;
set sas.a_&M.01:;
by symbol date time;
where symbol = &VAR1 and time between '9:30:00't and '16:00:00't;
run;
data xtemp2;
set all2009;
by symbol date time;
format itime rtime time12.;
if first.symbol=1 or first.date=1 then do;
*Initialize time and price when new symbol or date starts;
rtime=time;
iprice=bid;
oprice=ofr;
itime=&start_time;
end;
if time >= itime then do; *Intervalreached;
output; *rtime and iprice hold the last observation values;
itime = itime +&interval_seconds;
do while(time >= itime); *need to fill in alltime intervals;
output;
itime = itime +&interval_seconds;
end;
end;
rtime=time;
iprice=bid;
oprice=ofr;
retain itime rtime iprice oprice; *Carry time and price valuesforward;
*keep symbol date itime iprice rtime;
run;
proc download data=all2009 out=local.all30 (keep=SYMBOL DATE PRICE SIZE itime);
run;
endrsubmit;
(...)
%end;
%end;
%mend getthedata;
Options MPRINT;
%getthedata(3,2007,2007)
解决方案(根据Joe的答案)
我能够使用Joe发布的interval_seconds
解决方案成功创建start_time
和%NRSTR
变量。
以下是相关的修改代码部分:
(...)
signon username=_prompt_;
%syslput VAR1 = &var1;
%syslput M = &m;
rsubmit;
libname abc'/data/sasdata'; *Thisis where the datasets are located;
%nrstr(%%)let start_time = '9:30:00't; * CHANGED LINE;
%nrstr(%%)let interval_seconds =15*60; * CHANGED LINE;
data all2009;
set sas.a_&M.01:;
by symbol date time;
where symbol = &VAR1 and time between '9:30:00't and '16:00:00't;
run;
(...)
答案 0 :(得分:1)
我可以给你一个功能性的解决方案,但我还没弄明白这个问题。
基本上,%let语句(和%put语句)被忽略。它们没有被传下来 - 实际上它们是在本地机器上执行的。见:
%let var1="Region1";
signon;
libname uwork slibref=work server=unix;
data uwork.pricedata;
set sashelp.pricedata;
run;
%macro getthedata(nrows,ystart,yend); *nrows is the number of rows in the text file;
%do i=1 %to &nrows;
%do m=&ystart %to ¥d;
signon;
%syslput VAR1 = &var1;
%syslput ystart=&ystart;
%syslput yend=¥d;
%syslput start_time='01JAN1998'd;
%syslput interval_seconds=30;
rsubmit;
%*libname abc '/data/sasdata'; *Thisis where the datasets are located;
%let start_time = '01JAN1998'd; * starting time; *these are ignored by the rsubmit - why?;
%let interval_seconds =30; * interval is 15*60 seconds, 15min;
%put &start_time &interval_seconds;
data all2009;
set work.pricedata;
by date;
where year(date) ge &ystart. and year(date) le ¥d.;
run;
data xtemp2;
set all2009;
by date;
format itime rtime time12.;
if first.date=1 then do;
*Initialize time and price when new symbol or date starts;
rtime=date;
iprice=price;
oprice=cost;
itime=&start_time;
end;
if date >= itime then do; *Intervalreached;
output; *rtime and iprice hold the last observation values;
itime = itime +&interval_seconds;
do while(date >= itime); *need to fill in alltime intervals;
output;
itime = itime +&interval_seconds;
end;
end;
rtime=date;
iprice=price;
oprice=discount;
retain itime rtime iprice oprice; *Carry time and price valuesforward;
*keep symbol date itime iprice rtime;
run;
/*proc download data=all2009 out=local.all30 (keep=SYMBOL DATE PRICE SIZE itime);
run;
*/
endrsubmit;
%put &start_time &interval_seconds;
%end;
%end;
%mend getthedata;
Options MPRINT;
%getthedata(3,1998,1998)
请注意,在endrsubmit之后的末尾的%put语句实际上是有效的 - 即使它不应该(宏变量不应该在本地机器上定义)。在具有宏变量的宏内部,RSUBMIT必定存在一些问题,除了在提交之前%SYSLPUTting之外,我没有真正的答案(因此为什么我的示例有效)。
您可以考虑将RSUBMIT代码移动到您执行的远程批处理程序,而不是RSUBMITting,或者甚至是%include - 可能会绕过它(即,在RSUBMIT内部有一个%include,指的是远程程序)。
看一下this SAS article,它会给你一些解释正在发生的事情(基本上就是我所说的实际情况)以及如何解决它。 SYSLPUT
是第一个建议,使用%NRSTR
之类的其他解决方法也是可能的。
答案 1 :(得分:1)
代码看起来应该运行,但我尝试了类似的东西并遇到了同样的问题。 您创建本地宏,以便像LET这样的宏语句在本地执行。虽然datastep语句由远程SAS执行。 解决方案是在远程会话中定义宏。
请参见以下宏编译的效果:
1)本地宏:
%macro local_macro;
rsubmit;
%put %sysget(COMPUTERNAME);
endrsubmit;
%mend;
%local_macro
2)远程宏
rsubmit;
%macro remote_macro;
%put %sysget(COMPUTERNAME);
%mend;
endrsubmit;
rsubmit;
%remote_macro
;
endrsubmit;