0

我有一段代码连接到远程服务器,将一些变量传递给它,然后查询服务器上的数据,然后对其进行操作。这段代码完全按照我的预期工作,产生了我需要的数据。

但是,我需要在宏循环中运行代码。这就是一切都崩溃的地方。我不确定问题是什么,但我怀疑这是某种变量范围问题。我试图在网上研究这样做,但无法弄清楚。

问题出现在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.

另请注意,我有时会收到与rtimeipriceoprice和类似的错误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 &yend;

            (...)
            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)

解决方案(根据乔的回答)

我能够使用乔发布的解决方案成功创建interval_secondsstart_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;
(...)
4

2 回答 2

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 &yend;
            signon;
            %syslput VAR1 = &var1;
            %syslput ystart=&ystart;
            %syslput yend=&yend;
            %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 &yend.;
            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 肯定存在一些问题,除了 %SYSLPUT 在您 rsubmit 之前我没有其他真正的答案(因此我的示例有效)。

您可以考虑将 RSUBMIT 代码移动到您执行的远程批处理程序中,而不是 RSUBMITting,或者甚至 %include - 也许会绕过它(即,在 RSUBMIT 中有一个 %include 指的是远程程序) .

看看这篇 SAS 文章,它为您提供了一些关于正在发生的事情的解释(基本上我所说的实际上就是这种情况)以及如何解决它。 SYSLPUT是第一个建议,并且使用其他解决方法%NRSTR也有可能。

于 2013-08-23T14:23:53.410 回答
1

代码看起来应该运行,但我尝试了类似的东西并且遇到了同样的问题。您创建本地宏,以便像 LET 这样的宏语句在本地执行。而 datastep 语句由远程 SAS 执行。解决方案是在远程会话中定义宏。

查看 where is 宏编译的效果如下:

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;
于 2013-08-23T14:32:34.953 回答