【问题标题】:SAS Proc Format Executing Without All Datetime DirectivesSAS Proc 格式在没有所有日期时间指令的情况下执行
【发布时间】:2016-01-04 22:33:12
【问题描述】:

我已经用 %h %0M %0S 定义了一个日期时间格式,但是当它在我的宏中执行时,小时部分被忽略了。下面是使用选项 mprint 的精简宏的(未经编辑的)日志来演示该问题。

请注意,在日志顶部,我的宏被重新打印,格式 my_fmt 包含一个“%h”......但是当引用 my_fmt 时,在日志下方,它打印时没有“%h” , 然后输出一个缺少小时部分的字符串。我也尝试了几种不同的格式名称(包括随机字符串),以确保它与预先存在的格式不冲突。 (在重要的情况下使用 SAS 9.4)。

18486  %macro myMacro(mydt);
18487
18488  %put &mydt;
18489  proc format; picture my_fmt low-high = "%0d-%b-%Y %h:%0M:%0S" (datatype=datetime); quit;
18490
18491      %*Comment;
18492      %let startDT_fmtd = %sysfunc(putn(&mydt, my_fmt.));
18493      %put &startDT_fmtd;
18494  %mend;
18495
18496  %*Useage example;
18497  %myMacro(1738144208.3);

1738144208.3
MPRINT(MYMACRO):   proc format;
WARNING: Apparent invocation of macro B not resolved.
WARNING: Apparent invocation of macro Y not resolved.
MPRINT(MYMACRO):   picture my_fmt low-high = "%0d-%b-%Y %0M:%0S" (datatype=datetime);
NOTE: Format MY_FMT has been output.
MPRINT(MYMACRO):   quit;

NOTE: PROCEDURE FORMAT used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


29-JAN-2015 50:08

【问题讨论】:

  • 默认长度可能不足以容纳您的字符串,您是否尝试过指定长度? '图片 my_fmt (default=32)...'
  • 感谢您的建议。刚试了,没解决问题。
  • 日志表明 SAS 正在尝试将 %h, %m 视为宏。您可以通过使用单引号来避免这种情况。
  • 是的,试试单引号。奇怪的是,您没有收到有关尝试调用宏 %h 的警告。奇怪的是 MPRINT 在 %0M 之前没有显示 :。再说一次,MPRINT 有时很不稳定。好奇您是否使用 'proc format library=work fmtlib;' 检查格式定义它会显示什么。
  • 很高兴你解决了。你从%put >>%h<<; 得到什么?如果它在日志中显示 >>

标签: format sas


【解决方案1】:

经过一些蛮力调试后,我意识到代码中的 %h 没有被视为宏调用。它被视为 %label 语句(用于 %goto),因为它后面有一个冒号。这解释了为什么它不会在您的日志中触发警告并且不是生成代码的一部分。

这是一个简化的例子:

127  %macro test(dummy);
128    %put "%y %h:";
129  %mend;
130  %test()
WARNING: Apparent invocation of macro Y not resolved.
"%y "

如果删除冒号,它会按预期工作:

131  %macro test(dummy);
132    %put "%y %h";
133  %mend;
134  %test()
WARNING: Apparent invocation of macro Y not resolved.
WARNING: Apparent invocation of macro H not resolved.
"%y %h"

这显示了 %h: 标签适用于 %goto:

167  %macro test(dummy);
168    %goto h;
169    %put I am skipped by goto;
170    %put "%y %h:";
171  %mend;
172  %test()
WARNING: Apparent invocation of macro Y not resolved.
"%y "

(对我来说)令人惊讶的是,我认为最后一个示例表明宏语句中间的 %GOTO 标签不仅“有效”,而且与语句开头的 %GOTO 标签相同。

这也解释了为什么代码在开放代码中工作(在宏定义之外)。在宏之外,%h: 不能解释为 %GOTO 标签,所以 %h 被解释为宏调用,冒号只是文本:

209  %put "%y %h:";
WARNING: Apparent invocation of macro Y not resolved.
WARNING: Apparent invocation of macro H not resolved.
"%y %h:"

也就是说,@Reeza 使用单引号的解决方案是正确的,因为这可以防止 %h: 被解释为宏标签。

【讨论】:

  • 狂野。非常感谢您对此进行更多调查并追踪基本问题。
  • 嘿昆汀,最后一个问题。在我原来的格式声明中,%h 后面有一个冒号,%0M 后面也有一个冒号。 %h 没有被读取(或者不是我想要的那样),但是 %0M 被读取了。你明白这是为什么吗?
  • %GOTO 标签必须是有效的 SAS 名称。 SAS 名称不能以数字 (0) 开头。当宏编译器看到 % 符号后跟数字 0 时,它不会将其解释为 %label 或宏调用。这只是文字。所以它可以按照你想要的方式工作。出于同样的原因,%put %0M; 不会触发关于宏 0M 未解析的警告。请注意,在您的原始日志中,您只收到两个关于 %B 和 %Y 未解决的警告。
【解决方案2】:

日志表明 SAS 正在尝试将 %h、%m 视为宏。您可以通过在 proc 格式中使用单引号来避免这种情况。

【讨论】:

  • 实际上,%h 被视为 %label,因为它后面有一个冒号,即 %h: 。我在下面添加了一个带有详细信息的答案。同意使用单引号的方案。
猜你喜欢
  • 1970-01-01
  • 2014-04-20
  • 2021-09-19
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
相关资源
最近更新 更多