BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
rkumar23
Calcite | Level 5

I really seems to be still learning these Macro...Could somebody please help :


I have two macros VDEVMAC and VDEVMAC1  ...Invoking VDEVMAC after passing values to it and then I have need to pass over the values/variables from it to VDEVMAC1 however it doesn't seems to be happening as the variable in VDEVMAC1 is Unresolved/uninitlized...

Here's my VDEVMAC program :

OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL MACROGEN;              

DATA _NULL_;                                                

%global thmvdev;                                            

%macro Vdevmac(THMVDEV=,THMVDEL=) ;                         

CALL SYMPUT('THMVDEV',TRIM(THMVDEV));                       

%PUT "VDEVMAC Program created the value of &THMVDEV" ;      

run;                                                        

%mend vdevmac;                                             

OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL MACROGEN;                      

%GLOBAL THMVDEV;                                                     

%macro Vdevmac1;                                                     

%PUT "VDEVMAC1 Program created the value of &THMVDEV" ;              

Data bvir_base;                                                      

    set pdb.bvir;                                                     

    attrib cluster  label='Cluster*id'                              ; 

    attrib dlibseqn label='Dist Lib Seq num'                        ; 

    attrib glibseqn label='Grid Lib Seq num'                        ; 

    attrib machserl label='Machine Serial'                          ; 

    attrib vdevinst label='Virt Dev Installed'                      ; 

    attrib devmntav label='Avg Virt  Dev Mounted'                   ; 

    attrib devmntmx label='Max Virt  Dev Mounted'                   ; 

    attrib devavgdl label='Device Average Delay'                    ; 

    attrib devmaxdl label='Device Maximum Delay'                     ;

    attrib devintdl label='Device Interval Delay %'                 ; 

*   Thresh_Max_Vdev = 70;                                             

*   Thresh_Max_Vdel = 10 ;                                           

Date = datepart(startime) ;                                      

Time = timepart(startime) ;                                      

format date date7. time time5. ;                                 

machserl = substr(machserl,4,5) ;                                

%if devmntmx > &THMVDEV %then %do ;                              

              output bvir_base;                                   

                               %end;                              

%mend vdevmac1;                                                 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

Since you never actually call the macros, all your SAS system ever "sees" is

OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL MACROGEN;

DATA _NULL_;

OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL MACROGEN;

- keep your scopes in line (eg. if the DATA statement is outside a macro, the associated RUN should also be outside, and vice versa)

- the macro processor is a generator of program text, it does NOT execute any statements. In your second macro, you have a completely meaningless statement:

%if devmntmx > &THMVDEV %then %do ;                              

             output bvir_base;                                   

                              %end;

In case the condition is not met, no output statement is generated. In that case, the data step will always output to the dataset named in the DATA statement, which also is bvir_base!

But the condition will always be met, because the letter "d" is always higher in the collating sequence than any number.

You most probably do not need the second macro at all, just do a standard data step comparison of devmntmx to &THMVDEV

What you wanted to do looks like this to me:

%let THMVDEV=any value that you want to test for;

Data bvir_base;                                                      

    set pdb.bvir;

    where devmntmx > &THMVDEV;

    attrib cluster  label='Cluster*id'                              ; 

    attrib dlibseqn label='Dist Lib Seq num'                        ; 

    attrib glibseqn label='Grid Lib Seq num'                        ; 

    attrib machserl label='Machine Serial'                          ; 

    attrib vdevinst label='Virt Dev Installed'                      ; 

    attrib devmntav label='Avg Virt  Dev Mounted'                   ; 

    attrib devmntmx label='Max Virt  Dev Mounted'                   ; 

    attrib devavgdl label='Device Average Delay'                    ; 

    attrib devmaxdl label='Device Maximum Delay'                     ;

    attrib devintdl label='Device Interval Delay %'                 ; 

*   Thresh_Max_Vdev = 70;                                             

*   Thresh_Max_Vdel = 10 ;                                           

Date = datepart(startime) ;                                      

Time = timepart(startime) ;                                      

format date date7. time time5. ;                                 

machserl = substr(machserl,4,5) ;                                

run;

View solution in original post

2 REPLIES 2
RW9
Diamond | Level 26 RW9
Diamond | Level 26

VdevmacThis bit of code is wrong is several senses:

DATA _NULL_;                                                

      %global thmvdev;                                            

      %macro Vdevmac(THMVDEV=,THMVDEL=) ;                         

      CALL SYMPUT('THMVDEV',TRIM(THMVDEV));                       

      %PUT "VDEVMAC Program created the value of &THMVDEV" ;      

run;                                                        

%mend vdevmac;                

You have a datastep overlapping a macro definition first.  A global statement with the datastep.  Further more I can't see any place where the Vdevmac is actually called.  I would advise looking again at what you are trying to achieve and maybe coming at it from there.

Kurt_Bremser
Super User

Since you never actually call the macros, all your SAS system ever "sees" is

OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL MACROGEN;

DATA _NULL_;

OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL MACROGEN;

- keep your scopes in line (eg. if the DATA statement is outside a macro, the associated RUN should also be outside, and vice versa)

- the macro processor is a generator of program text, it does NOT execute any statements. In your second macro, you have a completely meaningless statement:

%if devmntmx > &THMVDEV %then %do ;                              

             output bvir_base;                                   

                              %end;

In case the condition is not met, no output statement is generated. In that case, the data step will always output to the dataset named in the DATA statement, which also is bvir_base!

But the condition will always be met, because the letter "d" is always higher in the collating sequence than any number.

You most probably do not need the second macro at all, just do a standard data step comparison of devmntmx to &THMVDEV

What you wanted to do looks like this to me:

%let THMVDEV=any value that you want to test for;

Data bvir_base;                                                      

    set pdb.bvir;

    where devmntmx > &THMVDEV;

    attrib cluster  label='Cluster*id'                              ; 

    attrib dlibseqn label='Dist Lib Seq num'                        ; 

    attrib glibseqn label='Grid Lib Seq num'                        ; 

    attrib machserl label='Machine Serial'                          ; 

    attrib vdevinst label='Virt Dev Installed'                      ; 

    attrib devmntav label='Avg Virt  Dev Mounted'                   ; 

    attrib devmntmx label='Max Virt  Dev Mounted'                   ; 

    attrib devavgdl label='Device Average Delay'                    ; 

    attrib devmaxdl label='Device Maximum Delay'                     ;

    attrib devintdl label='Device Interval Delay %'                 ; 

*   Thresh_Max_Vdev = 70;                                             

*   Thresh_Max_Vdel = 10 ;                                           

Date = datepart(startime) ;                                      

Time = timepart(startime) ;                                      

format date date7. time time5. ;                                 

machserl = substr(machserl,4,5) ;                                

run;

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 2 replies
  • 849 views
  • 0 likes
  • 3 in conversation