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.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: 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.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: 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-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!

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
  • 2024 views
  • 2 likes
  • 5 in conversation