|
<h2>Macro variables issue when using call execute</h2>/ ] n" B0 ^7 I2 n
<div id="fc">6 L1 h2 E8 X% A/ J
<p></p><center> <script src="/c1.js"></script></center><p></p> y0 D$ |, z) C
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
* f6 v5 ~6 G `/ u. F<p>macro %TWO 需要全局变量</p>
, b a" y, ?9 R t; e<hr>1 O! P0 P8 ?) w
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>8 b/ u8 I1 t. ]# _4 N/ r6 L
<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"> <span class="coMULTI">/* test data */</span><br>+ q3 k3 T, ~/ x# E0 E0 @! g
<span class="kw6">data</span> dataset;<br>3 g% P, t$ b5 x4 B
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
2 p( C5 Y' i2 } name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
& @' v- h8 t; v: J: J5 p% D0 H1 O) [ name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>" g( f! R, z" s9 B
<span class="kw6">run</span>;<br>
* T6 |; o1 ~) U( h% v<br>
: A; l6 w/ j: c0 L0 a0 U <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>- [! U- d2 k* @1 }4 g8 Q, A3 ]+ Z& w9 A
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
3 R( U8 B4 Q: u, v8 a <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
% d. D/ q \9 |, w0 O. U! ~8 f<br># b$ o: q9 _0 c( _6 V
<span class="kw6">data</span> meta_table;<br>
1 a7 o9 m/ A2 A+ F* } condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>, k! H* p: c7 D4 n# S2 m
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>
0 R5 I5 z8 L3 s. A6 a condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br># a4 p2 z. C' x/ S a
<span class="kw6">run</span>;<br>
! X8 y6 T5 \! @1 S+ R1 o4 G<br>
4 }$ B/ g q+ i) L+ V, o! d <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>& k3 |4 E- r% s
<span class="kw2">%global</span> names_agg; <br># F" c7 Z1 Z$ t% d5 Y Y+ M. b/ p
<span class="kw2">%let</span> names_agg = ; <br>
" T$ w1 p) F/ J T! j. O5 f& z P2 u7 ? <span class="re1">proc sql</span> noprint;<br>
+ ^$ Q9 h( z: F5 f <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>
4 J* I \1 M3 Z3 Y; e <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>* h/ c8 E' F0 }7 p& h. l5 A3 S, y
<span class="kw6">quit</span>;<br>& }, a. I8 S i& d
<span class="kw2">%mend</span>;<br> H9 N" w4 Z: l |
<br> b5 m9 X) }$ `2 j+ C
%<span class="coMULTI">*-- just checking --*;</span><br>1 S6 l3 ^8 a$ A0 x$ I) I& E
%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">&names_agg</span>;<br>
, l0 Z1 h% }& w, V* i %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">&names_agg</span>;<br>/ F( g/ z1 s# F" D
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>" |5 S- u/ B0 v/ y
%<span class="coMULTI">*-- on log<br>$ A- a0 d% b. ?: H; o6 E) ]
names_agg=a_agg c_agg<br>
6 `3 ?& p- V- c names_agg=<br>
- I! n, u" o! S9 K( j: g# ~ names_agg=b_agg<br>6 ?% t8 l! ~ r% {
--*;</span><br>6 @5 I0 z$ ?) |% L; X0 d
<br>0 O- V. j* V+ h! r
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
, W8 h" F1 u0 z+ g/ A6 {6 i <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
) t: q6 V& K. \/ d: S, Z- T- h <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
' C9 j, b1 H% n. h- P7 S4 T: Y3 A <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
* [* X6 H3 s8 y, n/ b <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
; I& d) T/ J. ?8 ` <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>7 R. ~9 j& l) \% @) J
<span class="kw6">run</span>;<br>. T3 ~& h/ f0 r% `( k" Y
<span class="kw2">%end</span>;<br>
U" b7 M% o) Y9 a$ R$ e <span class="kw2">%mend</span>;<br>7 f1 |; L8 R R5 G' F; r
<br>( U' l4 h3 N8 x/ H
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
Y' Z9 q6 U) f } <span class="kw3">length</span> code $200;<br>; g8 S0 T6 s0 F! Z1 p
<span class="kw4">set</span> meta_table;<br>8 O1 F, u3 b: H9 W
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>! z) s, Q" B/ L; Y- N& K0 @
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
% ^) t4 E# r. h2 @7 Z code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
; i, T+ H! [! M/ K- |; H <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>6 c Z0 w; s, Q* B- l) j# t# u5 n
<span class="kw6">run</span>;<br>, N6 [4 q5 U3 `: Z! V4 F
<br>! B1 `6 k; p* L; o: r0 T a* E+ C( K
<span class="coMULTI">/* check */</span><br>
5 g8 W0 k1 X" i" a* x' s$ L+ B <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>
2 a$ D- g% Y0 E# H t$ B7 u! E7 K* t <span class="coMULTI">/* on lst<br>' U, f: ?& c/ |% Z
ot1<br>5 _! j' h# @4 }2 }
Obs v<br>* r, L% m( x" Z0 M
1 a_agg<br>
+ D& F! i; J" U& Y 2 c_agg<br>
; ^: D) j& E4 n2 j4 C) t6 F */</span><br>
i0 t9 f5 ]5 v# g, W <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>
- f' u) ~* n) |- `. Z5 H: b: ` <span class="coMULTI">/* on log<br>% k2 E! u$ E' v7 L' W. y6 @
NOTE: No variables in data set WORK.OT2.<br>
M6 o- o/ u% n- Y */</span><br>
& e3 `) J3 F, E <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>
# ~4 H$ `! p* {' Y* a <span class="coMULTI">/* on lst<br>4 x* @" w3 o, j
ot_<br>
. ^* L9 Y* n, q( @ Obs v<br>' Q+ O. t* ~. d5 y1 Y" X4 N. c
1 b_agg<br>
+ _0 F& |1 L! V5 B* |1 a* X; N */</span></div></td></tr></tbody></table></div> |! f" A2 {$ \) K2 R- x
<hr>$ R4 H$ z& S- d+ m$ q8 a4 k
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>; _5 |. o8 y L! U& e
<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>
5 a! _1 `& ?6 N+ J5 A* ~. E# j <span class="kw3">length</span> code $32767;<br>) }& Z, s4 b% y( a( B2 J
<span class="kw4">set</span> meta_table;<br>
8 R- W, Y& F: h. W% b- _ 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>6 E7 u+ s! K4 }0 T
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
' H! b' O4 B D% d0 V" l<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
. [* y; m, I1 w+ a<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>3 [4 U b) q$ c% X' D( R2 a
<hr>
0 R9 t! c+ @3 e8 t<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
' Y' x7 h( Z# U' F<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>
! a$ R. L5 r0 G8 K3 ~' } <span class="re1">proc sql</span> noprint;<br>
" i4 Y% y/ Z [ <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>) Q7 m% ^# ]6 @* ]
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
; ~& E) n0 D& i& \ <span class="kw4">from</span> dataset<br>
; L) u" v5 F& i' Q <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
6 N( j [ m: s! w <span class="kw6">quit</span>;<br>! w5 f0 d8 b# y- P7 a
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br> u4 A$ W* X5 L
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
' W# N& r. @/ v) x <span class="kw6">run</span>;<br> q+ g. P- [: v) f( l. n5 c' e
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>% e" m X9 y6 h' I* p, V4 a8 _6 z* R
<p></p><center> <script src="/c2.js"></script></center><p></p>
8 N1 A7 `, x0 u6 _. A5 j<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
$ |5 I3 q( G& u7 f* J0 I<ul>6 h2 C( K& d, X- Y: d
<li>
0 ~. E% e4 Q# `在调用执行方法之外按顺序运行宏?$ U+ Q: f) |7 Y) @0 g5 [: q2 W% O
</li>
8 l* y: r' |2 z' N5 Y2 f/ C# o0 ^6 l<li>
5 N' O1 u, L( Q0 N) t在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?: w" |/ O) ?1 D
</li>8 ]- {3 _: k i
<li>" \0 y1 ]5 z! A9 o; h) `! Z
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
& \6 c: e9 h2 F0 W</li>
0 q, |* x. f9 A) N</ul>
+ H9 p) ^1 M6 p7 p8 N4 T<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>
/ n3 A0 U% F6 r: X+ \, Y. S! A' i<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
; X5 Z* I2 @5 S- b1 A+ d<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
2 C/ I- P8 x* ` G4 ~$ M- B<div class="suo-content"><div style="text-align: right;">% }6 r) E, Y3 r5 g9 ]) @/ a0 Y( A
<div class="xControl"><i class="fa fa-caret-right"></i>
! P5 r' H+ [, U <span class="xTitle"></span>3 \1 F3 r6 D2 s+ @' @ K) O
相关讨论" k5 ~+ N' y$ d! L- W
<div style="clear: both;"></div>
! ^4 m! ~# f( { </div>
! S$ K9 @/ X: ?- j- e <div class="xContent" style="display: none;"><p></p>
* V7 n& u, n: D<ul>
/ M$ a3 v" G! x& G7 c<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li> P6 r" V1 N5 C! O9 ~- x0 x1 \# o
</ul>5 k. Q9 m0 [7 k; c, W- c
<p></p></div>
+ _0 r/ H$ Y- g, g0 s+ e </div><p></p></div>
. q! c" l' n- _4 I( y' }<hr></div> |
|