|
<h2>Macro variables issue when using call execute</h2>
) [7 K% H8 d' K( A<div id="fc">/ D2 K \, u. A) t
<p></p><center> <script src="/c1.js"></script></center><p></p>
( Y+ f0 {7 _) J( G% _2 S( Q<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
, d/ h. c0 |5 }' q; m# J<p>macro %TWO 需要全局变量</p>
9 J+ w% G6 Z5 {% H$ P<hr>
1 R2 n) `9 O1 s) ^' D( B; @$ o<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>$ d2 A" M% I# x; c) ]. A% n% y6 a c
<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>- t3 ~% E Q, J- j* A3 p
<span class="kw6">data</span> dataset;<br>/ ~. i# W, Q+ g" y" K
name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
" _. d8 u- h' ^+ z/ P1 a+ H name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>% T6 E' K C( B; x
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
0 U2 ^5 r8 N [. p/ \ <span class="kw6">run</span>;<br>" x& n1 D) K% ?: X% s C
<br>
8 n6 w; j# e$ o! T: L) y <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>4 y, V8 z1 T. ^) L, b9 p4 p1 i
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>: n3 `- f8 Y+ n+ b. U4 q/ {
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
' n6 h, @ |& ~3 _# X( F<br>1 {( k% d& @# }5 ~, q/ R
<span class="kw6">data</span> meta_table;<br>
6 W4 O4 V5 S+ m$ ^4 ] condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>* I* W p& z9 O" `# x3 N1 R" l
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>2 k$ g) @# Q3 d
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>5 ?# ^) M/ ?! X5 e* C
<span class="kw6">run</span>;<br>- Q& A! H9 v3 K! p" N6 G6 e( Y
<br>) o/ i4 g; S [# F3 c& l
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
% f6 S5 O' U* @0 }$ v <span class="kw2">%global</span> names_agg; <br>
/ R; U2 W- l2 z% k/ z <span class="kw2">%let</span> names_agg = ; <br>
+ G- i5 W1 s# u" a <span class="re1">proc sql</span> noprint;<br>
5 q& N. V& @% x% S0 s' O' \# G <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>6 C& I( M2 v7 ]
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br># x8 e/ Y1 |/ n
<span class="kw6">quit</span>;<br>: k' A3 J; F) T" W# z# N
<span class="kw2">%mend</span>;<br>
* t% O5 c( d: G<br>, t8 t9 I$ a9 ?$ ^/ D3 [+ E
%<span class="coMULTI">*-- just checking --*;</span><br>
- S' g; I) S, @. K9 ` %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>
/ Z/ o w, f7 h. u %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>% T3 f! Q: T7 r
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
/ u' K/ f7 T- x. D) | %<span class="coMULTI">*-- on log<br>
1 e; {) W8 _$ P2 s names_agg=a_agg c_agg<br>
, ?. t: U( q8 X. t4 N/ P/ ~ names_agg=<br>
) N/ ?8 d l/ |- o" y( J1 A \ names_agg=b_agg<br>
1 O3 E* J/ J+ L/ @- G --*;</span><br>0 }# O1 P2 J) y H
<br>7 \$ P6 W, D( f; I
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>% E+ J0 Y# G) T
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>. c( A4 E P. a# [/ z8 T! F1 E
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>4 u9 y2 N0 w& E8 n
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
: T* i) }3 k4 ^ E, H <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>: c: R5 G0 v. _; ]
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
& [) S3 S7 v d. G <span class="kw6">run</span>;<br>: [ `3 w' S L" L7 H, U
<span class="kw2">%end</span>;<br>5 Q; O) G$ w8 _9 o6 d3 m) z
<span class="kw2">%mend</span>;<br>. v* p8 m% ~+ p$ V
<br>
' ?8 @- P6 e$ q6 J <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
0 i1 K$ E$ x+ d S0 W: v. t9 v' A <span class="kw3">length</span> code $200;<br>6 Z, h( D& |+ q5 I) J A
<span class="kw4">set</span> meta_table;<br>; x- `% b, v$ o m2 a7 c, [
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>$ R8 n( `# J, ~! j0 R& ~
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>; C' d+ ] k) G4 }3 x( a( k
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
9 S5 V( t( X, T0 ~/ F9 L7 t" l% o <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>7 v! C2 I3 _7 h& K% F
<span class="kw6">run</span>;<br>! U6 M! Y5 S" I# m
<br>1 I/ c2 v+ K c
<span class="coMULTI">/* check */</span><br>" f1 ~# u$ v0 T) t
<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>
7 F8 I% ^3 i8 j; z- M <span class="coMULTI">/* on lst<br>6 W1 K3 e# r$ H7 j
ot1<br>% o# c- x) Q c1 r1 } }$ y
Obs v<br>
" C+ d2 N$ A$ e 1 a_agg<br>. a7 F1 E# L9 B$ ]. I- O5 l. F; W
2 c_agg<br># H" S2 _# [( w/ [7 {) o
*/</span><br>* y$ d; S) L* j
<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>
; v* Z* c8 r! |9 ` <span class="coMULTI">/* on log<br>
z" K, t0 _9 P I |) I. x! ` NOTE: No variables in data set WORK.OT2.<br>- |8 |* g+ M( o7 J }! q
*/</span><br>3 u+ V1 d2 E7 Q, l3 w/ Z
<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>! X$ ~: N! w- ^6 j7 }
<span class="coMULTI">/* on lst<br>$ R- u. i9 H4 H o/ d& N
ot_<br>8 Y* ?# J$ b9 A9 Q/ t
Obs v<br>
8 o' `( U7 O$ h, g5 U 1 b_agg<br>
1 r9 W, P1 T, ~5 ]* V4 U, G% O5 e8 Y */</span></div></td></tr></tbody></table></div>$ q) A B: ^+ D2 ?8 V2 _
<hr>
3 p9 [# x7 ?- _+ I0 r8 J$ Z6 N D<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
( K: M! g3 o4 N& P; C<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>; Z$ P" g% ^8 j2 g; c9 [8 @
<span class="kw3">length</span> code $32767;<br>
7 J1 ?' V1 Z) P N4 H% u3 T <span class="kw4">set</span> meta_table;<br>
+ y9 ~3 g6 w! e D 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>% S; D: a/ n) Y; g/ J' q
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>, y5 T1 h) S1 V# p* `4 S
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>$ B4 ?+ R' y7 D' K/ k I, i8 Y
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>0 R2 x+ R' s' E2 ^
<hr>. o1 ?7 T7 X4 h
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
) I" D7 ?9 r @; e: @ j" S& U<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>
8 V, B# w! R" }7 t; C; M' r- V: ] <span class="re1">proc sql</span> noprint;<br>) p" T# ~% j0 O( m
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
+ `9 ?/ N* {* U* J <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
. k7 s b. C' n9 e9 X8 E: O <span class="kw4">from</span> dataset<br>7 H2 h8 r- L6 B( a# q
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>8 {+ i! ?7 q% l# U6 W
<span class="kw6">quit</span>;<br>0 D+ w0 R2 t% e
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>5 P8 }' F$ q: P
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br># C; I a: }- w R0 [0 C
<span class="kw6">run</span>;<br>
% Y2 O7 |5 a4 N$ k" P/ ]<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>! P) _5 @8 @8 s2 X
<p></p><center> <script src="/c2.js"></script></center><p></p>
; O2 |# |" u- v$ y3 X+ G<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
1 p, F4 k1 b. A+ `& p e<ul>0 Y' K8 C9 b1 I- P0 O# G7 N
<li># {6 n: I* c/ Y" V; ~
在调用执行方法之外按顺序运行宏?
2 R& N9 L' A$ X' D6 M/ n5 O</li>
7 z& x% B. p* u5 K6 D<li>( }' k' U0 L% G
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?" X8 X% Y0 r3 ^4 ^7 f* G% i# z$ H; |+ Q
</li>4 B- Q$ ^' f* X5 w, a# h
<li>3 s6 X. X" E' }* R- y, O+ V( q
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
1 R. k s* O; u! c& j% {2 `9 i9 A4 ]</li>3 S# {$ q. G1 f! T6 C1 J
</ul>( _7 V1 m) M N9 B
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p># ~! w. Y2 H2 X D
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
, P) M- d& _+ J) t6 u, v<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
4 S4 Q) {" F2 t% b<div class="suo-content"><div style="text-align: right;">7 T8 c9 I8 P$ u9 h7 j
<div class="xControl"><i class="fa fa-caret-right"></i>2 n; W |) O& Q5 P1 {' J
<span class="xTitle"></span>& I' i3 R- G& J: c
相关讨论
: G' x: K) u3 s& I6 b# ` <div style="clear: both;"></div>
* G, q3 Q: w. u# I; W h </div>
* d5 g9 A9 h9 ?6 L- g1 G" X <div class="xContent" style="display: none;"><p></p>
) j) z/ x5 r" j7 W! g5 ~<ul>
% y6 L4 Z# R+ Z4 {% e<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
( k9 o- y* T9 e* [' D</ul>
# q; z: \! J) S& _) N0 e<p></p></div>' [9 ~5 ?+ `2 _$ [
</div><p></p></div>$ A( |( u& h% @; r: g
<hr></div> |
|