飞雪团队

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 10276|回复: 0

关于sas:使用调用执行时的宏变量问题

[复制链接]

8915

主题

9003

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
29075
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<h2>Macro variables issue when using call execute</h2>
! B+ w0 a) K2 {" U/ S- q6 I<div id="fc">
; O* O9 c: a1 d5 ~4 Q4 i1 B2 i* _<p></p><center> <script src="/c1.js"></script></center><p></p>" @" h1 P- E3 z7 K! F
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>1 X4 x5 t0 E( ~- U& ~7 I
<p>macro %TWO 需要全局变量</p>% `, {6 p) u& [7 p7 f; o& o
<hr>0 ^. t% d' G* D; w+ t  L& f# e
<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>: R- x, d4 d) a7 p1 [) q$ {
<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">&nbsp; &nbsp;<span class="coMULTI">/* test data */</span><br>! L5 [$ D( m# c1 L5 L
&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
3 @* j$ J/ i0 s6 y- d( L&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
1 @' v3 y% o4 V8 l&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
3 X* ^* F. ^& e' {+ M  j0 r&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
9 b8 k6 y' p& L6 c  U&nbsp; &nbsp;<span class="kw6">run</span>;<br>: m& ^+ b% ~) y7 o. k
<br>3 F3 R3 [4 v0 e/ [( f2 z. @
&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>% g1 j( Q' A' U( O, l$ X' a& x
&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
) ]4 D, h8 E( Y&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>) T$ j) d8 }2 s5 H  z
<br>
9 t( F3 g% b% R. x8 `! q% t&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>
+ E$ e" h7 @3 k7 F  [&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
& R% m, }3 H4 K7 U' R) m&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>' [  p* r+ e# g: Z% n; b$ S3 _
&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>% I  ^8 a4 ?' q- O" k& N
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
, z: r) L1 {! t! t<br>. M/ J* h, F0 l# I" z. @/ B3 ~
&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>* v* h, j9 h: ^$ C1 a/ R& Q" ]" S( k
&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
7 j2 K; Q# C% F8 n$ L8 a&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>
7 T# M6 n, o/ b  Q1 c& r( w&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>  Z! p" C, Z0 W" h8 B
&nbsp; &nbsp; &nbsp; &nbsp;<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>" D! l1 i, g6 t/ g0 E+ f5 D  E
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>
# v" v5 J$ R  e- h, m2 j. N&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>/ b) C7 f" v8 b# N: C' w' W" [: G
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
3 {8 ]& s+ T% j# f7 A5 O+ K+ q<br>7 K! B8 B. B3 r( [* `, Y
&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>
) I, D' Q# L# m, {) k9 `&nbsp; &nbsp;%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">&amp;names_agg</span>;<br>
# X9 S9 v; D9 B$ Q2 l1 D&nbsp; &nbsp;%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">&amp;names_agg</span>;<br>' h% i& p0 i) Q
&nbsp; &nbsp;%one<span class="br0">(</span>condition= <span class="br0">)</span> <span class="kw2">%put</span> names_agg=<span class="re0">&amp;names_agg</span>;<br>
1 X# }4 b2 Z% |- F&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>" L% X/ }( j. P/ z3 g' ~
&nbsp; &nbsp;names_agg=a_agg c_agg<br>9 j$ T, c% ^8 F, x' m- v6 j; z
&nbsp; &nbsp;names_agg=<br>
8 J% H, ]' E7 ^( O; Y. F0 {" j&nbsp; &nbsp;names_agg=b_agg<br>
3 ?, f: A. W7 C8 W0 D&nbsp; &nbsp;--*;</span><br>8 g& o& F- n/ `+ u7 y' n& J) O
<br>/ V4 a9 x' K6 S$ n1 P. D* P
&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>: e0 V/ a" `% ]% ?0 F
&nbsp; &nbsp; &nbsp;<span class="kw2">%if</span> <span class="re0">&amp;names_agg</span>= <span class="kw2">%then</span> <span class="kw2">%do</span>;<br>
1 W0 N3 j; D! |0 v&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>, B0 U+ a4 z( |' E6 k
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>. \  E; |6 ?" N% Y2 ^. L; @% M
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
! U5 f6 Q9 ^9 D$ v9 _&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>
) p) ]* a' X1 q& P&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>$ n* s$ o1 y& B4 m/ ]  K6 V
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
' o8 B0 ~( f& o9 u% y8 V# r&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>: _: G" y# q, c" p2 B
<br>8 o% t4 Z$ d1 g( E3 z& h; A
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
1 {  Q) W) _$ C& S&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
" y5 N- l' L3 y6 c&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>
! c8 A- e/ |: g9 F&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
) E1 m* ^" B- h& L4 H&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span>code, <span class="st0">'%two('</span>, name_ot,<span class="st0">")"</span><span class="br0">)</span>;<br>
- |  W: ]" K1 ?( o" j&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>' Q5 b" p9 f! F' y4 I& S; T+ t$ b
&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>4 g! M+ L* A+ ?0 |* F5 h& s6 M
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
& A- F' d; h0 E" s<br>/ f, r7 M6 T- U8 n! y1 ~, M; X6 ~
&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>
* c0 F" C! G( ~) M$ S&nbsp; &nbsp;<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>
( O! n/ A" E& k&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
+ a/ g! b3 ?+ f5 s! @&nbsp; &nbsp;ot1<br>
9 N7 B$ p( e, p&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>* ~8 f; U+ s  k8 {6 q1 c" m' S
&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>
7 P# z3 O5 |: b. {/ B&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>) y; [  S* X) a* J% C  S6 `
&nbsp; &nbsp;*/</span><br>
% W7 g6 K! q) u' P/ t1 f&nbsp; &nbsp;<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>
* h$ A2 w) x# m8 t5 Y. _&nbsp; &nbsp;<span class="coMULTI">/* on log<br>9 A0 t" w8 K4 M/ G  G2 y& G/ U. ?! d
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>; `4 {' k6 Z- S, w$ s
&nbsp; &nbsp;*/</span><br>3 _( r* B$ l% z' k! \$ C/ L, O
&nbsp; &nbsp;<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>  y% {" W! V! i  v9 r9 |8 q
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
- b  Y6 J' q/ E  {&nbsp; &nbsp;ot_<br>
* c% r. Z3 L+ [) m&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>5 a, t! Y- d6 |2 x
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>6 f* x1 C$ X9 t5 L5 Q5 i  a6 D( c5 {% i
&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>4 v7 A; F5 d! G9 \# z' \$ `
<hr>
7 t) C' k1 ]0 z$ Y- N% F: }<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>
2 q& i/ ~2 t2 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>/ o, h# z# o7 X
&nbsp; <span class="kw3">length</span> code $32767;<br>
6 {9 c6 J2 {' N1 @" X% T6 H&nbsp; <span class="kw4">set</span> meta_table;<br>' w) v& L3 Q4 @& D
&nbsp; 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 A& g3 f* w  ]; M( J) |  o* y
&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>' O- [6 e& r1 {
<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
6 |: S* ^/ O! @- a7 Y6 h<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>- ]' q2 H- R' v
<hr>' O- t5 G0 g8 G! O# k; e1 B
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>; k6 ?, e0 u0 \( 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>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>. |! a8 I, P2 U: o
&nbsp; <span class="re1">proc sql</span> noprint;<br>6 n. |; z3 K" p0 X" s: [
&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>( y( e' K% B: y! \, ~% `# o
&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
0 @: k& y- j+ u- p' B7 }/ Q&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>
" ~* X  V6 {* ~, p9 \- B; c&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>- {( m' t6 u9 s0 }
&nbsp; <span class="kw6">quit</span>;<br>
3 g/ O5 B# i4 A& m&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>
0 O& J- y, v2 S9 y, y$ O. ?3 S6 }&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>
6 P( |( p# l" J" O3 H8 r&nbsp; <span class="kw6">run</span>;<br>! ^9 e* X9 U4 W* B
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>' A# f* a9 d- j  q1 N
<p></p><center> <script src="/c2.js"></script></center><p></p>
* W! m! r, c2 W/ |<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
9 ?  S, ~4 h  q2 k3 t  r<ul>! i* \# D3 p3 s0 }4 R( \+ p8 n! {
<li>$ }7 L9 L3 c2 ^8 \; D6 G8 n: K
在调用执行方法之外按顺序运行宏?* N2 _  \/ y; |/ A7 s
</li>+ i9 q1 A5 n* l& r* [+ M6 Z- {. ]
<li>+ a. A5 \( P/ p
在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?
" H% y! C# S: o4 w</li>
! V) p: x+ [2 b# @; `<li>% \' c3 U" T/ v1 z$ P
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?! ?. X0 z3 C: t; ?2 [
</li>1 O" J, P! x' t: ]8 q
</ul>7 o7 c; S* @. _; _( a$ {+ r4 s0 T) i3 q
<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>: t  Y: o" o' n' k' J# k: A( P
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
( I* A+ K  L7 l, i" ~  X. x3 r! f  x<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>
, `' K& J' z3 Z# _2 [8 W<div class="suo-content"><div style="text-align: right;">: N( {8 |* V7 H5 {
                <div class="xControl"><i class="fa fa-caret-right"></i>
4 a$ r2 [2 [) n( v( |                        <span class="xTitle"></span>
3 `8 p2 J- p* O  w* c% E$ o                        相关讨论
( K9 x1 J9 b" S4 \  A! }4 j8 D% u                        <div style="clear: both;"></div>
! v- I$ v  ]7 F                </div>6 K, ?! z8 F6 l
                <div class="xContent" style="display: none;"><p></p>
5 c' J0 s# @/ N- h2 ~1 r( v<ul>" x4 }6 t' _& n- i4 z
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>
8 J6 A- v$ ]0 q- J  _( X: l) O</ul>
5 E2 [0 H9 W$ I& R. V* X<p></p></div>8 H# [' @7 }( K; f" ^
        </div><p></p></div>
0 ?! ~  |; G- M& d<hr></div>
回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|飞雪团队

GMT+8, 2026-7-1 16:36 , Processed in 0.063127 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表