SAS-Can';在放入宏(远程服务器)时,无法使代码正常工作

SAS-Can';在放入宏(远程服务器)时,无法使代码正常工作,sas,Sas,我有一段代码连接到远程服务器,向它传递一些变量,然后查询服务器上的数据,然后对其进行操作。这段代码完全按照我的预期工作,生成了我需要的数据 但是,我需要在宏循环中运行代码。这就是一切崩溃的地方。我不确定问题是什么,但我怀疑这是某种可变范围的问题。我曾尝试在网上做过这方面的研究,但无法找到答案 问题出现在数据xtemp2块中。当我尝试运行此操作时,会出现以下错误: WARNING: Apparent symbolic reference INTERVAL_SECONDS not resolved.

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

但是,我需要在宏循环中运行代码。这就是一切崩溃的地方。我不确定问题是什么,但我怀疑这是某种可变范围的问题。我曾尝试在网上做过这方面的研究,但无法找到答案

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

还请注意,我有时会在
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 &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)
解决方案(根据Joe的回答)


我能够使用
%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;
(...)

我可以给你一个功能性的解决方案,但我还没有找到原因

基本上,%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肯定存在一些问题,除了在rsubmit之前%SYSLPUTting它之外,我没有其他真正的答案(因此我的示例可以工作)

您可以考虑将R提交代码移到您执行的远程批处理程序,而不是提交,甚至包括%-可能会绕过它(即RSUP里面有一个包含远程程序的%)。


看一看,它给了你一些关于发生了什么的解释(基本上我所说的就是事实),以及如何解决它
SYSLPUT
是第一个建议,使用其他解决方法,如
%NRSTR
也是可能的。

代码看起来应该运行,但我尝试过类似的方法,也遇到了同样的问题。 您可以创建本地宏,以便像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;

你展示的内容没有范围问题。在RSUBMIT内部,没有正在运行的宏,因此没有范围问题-它是一个全局变量。除非您没有告诉我们有关间隔秒的信息,否则我看不出为什么会发生这种情况。我要补充的是,这可能不是解决您整体问题的好办法。您可以在不使用宏循环的情况下解决问题,特别是不需要反复提交;这似乎可以通过正确构造更大的数据集和语句来解决,如果重复运行循环,效率可能会提高一到两个数量级。我这样循环的原因是我希望一次提取一小部分数据(其中“小”仍然是数百MB)。你能解释一下实际的错误是什么意思吗?是不是说这个变量是空的?不过你要拉几个小的子集。在一次拉动中同时拉动它们,给它们一个任意的编码变量(比如,
Pull=1;
),然后通过拉动执行您正在进行的任何分析。或者,如果您确实无法使用,甚至可以一次将所有数据向下拉,然后在需要之前在本地将其子集。无论哪种方式,都比宏循环中的一组rsubmit有效得多。(另外,您不需要
登录;
每个循环一次-如果您小心数据集名称和宏变量,整个程序只需登录一次即可。)哇,非常感谢。我现在来看看这个,如果我有更多的问题,我会回复你。再次感谢!在您链接的文章中,
SYSLPUT
解决方案是否与您在上述代码中演示的解决方案相同?这真的不起作用,对吧?我能够使用您发布的
%NRSTR
解决方案成功地创建
间隔秒
开始时间
变量。然而,现在我有一个与“itime”有关的不同问题。看起来好像从未创建过变量。我在我原来的帖子里写了更多的细节…哇,你完全正确。我刚换了,效果很好!非常感谢!通常,根据您试图开发的内容,您首先应该确定的是,您实际上是在为服务器(远程会话)编码,还是为在远程服务器上运行某些任务的本地SAS编码。在99%的情况下,我使用本地SAS作为编辑器,编写并运行服务器的所有代码。为此,我将F12键定义为“rsubmit”,并通过F12键(而不是F8键)运行所有代码。因此,我不需要编写RSUBMIT和endrsubmit。按F9键查看关键定义。我会将该注释添加到答案中,这是一个比其他答案更完整的答案;)
rsubmit;
    %macro remote_macro;
        %put %sysget(COMPUTERNAME);
    %mend;
endrsubmit;

rsubmit;
%remote_macro
;
endrsubmit;