【问题标题】:SAS Define a Macro on a Unix ServerSAS 在 Unix 服务器上定义宏
【发布时间】:2019-02-03 06:27:23
【问题描述】:

您好,我正在尝试在 Unix 服务器上定义和运行 SAS 宏。

options symbolgen mprint mlogic;
*options nosymbolgen nomprint nomlogic;

rsubmit;

%let trend_MM = 1;
%let run_date = &sysdate.;

/* loop through Trend_MM number of times to retrieve the MTR completed per each month. */
%macro Trend();
%local start_dt;
%local end_dt;
%local i;

/* loop through each month */
%do i = &Trend_MM. %to 0 %by -1;

/* Calculate set start/end dates to start/end of month */
%let start_dt = %qsysfunc(intnx(month,"&run_date."d,%eval(-1*&i.),b),date9.);
%let end_dt = %qsysfunc(intnx(month,"&run_date."d,%eval(-1*&i).,e),date9.);

    /* select MTR claims in month */
    proc sql;
        create table MTR_&i. as
        select a.claim_id_360
              ,a.claim_id_external 
              ,a.timestamp
              /* v02: a) export date part of the timestamp */
              ,datepart(a.timestamp) as timestamp_dt
              ,a.status_data 
              ,a.status_label 
              ,a.RFE_template_name 
              ,a.brand_name
              ,case when b.claim_id_360 is not missing then "Y" else "N" end as MTR_compl
              ,c.MTR_count
              ,b.last_MTR_comp format = ddmmyy10.
        from 
            /* Base population are all claims where final status is not   */
            (
             select distinct *
             from allg360r._travel_rfe_state_change_hist
             (keep = claim_id_360 claim_id_external timestamp status_data status_label RFE_template_name brand_name)
             where datepart(timestamp) between "&start_dt."d and "&end_dt."d
             group by claim_id_360 
             having timestamp = max(timestamp) and strip(upcase(status_label)) ne "Move to Review"
            ) a

            left join 
        /*     subset with claims that have had a  status in the reference period to obtain  */
        /*     claims that have had such status completed in the period.                                     */
        /*     Also retrieve date of last MTR completed                                                      */
            (
             select distinct claim_id_360, datepart(timestamp) as last_MTR_comp
             from allg360r._travel_rfe_state_change_hist
             (keep = claim_id_360 claim_id_external timestamp status_data status_label RFE_template_name brand_name)
             where (datepart(timestamp) between "&start_dt."d and "&end_dt."d) and status_label = "Move to Review"
             group by claim_id_360
             having timestamp = max(timestamp)
            ) b
            on a.claim_id_360 = b.claim_id_360

            left join 

        /*   Add count of how many since inception of claim  */
        /* v02: b) count how many times in MTR since beginning */
            (
             select distinct
                    claim_id_360
                   ,count(claim_id_360) as MTR_count
             from allg360r._travel_rfe_state_change_hist
             (keep = claim_id_360 claim_id_external timestamp status_data status_label RFE_template_name brand_name)
             where status_label = "Move to Review"
             group by claim_id_360
            ) C
            on a.claim_id_360 = c.claim_id_360
        ;
        quit;

    /* create/append to dataset of all months */

    %if &i. = &trend_MM. %then 
      %do;
        proc sql;
            drop table work.MTR;
            create table work.MTR like work.MTR_&i.;
        quit;
      %end;

    proc append base = work.MTR data = work.MTR_&i.;
    run;
%end;

%mend Trend;

%trend

endrsubmit;

它似乎工作正常,但我在日志中不断收到此错误:

995 结束提交; ---------- 180

ERROR 180-322:语句无效或使用不当 顺序。

如果我在宏调用后加上分号,错误似乎消失了。这对我来说没有意义,因为宏以运行结束;并在调用后加上分号不应该有任何区别。

任何想法为什么会发生这种情况?

【问题讨论】:

  • 没有线索。可能是远程提交和宏工具之间的相互作用,但我无法解释。最简单的方法是添加 ; 并继续。
  • 我还鼓励使用分号来终止仅包含单个宏调用的行。它使其他人更容易阅读代码 - 就像在每个句子的末尾加上句号
  • 日志错误之类的文本图像无法搜索,也无法访问。请edit问题并将图像替换为错误文本并将其格式化为引用。要将格式设置为引用,您可以在文本前放置>。要保留行尾,您可以在引号中的行尾放置两个空格。

标签: unix server macros sas


【解决方案1】:

信不信由你,因为您使用空参数列表定义了宏:

%macro Trend();
  %put TREND running;
%mend trend;

当您尝试调用像 %trend 这样的宏时,SAS 期望您向它发送参数列表,即使是一个空列表也足够了。所以宏调用还没有结束。分号将结束宏调用,但你是对的,它不是必需的,添加额外的分号是一个坏习惯。当您调用定义了参数列表的宏时(即使在这种情况下,有 0 个参数,括号在宏定义上,因此在某种意义上仍然定义了列表),您可以像 %trend() 一样调用它。括号结束宏调用。

使用 PC SAS,您可以通过突出显示 %trend 并提交它来很好地测试它。宏不会运行。然后如果你提交(),宏就会运行。

更新: 由于更正宏调用不起作用,我怀疑这可能是文字扫描仪识别 endrsubmit 语句的错误。假设它是可复制的,我可能会添加一个提供分号的注释。至少这样清楚分号不是结束宏调用的一部分。抱歉,我无法测试,因为没有可用的 SAS/connect。

类似:

* endrsubmit needs a semicolon before it ??? ;
endrsubmit ;

【讨论】:

  • 嗨@Quentin,我尝试在调用后添加括号,但我给了我同样的错误。它似乎运行正确,结果很好,但我在日志中不断收到此错误。
  • 我现在可能会这样做。谢谢!
【解决方案2】:

原因是 - 你用括号 () 定义了你的宏

在调用中添加一些括号,它将在没有分号的情况下执行。

%trend()

【讨论】:

  • 嗨@allan,宏确实执行但最后出错。我尝试在调用后添加括号,但没有任何区别。我得到同样的错误。
猜你喜欢
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2011-08-17
相关资源
最近更新 更多