飞雪团队

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

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

[复制链接]

8242

主题

8330

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
27056
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<h2>Macro variables issue when using call execute</h2>& q# W' f7 e& S( m0 X/ @$ a
<div id="fc">
& d0 o# J7 r! B  ~: s0 s  ~<p></p><center> <script src="/c1.js"></script></center><p></p>$ Y- k* q6 i. j  o& m$ t
<p>我在下面有 2 个宏,我正在尝试像使用元数据表的循环一样依次执行 1,并在数据步骤中调用执行命令。</p>5 Y# K7 B4 ]( U" n
<p>macro %TWO 需要全局变量</p>  E9 A6 x+ ~" i
<hr>
, _: d. r7 {+ q  N4 ^( L) }1 v- V<p>您可以使用 <wyn>%nrstr()</wyn> 延迟宏调用,然后它就可以正常工作了。</p>
# Z0 _0 ]1 m9 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>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>
3 B; V! |( M: d* B6 P&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
  j* V' v3 d/ P5 p" i, b&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
' ~6 B% b* T$ F3 _) q8 y' }9 c1 ^&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
# a: S5 w8 a) W& F6 N" U&nbsp; &nbsp; &nbsp;name=<span class="st0">"c"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>- S( E, j0 \9 Q/ P) w3 ]4 Z
&nbsp; &nbsp;<span class="kw6">run</span>;<br>& {9 g! _9 \4 |# l% \& x+ P' R
<br>; x5 x: ?- x! A# I) Z" ?
&nbsp; &nbsp;<span class="kw6">data</span> a_agg; v=<span class="st0">"a_agg"</span>; <span class="kw6">run</span>;<br>
' `  f: n% `# I8 V- J" \  F&nbsp; &nbsp;<span class="kw6">data</span> b_agg; v=<span class="st0">"b_agg"</span>; <span class="kw6">run</span>;<br>
8 o. f, B% N9 U% E5 p8 s&nbsp; &nbsp;<span class="kw6">data</span> c_agg; v=<span class="st0">"c_agg"</span>; <span class="kw6">run</span>;<br>0 m$ L6 G8 z% p$ i; F2 q
<br>
) a& L4 q- k! I' ?0 x+ z& \4 w&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>/ g# o- S/ h( J, L! d. N
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>
2 _5 s' P3 d% P) W/ v2 P) [&nbsp; &nbsp; &nbsp;condition=<span class="st0">"2"</span>; name_ot=<span class="st0">"ot2"</span>; <span class="kw4">output</span>;<br>& l" h$ [# S8 a, m% }
&nbsp; &nbsp; &nbsp;condition=<span class="st0">""</span>; name_ot=<span class="st0">"ot_"</span>; <span class="kw4">output</span>;<br>
% ~2 x2 y! l6 w+ B0 K6 O7 T&nbsp; &nbsp;<span class="kw6">run</span>;<br>4 t! @5 d4 o8 v4 Y' S
<br>
* ~0 b& N* Z6 [&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>
; P. ?6 _1 N" w+ Z: W&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
. V1 q3 \& x" V$ s+ C; W&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>
/ X3 P3 d# m1 I' ~# }6 U&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>$ c! Y4 h1 A8 T* j& G( u( }3 c- {  F: I' T
&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>, i! u1 U+ o! x0 `
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>2 X$ R  O, b0 u: K2 k. x# H& s
&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>
9 Z2 {) @6 T6 z&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
+ O7 l, i9 `: t7 k' U: R& S<br>8 d4 r; H4 H* Y0 B4 ~6 n
&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>0 N& H" N; |. a" \4 W3 G! U
&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>
' E+ K3 k( B$ u2 R, z- y+ 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>& o; n; e8 h+ a7 d  p9 Y* T
&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>
4 ~' E, W1 S! W+ ~0 f&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>
& f; K9 k" m, u6 d  v/ k% B&nbsp; &nbsp;names_agg=a_agg c_agg<br>
2 v* M/ a: N- w2 ~4 j, o&nbsp; &nbsp;names_agg=<br>
) ]7 h* X* n/ ?' D&nbsp; &nbsp;names_agg=b_agg<br>
+ o( y/ `0 K9 j8 H; w: u( o# `&nbsp; &nbsp;--*;</span><br>
8 V% g4 y9 y/ B! X9 K/ V. b<br>
0 Z( ~4 Z0 \4 k1 U  S2 ?&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>$ F* ?0 `: ]# F- i/ k" L) o
&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>
- a" h2 o! c9 K&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>
# h4 W; @9 S& y/ n: D* A+ v&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>; <span class="kw2">%else</span> <span class="kw2">%do</span>;<br># N( J1 E, P& p3 L( e' O# E+ @7 B
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>
8 n1 f. H. k0 h% F& @- g&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>' m, t; P% t) [# o; m. X; ?
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>+ b& A7 I6 c5 {& G; T6 d" M  ~
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>
! K2 z$ H4 {# l&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
, F. t3 |. H( a9 p( x/ o<br>" [" `# H7 _  \  u8 B; G. {
&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>
; @2 a+ M# w9 {1 \&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
7 X# A& G. `6 S( e&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>5 S4 N6 H: o% b: j3 ^. c' O1 O
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%one('</span>, condition,<span class="st0">")"</span><span class="br0">)</span>;<br>
! t% d! O) }' D. L6 i+ q! X&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>* e8 F4 N7 K3 f  e2 v1 A
&nbsp; &nbsp; &nbsp; code = catt<span class="br0">(</span><span class="st0">'%nrstr('</span>, code,<span class="st0">")"</span><span class="br0">)</span>;<br>
' p# s8 i6 d, ~1 Q/ ]* A&nbsp; &nbsp; &nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
8 J& Z7 ^$ H( `% e2 s&nbsp; &nbsp;<span class="kw6">run</span>;<br>
5 _6 @& f. `; l; K2 n( \<br>/ ~- [# p. M, k  Q: F
&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>( Q" g  \8 V2 q. E, Y  b- 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>! v" y4 E  k9 M% V/ [
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
! q  N2 Y3 h% V8 G% q  g% k, ^- x+ t* D&nbsp; &nbsp;ot1<br>+ a6 e/ w; f' B* r/ E( y
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
( s' I" ~! h& |8 |! c1 L&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>
& J4 J' `; f: \8 G! n  S6 p8 ^&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>
" |' B3 {2 T6 L& o5 u6 j&nbsp; &nbsp;*/</span><br>8 e% _& H) F9 U' k& j6 @$ [
&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>
% _& R6 X1 I- L5 V&nbsp; &nbsp;<span class="coMULTI">/* on log<br>
4 J5 v/ P% ^6 y) ~&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
) u2 j! [, x: }) r: B&nbsp; &nbsp;*/</span><br>, p- N& P6 [, @0 u" k6 ^0 B7 {
&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>
9 Q# k; L4 g  d0 Y&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>5 r, `  W3 b9 ^1 m
&nbsp; &nbsp;ot_<br>7 l  |0 E+ Y) q
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>
1 q- C8 c7 k& ]&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>$ t# N: U* ?* D# b
&nbsp; &nbsp;*/</span></div></td></tr></tbody></table></div>: V  i, a. {7 t
<hr>2 S& r7 ?! i  ^  `3 J
<p>您可能需要在数据步骤中将双引号更改为单引号,如下所示:</p>8 c. k1 R, X' _% f0 q; F5 y' r# r7 {
<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 d2 v8 U- Z8 s/ d- G1 o
&nbsp; <span class="kw3">length</span> code $32767;<br>
: h) N  l+ C, ^1 Z# q# G# K- h$ ?&nbsp; <span class="kw4">set</span> meta_table;<br>' n/ N( J0 @4 I: {7 P0 @. ?
&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>
0 Q5 G* M. Y! H8 ]0 F&nbsp; <span class="kw4">call</span> execute<span class="br0">(</span>code<span class="br0">)</span>;<br>
. V$ I, j$ ?9 r6 R) m" F- _1 G<span class="kw6">run</span>;</div></td></tr></tbody></table></div>
" R( l2 W; e9 ~) l# |7 |" p, U<p>现在宏处理器正在尝试解析第 3 行中的百分比符号。您可以通过使用单引号隐藏它们来阻止它这样做。</p>
1 T6 f- \# s& `, H; H6 x4 N* I<hr>/ h: @7 e. b& Q5 ?* g8 M$ r
<p>除非您已经为您发布的示例从宏中削减了很多,否则很难理解为什么要使用两个宏而不是一个宏来执行此操作(或者实际上为什么您\\ '会使用宏来做到这一点)像这样:</p>$ C' |" M1 w* x6 j* Y
<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>) \* e9 D- h5 _' S( h3 V# M
&nbsp; <span class="re1">proc sql</span> noprint;<br>
/ i  {# o3 ?5 R! R8 F; m&nbsp; &nbsp; <span class="kw4">select</span> cats<span class="br0">(</span>name,<span class="st0">"_agg"</span><span class="br0">)</span><br>
+ E% ]4 J/ m( t/ \9 m5 w&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
  h1 D5 T8 D' N3 [5 Q&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>: D% B' b, J7 e5 F, M7 [
&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>0 j. F, D: e+ g1 p
&nbsp; <span class="kw6">quit</span>;<br>, t; f( e5 ]; Z+ M! J
&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>
4 ?; z6 g$ F: P2 ]' T) L" D&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>
# S8 ?2 _+ x- W( T&nbsp; <span class="kw6">run</span>;<br>, c2 r; u7 A+ g) _6 P1 J
<span class="kw2">%mend</span>;</div></td></tr></tbody></table></div>
! m. L, p5 |2 |4 m+ ^7 h<p></p><center> <script src="/c2.js"></script></center><p></p>
, j  a" r1 L$ n( o' R# a<p>无论如何,关于调用之间的宏变量发生了什么等问题,你尝试过吗</p>
( _% W0 O0 |% l2 ~<ul>' m; A( m# ]5 P; {  q1 q5 c3 m
<li>$ M$ D& s6 I/ I0 @/ G0 G* C
在调用执行方法之外按顺序运行宏?5 W; R3 b/ s! o9 [3 l: {# C9 R
</li>  _$ r' i3 U( Q
<li>
) a- o  K2 B6 ?/ W1 Q! h* }! @; ]; @% N在执行之前设置 <wyn>options mprint mlogic symbolgen;</wyn> 以查看日志中的调试信息?) l; r, i. H7 T6 t7 s9 i- B
</li>
0 w) @! T( [# W( g  I! x<li>/ ]% w1 {5 t/ [
在您的宏中使用一些 <wyn>%put</wyn> 语句,并在您的 <wyn>call execute</wyn> 数据步中使用 <wyn>put</wyn> 语句,以便查看在各个点生成了什么?
! z( i: l5 v2 D5 s# D# x& Z</li>
7 O- L: i) P, ~5 k& X</ul>
& A( s) [3 ?5 ]9 f+ Y7 I<p>建议在开发宏应用程序时首先让代码运行而不使用宏,然后添加宏变量并显式 <wyn>%let</wyn>-ting 其值,然后在宏的上下文中对其进行测试。之后将移至 <wyn>call execute</wyn>。</p>. y: g  ?5 n$ \4 j8 j% ~6 H
<p>也许尝试以上几点,然后返回一些我们可以调试的日志输出。您发布的代码中还有一些其他错误/问题,但我没有指出它们,而是假设您正在将其缩减为 SO 帖子。</p>
0 U3 M6 D$ m4 A" m/ Y<p>顺便说一句,我喜欢使用 <wyn>data _null_</wyn> 和 <wyn>call execute</wyn> 驱动数据驱动代码的想法,我经常使用这种方法。</p>* G3 Q$ Y/ m! L3 H& {* ~; x
<div class="suo-content"><div style="text-align: right;">8 J1 X, S" V, N- f( D
                <div class="xControl"><i class="fa fa-caret-right"></i>
' m% O* ]  S/ S0 H* Z9 S* u" Y                        <span class="xTitle"></span>
4 P8 w. R: L$ O, ~4 R                        相关讨论0 Y5 o$ c, h; g6 t2 J; ]0 T
                        <div style="clear: both;"></div>$ N* h( i- ?! Y3 n$ g- T, q* H0 b
                </div>& ~, n1 ], q3 I" p7 e
                <div class="xContent" style="display: none;"><p></p>7 N, ]) T. h  L' W
<ul>2 F* d* ~& e* K7 M
<li>嗨 sasfrog,我最初确实使用了一个宏,该宏在正常运行宏时起作用,但在调用内部执行</li>/ y- g& }% v+ B/ z
</ul>( Y! g7 L0 W# y  S  p
<p></p></div>% J* g% w" y$ F# L0 q$ o8 l% N& w
        </div><p></p></div>& T: ?9 y) Y' M8 L8 F* \
<hr></div>
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2026-2-27 08:36 , Processed in 0.069847 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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