飞雪团队

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

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

[复制链接]

6379

主题

6467

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
21461
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<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">&nbsp; &nbsp;<span class="coMULTI">/* test data */</span><br>
& r( H' {3 V6 V9 M- A3 w&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
% r6 \& H+ S, x/ ^1 Z&nbsp; &nbsp; &nbsp;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&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>" @, }* _! ^, f% O! K' _, x
&nbsp; &nbsp; &nbsp;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&nbsp; &nbsp;<span class="kw6">run</span>;<br>6 O) L5 L3 o8 e+ t
<br>- y- u& X) Z. \" |' u  ?% O4 d
&nbsp; &nbsp;<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&nbsp; &nbsp;<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
&nbsp; &nbsp;<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&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>: `# T6 E" p; |0 d
&nbsp; &nbsp; &nbsp;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
&nbsp; &nbsp; &nbsp;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; }
&nbsp; &nbsp; &nbsp;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&nbsp; &nbsp;<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 ~
&nbsp; &nbsp;<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
&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>0 x9 B& U/ j9 g: G5 M8 \8 `) }
&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>
% T. F: f) N  s/ o&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>8 Z3 p* u( _* o% J& m$ u$ e
&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>8 _& b' ?- [: _0 X
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>
+ ~# |$ G! {7 u&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>
/ _5 A) u+ v# ^- O&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
# \# J: K/ \. y4 _! v, Z3 A: s<br>; v* m3 C4 ]6 j" f: S( u
&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>' Z4 ~0 M& B* e8 {2 c
&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>
  M6 k% N+ L. C" r$ K&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>
; b1 R. @% }8 E7 c&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>
( t7 j, C) K6 b7 b&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>
* W0 a/ z; o0 H' w6 F2 j2 v2 N8 D&nbsp; &nbsp;names_agg=a_agg c_agg<br>2 _/ F! |6 |. ]) |# h7 ^
&nbsp; &nbsp;names_agg=<br>
4 c+ P/ I" M' g/ r1 O6 V6 \% }&nbsp; &nbsp;names_agg=b_agg<br>5 [$ D# j) f# w# Y1 A! R5 k
&nbsp; &nbsp;--*;</span><br>+ Q4 n( V  x0 j# K3 e
<br>
" ~5 o& s, u4 P! o9 B9 U&nbsp; &nbsp;<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&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>
6 i, C3 \( o! [$ \" z- W, Y" B4 L&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>5 u# X$ U# U; E- I# e4 m
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br>* e) c% I, z4 x) L0 }
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
+ y9 N) b3 _# |0 g; ?6 b&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>4 q* B3 G  B9 N
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>8 D$ l5 `* {. R+ u! _
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
" ~8 k0 v7 T: a" K& W5 F&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>. T' V! [9 Y3 g& J
<br>5 r& F( g, k8 p+ i
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>" ^2 a0 Y3 S& |
&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
% {+ Y1 f+ t: J+ m6 [7 n  ^&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>: n+ d: ?* A9 t7 c- g6 T5 _3 {! _
&nbsp; &nbsp; &nbsp; 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 {/ ~
&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>! h: |! N0 s) z
&nbsp; &nbsp; &nbsp; 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&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
2 {9 [$ ]; L* o% i4 A5 S&nbsp; &nbsp;<span class="kw6">run</span>;<br>
0 O9 x% B6 ~- @+ G% t) p! u<br>
5 L3 j5 m! A4 o$ S&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>% p% A: ^' n7 C- F/ r
&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>% e. ]- R2 r  \! @/ C/ m
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>3 c# z. C. ~; `# i# S' j1 }
&nbsp; &nbsp;ot1<br>; H* \! n5 L; i0 }  V( p. T
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>8 \% @1 W7 R2 K& Z$ n( b' h2 t
&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>
3 E! @2 f( ~" W* l$ V) x# L; X&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>
: i) t6 |6 c8 p% M  X- m+ T&nbsp; &nbsp;*/</span><br>
7 b8 L* R! }4 S" Q, ?! K  A&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>5 j  H4 l5 ]# N6 B0 p; b. U; j
&nbsp; &nbsp;<span class="coMULTI">/* on log<br>8 C4 s* z1 ^9 i
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>7 {; Q" c2 m( Z( B; Q) D% v1 g0 F
&nbsp; &nbsp;*/</span><br>
; Y% f! s' l2 w&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>$ ^* o! G' A# q
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
+ @, \: J& _& y1 @* Q! V5 b6 q. x&nbsp; &nbsp;ot_<br>
5 g. Y! j+ O0 D) \2 L: A9 @8 q&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>. k9 I+ y, b: E! Z+ F& z7 {' _7 n
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>& p% g5 G+ C6 q; z6 ^# ^
&nbsp; &nbsp;*/</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&nbsp; <span class="kw3">length</span> code $32767;<br>
  I. P4 ?7 R8 `  r( a&nbsp; <span class="kw4">set</span> meta_table;<br>5 Z( J) n6 \$ L/ H3 x) b5 o
&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 R. n4 i# E5 Y1 h6 ~3 u! t5 d2 n2 ~&nbsp; <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
&nbsp; <span class="re1">proc sql</span> noprint;<br>
' U/ Y+ }5 |2 }3 \3 ]&nbsp; &nbsp; <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&nbsp; &nbsp; <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
&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>: o" u! T; j4 _" ]
&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>
/ E9 t7 ^0 N& Y: ?, _1 z; _&nbsp; <span class="kw6">quit</span>;<br>
' o6 `  _, W/ ~- g( v&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>+ ?5 b. ]$ }' s% Y# O+ i3 L0 O- J
&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>2 H& \! {# P# t) ]  d+ c# w
&nbsp; <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>
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-4-17 14:36 , Processed in 0.074491 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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