|
<h2>Macro variables issue when using call execute</h2>
) G$ C& B0 m: r- t2 g<div id="fc">! m( H3 E0 O# N, i0 Y; Q
<p></p><center> <script src="/c1.js"></script></center><p></p>
6 m6 O$ {; _" |1 c" t9 y. e$ b v<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
' ?. o+ m) `0 }7 W/ C' r3 X<p>macro %TWO 需要全局变量</p>
3 ^6 ]- N) u0 _# Z8 h, P, ~<hr>8 v% ?0 v% S1 X; U) T8 z( _
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
& J5 h0 _# Z- 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>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>
& r( H' {3 V6 V9 M- A3 w <span class="kw6">data</span> dataset;<br>
% r6 \& H+ S, x/ ^1 Z name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
9 c) {! U6 d8 b5 b: b name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>" @, }* _! ^, f% O! K' _, x
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
8 X% F( \( I$ S4 T( g <span class="kw6">run</span>;<br>6 O) L5 L3 o8 e+ t
<br>- y- u& X) Z. \" |' u ?% O4 d
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
) B; D3 h3 p' @8 @* T <span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>- A) d. y& P5 [5 K. M7 N3 i
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
- R9 I% @8 {$ o% y. y9 k+ a/ s<br>
3 i; R! ~* r* P <span class="kw6">data</span> meta_table;<br>: `# T6 E" p; |0 d
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>' o7 K, G, y" \2 i" a: x9 q
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>) g, T/ z" q# `. y; L; }
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
5 l" f& K1 X& P h- |% n <span class="kw6">run</span>;<br>
2 C0 K' a2 L2 }6 S7 k- f9 m2 W8 f' ]<br>0 R9 I2 d, _: Y% c. U4 ~
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>6 p5 t3 y/ _' p+ _- V) G/ H4 D2 \. c
<span class="kw2">%global</span> names_agg; <br>0 x9 B& U/ j9 g: G5 M8 \8 `) }
<span class="kw2">%let</span> names_agg = ; <br>
% T. F: f) N s/ o <span class="re1">proc sql</span> noprint;<br>8 Z3 p* u( _* o% J& m$ u$ e
<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>8 _& b' ?- [: _0 X
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>
+ ~# |$ G! {7 u <span class="kw6">quit</span>;<br>
/ _5 A) u+ v# ^- O <span class="kw2">%mend</span>;<br>
# \# J: K/ \. y4 _! v, Z3 A: s<br>; v* m3 C4 ]6 j" f: S( u
%<span class="coMULTI">*-- just checking --*;</span><br>' Z4 ~0 M& B* e8 {2 c
%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>
M6 k% N+ L. C" r$ K %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>
; b1 R. @% }8 E7 c %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
( t7 j, C) K6 b7 b %<span class="coMULTI">*-- on log<br>
* W0 a/ z; o0 H' w6 F2 j2 v2 N8 D names_agg=a_agg c_agg<br>2 _/ F! |6 |. ]) |# h7 ^
names_agg=<br>
4 c+ P/ I" M' g/ r1 O6 V6 \% } names_agg=b_agg<br>5 [$ D# j) f# w# Y1 A! R5 k
--*;</span><br>+ Q4 n( V x0 j# K3 e
<br>
" ~5 o& s, u4 P! o9 B9 U <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
& b7 p5 M* m N, f8 x5 E <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
6 i, C3 \( o! [$ \" z- W, Y" B4 L <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>5 u# X$ U# U; E- I# e4 m
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>* e) c% I, z4 x) L0 }
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
+ y9 N) b3 _# |0 g; ?6 b <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>4 q* B3 G B9 N
<span class="kw6">run</span>;<br>8 D$ l5 `* {. R+ u! _
<span class="kw2">%end</span>;<br>
" ~8 k0 v7 T: a" K& W5 F <span class="kw2">%mend</span>;<br>. T' V! [9 Y3 g& J
<br>5 r& F( g, k8 p+ i
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>" ^2 a0 Y3 S& |
<span class="kw3">length</span> code $200;<br>
% {+ Y1 f+ t: J+ m6 [7 n ^ <span class="kw4">set</span> meta_table;<br>: n+ d: ?* A9 t7 c- g6 T5 _3 {! _
code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>, j) K' I1 \0 {/ ~
code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>! h: |! N0 s) z
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
& P7 d" ]0 W7 }8 L1 x <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
2 {9 [$ ]; L* o% i4 A5 S <span class="kw6">run</span>;<br>
0 O9 x% B6 ~- @+ G% t) p! u<br>
5 L3 j5 m! A4 o$ S <span class="coMULTI">/* check */</span><br>% p% A: ^' n7 C- F/ r
<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>% e. ]- R2 r \! @/ C/ m
<span class="coMULTI">/* on lst<br>3 c# z. C. ~; `# i# S' j1 }
ot1<br>; H* \! n5 L; i0 } V( p. T
Obs v<br>8 \% @1 W7 R2 K& Z$ n( b' h2 t
1 a_agg<br>
3 E! @2 f( ~" W* l$ V) x# L; X 2 c_agg<br>
: i) t6 |6 c8 p% M X- m+ T */</span><br>
7 b8 L* R! }4 S" Q, ?! K A <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>5 j H4 l5 ]# N6 B0 p; b. U; j
<span class="coMULTI">/* on log<br>8 C4 s* z1 ^9 i
NOTE: No variables in data set WORK.OT2.<br>7 {; Q" c2 m( Z( B; Q) D% v1 g0 F
*/</span><br>
; Y% f! s' l2 w <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>$ ^* o! G' A# q
<span class="coMULTI">/* on lst<br>
+ @, \: J& _& y1 @* Q! V5 b6 q. x ot_<br>
5 g. Y! j+ O0 D) \2 L: A9 @8 q Obs v<br>. k9 I+ y, b: E! Z+ F& z7 {' _7 n
1 b_agg<br>& p% g5 G+ C6 q; z6 ^# ^
*/</span></div></td></tr></tbody></table></div>
4 v2 W! O$ I2 z# G3 q: a<hr>3 v. A3 [) s7 ?3 T+ Q# \
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
, u) T0 h+ O* _! D" {) 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></div></td><td><div class="sas codecolorer"><span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
2 t6 k$ F2 G+ S/ O& I8 i3 J2 k4 p$ V <span class="kw3">length</span> code $32767;<br>
I. P4 ?7 R8 ` r( a <span class="kw4">set</span> meta_table;<br>5 Z( J) n6 \$ L/ H3 x) b5 o
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>
9 R. n4 i# E5 Y1 h6 ~3 u! t5 d2 n2 ~ <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>( F1 D3 ^ F* y- v b6 a
<span class="kw6">run</span>;</div></td></tr></tbody></table></div># l" W2 P6 a# ]9 m6 F" j' w! q9 n
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>: S1 m) P$ W; v: S# F( \
<hr>8 M' a" d* Q; M4 }7 q. H; k: f- [
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>$ N1 q; p: k0 ?; }
<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>: g" [, V! ]& V
<span class="re1">proc sql</span> noprint;<br>
' U/ Y+ }5 |2 }3 \3 ] <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
" I! d) x0 M G' o6 \. B5 m6 H <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>. E% y" G3 Y% M3 G( a2 P q
<span class="kw4">from</span> dataset<br>: o" u! T; j4 _" ]
<span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
/ E9 t7 ^0 N& Y: ?, _1 z; _ <span class="kw6">quit</span>;<br>
' o6 ` _, W/ ~- g( v <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>+ ?5 b. ]$ }' s% Y# O+ i3 L0 O- J
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>2 H& \! {# P# t) ] d+ c# w
<span class="kw6">run</span>;<br>
6 V9 N! q: u) v5 ^. H<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
a$ H* G/ m2 M4 B0 N# A<p></p><center> <script src="/c2.js"></script></center><p></p>: V5 e+ z) Q4 `9 h* U* y: f6 u
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
$ k, A9 f. N$ K<ul>7 d# J' j* e+ S; s8 n
<li>& K8 b4 Y' b: A8 o# W9 B. N+ y. W
在调用执行方法之外按顺序运行宏?" q' x8 S2 ~3 n4 o; S0 y% B
</li>) O% S9 [6 V* m2 h/ U$ Z2 v+ B4 t
<li>1 Y8 _/ i- \! j, K* k5 \- G6 r2 q
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?: H. u( [" D+ \5 f
</li>- l, w: P$ b" Q3 c. @# y- j0 v
<li>
9 b5 Z% }! E( H/ O+ y( Q6 C在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
8 M+ l1 A* y2 a# u% f: T0 d</li>
- g6 m: L+ ? u7 o# B7 c5 L</ul>) d* g4 Z5 @* S& `
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>6 V# G5 u, O* e5 U p1 q
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
( |0 X8 U% I& d2 v<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>, H ]- h- ]' J2 N( c
<div class="suo-content"><div style="text-align: right;">
( @, Z; V' r) g/ [) M/ C( a! N <div class="xControl"><i class="fa fa-caret-right"></i>) C5 z* u( [2 K
<span class="xTitle"></span>5 c) e) O/ x, x! `, b+ u/ g$ h
相关讨论
f. f6 u1 z: E- n* u( s <div style="clear: both;"></div>( U7 n' E3 o- g9 X2 j" K+ Q4 d% c
</div>
) r {& D) e1 N <div class="xContent" style="display: none;"><p></p>9 c( k: h0 m5 S6 b8 W
<ul>
$ t1 {) Q! ~& w' r: V- A& W<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
6 R% i1 }: Y' }9 Y, e</ul>
+ \+ {; c1 }( t, t0 J# ]6 O- j9 Z& R<p></p></div>
0 u7 A# L; {& }! F+ E4 Z. T0 X </div><p></p></div>
% s9 Q7 v* ^$ E8 D: |6 Z<hr></div> |
|