|
<h2>Macro variables issue when using call execute</h2>
/ J% w5 G2 X0 Y/ a1 m e+ z( \% h<div id="fc">( F/ ^& V, y% m6 I
<p></p><center> <script src="/c1.js"></script></center><p></p>0 i8 M' r) }4 h- ?: Y, T0 t+ z$ w7 [
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>4 O- j; {/ b( n; x: e( G
<p>macro %TWO 需要全局变量</p>
6 K+ R1 m3 m ^, C* n<hr>
: S( L- L1 v. j4 T3 ?# |<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>8 r+ V2 Z1 C" m8 G
<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># S8 p* C( `& ?3 I2 S
<span class="kw6">data</span> dataset;<br>
, z/ `- b& T" H, L$ k name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>! E) ]. o1 r$ D* e, j
name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
# w+ P, Z/ I1 X2 |, ` name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>5 S9 J4 Z) x9 w. S/ O, J! l' D
<span class="kw6">run</span>;<br>/ |: w @% @. p/ g: e& m; J' @7 W
<br>
$ j4 i6 q* D/ \( I: k* e <span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>) X: L5 `; @4 b5 j' q6 i
<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
/ @/ A9 h" C( C1 m <span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>4 @4 r' d. N/ P7 p) r y
<br>
, L, a0 Y# g- s- ^- p <span class="kw6">data</span> meta_table;<br>
6 K4 c9 Y: \8 Q9 i$ K0 l% P3 m condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>; v- z) J9 W3 a% i0 d
condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>7 g7 K8 m. N* d/ z! @% y6 r
condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>- ^/ i9 Q4 d& j. w. G; N
<span class="kw6">run</span>;<br>
0 M5 E4 `+ u0 m9 _<br>6 X8 U% l }. b6 o7 k) g& X. A
<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>9 b: K+ e) Z2 F
<span class="kw2">%global</span> names_agg; <br>
: K' ^: [* t/ R3 a <span class="kw2">%let</span> names_agg = ; <br>
% h+ z8 l% y" { <span class="re1">proc sql</span> noprint;<br>, w1 \: F+ ^. C
<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>* J, Y% T$ K+ X# Y! T. Q
<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&condition."</span>;<br>; N) |- h0 a! Y1 Y& P6 J$ N
<span class="kw6">quit</span>;<br>
# y2 V3 }7 f. \0 M, | <span class="kw2">%mend</span>;<br>, m: J7 D2 c/ l' A# x/ N
<br>
4 b1 u* M+ F9 y$ I3 }8 O %<span class="coMULTI">*-- just checking --*;</span><br>0 [: ^! O0 }0 {* x$ q8 D
%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>
, h6 y) s0 w4 w9 g %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>) B- C( T, Z; u* X' g* s
%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&names_agg</span>;<br>
- P9 M9 I, S, A ^9 } %<span class="coMULTI">*-- on log<br> I# I! c7 J0 `6 N4 }
names_agg=a_agg c_agg<br>: P6 |) N8 J' |2 |$ i! ^
names_agg=<br>
* Z1 Q8 J+ M9 d; D names_agg=b_agg<br>
2 T5 z8 o& l W1 D9 o6 `& _ --*;</span><br>- E' V4 D" [/ F& Z
<br>; Q% D) m6 z; x7 p3 G4 d' R4 D' N
<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>* }' p0 m9 c6 o! g: }- Y3 I
<span class="kw2">%if</span> <span class="re0">&names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>; F! @' \; P/ o* C& U. R
<span class="kw6">data</span> <span class="re0">&name_ot</span>.; <span class="kw6">run</span>;<br>
" T, R1 R6 b9 k* Y+ J# E <span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>
6 r3 J9 d u: [! b& K <span class="kw6">data</span> <span class="re0">&name_ot</span>.;<br>
8 t. B2 E/ o' Y" a8 ` <span class="kw4">set</span> <span class="re0">&names_agg</span>.;<br>+ o, n/ m4 M5 V+ N* Z ?
<span class="kw6">run</span>;<br># v* a; t( x. ^. p, }7 `
<span class="kw2">%end</span>;<br>4 ?) [' [* x1 w8 e
<span class="kw2">%mend</span>;<br>
" }$ H1 t( F) J<br>
& k7 i" A6 B# T2 O) q, G/ j <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>; F7 }( O# h+ C
<span class="kw3">length</span> code $200;<br>9 o8 T3 E$ z" d( {
<span class="kw4">set</span> meta_table;<br>
( q, e5 l" }8 D; W3 w/ w code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
: E' T* g5 x% p- i0 ~" V code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
. a1 u; v: ^& N9 H$ o+ k" ?5 V code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
/ u7 n* d& s: I' t <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>5 d5 G; f+ y* |9 T1 ^
<span class="kw6">run</span>;<br>3 r& W+ {8 k1 z( M7 `
<br>
0 O! Y* M5 o ?5 J/ s( {: h; A& [( f <span class="coMULTI">/* check */</span><br>
$ K& O2 t( R& y <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 |: w5 K" b9 i+ l2 J+ v( i
<span class="coMULTI">/* on lst<br>3 r9 ^9 S5 t3 n5 Q& r
ot1<br>
4 S+ V- c9 R5 b4 [# O2 m; s1 x Obs v<br>0 D+ X1 Z' b! c" }! y
1 a_agg<br># ?6 P! |: Y7 `% l$ k8 [" p7 J
2 c_agg<br>
9 z. [+ n) O$ ? */</span><br>/ P V b" p+ X& l# S
<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>
/ x4 q# d# ]. Z. O4 b <span class="coMULTI">/* on log<br>
: `7 M9 ?( D, g$ b NOTE: No variables in data set WORK.OT2.<br>7 c5 b! Q) Z( f& c( n# c8 o! B
*/</span><br>6 P3 s. G( L: w' o
<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>) R3 U# J6 G+ K* d3 i
<span class="coMULTI">/* on lst<br>
0 Z7 w4 ^8 r Q& a ot_<br>
/ C9 G$ p9 G3 f0 v6 t+ n Obs v<br>
2 ~+ o) `2 S. A4 [7 \2 R( C% E8 w: ~ 1 b_agg<br>
* B9 x: }$ |- }' S' `1 e' }" D */</span></div></td></tr></tbody></table></div>+ ?7 Q! ?% r' G3 g4 ]
<hr>4 J) Q( \+ \+ A0 Q( ~! a9 ~
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>/ q0 W5 S& O* X" k
<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>
$ V( o C) f; } <span class="kw3">length</span> code $32767;<br>( _! i& \6 K# H/ ]
<span class="kw4">set</span> meta_table;<br>
0 r% ^3 \; y8 c& K7 |4 X 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>& f4 o& A1 n+ g) i( [4 H* n
<span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>8 {2 S. D( ?; @* L
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
3 k9 O" S4 Q4 }; D- g) J. ^6 [' o<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>" T0 o% u( x2 d1 K
<hr>
( A" `7 n" W7 e" G6 ?: H! N0 A. i<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>4 P. H- r: D- |$ F$ 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>
: Z* @0 e8 u# F* y6 u. E: J <span class="re1">proc sql</span> noprint;<br>
# Q6 T+ N1 K* h* P <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>( E8 y% K. ~3 j* `% f/ a# [; B
<span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>2 M5 B% N9 @9 m0 \2 I
<span class="kw4">from</span> dataset<br>
1 ]! b( G. d+ s! T$ f# p2 W. \! c <span class="kw4">where</span> condition=<span class="st0">"&condition"</span>;<br>
: _1 [3 _$ G) [: ]: r% U( N b& ^ <span class="kw6">quit</span>;<br>
5 l7 b |5 v4 Y& n3 d( b4 \ <span class="kw6">data</span> <span class="re0">&name_OT</span>;<br>
0 j, \! _4 H# S) v <span class="kw4">set</span> <span class="re0">&names_agg</span>;<br>
' R& D7 R+ k7 _. m# b7 P <span class="kw6">run</span>;<br>
" k; ^( }; f$ N<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
. Z; f! C) a- D8 S+ l+ x0 S5 A# ^<p></p><center> <script src="/c2.js"></script></center><p></p>
! u- V0 _# k" D, i; L1 @- [2 i& Q4 n5 Y<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>6 |9 P8 K1 E7 I' M7 e
<ul>1 O l5 {0 n0 b6 R6 }( j
<li>
" w8 C0 M9 ?# R! t9 c5 M7 f( ]! X( a在调用执行方法之外按顺序运行宏?
3 j0 w+ M, l+ P* ?</li>
^8 [% U3 r! i6 m. s<li>
2 Y, D2 a" y3 y4 R$ t% e在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
: q- t3 D W& I) c* ?</li>* g9 |1 I0 I/ Z7 k0 ~: ~
<li>0 o" k5 m( E9 w9 }6 n9 _4 q
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?# M; _9 Z% d" u7 v) {
</li>
1 }, E: ^+ l1 ~; ^9 K2 p1 n1 ]% m</ul>. Z/ ~" M+ c/ `) P# c+ G
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>8 m; X3 }/ ^% g) l( N
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>) d1 s# p# U& K
<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p> w- N" R* l6 `" D
<div class="suo-content"><div style="text-align: right;">& a) w* Z# R' C: b% n& A$ ]1 O
<div class="xControl"><i class="fa fa-caret-right"></i>
' J, S9 v2 M* y" Y [9 j+ y) m. u# P <span class="xTitle"></span>7 ~6 n: S1 U3 {% m% E# E* _
相关讨论& u' n1 M5 Q5 X# H
<div style="clear: both;"></div>& ~! D: j7 b; w! G
</div> P; G0 [; \' O
<div class="xContent" style="display: none;"><p></p>% k8 c1 U( `- n/ W$ y
<ul>
4 d0 }3 \) H c! ]* I<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>$ m5 J- S/ H9 c* Y
</ul>
s$ s5 ^# U4 B6 O0 {<p></p></div>. M5 C- f+ h2 v. d% o+ M
</div><p></p></div>1 R3 ]2 b- u# M0 c5 Z
<hr></div> |
|