|
<h2>Macro variables issue when using call execute</h2>
: {# {0 S6 P: a4 E9 z$ G4 O<div id="fc">
( q: X9 {* K$ [8 i4 ~<p></p><center> <script src="/c1.js"></script></center><p></p> v& O* J- }, q# C
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
$ z3 V) \9 l# v7 L<p>macro %TWO 需要全局变量</p>0 l7 p9 F- g5 K. p* v
<hr>
# U8 }) b* w; z/ [+ C<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>, z* q+ X& J% I9 t
<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>
, j. L! e& i& ~ <span class="kw6">data</span> dataset;<br>
( ?. L9 R' v8 H- @ name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>9 p+ o7 H5 v; n! Y* E4 i
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>8 l! d" O5 x7 }% f j
name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>9 m' N/ }" ]/ m# E: Q9 B: L
<span class="kw6">run</span>;<br>
% ` C$ x8 T4 C I<br>. @8 [; R! d% C) e
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>1 G4 P: n' _# B' r
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>) _3 g1 ?; s; G/ M, ]# k
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>
% t, v! b! m3 O4 s* O! H q<br>
" }- w2 s/ A8 |, Y5 H6 r5 m( }2 U <span class="kw6">data</span> meta_table;<br>: }5 A$ e @3 Z# q
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>( c" k0 I' w4 S3 ]5 D( m
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>- B; g$ I" `* B) c6 q2 T2 u' P" ~
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
9 b6 d9 _0 P \( k <span class="kw6">run</span>;<br>
( M$ U! _" j; g% Z0 R! f' q1 W<br>: L; e5 }# x% y; H* p
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>" x7 p% Z2 v+ J( g6 l; B7 |; A
<span class="kw2">%global</span> names_agg; <br>
' u9 f& d) d$ Y! c <span class="kw2">%let</span> names_agg = ; <br>0 r- W- m0 J( @9 s6 g
<span class="re1">proc sql</span> noprint;<br>
, ^% @, }8 q- |: P* t# I% 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>
3 {4 n* T+ _( P9 I) c: S <span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>8 m/ p% z+ H0 _ k! o
<span class="kw6">quit</span>;<br>
% A, v3 R5 R: m6 h( ]$ h <span class="kw2">%mend</span>;<br>
( I3 n8 e6 U. i! J2 f% e2 P: Y d9 X8 z3 M<br> u. }" [8 e# j8 o- f
%<span class="coMULTI">*-- just checking --*;</span><br>
: I$ }# O; o& G9 ~8 o) B) Y% E* Y %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>
5 P2 r4 L; ]# b. `: W, O: A %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>
+ C" P' Z5 }2 s4 l %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>$ ?; j) p7 \! q+ J7 g- O
%<span class="coMULTI">*-- on log<br>
1 U& d) z$ N4 S E" z names_agg=a_agg c_agg<br>" s3 X! `; ^: e+ y( Y
names_agg=<br>) g* H2 `* z' h- E! I% ~
names_agg=b_agg<br>
, z/ f# D$ M8 U0 c! R --*;</span><br>" N; j' p( U6 |8 H
<br>1 M, | `/ z- L8 {6 | n% c2 D
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>+ _! r9 @$ V+ n8 D( x' e
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>9 W1 ^! R) D$ d6 ^
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>( g. p! ^. P( @: H
<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
( o/ d7 K0 W! W9 ]: @6 e <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
' @! P5 S3 ^9 o( N) M/ L) h <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>
3 V: K1 ?+ l" P( g <span class="kw6">run</span>;<br>, F$ F" X! w+ z5 q/ o! H
<span class="kw2">%end</span>;<br>' w2 @4 g' N% Q" y2 w4 m7 V
<span class="kw2">%mend</span>;<br>
3 M- \1 r% H& y& N& b/ ?" L0 ~+ q<br>/ x; x1 n+ P3 J+ M' J
<span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
/ |% ~# ~+ i' b' Q* ` <span class="kw3">length</span> code $200;<br>
) z% Q9 Q2 S1 }' ` <span class="kw4">set</span> meta_table;<br>
9 Y- R2 q; ^% A( q code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
% ` c$ \7 s3 ?- ^/ u code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
2 u3 p5 e. P& r* }* g code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>$ u* m- `% Q7 F
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
, g' p. s$ n" d2 N <span class="kw6">run</span>;<br>
9 @, [; C. e1 P* s<br>
/ }8 h! i% z- a/ |6 G& h. `- g <span class="coMULTI">/* check */</span><br>: K# n8 T# t: z7 @6 j" _9 g8 ~
<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>
5 s9 T3 W( K" {, R3 | <span class="coMULTI">/* on lst<br>
8 `7 D1 J2 H- A: }0 v) V& N) t ot1<br>; ^6 J4 t4 z; f0 i8 R9 W; x0 g: s5 \
Obs v<br>6 c+ m1 h8 D, t" K# \' e9 x. r
1 a_agg<br>; F7 V. V3 Z: R, o& U
2 c_agg<br>4 j( Q, ^# w* d* ]# K7 B i
*/</span><br>! G2 |4 ^4 ~' j& N( h- Z
<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>
1 X5 J/ `) B# _& Y2 Q0 x3 H <span class="coMULTI">/* on log<br>! C( a# d- J* k; |3 Q- v
NOTE: No variables in data set WORK.OT2.<br>
% r6 G, M w' _% c */</span><br>% Z/ r7 Y( {1 B7 F/ R" k! J
<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>" d6 h; N/ k. P* }6 b3 e
<span class="coMULTI">/* on lst<br>
0 ?: v: d. \# r/ y3 ~; H ot_<br>
; T9 w) Q+ P6 E Obs v<br>+ T: c: q. l: c& c( p0 U3 O& |
1 b_agg<br>8 J1 N" O8 ^/ l7 n
*/</span></div></td></tr></tbody></table></div>9 i3 o2 K9 t, i! `1 X2 ?/ z2 L$ X9 i
<hr>
) _$ s7 x, ], t, b5 B8 }8 `1 N<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
, ^2 v! Y1 ]: s; {# V<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>; E s# M; Z6 `, S6 o
<span class="kw3">length</span> code $32767;<br>
8 O- j; X* Q' G( G <span class="kw4">set</span> meta_table;<br>
0 e% W& V$ w6 m# I* k 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 a. y$ V) R1 I4 ?& [; p D <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
+ d0 p1 o# X. I- g# L<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
( ^$ a S4 |8 ]# p1 F9 K! O5 |<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
3 X6 B. \9 F4 r8 e$ I3 Z<hr>
, C; m' x9 k0 ]+ u! p<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>
3 w4 _' B% Y* Q' ?; h, 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></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>
2 u8 Q+ L% X* B e/ B <span class="re1">proc sql</span> noprint;<br>9 Y/ J" Y9 f& l. C1 V
<span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br># k, j% `( j3 X7 \
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
# h6 |8 A7 k6 ?& z$ ^6 ?+ j <span class="kw4">from</span> dataset<br>
2 n6 H. z7 g* Q4 | <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>; C- V/ v- a6 f+ J
<span class="kw6">quit</span>;<br>) T. f# I( O* r& Z& h$ a4 L
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>) `/ ^% X( y' }: E1 I
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>" m3 `) |5 r& T2 L* m7 C
<span class="kw6">run</span>;<br>
' [9 A( N6 ~8 v<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
# f$ {+ Y3 Y4 T6 D6 e<p></p><center> <script src="/c2.js"></script></center><p></p>
3 i2 n6 \) C) g8 [6 z. ^! T- h<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
" w- \7 C# I- T& o: y$ J<ul> W" K0 _2 `/ r" C
<li>5 }' s: c/ |2 s5 m& R: z/ S" b/ p
在调用执行方法之外按顺序运行宏?
( f4 T8 h) @/ W</li>, M3 T8 p# o1 P- _2 z o
<li>
9 I% s2 m& K+ p x' l在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
0 {0 S) n7 Q! Q6 t7 [# |</li># k, @9 R2 r7 K
<li>" W' u- f6 b7 Y7 L7 N
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
0 O r. H5 } Q! f$ y1 c</li>, j( L0 F3 e! x' ]6 q- O
</ul>, u4 d2 w; l) H" l$ a4 ?5 i2 {
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>- x R$ [: |* ~
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>1 L) ]& ~% f! q* o! x
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
+ R. a8 J' z8 C! K<div class="suo-content"><div style="text-align: right;">
]! d4 Q8 y; R9 l5 @ <div class="xControl"><i class="fa fa-caret-right"></i>
6 s9 D9 T2 D N, i6 K2 x( U' } <span class="xTitle"></span>
& S8 ]2 K+ Y+ h4 @! q' b 相关讨论
% Z, H& ]2 J C4 g% t" ?( x <div style="clear: both;"></div>
0 @9 i/ }# p/ N+ A$ U </div>
7 n1 {0 O+ z, `2 |# J' } <div class="xContent" style="display: none;"><p></p>
" j8 i4 J6 f8 O1 d<ul>
3 g' y7 _# k. [<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>( N0 d3 m H' G3 p9 [
</ul>. H+ N& P+ u2 _3 d1 a1 k6 V
<p></p></div>2 u% e% v" V. | I5 H( T
</div><p></p></div>. S8 F4 s9 D- i5 y. \
<hr></div> |
|