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

Hello everyone,

 

I have a question about macro. I try to print dataset sasuser.admit with name="Murray, W"; the name value can be replaced, for example, it can be "Murray, W" or "Almers, C" next time. I wrote a macro, but something is wrong. My code is following:

%macro output(name=);
title "print dataset with name: &name";
proc print data=sasuser.admit;
   where name  in ("&name");
run;
%mend output;

%macro output(name=%str(Murray, W))

But no result came out. Any suggestion? Furthermore, when name in ("Murray, W", "Almers, C"), how to do it? Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Probably best to just put the quotes into the values passed to the macro.  (Also do not include %MACRO when CALLING the macro as that is instead an attempt to re-create the macro).

%macro output(name=);
title "print dataset with name: " %sysfunc(quote(&name));
proc print data=admit;
   where name in (&name);
run;
%mend output;

%output(name="Murry. W")
%output(name="Murry. W" "Almers. C")

 

View solution in original post

17 REPLIES 17
ballardw
Super User

Show the Proc print that worked correctly without any macro variables.

Shmuel
Garnet | Level 18

Maybe the comma in the name makes an issue.

1) Please post few lines from your input using data step with infile statement

2) What do you mean by "But no result came out." ? 

    Are you sure there is a name "Murray, W" in the input? No case issue?
    Whole characters given?

3) You are comparing just one variable so you can replace in by = in the

    where statement

Astounding
PROC Star
Quoted characters in a WHERE comparison can be parsed incorrectly. Try:

where name in ("%unquote(&name)");
lc7033907
Obsidian | Level 7

Thanks for all help. Let me describe my question more clearly:

data admit;
  input ID $4. Name :&$14. @23 Sex $1. Age Date Height Weight Actlevel $4. Fee 7.2;
  datalines;
2458 Murry. W         M 27 1 72 168 HIGH 85.20
2462 Almers. C        F 34 3 66 152 HIGH 124.80
2501 Bonaventure, T   F 31 17 61 123 LOW 149.75
2523 Johnson, R       F 43 31 63 137 MOD 149.75
2539 LaMance, K       M 51 4 71 158 LOW 124.80
2544 Jones, M         M 29 6 76 193 HIGH 124.80
;
 
proc print data=admit;
where name="Murry. W";
title "print dataset with name: Murry. W";
run;

proc print data=admit;
where name in ("Murry. W", "Almers. C");
title "print dataset with name: Murry. W, Almers. C";
run;

I have a dataset, called admit, and i want to print some records with where statement. The value of name can be one, like the first proc print; the name value might be two, like second print. Now I want to write a macro to combine these two cases. My macro is in the following:

options symbolgen;
%macro output(name=);
title "print dataset with name: &name";
proc print data=admit;
   where name  in ("&name");
run;
%mend output;

%macro output(name=Murry. W)

But when I invoke the above macro, nothing comes out and even there is nothing showing up in LOG, so something must be wrong. Any suggestions? Thanks.

Shmuel
Garnet | Level 18

You can use any of both next methods:

/*1*/
%let names = 'Murry. W'  'Almers. C';
proc print data=admit(where=(name in(&names))); 
run;

/*2*/
%macro output(name=);
	title "Print dataset for &name";
	proc print data=admit(where=(name in(&name))); 
	run;
%mend output;
%output(name='Murry. W'  'Almers. C');

Pay attention, names need be quoted with single quotes.

lc7033907
Obsidian | Level 7

Hello Shmuel, thanks. I tried your two ways and they both work perfect. One more thing, why do we need single quotation marks ' '? Could you please give me some explanation? Thanks.

Shmuel
Garnet | Level 18

@lc7033907 wrote:

Hello Shmuel, thanks. I tried your two ways and they both work perfect. One more thing, why do we need single quotation marks ' '? Could you please give me some explanation? Thanks.


Look at net line:

title "Print dataset for &name";

Suppose name is defined with double quotes, as "xxxxx" then above line will be interpreted as:

title "Print dataset for "xxxxx"";

which is erroneous. With single quotes it will show:.

title "Print dataset for 'xxxxx'";
Tom
Super User Tom
Super User

Or just let the QUOTE() function figure out how to handle any potential embedded quotes.

title %sysfunc(quote(Print dataset for &name));
lc7033907
Obsidian | Level 7

I see, thank you so much. I really appreciate.

Tom
Super User Tom
Super User

Probably best to just put the quotes into the values passed to the macro.  (Also do not include %MACRO when CALLING the macro as that is instead an attempt to re-create the macro).

%macro output(name=);
title "print dataset with name: " %sysfunc(quote(&name));
proc print data=admit;
   where name in (&name);
run;
%mend output;

%output(name="Murry. W")
%output(name="Murry. W" "Almers. C")

 

lc7033907
Obsidian | Level 7

Hello Tom, thanks. Your way also worked perfectly. But I know nothing about %sysfunc and %qsysfunc, could you explain them? Thank you very much.

 

Tom
Super User Tom
Super User

Read the documentation on sysfunc and quote.

Or just try it out.

151   %let list="A" "B" "C";
152
153   data _null_;
154     put &list ;
155     put %sysfunc(quote(&list));
156   run;

ABC
"A" "B" "C"

 

lc7033907
Obsidian | Level 7

Thank you, Tom. I see. %sysfunc(quote()) can keep macro values as what they are, including " " . I also tried just 

 put quote(&list);

but error occurs

1 "A" "B" "C"
---
22
76
ERROR 22-322: Syntax error, expecting one of the following: a name, arrayname, _ALL_, _CHARACTER_,
_CHAR_, _NUMERIC_.

ERROR 76-322: Syntax error, statement will be ignored.

 

It seems %sysfunc is needed in macro invocation when quoting something. Thanks.

Tom
Super User Tom
Super User

As the error message says you cannot just call a function in the middle of PUT statement. 

So this is invalid:

put quote(somevariable);

But if you call the MACRO function %SYSFUNC() then that will happen BEFORE the code is passed onto SAS to interpret. So code like this:

put %sysfunc(quote(&list));

Get's converted to 

put """A"" ""B"" ""C""";

Which will result in this being written by the data step.

"A" "B" "C"

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 17 replies
  • 1298 views
  • 7 likes
  • 5 in conversation