飞雪团队

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

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

[复制链接]

7735

主题

7823

帖子

2万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
25535
发表于 2022-2-12 18:06:13 | 显示全部楼层 |阅读模式
<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">&nbsp; &nbsp;<span class="coMULTI">/* test data */</span><br>% s* {: r" ]  J$ N# F7 K- Y+ A
&nbsp; &nbsp;<span class="kw6">data</span> dataset;<br>
# [8 ?) ]" ]$ s, v2 F* q" p&nbsp; &nbsp; &nbsp;name=<span class="st0">"a"</span>; condition=<span class="st0">"1"</span>; <span class="kw4">output</span>;<br>
5 b7 w" q- Y$ U&nbsp; &nbsp; &nbsp;name=<span class="st0">"b"</span>; condition=<span class="st0">""</span>; <span class="kw4">output</span>;<br>
( g& i2 o$ s' b&nbsp; &nbsp; &nbsp;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&nbsp; &nbsp;<span class="kw6">run</span>;<br>
! o% r, g* A. k' ^' [<br>' X# D& ~) C, X
&nbsp; &nbsp;<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
&nbsp; &nbsp;<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
&nbsp; &nbsp;<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&nbsp; &nbsp;<span class="kw6">data</span> meta_table;<br>. D8 c5 T3 l, D
&nbsp; &nbsp; &nbsp;condition=<span class="st0">"1"</span>; name_ot=<span class="st0">"ot1"</span>; <span class="kw4">output</span>;<br>% u, l: b6 U# D8 `
&nbsp; &nbsp; &nbsp;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
&nbsp; &nbsp; &nbsp;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
&nbsp; &nbsp;<span class="kw6">run</span>;<br>
2 _7 n( X% h; m" D5 p" [<br>
$ p9 @# i* A- ~8 V1 R8 w8 t&nbsp; &nbsp;<span class="kw2">%macro</span> one<span class="br0">(</span>condition<span class="br0">)</span>; <br>7 I# Y& f% Q* D
&nbsp; &nbsp; &nbsp;<span class="kw2">%global</span> names_agg; &nbsp;<br>
  O  i; P# ~  D& T3 i& k  f&nbsp; &nbsp; &nbsp;<span class="kw2">%let</span> names_agg = ; <br>
! w! D2 P$ @' a7 {" ^&nbsp; &nbsp; &nbsp;<span class="re1">proc sql</span> noprint;<br>
' W! Z! L2 j+ o2 a&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>2 a- X! u% x$ X2 u; v
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">from</span> dataset <span class="kw4">where</span> condition =<span class="st0">"&amp;condition."</span>;<br>  |3 r8 b9 n7 _- `% d  }7 {
&nbsp; &nbsp; &nbsp;<span class="kw6">quit</span>;<br>" V, E1 [# N7 k; E& m; u- z
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>' r  [- g) |8 m4 U* J/ o, u  M" |
<br>
" U. r  C+ m+ {7 O3 Y4 }&nbsp; &nbsp;%<span class="coMULTI">*-- just checking --*;</span><br>
: T4 D  _/ R( x&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>, u1 s' Y% y- z: h/ S6 v8 c" u2 L
&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>
' {) F# I% z8 ?7 t* D+ G: @&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>
2 H3 m+ s# G4 V+ i&nbsp; &nbsp;%<span class="coMULTI">*-- on log<br>$ P) |. c" q5 E, o
&nbsp; &nbsp;names_agg=a_agg c_agg<br>
6 `) i  W# P% r: u&nbsp; &nbsp;names_agg=<br>
" l. r8 n0 b9 w+ `: @7 J; C&nbsp; &nbsp;names_agg=b_agg<br>
* f9 T; P8 _: k+ @  p3 ]( v&nbsp; &nbsp;--*;</span><br>, Q& O+ W! T2 @+ w. M0 X% a
<br>
( _6 `6 @7 c7 N8 L1 H' @2 j&nbsp; &nbsp;<span class="kw2">%macro</span> two<span class="br0">(</span>name_ot<span class="br0">)</span>;<br>
1 z2 x8 A3 W2 c1 P&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>
7 h' F* E" U& z5 v* S) s& C" H* ~&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.; <span class="kw6">run</span>;<br>
8 G7 h4 \. N/ m0 P( d8 d$ v" G# `&nbsp; &nbsp; &nbsp;<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
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">data</span> <span class="re0">&amp;name_ot</span>.;<br>! I/ Z1 G0 N, Y$ e3 G
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw4">set</span> <span class="re0">&amp;names_agg</span>.;<br>0 g. r6 ~" W. o& o4 i
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw6">run</span>;<br>" m6 B) s9 r" V, g
&nbsp; &nbsp; &nbsp;<span class="kw2">%end</span>;<br>8 U5 `. l! T" I3 A, G
&nbsp; &nbsp;<span class="kw2">%mend</span>;<br>
  H6 Q/ M( D; ?3 M! l! A: c+ k<br>
' N0 V6 Q: K6 n9 L3 V&nbsp; <span class="kw6">data</span> <span class="kw1">_null_</span>;<br>; R" W7 P* H9 n% Y" I
&nbsp; &nbsp; &nbsp; <span class="kw3">length</span> code $200;<br>
1 E% K' N* |6 _* `! M&nbsp; &nbsp; &nbsp; <span class="kw4">set</span> meta_table;<br>
4 O. J0 y# w5 K* }&nbsp; &nbsp; &nbsp; 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&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>5 a7 x( L+ m7 J0 ^
&nbsp; &nbsp; &nbsp; 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 |
&nbsp; &nbsp; &nbsp; <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&nbsp; &nbsp;<span class="kw6">run</span>;<br>. T+ U/ J% y& ^8 y6 i/ D7 h' O2 E
<br>
9 d  B! [' y' B& ]&nbsp; &nbsp;<span class="coMULTI">/* check */</span><br>
5 L) o9 o/ z1 w' o4 n&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>
2 O5 q) s1 R2 Q&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
  ?$ H. L! J  N8 ^&nbsp; &nbsp;ot1<br>% l- T8 v$ y+ V: C- i5 \+ l2 }4 p9 [
&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>& g- V9 g1 A: w$ V" P: ?
&nbsp; &nbsp; 1 &nbsp; &nbsp; a_agg<br>
; ?. k0 t; X( H) E% B% Z! y% B- y&nbsp; &nbsp; 2 &nbsp; &nbsp; c_agg<br>
1 P9 G' I+ h7 M  S8 `9 q&nbsp; &nbsp;*/</span><br>! M8 f/ g$ _) N/ S0 c: |
&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>& Z; P( C* H5 y3 i* I5 W5 s- n
&nbsp; &nbsp;<span class="coMULTI">/* on log<br>9 i6 V5 @! _; W+ ?
&nbsp; &nbsp;NOTE: No variables in data set WORK.OT2.<br>
0 y9 v5 ]2 P, M; M&nbsp; &nbsp;*/</span><br>3 y' S; ~. d" e% b3 }' T
&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>5 O- S9 B! v3 c. i
&nbsp; &nbsp;<span class="coMULTI">/* on lst<br>
$ f/ |0 ^  u! T6 A&nbsp; &nbsp;ot_<br>
8 ~& l( [3 y: W3 X( G&nbsp; &nbsp;Obs &nbsp; &nbsp; &nbsp;v<br>' E! x. v8 g4 ^# Q* W7 o( ?; O
&nbsp; &nbsp; 1 &nbsp; &nbsp; b_agg<br>) o8 \0 N- \% M+ J6 i
&nbsp; &nbsp;*/</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* }&nbsp; <span class="kw3">length</span> code $32767;<br>3 a4 `2 D% Z4 a+ E- f
&nbsp; <span class="kw4">set</span> meta_table;<br>' d: w: h. U6 M* 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>/ l1 I% Q4 P9 q' o* A5 \- o
&nbsp; <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
&nbsp; <span class="re1">proc sql</span> noprint;<br>
. N1 N7 I0 i2 b$ ~% Q2 J&nbsp; &nbsp; <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&nbsp; &nbsp; <span class="kw4">into</span> :names_agg separated <span class="kw4">by</span><span class="st0">""</span><br>
: X3 ]( ?5 G2 i1 w4 z&nbsp; &nbsp; <span class="kw4">from</span> dataset<br>
3 l7 k5 p% `  V2 z; H/ Z&nbsp; &nbsp; <span class="kw4">where</span> condition=<span class="st0">"&amp;condition"</span>;<br>
3 O- Z' B# j; J! L&nbsp; <span class="kw6">quit</span>;<br>, d; r2 T( |( [% t
&nbsp; <span class="kw6">data</span> <span class="re0">&amp;name_OT</span>;<br>4 S3 k- ]" n+ F, f9 M) _
&nbsp; &nbsp; <span class="kw4">set</span> <span class="re0">&amp;names_agg</span>;<br>
! e% T! V' V1 y) z&nbsp; <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>
回复

使用道具 举报

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

本版积分规则

手机版|飞雪团队

GMT+8, 2025-11-1 13:46 , Processed in 0.071323 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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