|
|
<h2>Macro variables issue when using call execute</h2>
% `% P% w# D# A<div id="fc">4 ^; R) T I" P x/ K6 r/ `. A
<p></p><center> <script src="/c1.js"></script></center><p></p>
+ v3 A- S ~* q<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>
* D p$ K8 S! K4 l: X9 U" \& e<p>macro %TWO 需要全局变量</p>
5 Y n, e- |8 B8 b' y* B% y O<hr>- C1 Z0 J- \! x# P6 {9 I2 M% h+ B! S
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
* E* o# k& _( [! Z3 q( 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>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>% s* {: r" ] J$ N# F7 K- Y+ A
<span class="kw6">data</span> dataset;<br>
# [8 ?) ]" ]$ s, v2 F* q" p name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
5 b7 w" q- Y$ U name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
( g& i2 o$ s' b name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
! E; s8 E, m9 _6 W/ d2 s6 f3 r <span class="kw6">run</span>;<br>
! o% r, g* A. k' ^' [<br>' X# D& ~) C, X
<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>( S4 M B6 g8 k0 I* R
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>) f; Q9 A; d& {, |6 ` j3 y
<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br> C3 p2 W" c* W! i
<br>
* m& i! l2 t" h7 b3 T+ a <span class="kw6">data</span> meta_table;<br>. D8 c5 T3 l, D
condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>% u, l: b6 U# D8 `
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>' m6 S* J/ v4 H7 }- Q
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>; P$ s @3 P8 I& C1 U7 T8 W# u
<span class="kw6">run</span>;<br>
2 _7 n( X% h; m" D5 p" [<br>
$ p9 @# i* A- ~8 V1 R8 w8 t <span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>7 I# Y& f% Q* D
<span class="kw2">%global</span> names_agg; <br>
O i; P# ~ D& T3 i& k f <span class="kw2">%let</span> names_agg = ; <br>
! w! D2 P$ @' a7 {" ^ <span class="re1">proc sql</span> noprint;<br>
' W! Z! L2 j+ o2 a <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>2 a- X! u% x$ X2 u; v
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br> |3 r8 b9 n7 _- `% d }7 {
<span class="kw6">quit</span>;<br>" V, E1 [# N7 k; E& m; u- z
<span class="kw2">%mend</span>;<br>' r [- g) |8 m4 U* J/ o, u M" |
<br>
" U. r C+ m+ {7 O3 Y4 } %<span class="coMULTI">*-- just checking --*;</span><br>
: T4 D _/ R( x %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>, u1 s' Y% y- z: h/ S6 v8 c" u2 L
%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# I% z8 ?7 t* D+ G: @ %one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
2 H3 m+ s# G4 V+ i %<span class="coMULTI">*-- on log<br>$ P) |. c" q5 E, o
names_agg=a_agg c_agg<br>
6 `) i W# P% r: u names_agg=<br>
" l. r8 n0 b9 w+ `: @7 J; C names_agg=b_agg<br>
* f9 T; P8 _: k+ @ p3 ]( v --*;</span><br>, Q& O+ W! T2 @+ w. M0 X% a
<br>
( _6 `6 @7 c7 N8 L1 H' @2 j <span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
1 z2 x8 A3 W2 c1 P <span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
7 h' F* E" U& z5 v* S) s& C" H* ~ <span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
8 G7 h4 \. N/ m0 P( d8 d$ v" G# ` <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>3 V: @4 v6 F; E+ e! r% {6 t/ s
<span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>! I/ Z1 G0 N, Y$ e3 G
<span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>0 g. r6 ~" W. o& o4 i
<span class="kw6">run</span>;<br>" m6 B) s9 r" V, g
<span class="kw2">%end</span>;<br>8 U5 `. l! T" I3 A, G
<span class="kw2">%mend</span>;<br>
H6 Q/ M( D; ?3 M! l! A: c+ k<br>
' N0 V6 Q: K6 n9 L3 V <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>; R" W7 P* H9 n% Y" I
<span class="kw3">length</span> code $200;<br>
1 E% K' N* |6 _* `! M <span class="kw4">set</span> meta_table;<br>
4 O. J0 y# w5 K* } code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
+ t2 O6 u, h& M8 E+ k/ q8 a code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>5 a7 x( L+ m7 J0 ^
code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>; f$ B& F# H5 |
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
; v# Q' z2 ?% p8 _1 p* `. |0 T5 r8 s <span class="kw6">run</span>;<br>. T+ U/ J% y& ^8 y6 i/ D7 h' O2 E
<br>
9 d B! [' y' B& ] <span class="coMULTI">/* check */</span><br>
5 L) o9 o/ z1 w' o4 n <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 O5 q) s1 R2 Q <span class="coMULTI">/* on lst<br>
?$ H. L! J N8 ^ ot1<br>% l- T8 v$ y+ V: C- i5 \+ l2 }4 p9 [
Obs v<br>& g- V9 g1 A: w$ V" P: ?
1 a_agg<br>
; ?. k0 t; X( H) E% B% Z! y% B- y 2 c_agg<br>
1 P9 G' I+ h7 M S8 `9 q */</span><br>! M8 f/ g$ _) N/ S0 c: |
<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>& Z; P( C* H5 y3 i* I5 W5 s- n
<span class="coMULTI">/* on log<br>9 i6 V5 @! _; W+ ?
NOTE: No variables in data set WORK.OT2.<br>
0 y9 v5 ]2 P, M; M */</span><br>3 y' S; ~. d" e% b3 }' T
<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>5 O- S9 B! v3 c. i
<span class="coMULTI">/* on lst<br>
$ f/ |0 ^ u! T6 A ot_<br>
8 ~& l( [3 y: W3 X( G Obs v<br>' E! x. v8 g4 ^# Q* W7 o( ?; O
1 b_agg<br>) o8 \0 N- \% M+ J6 i
*/</span></div></td></tr></tbody></table></div>( g( _4 k; b' [1 O
<hr>; M( W+ S) ]2 `0 I: [3 t3 j3 ]
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>' S" Q; ?' X( q2 ^8 O$ [6 J8 j
<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>
6 a$ ^. w4 q* } <span class="kw3">length</span> code $32767;<br>3 a4 `2 D% Z4 a+ E- f
<span class="kw4">set</span> meta_table;<br>' d: w: h. U6 M* 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>/ l1 I% Q4 P9 q' o* A5 \- o
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>( _. u& E1 q1 |
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>. f. v2 x$ u- O d. x h
<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
6 ^2 {! Y* e$ }" e! z1 W. X$ C<hr>
7 x) b, m* n, j<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>+ z S7 j- a7 |: r
<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>$ @) S/ d- l+ r
<span class="re1">proc sql</span> noprint;<br>
. N1 N7 I0 i2 b$ ~% Q2 J <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
5 d' A9 n: [( t) ]1 T <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
: X3 ]( ?5 G2 i1 w4 z <span class="kw4">from</span> dataset<br>
3 l7 k5 p% ` V2 z; H/ Z <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
3 O- Z' B# j; J! L <span class="kw6">quit</span>;<br>, d; r2 T( |( [% t
<span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>4 S3 k- ]" n+ F, f9 M) _
<span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
! e% T! V' V1 y) z <span class="kw6">run</span>;<br>
2 t4 e5 v) N' A" Q3 r% ?<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
6 k3 [: }/ w5 P% s4 K: O g<p></p><center> <script src="/c2.js"></script></center><p></p>( N; ?- l! q( h" _8 s% n
<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
% _! V4 d9 {! a. K<ul>
8 J6 X8 }7 K4 }/ t) ~. x+ R1 G<li>- I) ?) ?% W! V3 @7 F; f
在调用执行方法之外按顺序运行宏?
* G7 }0 N6 p# T</li>
+ t0 o' [- `% j2 x( Y6 H# r3 m<li>6 l# T* a+ n4 }9 Z" y
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
- d# t8 g: y1 m+ S) @</li>& l; H: P% U: Y# C7 k
<li>8 Y3 z* y! Q1 `5 e! z4 d
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
* J$ [$ I5 I3 |( Q- J& h</li>
7 v" o- p c' v t/ t% |</ul>
3 @6 K7 M' Y8 y# }% N: ~<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>/ O8 Y& p/ N$ {+ A
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
/ j! ?! z& W( ]! K6 b<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
" w% F0 N% q3 }( n4 B! E. z<div class="suo-content"><div style="text-align: right;">2 n# h+ D# c7 ?, c( \$ {! s
<div class="xControl"><i class="fa fa-caret-right"></i>
, P2 z4 ]4 u) Y L) h <span class="xTitle"></span>
. T* z6 @5 P; F$ m3 l& A; ? 相关讨论
4 u4 @5 q7 a7 F <div style="clear: both;"></div>
. f! u8 d+ j* F. v5 z; N5 c0 r$ q2 k </div>" g; e# f4 _7 C# [
<div class="xContent" style="display: none;"><p></p>
9 S& X! Y& K. [6 @0 A<ul>
: [, V7 y1 h; y2 G) e( F<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
$ \# s1 }# p( }</ul>
0 i8 N. U% B, Z p' G' g<p></p></div>/ ?9 g3 p! M/ b! P% r
</div><p></p></div>& I: i6 \, O3 Q2 ?2 I
<hr></div> |
|