飞雪团队

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 9839|回复: 0

关于sas:使用调用执行时的宏变量问题

[复制链接]

8111

主题

8199

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
26663
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<h2>Macro variables issue when using call execute</h2>
; U5 `1 w2 A0 U. C<div id="fc">3 R$ U: h+ C2 `0 ~3 H' Y
<p></p><center> <script src="/c1.js"></script></center><p></p>+ v4 `4 |! z% h+ U  y8 [
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
) L7 c2 c; n" m, o  B/ ]8 r0 `<p>macro %TWO 需要全局变量</p>
( I* n7 a- V6 |5 ?( m8 @<hr>5 x6 W3 j8 k$ \  h7 j
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
) S1 V8 x& ]7 V' i, D$ B<div class="codecolorer-container sas dawn" style="overflow:auto;white-space:nowrap;width:100%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>13<br>14<br>15<br>16<br>17<br>18<br>19<br>20<br>21<br>22<br>23<br>24<br>25<br>26<br>27<br>28<br>29<br>30<br>31<br>32<br>33<br>34<br>35<br>36<br>37<br>38<br>39<br>40<br>41<br>42<br>43<br>44<br>45<br>46<br>47<br>48<br>49<br>50<br>51<br>52<br>53<br>54<br>55<br>56<br>57<br>58<br>59<br>60<br>61<br>62<br>63<br>64<br>65<br>66<br>67<br>68<br>69<br>70<br>71<br>72<br>73<br></div></td><td><div class="sas codecolorer">&nbsp; &nbsp;<span class="coMULTI">/* test data */</span><br>5 O1 T3 ~  f0 l9 j: {9 {
&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>' u7 M8 C6 q% x+ e( q! Y
&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
; u2 E  b& g% m7 k&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
  k$ o: V6 R/ m5 M8 m&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>) V$ I+ i5 O2 v/ t9 M# U
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
/ Y: x. s/ k- V3 H' v<br>( }- _/ ~2 [6 S+ F/ f& D1 ^1 k: n9 C/ b
&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
4 g, l+ t, o! a7 ^1 Q. e8 w! u&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>4 t: [4 J. E( r* H! |  P3 L
&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
4 |3 C. y" S* j2 ~8 M3 K. v- ^<br>+ t3 |" V* H* D" |+ N% g
&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>
* n( S+ n- |2 G1 ^. p) T3 o4 E6 R9 S&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>2 k  O7 |# ~+ T9 v
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>% ^* s6 ^8 f" ]$ c& N! c( [5 f% h5 e
&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
7 r/ z8 \6 N; y&nbsp; &nbsp;<span class="kw6">run</span>;<br>
5 \2 \, V8 B( `3 W$ B; k( |0 U<br>
, B( i+ o# ?' ^5 l&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>. h' U6 q# Z/ i  h
&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
( N! X2 ~  G- _+ E# U) Z% }% L&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>- V. `# p+ I+ @/ ]( q" c9 u4 `
&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>; ~  v% l; Q% y. U" b8 k
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span> <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
. y) j# Y: f$ c1 x1 l&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>
  ^) V! O; R$ _&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>
1 N  ^( K* r4 w+ e2 }6 ]  u&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
6 d4 E" U; d9 k; O, a<br>' y3 x% m; g/ Z! ?* A/ t
&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>
! i  m7 u. l% H" \3 m4 d4 V&nbsp; &nbsp;%one<span class="br0">(</span>condition=<span class="nu0">1</span><span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>
! E1 c2 W& X) O, z8 J. P5 X&nbsp; &nbsp;%one<span class="br0">(</span>condition=<span class="nu0">2</span><span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>$ ^% y8 {8 K, V' ~+ K2 C
&nbsp; &nbsp;%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>
1 t! [! Z2 V/ v* c4 C( ^6 I&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>
- A: I2 _  u3 h( v: N&nbsp; &nbsp;names_agg=a_agg c_agg<br>5 X* s+ P0 w9 t1 {5 {! {
&nbsp; &nbsp;names_agg=<br>
/ x; V5 ~  M! l% ^/ c&nbsp; &nbsp;names_agg=b_agg<br>
/ P! [6 q+ s) Z4 H2 R: t5 o&nbsp; &nbsp;--*;</span><br>
$ l' L  V$ [& ], C. s" V3 V<br>, Z4 Q" u# L( [! t1 X: b' G
&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
. o3 r5 W6 f/ C&nbsp; &nbsp; &nbsp;<span class="kw2">%if</span> <span class="re0">&amp;names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
$ A! k2 I6 ^# a% V% K9 z3 c&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>( V, k/ v; ]6 f
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>0 S- j, a' T* q9 L
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
2 O) g$ B& D) Q# V5 Y% j$ l! q4 L&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>
0 U2 H. Y$ Y' ~) l3 l* D7 G&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>
' B  a) R7 i  d# i  r7 o, P( @&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
; K- Y0 [6 d- ?. @&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>8 q/ g- [7 w% X' H9 T
<br>  ~- O% K; ?  C0 A5 |
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
7 B  Z, r$ k: R3 G9 s4 X&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
' f  I: u" p3 X2 A, l6 M/ [6 N+ R&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>
* D- F0 _# a3 i% f8 ?&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>  V) ]: w  a5 y; f4 X  \6 b& t
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
1 _' U: |. n: O, z4 d&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>" c% h+ l% [9 I! k; B5 X
&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
1 ?. w2 @8 V1 k/ [, ]9 Y! |7 ?&nbsp; &nbsp;<span class="kw6">run</span>;<br>' C4 L4 Y1 b) r( v
<br>
. x5 }- C8 h7 E: p7 @7 v  ]9 z&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>/ a" ?. M0 _+ Y2 `0 A& Q' O* f( s1 w
&nbsp; &nbsp;<span class="kw4">title</span> ot1; proc print <span class="kw6">data</span>=ot1; <span class="kw6">run</span>; <span class="kw4">title</span>;<br>8 F6 s% h) _/ G2 ?: z' l
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>9 e. S# E0 u5 D. j9 F
&nbsp; &nbsp;ot1<br>  m+ Z. [$ T1 N* N
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>2 _' Q; X4 o  A- t
&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>' Q7 D& P* u' J+ `2 N8 Q
&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>2 a: d( y, U/ ?' _& V, d
&nbsp; &nbsp;*/</span><br>
3 C& w: s* E7 Z/ I! I$ x  U&nbsp; &nbsp;<span class="kw4">title</span> ot2; proc print <span class="kw6">data</span>=ot2; <span class="kw6">run</span>; <span class="kw4">title</span>;<br>& m4 F) Y7 j. {5 Q% r+ O
&nbsp; &nbsp;<span class="coMULTI">/* on log<br>( ~7 w5 D. Q3 e( `& @  f! i
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
8 R( m$ t0 T/ R6 W, Z&nbsp; &nbsp;*/</span><br>
8 a& U8 b- j2 _9 f&nbsp; &nbsp;<span class="kw4">title</span> ot_; proc print <span class="kw6">data</span>=ot_; <span class="kw6">run</span>; <span class="kw4">title</span>;<br>! @& [8 v% W1 X8 _: z3 \9 h
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
: h3 J# w7 Y. X&nbsp; &nbsp;ot_<br>4 M2 E& ^( s% i4 T  F, w! `: \# h
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>8 s3 L+ Z7 W1 I/ v" V
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>
+ s9 b& L8 c8 i1 H6 ?&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>+ G8 p5 N& E5 f5 ]. ?1 V2 z+ l
<hr>! V1 C& N$ `7 V2 k& _
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
! |7 @1 b5 ?$ H0 B8 D# `. m( g5 o<div class="codecolorer-container sas dawn" style="overflow:auto;white-space:nowrap;width:100%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br>2<br>3<br>4<br>5<br>6<br></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
9 D: [. q4 _6 v( V, s3 }&nbsp; <span class="kw3">length</span> code $32767;<br>9 k5 Y# v4 ~; O5 M2 u
&nbsp; <span class="kw4">set</span> meta_table;<br>
9 G4 F$ w) |4 y% L&nbsp; code = <span class="st0">'%ONE('</span> || cats<span class="br0">(</span>condition<span class="br0">)</span> || <span class="st0">'); %TWO('</span> || cats<span class="br0">(</span>Name_OT<span class="br0">)</span> ||<span class="st0">");"</span>;<br>
* w' J; x3 H9 W: J. a1 N6 M9 H&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>8 ]. o7 @! L9 y# T" s' b
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>0 W; {9 w# y0 t' w+ x7 W8 y* l, `
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>1 `/ Q- B3 Z1 x/ K5 L$ m
<hr>
& k1 F3 C3 f, i$ }! {8 x0 ?<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
! h5 s, q' }9 x* @) a: v) f0 \0 S<div class="codecolorer-container sas dawn" style="overflow:auto;white-space:nowrap;width:100%;"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br></div></td><td><div class="sas codecolorer"><span class="kw2">%macro</span> TheOnlyOne<span class="br0">(</span>condition,name_OT<span class="br0">)</span>;<br>7 I$ |/ c$ i. c7 h# x$ n% m+ {
&nbsp; <span class="re1">proc sql</span> noprint;<br>
  a9 m1 i# U0 G, s& q) a3 W&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
( w/ g3 g( v) H! k&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>) `# I$ x- J* j
&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>
4 t$ T3 c2 |) H$ K&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>" {% a9 k; F+ X# m
&nbsp; <span class="kw6">quit</span>;<br>
3 K8 j3 Q+ g" D; O& l4 L' J- P&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>( [" k' e4 S" s# S" Q8 T- q
&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>6 ^; y8 }7 d  ~  z" e* R
&nbsp; <span class="kw6">run</span>;<br>  f+ ?0 r( z  C9 D9 C  X+ R; _6 w8 w
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>: }0 L% f, B9 ~4 b: p# P9 Q9 ~3 O
<p></p><center> <script src="/c2.js"></script></center><p></p>
, f2 g, |1 p, A% d<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
. I$ A& ~; k. F9 @: C/ J7 f<ul>
9 w3 l4 E; X2 E6 Q; G! e8 r0 K# T<li>
' |( I) i. u" \% ]在调用执行方法之外按顺序运行宏?
: x3 k  _( t2 ~; l% ?3 g</li>1 Z3 W: j, G  q) v6 F
<li>
- L* B% N: N! l7 Y  _在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
# m! |# K! i- `- {</li>
# L+ y; i5 t9 N8 F% |<li>
; u' S$ ^; P% T5 I2 n在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
6 {$ R, p6 X' s: b6 x  }8 m</li>8 x" \7 {7 D$ A! @( b& l
</ul>
0 E; C0 t( R, `$ N' y<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
  a4 p' g( e+ F  l5 D! ~+ P6 v<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>- \9 g3 Z) a3 J8 m
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
! z( j% P7 `+ ?5 f<div class="suo-content"><div style="text-align: right;">
1 }4 D- o8 \9 I# L! V. Z! a                <div class="xControl"><i class="fa fa-caret-right"></i>, p. i. i& ]/ S$ x6 V2 m1 ~
                        <span class="xTitle"></span>
7 |4 d3 F3 S# t: E6 z' Q: ]3 j  U8 J' ]                        相关讨论
4 E; j3 j& x( @: ?( a+ K                        <div style="clear: both;"></div>
3 K& p$ g  U- _6 b# P' H- j                </div>
" X9 _( j$ @+ s/ F                <div class="xContent" style="display: none;"><p></p>
) b# D4 q; V7 ]0 q7 q9 j8 u<ul>2 B' ?# {( B5 _4 F( i# Z
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
  }# k# ^3 _1 ~6 }3 }</ul>) y; i% z! m& z2 a, z6 U
<p></p></div>
2 @; }: O2 f: j" q& h        </div><p></p></div>/ H/ Z7 q+ F, p. U6 Y1 f+ ~5 V# v
<hr></div>
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|飞雪团队

GMT+8, 2025-12-18 17:05 , Processed in 0.073681 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表