【问题标题】:Passing special characters (ampersand, hyphen) in a SAS macro call在 SAS 宏调用中传递特殊字符(和号、连字符)
【发布时间】:2021-06-11 16:31:50
【问题描述】:

我正在使用 SAS 宏来执行一个函数,其中一个输入参数来自 SAS 数据表,第二个参数(日期)是硬编码的,像这样-

data _null_;
  set RTick.Co_list;
  call execute('%trade_participation(01012013,'|| scrip10 ||');');
run ;

宏如下-

%macro trade_participation(date,scrip10);

data Trade_data (drop = time Record_ind segment series trade_no symbol trd_prc trd_q trade_time
buy_order_no buy_client_flg buy_algo_ind sell_order_no sell_client_flg sell_algo_ind);
    set Rttrade.Cash_trades_&date;

    if symbol = "&scrip10"; 
    if Record_ind = "RM";
    if segment = "CASH";
    if series = "EQ";
    time = trade_time/65536;
    time = time/3600;
    timeseqno = int((time-9)*60)+1;
    if timeseqno > 15;      
    if (buy_client_flg = 2)&((buy_algo_ind = 0)|(buy_algo_ind = 2)) = 1 then buy_HFT = 1;
    if (sell_client_flg = 2)&((sell_algo_ind = 0)|(sell_algo_ind = 2)) = 1 then sell_HFT = 1;
    trade_val = trd_prc*trd_q/100;
run;

/* more SAS code to do a bunch of other tasks to do on the subsetted 
file Trade_data */

%修补;

我现在面临的问题是 Co_list 文件(scrip10 变量)中的某些输入值具有特殊字符,例如“bbbbbbM&M”或“BAJAJ-AUTO”。一旦这些通过宏,它就会失败 - “未解析明显的符号引用 M。” (对于第一个例子-bbbbbbM&M')

任何人都可以提出解决方法吗?

【问题讨论】:

    标签: sas sas-macro


    【解决方案1】:

    在您的特定情况下,为什么不将实际引号包含在宏参数值中,而不是将它们添加到宏中?

    所以改变宏定义:

    if symbol = &scrip10 ; 
    

    然后在代码生成步骤中添加引号。使用单引号,任何 & 或 % 字符都将被宏处理器忽略。

    call execute(cats('%nrstr(%trade_participation)(01012013,',quote(scrip10,"'"),')'));
    

    将宏调用 %trade_participation 包装在 %nrstr() 宏函数内将使您的 SAS 日志更易于阅读。示例:

    +     %trade_participation(01012013,'bbbbbbM&M')
    +     %trade_participation(01012013,'BAJAJ-AUTO')
    

    【讨论】:

      【解决方案2】:

      如果您要执行宏引用路由,则必须两次 %nrstr - 因为它被“解决”了两次,一次是在 call execute 执行它的操作时,一次是在宏内。

      data have;
        input @1 callparam $10.;
        datalines;
      abcdefghij
      a&bc&de&fg
      a%bc%de%fg
      ;;;;
      run;
      
      %macro showme(param=);
         data _null_;
          x = "&param";
          put x=;
         run;
      %mend showme;
      
      options mprint symbolgen;
      data want;
        set have;
        paramstr = cats('%nrstr(',callparam,')');
        callstr = cats('%nrstr(%showme(param=',paramstr,'))');
        call execute(callstr);
      run;
      

      适用于一种特殊情况,但是:变量内的引号。这必须通过将它们加倍(' -> '')或其他一些选项(例如 %quote 块内的 %')来解决。

      一般来说,这不是一个很好的做事方式。这是参数和宏语言的缺点——太容易陷入混乱。相反,如果我这样做,我可能会从宏内部的数据中提取值。这避免了大多数这些问题。创建一个格式,也许。或者使用DOSUBL 和/或RUN_MACRO 两者都可以让您在没有那么多步骤的情况下执行此操作。或者一次性完成所有这些操作,不要尝试为每个符号拆分它。有很多方法可以避免使用宏语言——这往往会被过度使用——而且通常更快!

      【讨论】:

        猜你喜欢
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-31
        • 2012-09-07
        • 1970-01-01
        • 1970-01-01
        • 2013-10-22
        相关资源
        最近更新 更多