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

Hi, 

Please, could you help me regarding my program which doesn't work well. Thanks in advance.

 

I have this message on my Log which is contradictory:

ERROR: BE is an invalid country code
Valid country codes include
AT,AU,BE,CA,CH,CI,DE,DK,EG,ES,FI,FR,GB,GR,HR,IE,IL,IN,IT,LT,LU,MZ,NL,NO,NZ,PL,PT,SE,SI,TR,US,YU,ZA
103
104
105 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
115
 
My progrm code is below:

%macro customerlist(ctry)/minoperator;
%if %SUPERQ(ctry)= %then %do;
title "Customers from all countries";
proc sgplot data=mc1.customers noborder;
vbar Group / filltype=gradient stat=percent;
yaxis grid display=(noticks noline nolabel);
run;
%end;
%else %do;
  %let ctry=%upcase(&ctry);
     proc sql ;
     select distinct Country
     into :ctrylist separated by ','
     from mc1.customers;
    quit;

 %if %SUPERQ(ctry) in %SUPERQ(ctrylist) %then %do;
    title "Customers from &ctry";
    proc sgplot data=mc1.customers noborder;
    vbar Group / filltype=gradient stat=percent;
   yaxis grid display=(noticks noline nolabel);
   where Country="&ctry";
  run;
 %end;
%else %do;
     %put ERROR: &ctry is an invalid country code;
     %put ERROR- Valid country codes include &ctrylist;
%end;

%end;
%mend customerlist;

%customerlist(be)

 

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Your list of countries in CTRYLIST is delimited by commas.

 

If you want to use the IN operator in the macro language, it's probably a good practice to specify the delimiter in the macro definition, i.e.:

 

%macro customerlist(ctry)/minoperator mindelimiter=',' ;

If you don't specify the delimiter on the macro definition, you'll be at the mercy of whatever value is set for mindelimiter when the macro is called.  The default is a space, which would explain why your macro isn't working as you had hoped.

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.

View solution in original post

6 REPLIES 6
PaigeMiller
Diamond | Level 26

Please provide us the entire LOG for this macro (and in the future, always provide the entire LOG for the code in question, always, always, always). First turn on these options before you run the code.

 

options mprint mlogic symbolgen;

Then copy the log (all of it, every single line in the log from this macro, do no chop anything out of the log) and paste it into the window that appears when you click on the </> iconDO NOT SKIP THE INSTRUCTIONS IN RED.

--
Paige Miller
CorinneT
Obsidian | Level 7
Yes, it's a good tip regarding the "options mprinen ....."
I have to add it to monitor my macro program.
Thanks
ballardw
Super User

Syle note: Generally Error checks, like in the list go at the beginning of a macro, not after generating a bunch of procedure steps that could fail.

 

I see option minnoperator. How about Mindelimiter? Did you set that to comma?

Note: may want a different delimiter than comma as comma is used is many places in macro code and can easily lead to other hard to trace issues like "too many parameter" errors.

Quentin
Super User

Your list of countries in CTRYLIST is delimited by commas.

 

If you want to use the IN operator in the macro language, it's probably a good practice to specify the delimiter in the macro definition, i.e.:

 

%macro customerlist(ctry)/minoperator mindelimiter=',' ;

If you don't specify the delimiter on the macro definition, you'll be at the mercy of whatever value is set for mindelimiter when the macro is called.  The default is a space, which would explain why your macro isn't working as you had hoped.

The Boston Area SAS Users Group (BASUG) is hosting our in person SAS Blowout on Oct 18!
This full-day event in Cambridge, Mass features four presenters from SAS, presenting on a range of SAS 9 programming topics. Pre-registration by Oct 15 is required.
Full details and registration info at https://www.basug.org/events.
CorinneT
Obsidian | Level 7
Thank you so much, Quentin. It's the solution 🙂
with:
" mindelimiter=','"

Tom
Super User Tom
Super User

You added the MINOPERATOR option to make sure the macro supports the IN operator, but you did not tell it what character to use a the delimiter.

 

But you don't really need to use the IN operator in your macro code. 

Since you already had to run some SAS code just test the country code with the SAS code. SAS code is much easier to debug than macro code.

%macro customerlist(ctry);
%local ctrylist found ;
%if 0=%length(ctry) %then %let ctry=ALL;
%else ctry=%qupcase(&ctry);

%if &ctry = ALL %then %let found=1;
%else %do ;
  proc sql noprint;
    select distinct country
         , max(upcase(country)="&ctry")
      into :ctrylist separated by ' '
         , :found 
    ;
  quit;
%end;

%if not &found %then do;
   %put ERROR: &ctry is an invalid country code;
   %put ERROR- Valid country codes include &ctrylist;
%end;
%else %do;

TITLE "Customers from country: &ctry";

  proc sgplot data=mc1.customers noborder;
    vbar Group / filltype=gradient stat=percent;
    yaxis grid display=(noticks noline nolabel);
  %if &ctry ne ALL %then %do;
    where Country="&ctry";
  %end;
  run;
%end;
%mend customerlist;

%customerlist(be)

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Autotuning Deep Learning Models Using SAS

Follow along as SAS’ Robert Blanchard explains three aspects of autotuning in a deep learning context: globalized search, localized search and an in parallel method using SAS.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 6 replies
  • 2263 views
  • 2 likes
  • 5 in conversation